回到基础的这本书,进行回归的学习
线性模型
import numpy as np
import matplotlib.pyplot as plt
x = np.linspace(-5,5,100)
y = 0.5*x+3
plt.plot(x,y,c='orange')
plt.title('Straight Line')
plt.show()
import matplotlib.pyplot as plt
import numpy as np
from sklearn.linear_model import LinearRegression
X = [[1],[4]]
y = [3,5]
lr = LinearRegression().fit(X,y)
z = np.linspace(0,5,20)
plt.scatter(X,y,s=80)
plt.plot(z,lr.predict(z.reshape(-1,1)),c='k')
plt.title('Straight Line')
plt.show()
出现报错
TypeError: _linspace_dispatcher() missing 2 required positional arguments: 'start' and 'stop'
原因是
z = np.linspace(0,5,20)没有输入参数
两点确定一个直线,再增加一个点
X = [[1],[4],[3]] y = [3,5,3]
这次的直线位于1个和3个点的距离相加最小的位置。以数据集为例来进行大量数据的实验
import matplotlib.pyplot as plt
import numpy as np
from sklearn.linear_model import LinearRegression
from sklearn.datasets import make_regression
X,y=make_regression(n_samples=50,n_features=1,n_informative=1,noise=50,random_state=1)
reg = LinearRegression()
reg.fit(X,y)
z=np.linspace(-3,3,200).reshape(-1,1)
plt.scatter(X,y,c='b',s=60)
plt.plot(z,reg.predict(z),c='k')
plt.title('Linear Regression')
plt.show()
上课
线性回归---最基本的线性模型
原理:找到当前训练数据集中y的预测值和其真实值得平方差最小的时候,所对应的w值和b值。
train_test_split()函数:
随机划分训练集和测试集的函数
test_size,train_size:测试集大小,训练集大小
random_state:指定随机方式。一个整数或者RandomState实例,或者None 。如果为整数,则它指定了随机数生成器的种子;如果为RandomState实例,则指定了随机数生成器;如果为None,则使用默认的随机数生成器,随机选择一个种子。
LinearRegression()
fit_intercept:是否有截据,如果没有则直线过原点。
normalize:是否将数据归一化。
copy_X:默认为True,当为True时,X会被copied,否则X将会被覆写。
n_jobs:默认值为1。计算时使用的核数。
from sklearn.linear_model import LinearRegression
from sklearn.datasets import make_regression
from sklearn.model_selection import train_test_split
X,y = make_regression(n_samples=10,n_features=2,n_informative=2,random_state=38)
X_train,X_test,y_train,y_test = train_test_split(X,y,random_state=8)
lr = LinearRegression().fit(X_train,y_train)
print("lr.coef_:{}".format(lr.coef_[:]))
print("lr.intercept_:{}".format(lr.intercept_))
岭回归
岭回归实质上是一种能够避免过拟合的线型模型,模型会保留所有的特征变量,但是会缩小特征变量的系数值,让特征变量对预测结果的影响变小。实际上是一种改良的最小二乘法。通过改变alpha参数来控制减小特征变量系数的程度,称之为L2正则化。
from sklearn.linear_model import Ridge
rigde = Ridge().fit(X_train,y_train)
可以使用alpha参数控制模型,增加alpha的值会降低特征变量的系数,使其趋于0,从而降低在训练集的性能,但更有助于泛化。
提高alpha值之后可以看到模型的得分大幅度下降,说明可以提高alpha的值来处理过拟合现象,如果用一个很小的值,那么达到的结果也会非常接近线性回归。
接下来我们用图像来观察不同alpha值对应的模型的coef_属性,在较高的alpha值下,coef_属性的数值会更小.
from sklearn.datasets import load_diabetes
from sklearn.model_selection import train_test_split
from sklearn.linear_model import LinearRegression
from sklearn.linear_model import Ridge
from matplotlib import pyplot as plt
X,y = load_diabetes().data,load_diabetes().target
X_train,X_test,y_train,y_test = train_test_split(X,y,random_state=8)
lr = LinearRegression().fit(X_train,y_train)
ridge = Ridge().fit(X_train,y_train)
ridge10 = Ridge(alpha=10).fit(X_train,y_train)
ridge01 = Ridge(alpha=0.1).fit(X_train,y_train)
plt.plot(ridge.coef_,'s',label = 'Ridge alpha=1')
plt.plot(ridge10.coef_,'^',label = 'Ridge alpha=10')
plt.plot(ridge01.coef_,'v',label = 'Ridge alpha=0.1')
plt.plot(lr.coef_,'o',label='linear regression')
plt.xlabel("confficient index")
plt.ylabel("confficient magnitude")
plt.hlines(0,0,len(lr.coef_))
plt.legend()
plt.show()
横轴代表的是coef_属性,alpha越小,特征系数越大。
可以取一个固定的alpha的值,然后改变训练数据集的数据量,用这些子集对线性回归模型和alpha=1的领回归模型进行评估,其中的折线称为学习曲线。
import matplotlib.pyplot as plt
import numpy as np
from sklearn.linear_model import Ridge
from sklearn.model_selection import learning_curve,KFold
from sklearn.datasets import load_diabetes
from sklearn.model_selection import train_test_split
from sklearn.linear_model import LinearRegression
from sklearn.linear_model import Ridge
from matplotlib import pyplot as plt
def plot_learning_curve(est,X,y):
training_set_size,train_scores,test_scores = learning_curve(est,X,y,train_sizes=np.linspace(.1,1,20),cv=KFold(20,shuffle=True,random_state=1))
estimator_name = est.__class__.__name__
line = plt.plot(training_set_size,train_scores.mean(axis=1),'--',label="training"+estimator_name)
plt.plot(training_set_size,test_scores.mean(axis=1),'-',label="test"+estimator_name,c=line[0].get_color())
plt.xlabel('Training set size')
plt.ylabel('Score')
plt.ylim(0,1.1)
X,y = load_diabetes().data,load_diabetes().target
X_train,X_test,y_train,y_test = train_test_split(X,y,random_state=8)
lr = LinearRegression().fit(X_train,y_train)
ridge = Ridge().fit(X_train,y_train)
plot_learning_curve(Ridge(alpha=1),X,y)
plot_learning_curve(LinearRegression(),X,y)
plt.legend(loc=(0,1.05),ncol=2,fontsize=11)
plt.show()
在数据量小于50的情况下,线性回归几乎不能让机器学习学到任何东西
learning_curve()
在画训练集的曲线时:横轴为 train_sizes,纵轴为 train_scores_mean;
画测试集的曲线时:横轴为train_sizes,纵轴为test_scores_mean。
cv : int, 交叉验证生成器或可迭代的可选项,确定交叉验证拆分策略。
cv的可能输入是:
- 无,使用默认的3倍交叉验证,
- 整数,指定折叠数。
- 要用作交叉验证生成器的对象。
- 可迭代的yielding训练/测试分裂。
ShuffleSplit:它返回的是每组训练集与测试集的下标索引,由此可以知道哪些是train,那些是test。
ylim:定义绘制的最小和最大y值
n_jobs : 整数,可选并行运行的作业数(默认值为1)。windows开多线程需要在"__name__"==__main__中运行。
使用L1正则化的线性模型----套索回归
套索回归也会将系数限制在非常接近0的范围内,但它会有一部分特征的系数正好等于0,也就是说这些特征会被模型彻底忽略掉。
from sklearn.datasets import load_diabetes
from sklearn.model_selection import train_test_split
from sklearn.linear_model import Lasso
import numpy as np
X,y = load_diabetes().data,load_diabetes().target
X_train,X_test,y_train,y_test = train_test_split(X,y,random_state=8)
lasso = Lasso().fit(X_train,y_train)
print("训练:{:.2f}".format(lasso.score(X_train,y_train)))
print("测试:{:.2f}".format(lasso.score(X_test,y_test)))
print("使用特征数:{}".format(np.sum(lasso.coef_!=0)))
根据得分我们得知,模型法发生了欠拟合的问题,我们可以试着降低alpha的值,与此同时我们还要增加最大迭代次数(max_iter)的默认设置
lasso01 = Lasso(alpha=0.1,max_iter=100000).fit(X_train,y_train)
降低alpha的值可以拟合出更复杂的模型,从而在训练数据集和测试数据集都能获得良好的表现
接下来用图像 的方式来进行对比:
在实践中,岭回归往往是首选,但是如果特征值较多,而且只有一小部分是真正重要的,选择套索回归。