线性回归入门(2)
1、多元线性回归
前一篇为简单的一元线性回归,它反映的是单个自变量对因变量的影响。然而,实际情况中,影响因变量的自变量往往不止一个,需要将一元线性回归模型拓展到多元线性回归模型。
多元线性回归指的就是一个样本有多个特征的线性回归问题。对于一个有n个特征的样本而言,它的回归结果可以写作下面方程:
其中,y和w为一维列向量,X为二维矩阵。
根据一元回归的最小二乘法思想,我们就是要构造一个目标函数:
使其取值最小。接下来我们对w进行求导:
我们先把式子展开成下面的样子(注意:(Xw)T=wTXT):
然后就可以写成四个部分求导的形式如下(累加后求导=求导后累加):
分别对上面四个部分求导步骤如下:
最后整合:
我们让求导后的一阶导数为0,并且我们的特征矩阵X肯定不会是一个所有元素都为0的矩阵,因此我们的XTX不会为0,因此我们可以得到:
而此时我们的w就是我们参数的最优解。求解出这个参数向量,我们就解出了我们的Xw,也就能够计算出我们的预测值yhat了。
2、多元线性回归模型实例
根据特征值预测加利福尼亚房屋价值
- 导入模块
from sklearn.linear_model import LinearRegression
from statsmodels.api as sm
from sklearn.model_selection import train_test_split
from sklearn.model_selection import cross_val_score
from sklearn.datasets import fetch_california_housing as fch # 加利福尼亚房屋价值数据集
import pandas as pd
- 导入数据,探索数据
x = pd.DataFrame(housevalue.data)
y = housevalue.target
x.shape, y.shape
((20640, 8), (20640,))
housevalue.feature_names # 特征值
- MedInc:该街区住户的收入中位数
- HouseAge:该街区房屋使用年代的中位数
- AveRooms:该街区平均的房间数目
- AveBedrms:该街区平均的卧室数目
- Population:街区人口
- AveOccup:平均入住率
- Latitude:街区的纬度
- Longitude:街区的经度
x.columns = housevalue.feature_names
x.head()
MedInc HouseAge AveRooms AveBedrms Population AveOccup Latitude Longitude
0 8.3252 41.0 6.984127 1.023810 322.0 2.555556 37.88 -122.23
1 8.3014 21.0 6.238137 0.971880 2401.0 2.109842 37.86 -122.22
2 7.2574 52.0 8.288136 1.073446 496.0 2.802260 37.85 -122.24
3 5.6431 52.0 5.817352 1.073059 558.0 2.547945 37.85 -122.25
4 3.8462 52.0 6.281853 1.081081 565.0 2.181467 37.85 -122.25
- 分训练集和测试集
xtrain, xtest, ytrain, ytest = train_test_split(x, y, test_size=0.3, random_state=420)
for i in [xtrain, xtest]:
i.index = range(i.shape[0]) # 为训练集重进建立索引
xtrain.shape
(14448, 8))
- 建模
reg = LinearRegression().fit(xtrain, ytrain)
yhat = reg.predict(xtest) # 得出预测数据
yhat
reg.coef_ # 系数
reg.intercept_ # 截距
- 评估
1 是否预测到了正确的数值
指标:均方误差MSE,每个样本的平均误差,用来衡量预测值和真实值的差异
from sklearn.metrics import mean_squared_error as MSE
MSE(yhat, ytest)
0.5309012639324572
2 是否拟合到了足够的信息
指标:决定系数R2
from sklearn.metrics import r2_score
r2_score(ytest, yhat)
0.6043668160178817
我们观察到,虽然我们在加利福尼亚房子价值数据集上的MSE相当小,但我们的R2却不高,这证明我们的模型比较好地拟合了数据的数值,却没有能正确拟合数据的分布。让我们与绘图来看看,究竟是不是这样一回事。我们可以绘制一张图上的两条曲线,一条曲线是我们的真实标签Ytest,另一条曲线是我们的预测结果yhat,两条曲线的交叠越多,我们的模型拟合就越好。
import matplotlib.pyplot as plt
%matplotlib inline
plt.plot(range(len(ytest)), sorted(ytest), c='b', label='Data')
plt.plot(range(len(yhat)), sorted(yhat), c='r', label='Predict')
plt.legend()
可见,虽然我们的大部分数据被拟合得比较好,但是图像的开头和结尾处却又着较大的拟合误差。如果我们在图像右侧分布着更多的数据,我们的模型就会越来越偏离我们真正的标签。这种结果类似于我们前面提到的,虽然在有限的数据集上将数值预测正确了,但却没有正确拟合数据的分布,如果有更多的数据进入我们的模型,那数据标签被预测错误的可能性是非常大的。