05 机器学习算法之岭回归

一、 岭回归简介

在处理复杂的数据的回归问题时,普通的线性回归会遇到一些问题。

简单线性回归最主要问题是对异常值敏感。在真实世界的数据收集过程中,经过会遇到错误的度量结果。而线性回归使用的普通最小二乘法,其目标是使平方误差最小化。这时,由于异常值误差的绝对值很大,因此破坏整个模型。

对此,我们引入正则化项的系数作为阈值来消除异常的影响。这个方法称为岭回归。

岭回归在最小二乘法的基础上加上了一个l_{2}惩罚项。

损失函数:             

 

二、岭回归器的构建

# 数据集存在异常点时,线性回归器的拟合效果不好,“被异常点带到沟里去了”
import numpy as np
import matplotlib.pyplot as plt

np.random.seed(42) # 使得每次运行得到的随机数都一样
x=np.arange(10,20) # 自变量,随便定义的

error=np.random.normal(size=x.shape)
y=1.8*x+5.9+error # 添加随机数作为噪音
print('x={}'.format(x))
print('noise y={}'.format(y))
print('target y={}'.format(1.8*x+5.9))

代码运行结果:

x=[10 11 12 13 14 15 16 17 18 19]
noise y=[24.39671415 25.5617357  28.14768854 30.82302986 30.86584663 32.66586304
 36.27921282 37.26743473 37.83052561 40.64256004]
target y=[23.9 25.7 27.5 29.3 31.1 32.9 34.7 36.5 38.3 40.1]
plt.scatter(x,y)
plt.plot(x,1.8*x+5.9,'-r') # 绘制的是红色的直线
plt.show()

# 以下加入两个异常点,再用线性回归器进行拟合
abnormal_x=[16.5,17.9]
abnormal_y=[25.98,24.12]

# 将异常点绘制出来
plt.scatter(abnormal_x,abnormal_y,marker='x')

# 将异常点加入到原数据集中,构建线性回归器进行拟合,绘制拟合直线
whole_x=np.append(x,abnormal_x).reshape(-1,1)
whole_y=np.append(y,abnormal_y).reshape(-1,1)

from sklearn import linear_model
linear_regressor=linear_model.LinearRegression() # 创建线性回归器对象
linear_regressor.fit(whole_x,whole_y) # 使用训练数据集训练该回归器对象
# 查看拟合结果
y_predict=linear_regressor.predict(whole_x) 
plt.plot(whole_x,y_predict,'-b',linewidth=3)
plt.show()

# 岭回归器的构建  
from sklearn import linear_model  
ridge_regressor=linear_model.Ridge(alpha=0.02,fit_intercept=True,max_iter=10000)  
# 构建岭回归器对象,使用的偏差系数为alpha=0.02
ridge_regressor.fit(whole_x,whole_y) # 使用岭回归器进行训练  
  
# 使用训练完成的岭回归器预测数值  
y_train_predict=ridge_regressor.predict(whole_x)  
plt.scatter(whole_x,whole_y)  
plt.plot(whole_x,y_predict,'-b')  
plt.plot(whole_x,y_train_predict,'-r')  
plt.show()

图中蓝色线条为使用线性回归器得到的结果,红色为使用alpha为0.02时得到的拟合直线,两个重合了,貌似是alpha取值太小所致。

alpha参数控制岭回归器的复杂程度,但alpha趋近于0时,岭回归器就相当于普通的最小二乘法(从图中可以看出,alpha=0.02时,两条直线几乎重合),所以,如果希望该岭回归器模型对异常值不那么敏感,就需要设置一个比较大的alpha值(《Python机器学习经典实例》是这么说的)。所以alpha值的选取是个技术活。


三、 岭回归器模型的评估

和线性回归一样,可以使用均方误差MSE来评估该模型的好坏。

为了对本模型进行评估,需要有评估所需的测试集,此处用随机数生成了一些测试集,如下为测试集生成代码

# 岭回归器模型的评估

