副标题[/!--empirenews.page--]
本文主要介绍,Python数据科学:正则化方法。正则化方法的出现,通过收缩方法(正则化方法)进行回归。
正则化方法主要包括岭回归与LASSO回归。
一、岭回归
岭回归通过人为加入的惩罚项(约束项),对回归系数进行估计,为有偏估计。
有偏估计,允许估计有不大的偏度,以换取估计的误差显著减小,并在其残差平方和为最小的原则下估计回归系数。
通常岭回归方程中的R²会稍低于线性回归分析,但回归系数的显著性往往明显高于普通线性回归。
这里不对相应的理论知识进行细说,说实话小F也是晕乎乎...
所以选择先调包,看看效果是啥样的。
使用机器学习框架scikit-learn进行岭回归参数的选择(正则化系数)。
数据是书中的数据,已上传网盘,公众号回复「正则化」,即可获取。
scikit-learn当中的模型不会默认对数据标准化,必须手动执行。
标准化后的数据可以消除量纲,让每个变量的系数在一定意义下进行直接比较。
- import numpy as np
- import pandas as pd
- import matplotlib.pyplot as plt
- from sklearn.linear_model import Ridge
- from sklearn.linear_model import RidgeCV
- from sklearn.preprocessing import StandardScaler
-
- # 消除pandas输出省略号情况及换行情况
- pd.set_option('display.max_columns', 500)
- pd.set_option('display.width', 1000)
- # 读取数据,skipinitialspace:忽略分隔符后的空白
- df = pd.read_csv('creditcard_exp.csv', skipinitialspace=True)
- # 获取信用卡有支出的行数据
- exp = df[df['avg_exp'].notnull()].copy().iloc[:, 2:].drop('age2', axis=1)
- # 获取信用卡无支出的行数据,NaN
- exp_new = df[df['avg_exp'].isnull()].copy().iloc[:, 2:].drop('age2', axis=1)
-
- # 选择4个连续变量,分别是年龄 收入 当地小区价格 当地人均收入
- continuous_xcols = ['Age', 'Income', 'dist_home_val', 'dist_avg_income']
- # 标准化
- scaler = StandardScaler()
- # 解释变量,二维数组
- X = scaler.fit_transform(exp[continuous_xcols])
- # 被解释变量,一维数组
- y = exp['avg_exp_ln']
-
- # 生成正则化系数
- alphas = np.logspace(-2, 3, 100, base=10)
- # 使用不同的正则化系数对模型进行交叉验证
- rcv = RidgeCV(alphas=alphas, store_cv_values=True)
- # 使用数据集训练(fit)
- rcv.fit(X, y)
- # 输出最优参数,正则化系数及相应模型R²
- print('The best alpha is {}'.format(rcv.alpha_))
- print('The r-square is {}'.format(rcv.score(X, y)))
-
- # 训练好后使用transform进行数据转换
- X_new = scaler.transform(exp_new[continuous_xcols])
- # 使用模型对数据做预测
- print(np.exp(rcv.predict(X_new)[:5]))
输出结果如下。

最优正则化系数为0.29,模型R²为0.475。
并使用最优正则化系数下的岭回归模型预测数据。
对不同正则化系数下模型的均方误差进行可视化。
- # 正则化系数搜索空间当中每轮交叉验证的结果,模型的均方误差
- cv_values = rcv.cv_values_
- n_fold, n_alphas = cv_values.shape
- # 模型均方误差上下波动值
- cv_mean = cv_values.mean(axis=0)
- cv_std = cv_values.std(axis=0)
- ub = cv_mean + cv_std / np.sqrt(n_fold)
- lb = cv_mean - cv_std / np.sqrt(n_fold)
- # 绘制折线图,x轴是指数型形式
- plt.semilogx(alphas, cv_mean, label='mean_score')
- # y1(lb)和y2(ub)之间进行填充
- plt.fill_between(alphas, lb, ub, alpha=0.2)
- plt.xlabel('$alpha$')
- plt.ylabel('mean squared errors')
- plt.legend(loc='best')
- plt.show()
输出结果如下。

发现正则化系数在40或50以下时,模型的均方误差相差不大。
当系数超过该阈值时,均方误差则快速上升。
(编辑:晋中站长网)
【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!
|