回归类的模型评估指标2:是否拟合了足够的信息

85 篇文章 5 订阅
58 篇文章 2 订阅

回归类算法中,有两种不同的角度来看待回归的效果:
第一,是否预测到了正确的数值。
第二,是否拟合到了足够的信息。
上篇博文已经讨论了第一种角度,本文讨论第二种角度:

是否拟合了足够的信息

对于回归类算法而言,只探索数据预测是否准确是不够的。除了数据本身的数值大小之外,还希望模型能够捕捉到数据的“规律”,比如数据的分布规律、单调性等,而是否捕获了这些信息并无法使用MSE来衡量。
在这里插入图片描述
上图,红色线是真实标签,蓝色线是拟合模型。这是一种比较极端,但的确可能发生的情况。这张图像上,前半部分的拟合非常成功,看上去真实标签和预测结果几乎重合,但后半部分的拟合却非常糟糕,模型向着与真实标签完全相反的方向去了。对于这样的一个拟合模型,如果使用MSE判断,它的MSE会很小,因为大部分样本其实都被完美拟合了,少数样本的真实值和预测值的巨大差异在被均分到每个样本上之后,MSE就会很小。但这样的拟合结果必然不是一个好结果,因为一旦新样本是处于拟合曲线的后半段的,预测结果必然会有巨大的偏差。所以,希望找到新的指标,除了判断预测的数值是否正确之外,还能够判断模型是否拟合了足够多的,数值之外的信息。
降维算法PCA通过使用方差来衡量数据上的信息量。如果方差越大,代表数据上的信息量越多,此信息量不仅包括数值的大小,还包括希望模型捕捉的那些规律。
为了衡量模型对数据上的信息量的捕捉,定义了 R 2 R^2 R2来帮助我们:
R 2 = 1 − ∑ i = 0 m ( y i − y ^ i ) 2 ∑ i = 0 m ( y i − y ˉ i ) 2 = 1 − R S S ∑ i = 0 m ( y i − y ˉ i ) 2 R^2=1-\large{\frac{\sum_{i=0}^m(y_i-\hat{y}_i)^2}{\sum_{i=0}^m(y_i-\bar{y}_i)^2}}\small=1-\large{\frac{RSS}{\sum_{i=0}^m(y_i-\bar{y}_i)^2}} R2=1i=0m(yiyˉi)2i=0m(yiy^i)2=1i=0m(yiyˉi)2RSS
其中, y y y是真实标签, y ^ \hat{y} y^是预测结果, y ˉ \bar{y} yˉ是均值, ( y i − y ˉ y_i-\bar{y} yiyˉ)除以样本量m就是方差。方差的本质是任意一个y值和样本均值的差异,差异越大,这些值所带的信息越多。在R2中,减数分子是真实值和预测值之差平方的合计,也就是模型没有捕获到的信息总量,分母是真实标签所带的信息量,所以其衡量的是1 - 模型没有捕获到的信息量占真实标签中所带的信息量的比例,所以,R2越接近1越好。
R2可以用三种方式调用,一种是直接从metrics中导入r2_score,输入预测值和真实值后打分。第二种是直接从线性回归LinearRegression的接口score进行调用。第三种是在交叉验证中,输入"r2"来调用。

#从metrics中导入r2_score
from sklearn.metrics import r2_score
#r2_score(y_true, y_pred, sample_weight=None, multioutput='uniform_average')
r2_score(Ytest,yhat)
0.6043668160178817
#LinearRegression的接口score
#reg.score(X, y, sample_weight=None)
r2 = reg.score(Xtest,Ytest)
r2
0.6043668160178817
#交叉验证中,设定参数scoring="r2"
cross_val_score(reg,X,y,cv=10,scoring="r2").mean()
0.5110068610524564

在加利福尼亚房屋价值数据集上的MSE其实不是一个很大的数(0.5),但R^2不高,这证明模型比较好地拟合了一部分数据的数值,却没有能正确拟合数据的分布。可以在一张图上绘制出预测值的散点图和真实值的折线图,两者趋势越接近,并且预测值的散点图越靠近真实值,则认为模型拟合越优秀。

import matplotlib.pyplot as plt
%matplotlib inline
import numpy as np
#对Ytest绘图
plt.scatter(range(len(Ytest)),Ytest,c="purple",label= "Data",s=2)
plt.legend()
plt.show()

在这里插入图片描述

#因此需要对图像进⾏排序:如果Ytest能够从⼩到大显示,就能看出趋势
plt.scatter(range(len(Ytest)),sorted(Ytest),c="purple",label= "Data",s=2)
plt.legend()
plt.show()

在这里插入图片描述

#使⽤用argsort函数对测试集进行从小到大的排序后返回数据在原顺序中的索引
ind = np.argsort(Ytest)
ind
array([2477, 4318, 4930, ..., 2806, 2786, 3736], dtype=int64)
#和直接使用sorted进行排序的结果是⼀致的,从小到大进行排序
Ytest.min()
0.14999
Ytest.tolist().index(Ytest.min())
2477
sorted(Ytest)
[0.14999,
 0.14999,
 0.225,
 0.325,
 0.35,
 0.375,
 0.388,
 ...
#让yhat按照Ytest中从小到大的排序进行排序
yhat = pd.DataFrame(yhat)
yhat.head(5)

	0
0 	1.513849
1 	0.465662
2 	2.256773
3 	2.313086
4 	2.458239
yhat = pd.DataFrame(yhat,index=ind)
yhat.head(5)
0
2477 	1.053998
4318 	0.190345
4930 	1.923386
173 	2.046919
948 	1.040453
#绘制图像
plt.plot(range(len(Ytest)),sorted(Ytest),c="black",label= "Data")
plt.scatter(range(len(yhat)),yhat,c="red",label = "Predict",s=1)
plt.legend()
plt.show()

在这里插入图片描述

#如果简单粗暴排序来绘制曲线呢?
#可以绘制⼀张图上的两条曲线,⼀条曲线是真实标签Ytest,另⼀条曲线是预测结果yhat
#两条曲线的交叠越多,我们的模型拟合就越好
plt.plot(range(len(Ytest)),sorted(Ytest),c="black",label= "Data")
plt.plot(range(len(yhat)),sorted(yhat.iloc[:,0]),c="red",label = "Predict")
plt.legend()
plt.show()

在这里插入图片描述
可见,大部分数据的拟合其实还是围绕在真实值周围的,但是图像的整体趋势却不一致。如果在图像右侧分布着更更多的数据,模型就会越来越偏离我们真正的标签。这种结果类似于我们前面提到的,虽然在有限的数据集上将数值预测相对正确了,但却没有正确拟合数据的分布,如果有更多的数据进入模型,那数据标签被预测错误的可能性是非常大的。

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值