理论+实践,一文带你读懂线性回归的评价指标

2019-11-24 16:10:11 浏览数 (1)

关于作者:饼干同学,某人工智能公司交付开发工程师/建模科学家。专注于AI工程化及场景落地,希望和大家分享成长中的专业知识与思考感悟。

0x00 前言:

本篇内容是线性回归系列的第三篇。

在《模型之母:简单线性回归&最小二乘法》、《模型之母:简单线性回归&最小二乘法》中我们学习了简单线性回归、最小二乘法,并完成了代码的实现。在结尾,我们抛出了一个问题:在之前的kNN算法(分类问题)中,使用分类准确度来评价算法的好坏,那么回归问题中如何评价好坏呢?

本篇内容就是关于回归模型的评价,首先介绍线性回归模型的三个常用评价方法,然后通过波士顿房产预测的实际例子,对评价方法进行代码实现。最后我们会隆重引出最好的衡量线性回归法的指标:R Square

0x01 线性回归算法的衡量标准

简单线性回归的目标是:

已知训练数据样本、 ,找到和的值,使 尽可能小

实际上是找到训练数据集中 最小。

衡量标准是看在测试数据集中y的真实值与预测值之间的差距。

因此我们可以使用下面公式作为衡量标准:

但是这里有一个问题,这个衡量标准是和m相关的。在具体衡量时,测试数据集不同将会导致误差的累积量不同。因此很快的

首先我们从“使损失函数尽量小”这个思路出发:

对于训练数据集合来说,使 尽可能小

在得到a和b之后将 代入a、b中。可以使用 来作为衡量回归算法好坏的标准。

1.1 均方误差MSE

测试集中的数据量m不同,因为有累加操作,所以随着数据的增加 ,误差会逐渐积累;因此衡量标准和 m 相关。为了抵消掉数据量的形象,可以除去数据量,抵消误差。通过这种处理方式得到的结果叫做 均方误差MSE(Mean Squared Error)

1.2 均方根误差RMSE

但是使用均方误差MSE收到量纲的影响。例如在衡量房产时,y的单位是(万元),那么衡量标准得到的结果是(万元平方)。为了解决量纲的问题,可以将其开方(为了解决方差的量纲问题,将其开方得到平方差)得到均方根误差RMSE(Root Mean Squarde Error)

1.3 平均绝对误差MAE

对于线性回归算法还有另外一种非常朴素评测标准。要求真实值 与 预测结果 之间的距离最小,可以直接相减做绝对值,加m次再除以m,即可求出平均距离,被称作平均绝对误差MAE(Mean Absolute Error)

在之前确定损失函数时,我们提过,绝对值函数不是处处可导的,因此没有使用绝对值。但是在评价模型时不影响。因此模型的评价方法可以和损失函数不同。

0x02 评价标准的代码实现

2.1 数据探索

代码语言:javascript复制
import numpy as npimport matplotlib.pyplot as pltfrom sklearn import datasets
# 查看数据集描述boston = datasets.load_boston()print(boston.DESCR)

(输出略)

因为是测试简单回归算法,因此我们选择其中的一个特征进行建模。选择:

  • RM average number of rooms per dwelling 每个住宅的平均房间数

下面我们进行简单的数据探索:

代码语言:javascript复制
# 查看数据集的特征列表boston.feature_names输出:array(['CRIM', 'ZN', 'INDUS', 'CHAS', 'NOX', 'RM', 'AGE', 'DIS', 'RAD',       'TAX', 'PTRATIO', 'B', 'LSTAT'], dtype='<U7')       # 取出数据中的第六例的所有行(房间数量)x = boston.data[:,5]x.shape输出:(506,)
# 取出样本标签y = boston.targety.shape输出:(506,)
plt.scatter(x,y)plt.show()

在图中我们可以看到 50W 美元的档分布着一些点。这些点可能是超出了限定范围(比如在问卷调查中,价格的最高档位是“50万及以上”,那么就全都划到50W上了,因此在本例中,可以将这部分数据去除)

代码语言:javascript复制
np.max(y)# 这里有一个骚操作,用比较运算符返回一个布尔值的向量,将其作为索引,直接在矩阵里对每个元素进行过滤。x = x[y < 50.0]y = y[y < 50.0]plt.scatter(x,y)plt.show()

2.2 简单线性回归预测

代码语言:javascript复制
from myAlgorithm.model_selection import train_test_split
x_train, x_test, y_train, y_test = train_test_split(x, y, seed=666)print(x_train.shape)    # (392,)print(y_train.shape)    #(392,)print(x_test.shape)     #(98,)print(y_test.shape)     #(98,)
from myAlgorithm.SimpleLinearRegression import SimpleLinearRegression
reg = SimpleLinearRegression()reg.fit(x_train,y_train)print(reg.a_)   # 7.8608543562689555print(reg.b_)   # -27.459342806705543
plt.scatter(x_train,y_train)plt.plot(x_train, reg.predict(x_train),color='r')plt.show()
代码语言:javascript复制
y_predict = reg.predict(x_test)print(y_predict)

(输出略)

2.3 MSE 均方误差

代码语言:javascript复制
mse_test = np.sum((y_predict - y_test) ** 2) / len(y_test)mse_test

24.156602134387438

2.4 RMSE 均方根误差

代码语言:javascript复制
from math import sqrt
rmse_test = sqrt(mse_test)rmse_test

4.914936635846635

RMSE消除了量纲的差异,输出的结果是4.9,与y的量纲相同。解释为在RMSE指标下,我们预测的房产数据平均误差在4.9万美元左右。

2.5 MAE 平均绝对误差

代码语言:javascript复制
mae_test = np.sum(np.absolute(y_predict - y_test)) / len(y_test)mae_test