# 第一步:构建评估数据,即test set
test_x=np.arange(10,20) # 自变量,随便定义的
shift=np.random.normal(size=test_x.shape)
test_x=test_x+shift # 对test_x进行偏置得到测试集的X

error=np.random.normal(size=x.shape)
test_y=1.8*test_x+5.9+error # 添加随机数作为噪音
plt.scatter(whole_x,whole_y,color='blue',label='train_set')
plt.scatter(test_x,test_y,color='red',label='test_set')
plt.legend()
plt.show()
# 把train set和test set都绘制到一个图中,可以看出偏差不大

从上面数据点的分布来看,除了train set中异常点的位置没有test set之外,其余点都和test set的分布是一致的,表明这个test set可以用于进行测试。

# 第二步:使用test set计算MSE
y_test_predict=ridge_regressor.predict(test_x.reshape(-1,1))

# 第三步:使用评价指标来评估模型的好坏
import sklearn.metrics as metrics
test_y=test_y.reshape(-1,1)
print('平均绝对误差:{}'.format(
    round(metrics.mean_absolute_error(y_test_predict,test_y),2)))
print('均方误差MSE:{}'.format(
    round(metrics.mean_squared_error(y_test_predict,test_y),2)))
print('中位数绝对误差:{}'.format(
    round(metrics.median_absolute_error(y_test_predict,test_y),2)))
print('解释方差分:{}'.format(
    round(metrics.explained_variance_score(y_test_predict,test_y),2)))
print('R方得分:{}'.format(
    round(metrics.r2_score(y_test_predict,test_y),2)))
平均绝对误差:1.49
均方误差MSE:3.49
中位数绝对误差:1.37
解释方差分:0.72
R方得分:0.69

小结:

1、在考察train set和test set时需要考虑两个数据集中数据点的分布,尽量使得两者在空间上的分布一致,这样才能准确地测试模型。

2、本次模型在test set上的效果并不太理想,虽然得到的MSE比较小,但是R方得分,解释方差分都偏低,还需改进。

 

四、岭回归器模型的改进

从上面得到的岭回归器模型在测试集上的表现可以看出,本模型效果并不太好,可以改进的地方至少有两个

1、是对train set中数据点进行删减,比如发现了很明显偏离的异常点,可以直接将这些异常点删除,但是这就涉及到异常点的鉴定方法,把哪些点标注为可以删除的异常点,偏离中心位置多少距离就被认定为异常点,等等。

2、是优化岭回归器的alpha值,下面是我尝试优化alpha的结果图。
 

# 对岭回归器模型进行优化,主要优化alpha的取值
alpha_candidates=[-20,-10,-5.0,-2.0,2.0,5.0,10,20,50]

from sklearn import linear_model
for alpha in alpha_candidates:
    ridge_regressor=linear_model.Ridge(alpha=alpha,fit_intercept=True,max_iter=10000)
    # 构建岭回归器对象,使用不同的alpha值
    ridge_regressor.fit(whole_x,whole_y) # 使用岭回归器进行训练
    # 使用训练完成的岭回归器预测数值
    y_train_predict=ridge_regressor.predict(whole_x)
    plt.plot(whole_x,y_train_predict,label='alpha='+str(alpha))
    
plt.legend() 
plt.scatter(whole_x,whole_y)
plt.show()

从上图中可以看出,随着alpha的取值由0到50慢慢变化,拟合直线会进行顺时针旋转,或者是朝向异常点的方向旋转,貌似是因为alpha越大,异常点对直线越“吸引”,故而拟合直线收到异常点的影响也越来越大。而alpha由0变到负值,且越来越小时,异常点对拟合直线的影响也越来越小。(不知道这么总结对不对???)。虽然linear_model. Ridge的函数说明文档要求alpha取值是positive float,但是此处负值貌似也没有问题,而且貌似alpha为负值时拟合的更好一些。

下面打印出各种不同alpha值时的各种误差:

# 对岭回归器模型进行优化,使用不同alpha值优化后得到的模型计算测试集
alpha_candidates=[-20,-10,-5.0,-2.0,2.0,5.0,10,20,50]

