5 线性回归
Sklearn类的线性回归以sklearn.linear_model.LinearRegression为基础,以sklearn.linear_model.Ridge(岭回归)、sklearn.linear_model.Lasso(套索回归)和sklearn.linear_model.ElasticNet(弹性网络)为优化。
我们首先来看一下如何通过Python画一条直线。
画出y = 0.5 × x + 3的直线。
# 导入NumPy库 import numpy as np # 导入画图工具 import matplotlib.pyplot as plt def Line_base(): x = np.linspace(-5,5,100) y = 0.5 * x + 3 plt.plot(x,y,c='green') plt.title('Straight Line') plt.show()
画出经过[2,3]和[3,4]的直线。
# 通过两个点([2,3]和[3,4])画出直线 from sklearn.linear_model import LinearRegression def Line_base_by_two_point(): X = [[2],[3]] y = [3,4] # 用线性模型拟合这两个点 lr = LinearRegression().fit(X,y) # 画出通过两个点([2,3]和[3,4])直线 z = np.linspace(-5,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() # 显示这条线的斜率和截距 print('y={:.3f}'.format(lr.coef_[0]),'x','+{:.3f}'.format(lr.intercept_))
输出:
y=1.000 x +1.000
可以看到,斜率与截距均为1.000。
我们加入第三个点[4,4]来看一下。
# 画出通过三个点([2,3]、[3,4]和[4,4])直线 def Line_base_by_three_point(): X = [[2],[3],[4]] y = [3,4,4] # 用线性模型拟合这两个点 lr = LinearRegression().fit(X,y) # 画出通过三个点([2,3]、[3,4]和[4,4])直线 z = np.linspace(-5,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() # 显示这条线的斜率和截距 print('y={:.3f}'.format(lr.coef_[0]),'x','+{:.3f}'.format(lr.intercept_))
输出
y=0.500 x +0.500
斜率为0.500,截距为0.500。
该直线到这三个点偏差最小,正如前面所说的,线性回归方法即找出一条直线,使得各个点到这条直线上的误差最小。
接下来介绍一下LinearRegression。
表达式
sklearn.linear_model.LinearRegression(*, fit_intercept=True, normalize=False, copy_X=True, n_jobs=None, positive=False)
属性
属性 |
解释 |
coef_ |
array of shape (n_features, ) or (n_targets, n_features)。训练后的输入端模型系数,如果label有两个,即y值有两列。那么是一个2D的array |
intercept_ |
float or array of shape (n_targets,).线性模型中的独立项(截距)。如果fit_intercept=False,则设置为0.0 |
rank_ |
Int.矩阵X的秩。仅在X稠密时可用。 |
singular_ |
array of shape (min(X, y),) . X的奇异值。仅在X为稠密时可用。 |
方法
fit(X, y[, sample_weight]) |
拟合线性模型。 |
get_params([deep]) |
获取此估计器的参数。 |
predict(X) |
用线性模型预测。 |
score(X, y[, sample_weight]) |
返回预测的确定系数R2。 |
set_params(**params) |
设置此估计器的参数。 |
这里,特别介绍一下score方法
score (X, y, sample_weight=None)
返回给定测试数据和标签的平均精确度。在多标签分类中,这是子集精度,这是一个苛刻的度量标准,因为您需要为每个样本准确地预测每个标签集。
输入
X:array-like, shape = (n_samples, n_features)。样本。
y :array-like, shape = (n_samples) or (n_samples, n_outputs)。真的X标签。
sample_weight:array-like, shape = [n_samples], optional。测试权重。
输出
score :float。R2平均精度self.predict(X) wrt. y.
比如:
clf.score(X_train,y_train))) clf.score(X_test,y_test)))
5.1 用make_regression数据(无噪音)进行线性回归
def LinearRegression_for_make_regression(): myutil = util() X,y = make_regression(n_samples=100,n_features=1,n_informative=2,random_state=8) X_train,X_test,y_train,y_test = train_test_split(X, y, random_state=8,test_size=0.3) clf = LinearRegression().fit(X,y) print('lr.coef_: {} '.format(clf.coef_[:])) print('reg.intercept_: {}'.format(clf.intercept_)) print('训练集得分: {:.2%}'.format(clf.score(X_train,y_train))) print('测试集得分: {:.2%}'.format(clf.score(X_test,y_test)))
输出
lr.coef_: [63.7840862] reg.intercept_: 4.440892098500626e-15 训练集得分: 100.00% 测试集得分: 100.00%
由于有两个参数,线性回归方程:
y = 63.7840862X+4.440892098500626×10-15。
由于数据集没有噪声,所以score为100.00%。
在util类定义方法show_pic和draw_line
#显示图片 def show_pic(self,title): plt.rcParams['font.sans-serif']=['SimHei'] plt.rcParams['axes.unicode_minus']=False plt.suptitle(title) plt.show() #画拟合线 def draw_line(self,X,y,clf,title): Z = np.linspace(-3,3,100) plt.scatter(X,y,c='b',s=60) try: plt.plot(Z,clf.predict(Z.reshape(-1,1)),c='k') except Exception as e: print("不支持画线") self.show_pic(title)
在上面代码后面加入:
myutil = util() title = "make_regression LinearRegression()回归线(无噪音)" myutil.draw_line(X[:,0],y,clf,title)
得到如下图。
很显然,拟合度相当好。
最后调用util类中的学习曲线方法。
myutil.plot_learning_curve(LinearRegression(),X,y,title) myutil.show_pic(title)