3.5430974409463873

在MAE指标下,我们预测的房产数据平均误差在3.54万美元左右。我们看到MAE指标得到的误差要比RMSE指标得到的误差小。说明不同的评价指标的结果不同

从数学角度来分析,RMSE和MAE的量纲相同,但RMSE的结果较大,这是因为RMSE是将错误值平方,平方操作会放大样本中预测结果和真实结果较大的差距。MAE没有放大。而我们就是要解决目标函数最大差距,因为选RMSE更好一点

0x03 封装及调用

3.1 在工程文件中封装

在工程文件的metrics.py中添加以上评价指标:

代码语言:javascript复制
mport numpy as npfrom math import sqrt
def accuracy_score(y_true, y_predict):    """计算y_true和y_predict之间的准确率"""    assert y_true.shape[0] != y_predict.shape[0],         "the size of y_true must be equal to the size of y_predict"    return sum(y_true == y_predict) / len(y_true)
def mean_squared_error(y_true, y_predict):    """计算y_true和y_predict之间的MSE"""    assert len(y_true) == len(y_predict),         "the size of y_true must be equal to the size of y_predict"    return np.sum((y_true - y_predict) ** 2) / len(y_true)
def root_mean_squared_error(y_true, y_predict):    """计算y_true和y_predict之间的RMSE"""    return sqrt(mean_squared_error(y_true, y_predict))
def mean_absolute_error(y_true, y_predict):    """计算y_true和y_predict之间的MAE"""    assert len(y_true) == len(y_predict),         "the size of y_true must be equal to the size of y_predict"
    return np.sum(np.absolute(y_predict - y_true)) / len(y_predict)

3.2 调用

我们可以在jupyter notebook进行调用:

代码语言:javascript复制
from myAlgorithm.metrics import mean_squared_errorfrom myAlgorithm.metrics import root_mean_squared_errorfrom myAlgorithm.metrics import mean_absolute_error
mean_squared_error(y_test, y_predict)# 输出:24.156602134387438
root_mean_squared_error(y_test, y_predict)# 输出:4.914936635846635
mean_absolute_error(y_test, y_predict)# 输出:3.5430974409463873

3.3 sklearn中的MSE和MAE

sklearn中不存在RMSE,我们可以手动对MSE开方:

代码语言:javascript复制
from sklearn.metrics import mean_squared_errorfrom sklearn.metrics import mean_absolute_error
mean_squared_error(y_test, y_predict)# 输出:24.156602134387438
mean_absolute_error(y_test, y_predict)# 输出:3.5430974409463873

0x04 更好用的 R Square

4.2 R Square介绍以及为什么好

分类准确率,就是在01之间取值。但RMSE和MAE没有这样的性质,得到的误差。因此RMSE和MAE就有这样的局限性,比如我们在预测波士顿方差,RMSE值是4.9(万美元) 我们再去预测身高,可能得到的误差是10(厘米),我们不能说后者比前者更准确,因为二者的量纲根本就不是一类东西。

其实这种局限性,可以被解决。用一个新的指标R Squared。

R方这个指标为什么好呢?

  • 对于分子来说,预测值和真实值之差的平方和,即使用我们的模型预测产生的错误。
  • 对于分母来说,是均值和真实值之差的平方和,即认为“预测值=样本均值”这个模型(Baseline Model)所产生的错误。
  • 我们使用Baseline模型产生的错误较多,我们使用自己的模型错误较少。因此用1减去较少的错误除以较多的错误,实际上是衡量了我们的模型拟合住数据的地方,即没有产生错误的相应指标

我们根据上述分析,可以得到如下结论:

  • R^2 <= 1
  • R2越大也好,越大说明减数的分子小,错误率低;当我们预测模型不犯任何错误时,R2最大值1
  • 当我们的模型等于基准模型时,R^2 = 0
  • 如果R^2 < 0,说明我们学习到的模型还不如基准模型。此时,很有可能我们的数据不存在任何线性关系。

4.2 R Square实现

下面我们从具体实现的层面再来分析一下R方:

如果分子分母同时除以m,我们会发现,分子就是之前介绍过的均方误差,分母实际上是y这组数据对应的方差:

下面我们具体编程实践一下:

代码语言:javascript复制
1 - mean_squared_error(y_test, y_predict) / np.var(y_test)

输出:0.61293168039373225

下面我们在工程文件metrics.py中添加自己实现的r2_score方法:

代码语言:javascript复制
def score(self, x_test, y_test):    """根据测试数据x_test、y_test计算简单线性回归准确度(R方)"""    y_predict = self.predict(x_test)    return r2_score(y_test, y_predict)

然后我们再来调用它:

代码语言:javascript复制
from myAlgorithm.metrics import r2_scorer2_score(y_test, y_predict)

其实这跟掉sklearn中的方法相同

代码语言:javascript复制
from sklearn.metrics import r2_scorer2_score(y_test, y_predict)

0xFF 总结

线性回归的评价指标与分类的评价指标有很大的不同,本篇介绍了均方误差MSE(预测值与真实值之差的平方和,再除以样本量)、均方根误差RMSE(为了消除量纲,将MSE开方)、平均绝对误差MAE(预测值与真实值之差的绝对值,再除以样本量)、以及非常重要的、效果非常好的R方(因此用1减去较少的错误除以较多的错误,实际上是衡量了我们的模型拟合住数据的地方,即没有产生错误的相应指标)。

在实际应用过程中,我们需要这些评价指标,来判别模型的好坏。

在下一篇,我们将会抛弃简单线性回归中每个样本只能有一个特征的限制,考虑更一般的、多个特征的多元线性回归。

0 人点赞