Press "Enter" to skip to content

回归模型的评价指标

回归模型的评价指标

在我们的回归类算法中,我们有两种不同的角度来看待回归的效果:

第一,我们是否预测到了正确或者接近正确的数值(因为误差的存在)。
第二,我们是否拟合到了足够的信息。(是否模型预测的结果线性和样本真实的结果的线性更加吻合)

##1. 是否预测到了正确的值

 

使用均方误差MSE(mean squared error)来衡量我们的预测值和真实值的差异

 

均方误差,本质上是在RSS的基础上除以样本总量,得到每一个样本量上的平均误差,将平均误差和我们的标签取值范围(最大值和最小值)一起比较,以获得一个较为可靠的评估依据(查看预测结果错误的严重性)

因为标签的最大值和最小值可以表示标签的一个分布情况,那幺将其最大值和最小值和平均误差比较就可以大概看出在每个样本上的误差或者错误有多严重。

sklearn 中,有两种方式调用这个估计指标

1.是使用 sklearn 专用的模型评估模块 mean_squared_error
2.调用交叉验证类 cross_val_score 并使用里面的 scoring 参数设置为 net_mean_squared_error 使用均方误差

from sklearn.linear_model import LinearRegression
from sklearn.model_selection import train_test_split
from sklearn.metrics import mean_squared_error
from sklearn.model_selection import cross_val_score
from sklearn.datasets import fetch_california_housing as fch
feature=fch().data
target=fch().target
x_train,x_test,y_train,y_test=train_test_split(feature,target,test_size=0.1,random_state=2020)
linner=LinearRegression()
linner.fit(x_train,y_train)
y_pred = linner.predict(x_test)
#方式一
mean_squared_error(y_test,y_pred)  #0.5273022319571918
# 方式二
cross_val_score(linner,x_train,y_train,cv=5,scoring='neg_mean_squared_error').mean()
#-0.5273022319571918

 

注意:交叉验证的均方误差为负值

均方误差的计算公式中求得的均方误差的值不可能为负。但是sklearn中的参数scoring下,均方误差作为评判 标准时,却是计算”负均方误差“(neg_mean_squared_error)。这是因为sklearn在计算模型评估指标的时候,会考 虑指标本身的性质,均方误差本身是一种误差,所以被sklearn划分为模型的一种损失(loss)。
在sklearn当中,所有 的损失都使用负数表示,因此均方误差也被显示为负数了。真正的均方误差MSE的数值,其实就是neg_mean_squared_error去掉负号的数字。

绝对值误差

 

其表达的概念与均方误差完全一致,不过在真实标签和预测值之间的差异外我们使用的是L1范式(绝对值)。现实使 用中,MSE和MAE选一个来使用就好了。
sklearn 中,有两种方式调用这个估计指标

1.在 sklearn 当中使用 from sklearn.metrics import mean_absolute_error 来调用绝对值误差
2.调用交叉验证类 cross_val_score 并使用里面的 scoring 参数设置为 neg_mean_absolute_error 使用绝对值误差

2. 是否拟合了足够的信息

 

对于回归类算法而言,只探索数据预测是否准确是不足够的。除了数据本身的数值大小之外,我们还希望我们的模型能够捕捉到数据的”规律“,比如数据的分布规律(抛物线),单调性等等。而是否捕获到这些信息是无法使用MSE来衡量的。

 

这张图中红色线是真实标签,而蓝色线是模型预测的值。这是一种比较极端但的确可能发生的情况。前半部分的拟合非常成功,但后半部分的拟合 却非常糟糕,模型向着与真实标签完全相反的方向。

 

对于这样的一个拟合模型,如果我们使用MSE来对它进行判 断,MSE会很小,因为大部分样本其实都被完美拟合了,少数样本的真实值和预测值的巨大差异在被均分到每个 样本上之后,MSE就会很小。但这样的拟合结果必然不是一个好结果,因为一旦我的新样本是处于拟合曲线的后半段的,我的预测结果必然会有巨大的偏差,而这不是我们希望看到的。所以,我们希望找到新的指标,除了判断预测的 数值是否正确之外,还能够判断我们的模型是否拟合了足够多的,数值之外的信息。

 

在我们学习降维特征选择的时候,我们提到我们使用方差来衡量数据上的信息量。如果方差越大,代表数据上的信息量越多,而这个信息量(模型潜在的规律)不仅包括了数值的大小,还包括了我们希望模型捕捉的那些规律。为了衡量模型对数据上的信息量的捕捉,我们定义了R2来帮助我们:

 

 

分母其实可以表示称为样本的潜在规律,分子为模型的误差(损失),那幺样本数据潜在的规律是不变的,则误差越小则分子分母表达式返回的结果越小,则r2越接近1.

 

可以使用三种方式来调用

LinearRegression
from sklearn.metrics import r2_score
from sklearn.linear_model import LinearRegression
from sklearn.model_selection import train_test_split
from sklearn.metrics import mean_squared_error
from sklearn.model_selection import cross_val_score
from sklearn.datasets import fetch_california_housing as fch
feature=fch().data
target=fch().target
x_train,x_test,y_train,y_test=train_test_split(feature,target,test_size=0.1,random_state=2020)
linner=LinearRegression()
linner.fit(x_train,y_train)
y_pred = linner.predict(x_test)
#方式一
r2_score(y_test,linner.predict(x_test)) #0.6012662971377257
#方式二
r2=linner.score(x_test,y_test) #0.6012662971377257
#方式三
cross_val_score(linner,x_train,y_train,cv=10,scoring='r2').mean() #0.6012662971377257

绘制拟合图

%matplotlib inline
import matplotlib.pyplot as plt
y_pred=linner.predict(x_test)
plt.plot(range(len(y_test)),sorted(y_test),c='black',label='y_true')
plt.plot(range(len(y_pred)),sorted(y_pred),c='red',label='y_predict')
plt.legend()
plt.show()

 

Be First to Comment

发表回复

您的电子邮箱地址不会被公开。 必填项已用*标注