线性模型利用输入特征的 线性函数(linear function)进行预测
1. 用于回归的线性模型
下列代码可以在一维wave数据集上学习参数 w [ 0 ] w[0] w[0]和 b b b:
import matplotlib.pyplot as plt import mglearn as mglearn mglearn.plots.plot_linear_regression_wave() plt.show() ----------------------- w[0]: 0. b: -0.031804

我们在图中添加了坐标网格,便于理解直线的含义。
- 从 w [ 0 ] w[0] w[0]可以看出,斜率应该在0.4左右,在图像中也可以直观地确认这一点。
- 截距是指预测直线与y轴的交点:比0略小,也可以在图像中确认。
用于回归的线性模型可以表示为这样的回归模型:
- 对单一特征的预测结果是一条直线
- 两个特征时是一个平面
- 在更高维度(即更多特征)时是一个超平面。
2. 线性回归(普通最小二乘法)
LinearRegression拟合一个带有系数 w = ( w 1 , . . . , w p ) w = (w_1, …, w_p) w=(w1,...,wp) 的线性模型,使得数据集实际观测数据和预测数据(估计值)之间的残差平方和最小。其数学表达式为::
m i n w ∣ ∣ X w − y ∣ ∣ 2 2 \underset{w}{min\,} {|| X w – y||_2}^2 wmin∣∣Xw−y∣∣22
LinearRegression会调用fit方法来拟合数组 X , y X, y X,y,并且将线性模型的系数$ w $存储在其成员变量coef_中:>>>from sklearn import linear_model >>>reg = linear_model.LinearRegression() >>>reg.fit ([[0, 0], [1, 1], [2, 2]], [0, 1, 2]) LinearRegression(copy_X=True, fit_intercept=True, n_jobs=1, normalize=False) >>>reg.coef_ array([ 0.5, 0.5])然而,对于普通最小二乘的系数估计问题,其依赖于模型各项的相互独立性。当各项是相关的,且设计矩阵$ X $的各列近似线性相关,那么,设计矩阵会趋向于奇异矩阵,这会导致最小二乘估计对于随机误差非常敏感,产生很大的方差。例如,在没有实验设计的情况下收集到的数据,这种多重共线性(multicollinearity)的情况可能真的会出现。
普通最小二乘法复杂度:
该方法使用 X X X 的奇异值分解来计算最小二乘解。如果 X X X是一个 s i z e size size为 ( n , p ) (n, p) (n,p) 的矩阵,设 n ≥ p n \geq p n≥p ,则该方法的复杂度为 O ( n p 2 ) O(n p^2) O(np2)
线性回归,或者普通最小二乘法(ordinary least squares, OLS),是回归问题最简单也最经典的线性方法。
线性回归寻找参数 w w w和 b b b,使得对训练集的预测值与真实的回归目标值y之间的均方误差最小。
均方误差(mean squared error)是预测值与真实值之差的平方和除以样本数。
线性回归没有参数,这是一个优点,但也因此无法控制模型的复杂度。
构建模型,“斜率”参数(w,也叫作权重或系数)被保存在coef_属性中,而偏移或截距(b)被保存在intercept_属性中:
from sklearn.linear_model import LinearRegression import mglearn as mglearn from sklearn.model_selection import train_test_split X, y = mglearn.datasets.make_wave(n_samples=60) X_train, X_test, y_train, y_test = train_test_split(X, y, random_state=42) lr = LinearRegression().fit(X_train,y_train) # 斜率参数(w,也叫权重或系数)被保存在coef_属性中 # 偏移或截距(b)被保存在intercept_属性中 print("lr.coef: {}".format(lr.coef_)) print("lr.intercept: {}".format(lr.intercept_)) -------------------------------------- lr.coef: [0.] lr.intercept: -0.0
scikit-learn总是将从训练数据中得出的值保存在以下划线结尾的属性中。这是为了将其与用户设置的参数区分开。
intercept_属性是一个浮点数,而coef_属性是一个NumPy数组,每个元素对应一个输入特征。由于wave数据集中只有一个输入特征,所以lr.coef_中只有一个元素。
看一下训练集和测试集的性能:
# 训练集和测试集的性能 print("Training set score: {:.2f}".format(lr.score(X_train, y_train))) print("Test set score: {:.2f}".format(lr.score(X_test, y_test))) ----------------------------------- Training set score: 0.67 Test set score: 0.66
R 2 R^2 R2约为0.66,这个结果不是很好,但我们可以看到,训练集和测试集上的分数非常接近。这说明可能存在欠拟合,而不是过拟合。
对于这个一维数据集来说,过拟合的风险很小,因为模型非常简单(或受限)。然而,对于更高维的数据集(即有大量特征的数据集),线性模型将变得更加强大,过拟合的可能性也会变大。
看一下LinearRegression在更复杂的数据集上的表现,比如波士顿房价数据集。
记住,这个数据集有506个样本和105个导出特征。
首先,加载数据集并将其分为训练集和测试集。然后像前面一样构建线性回归模型:
import mglearn as mglearn from sklearn.model_selection import train_test_split from sklearn.linear_model import LinearRegression X, y = mglearn.datasets.load_extended_boston() X_train, X_test, y_train, y_test = train_test_split(X, y, random_state=0) lr = LinearRegression().fit(X_train, y_train) # 训练集和测试集的性能 print("Training set score: {:.2f}".format(lr.score(X_train, y_train))) print("Test set score: {:.2f}".format(lr.score(X_test, y_test))) ================================================= Training set score: 0.95 Test set score: 0.61
可以看出在训练集上的预测非常准确,但测试集上的 R 2 R^2 R2要低很多
训练集和测试集之间的性能差异是过拟合的明显标志,因此我们应该试图找到一个可以控制复杂度的模型。标准线性回归最常用的替代方法之一就是岭回归(ridge regression)
发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/177775.html原文链接:https://javaforall.net
