用线性回归模型进行预测常见问题:
1.实际数据可能不是线性的;如下图的模型:
安斯库姆四重奏里的四个不同的数据集,用线性回归模型拟合出来的直线相同,这些数据的均值方差都相同,为了看出拟合的效果,我们会利用R^2等指标进行模型诊断。
2.多重共线性(一些特征向量之间线性相关):
解决办法:正则化、主成分回归、偏最小二乘回归。
3.过度拟合问题:
当模型变量过多时,线性回归可能会出现过度拟合问题,例如在房价预测问题中,假设x表示房屋面积,如果将x^2,x^3等独立变量引入可能会出现如下情况:
4.优化泛化误差:
噪音(noise):无法变小
偏差(bias):模型依靠自身能力进行预测的平均准确程度
方差(variance):模型在不同训练集上表现出来的差异程度
正则化:减小线性回归的过度拟合和多重共线性等问题
当q = 1 :LASSO Regression ;q = 2:岭回归(Ridge Regression)。
岭回归(Ridge Regression):
思路:在最小二乘法的目标函数上加上一个对w的惩罚函数
线性回归的目标函数:
岭回归的目标函数:
直接对w求导并令梯度等于0 易得
岭迹分析:
当不断增大正则化参数lambda,估计参数(也称岭回归系数)在坐标系上的变化曲线成为岭迹;当岭迹波动很大时,说明该变量有共线性。
一个二元岭回归的结果:
根据岭迹图做超参数lambda的选择,lambda在(0,0.5)的范围内波动较大,故需加入正则化项重新进行参数估计,可选lambda=1,一般认为是的w1和w2比较稳定时的lambda比较好。
岭回归参数:
alpha:正则化强度,即正则化参数lambda
fit_intercept:是否计算截距,默认为True
LASSO回归:
LASSO是一种系数压缩估计方法,基本思想是通过追求稀疏性自动选择重要的变量;
LASSO的目标函数:
LASSO的解没有解析表达式,常用的求解算法包括坐标下降法、LARS算法和ISTA算法等。
岭回归和LASSO回归如何寻求最优解?(惩罚函数(绿色) 目标函数(橙色))
如上图:图中绿色区域表示约束区域,黄色线为残差平方和函数的等高线;
通过添加L1惩罚函数,LASSO回归可以得到角点解,即稀疏的最优解w,此时w=0,我们可以将对应的变量从模型中删除。
正则化路径图:
随着lambda增大,LASSO的变量系数逐个减小为0,适合做特征选择;而岭回归变量系数几乎同时趋近于0。
LASSO回归参数:
alpha:正则化强度,即正则化参数lambda
fit_intercept:是否计算截距,默认为True
弹性网络回归(ElasticNet Regression):
综合岭回归与LASSO回归,适应复杂多样的数据集;
弹性网络目标函数:
弹性回归回归参数:
alpha:正则化强度,即正则化参数lambda
l1_retio:弹性网络混合参数,即参数ρ,若为0,则正则化项只有L2范数,若为1,则只有L1范数,若属于(0,1)则为L2和L1范数的混合
fit_intercept:是否计算截距,默认为True
对预测医疗保险费用的数据集应用岭回归,输出训练集/测试集决定系数
from sklearn,linear_model import Ridge rid = Ridge(alpha = 20) rid.fit(x_train,y_train) print("训练集决定系数: %s” %round(rid.score(x_train,y_train),4)) print("测试集决定系数: %s” %round(rid.score(x_test,y_test),4))
为了做出岭迹图,首先整合各惩罚系数下的各自变量系数,log(alpha)表示惩罚系数的对数值。
发现smoker系数相对其他系数过大,导致无法观测各系数的收敛情况,如下左图,对各系数作如下处理,可得下右图:
处理:log_coef = np.sign(coef)*np.log(np.abs(coef)+1)
LASSO回归:
from sklearn.linear_model import Lasso las = Lasso(alpha=0.1) las.fit(x_train,y_train) print("训练集决定系数 %s” %round(las.score(x_train,y_train),4)) print("测试集决定系数 %s” %round(las.score(x_test,y_test),4))
弹性网络回归:
from skleanr.linear_model import ElasticNet En = ElasticNet(alpha=1,l1_ratio=0.5) EN.fit(x_train,y_train)
print("训练集决定系数 %s” %round(las.score(x_train,y_train),4))
print("测试集决定系数 %s” %round(las.score(x_test,y_test),4))