from sklearn import linear_model
for alpha in alpha_candidates:
    ridge_regressor=linear_model.Ridge(alpha=alpha,fit_intercept=True,max_iter=10000)
    # 构建岭回归器对象,使用不同的alpha值
    ridge_regressor.fit(whole_x,whole_y) # 使用岭回归器进行训练
    y_test_predict=ridge_regressor.predict(test_x.reshape(-1,1))
    print('------------alpha='+str(alpha)+'---------------------->>>')
    print('均方误差MSE:{}'.format(
    round(metrics.mean_squared_error(y_test_predict,test_y),2)))
    print('中位数绝对误差:{}'.format(
        round(metrics.median_absolute_error(y_test_predict,test_y),2)))
    print('解释方差分:{}'.format(
        round(metrics.explained_variance_score(y_test_predict,test_y),2)))
    print('R方得分:{}'.format(
        round(metrics.r2_score(y_test_predict,test_y),2)))
------------alpha=-20---------------------->>>
均方误差MSE:2.07
中位数绝对误差:1.21
解释方差分:0.94
R方得分:0.89
------------alpha=-10---------------------->>>
均方误差MSE:2.63
中位数绝对误差:1.1
解释方差分:0.86
R方得分:0.81
------------alpha=-5.0---------------------->>>
均方误差MSE:3.04
中位数绝对误差:1.24
解释方差分:0.8
R方得分:0.76
------------alpha=-2.0---------------------->>>
均方误差MSE:3.3
中位数绝对误差:1.32
解释方差分:0.75
R方得分:0.72
------------alpha=2.0---------------------->>>
均方误差MSE:3.68
中位数绝对误差:1.42
解释方差分:0.69
R方得分:0.66
------------alpha=5.0---------------------->>>
均方误差MSE:3.96
中位数绝对误差:1.48
解释方差分:0.64
R方得分:0.61
------------alpha=10---------------------->>>
均方误差MSE:4.45
中位数绝对误差:1.59
解释方差分:0.54
R方得分:0.52
------------alpha=20---------------------->>>
均方误差MSE:5.43
中位数绝对误差:1.81
解释方差分:0.31
R方得分:0.3
------------alpha=50---------------------->>>
均方误差MSE:8.13
中位数绝对误差:2.81
解释方差分:-0.67
R方得分:-0.67

小结:
1,通过修改alpha值,可以修改模型在test set上的表现,由于test set不包含异常点,所以要求alpha取的越小越好,拟合的直线越偏离异常点。
2,alpha取值越大,岭回归得到的拟合直线越“偏向”异常点,此时异常点对直线的影响越大;alpha越小,拟合直线越“偏离”异常点,此时异常点对直线的影响越小,我们所期望的是异常点对直线影响越小越好,所以貌似alpha应该往越小的方向取值。
 

  • 0
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Ridge回归是一种机器学习算法,它是线性回归的一种变种。它在标准线性回归的基础上加入了一个正则化项,以防止过拟合。Ridge回归的核心思想是通过最小化代价函数来找到最优的回归系数。代价函数由两部分组成,一部分是均方误差,用来衡量预测值与实际值之间的差距;另一部分是正则化项,用来控制回归系数的大小。正则化项中的参数λ决定了正则化的程度,越大则对回归系数的限制越严格。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* [机器学习算法-线性回归、Lasso回归、Ridge回归算法python实现](https://download.csdn.net/download/LYQZDX/87921627)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v92^chatsearchT0_1"}}] [.reference_item style="max-width: 33.333333333333336%"] - *2* [机器学习算法系列(四)- 岭回归算法(Ridge Regression Algorithm)](https://blog.csdn.net/sai_simon/article/details/122337097)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v92^chatsearchT0_1"}}] [.reference_item style="max-width: 33.333333333333336%"] - *3* [机器学习算法系列篇9:Lasso 和 Ridge回归算法](https://blog.csdn.net/robot_learner/article/details/103942849)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v92^chatsearchT0_1"}}] [.reference_item style="max-width: 33.333333333333336%"] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值