机器学习笔记(八):线性回归算法的评测标准 | 凌云时刻

凌云时刻 · 技术

导读:这篇笔记主要介绍线性回归算法,对在第一篇笔记中介绍过的线性回归算法进行实现。kNN算法主要解决的是分类问题,并且它的结果不具备良好的解释性。线性回归算法主要解决回归问题,它的结果具有良好的可解释性,和kNN算法的介绍过程一样,线性回归算法也蕴含了机器学习中很多重要的思想,并且它是许多强大的非线性模型的基础。

作者 | 计缘

来源 | 凌云时刻(微信号:linuxpk)

线性回归算法的评测标准

在讲kNN算法时,我们分类问题的评测标准是基于将样本数据拆分为训练数据和测试数据的前提下的,那么在线性回归算法中也是一样的。我们使用训练数据计算出ab的值,然后将测试数据代入拟合直线方程算出结果,进行比较。我们通过公式来看一下。

   

将训练数据代入公式算出ab,然后代入拟合直线方程算出   :

   

此时我们的衡量标准既为:

   

也就是上面的公式值越小说明我们拟合的越好。



 均方误差(MSE)

上面这个公式有一个问题,那就是最终值受   
的影响,比如某个算法10个样本数据求出的值为80,另一个算法10000个样本数据求出的值为100,也不能表明第一个算法就比第二个算法好,因为样本数据量相差巨大,所以将上面公式改变一下,将值除以   :

   

这个衡量标准称为均方误差(MSE, Mean Squared Error)

 均方根误差(RMSE)

在对量纲不敏感的情况下,使用均方误差没什么问题,但是在一些对量纲比较敏感的场景下,均方误差就会有问题,因为均方误差的量纲为XX平方,比如房屋面积售价的例子,均方误差的量纲就成了  ,所以就有了均方根误差(RMSE, Root Mean Squared Error)用以统一量纲:

   

 

 平均绝对误差(MAE)

另外一个能统一量纲的衡量公式为平均绝对误差,既将真实值与预测值的差取绝对值而不是平方:

   

 实现MSE, RMSE, MAE

实现这三个指标我们使用Scikit Learn中提供的波士顿房价的数据集,我们先使用简单线性回归进行预测:

 

import numpy as np
from sklearn import datasets
import matplotlib.pyplot as plt

boston = datasets.load_boston()
boston.feature_names
# 结果
array(['CRIM', 'ZN', 'INDUS', 'CHAS', 'NOX', 'RM', 'AGE', 'DIS', 'RAD',
	   'TAX', 'PTRATIO', 'B', 'LSTAT'],
	  dtype='<U7')

# 波士顿房价数据提供了13个特征数据,因为是简单线性回归,所以我们只使用房间数量这个特征来预测房价
x = boston.data[:, 5]

# 将数据绘制回来
plt.scatter(x, y)
plt.show()

 

  

从图中我们可以看到在顶部有一些似乎到最大值的数据,这是因为在真实的数据中有一些类似50万以上这类数据,都会被归为数据集最大值一类,这些数据对我们的预测不但没有帮助,反而会有影响,所以我们将这些数据去掉:

 

x = x[y < 50]
y = y[y < 50]

# 导入我们封装好的简单线性回归对象和训练/测试数据拆分的对象
from myML.SimpleLinearRegression import SimpleLinearRegression
from myML.modelSelection import train_test_split

x_train, y_train, x_test, y_test = train_test_split(x, y, seed=666)
slr = SimpleLinearRegression()
slr.fit(x_train, y_train)
y_train_predict = slr.predict(x_train)

# 绘制出拟合直线
plt.scatter(x_train, y_train)
plt.plot(x_train, y_train_predict, color="r")
plt.show()

 

下面我们来计算MSE:

 

y_test_predict = slr.predict(x_test)
mse_test = np.sum((y_test - y_test_predict)**2) / len(y_test)
mse_test
# 结果
24.156602134387402

再来计算RMSE:

 

rmse_test = np.sqrt(mse_test)
rmse_test
# 结果
4.9149366358466313

再来看看MAE:

 

mae_test = np.sum(np.absolute(y_test - y_test_predict)) / len(y_test)
mae_test
# 结果
3.5430974409463842

从结果可以看出RMSE比MAE的值要大,那是因为RMSE是差值先平方然后求和然后再开方,所以如果有某个真实值和预测值之间差距比较大的时候,平方操作就会放大数据的量级。所以一般我们使用RMSE更有实际意义,因为RMSE的值小,说明了最大误差比较小。



 封装MSE, RMSE, MAE

我们将这三个衡量指标封装起来,在metrics.py文件中增加三个方法:

 

import numpy as np

def accuracy_score(y_true, y_predict):
	assert y_true.shape[0] == y_predict.shape[0], \
		"y_true 和 y_predict 数据的行数必须一致"

	return np.sum(y_true == y_predict) / len(y_predict)

def mean_squared_error(y_true, y_predict):
	assert len(y_true) == len(y_predict), "y_true与y_predict的数量必须一致"

	return np.sum((y_true - y_predict)**2) / len(y_true)

def root_mean_squared_error(y_true, y_predict):
	return np.sqrt(mean_squared_error(y_true, y_predict))

def mean_absolute_error(y_true, y_predict):
	assert len(y_true) == len(y_predict), "y_true与y_predict的数量必须一致"

	return np.sum(np.absolute(y_true - y_predict)) / len(y_true)

这样就可以在Jupyter Notebook中方便的使用了:

 

from myML.metrics import mean_squared_error
from myML.metrics import root_mean_squared_error
from myML.metrics import mean_absolute_error

mean_squared_error(y_test, y_test_predict)
# 结果
24.156602134387402

root_mean_squared_error(y_test, y_test_predict)
# 结果
4.9149366358466313

mean_absolute_error(y_test, y_test_predict)
# 结果
3.5430974409463842

R Squared

在之前的分类问题中,衡量标准的值都是在0/1之间,1表示最好,0表示最差,这个值和量纲无关。但是在线性回归问题中衡量标准的值是带有量纲的,比如某个算法在预测房价的场景中RMSE是5万,但在预测学生分数的场景中RMSE是10分,那么这个算法是在预测房价场景中好呢还是在预测学生分数场景中好呢?这个是无法判断的,这就是RMSE和MAE的局限性。那么为解决这个问题,就出现了一个新的衡量指标R Squared,也就是   。这个指标也是目前机器学习算法使用比较广泛的一个指标。我们先来看看   的公式:

   

这个公式的分子其实就是简单线性回归的模型预测产生的错误,既Loss函数。分母中的 就无限接近于1,说明我们的模型拟合的非常好。如果比值接近1,说明我们的模型和均值模型没差多少,表明我们的模型比较烂,此时   就会接近0。那么综上,   的值小于等于1,值越大表示模型越好,当值为负数时表明我们的模型还不如均值模型,也表明了我们分析的数据之间可能根本就没有线性关系。

我们对   的公式再处理一下,将1后面的分数分子分母各除以   :

   

此时,分子其实就是上文中讲到的MSE,而分母就是我们在第二篇笔记中讲过的方差,所以   又可以写为:

   



 实现R Squared
实现   其实是非常简单的:

 

r_square = 1 - mean_squared_error(y_test, y_test_predict)/np.var(y_test)
r_square
# 结果
0.6129316803937328

我们同样将   的方法封装起来:

 

import numpy as np

def accuracy_score(y_true, y_predict):
	assert y_true.shape[0] == y_predict.shape[0], \
		"y_true 和 y_predict 数据的行数必须一致"

	return np.sum(y_true == y_predict) / len(y_predict)

def mean_squared_error(y_true, y_predict):
	assert len(y_true) == len(y_predict), "y_true与y_predict的数量必须一致"

	return np.sum((y_true - y_predict)**2) / len(y_true)

def root_mean_squared_error(y_true, y_predict):
	return np.sqrt(mean_squared_error(y_true, y_predict))

def mean_absolute_error(y_true, y_predict):
	assert len(y_true) == len(y_predict), "y_true与y_predict的数量必须一致"

	return np.sum(np.absolute(y_true - y_predict)) / len(y_true)

def r2_score(y_true, y_predict):
	return 1 - mean_squared_error(y_true, y_predict) / np.var(y_true)

这样就可以在Jupyter Notebook中方便的使用了:

 

from myML.metrics import r2_score
r2_score = r2_score(y_test, y_test_predict)
r2_score
# 结果
0.6129316803937328

Scikit Learn中的   用法也是一样的:

 

from sklearn.metrics import r2_score
r2_score(y_test, y_test_predict)
# 结果
0.6129316803937328

  

 

END

往期精彩文章回顾

机器学习笔记(七):线性回归

机器学习笔记(六):数据归一化

机器学习笔记(五):超参数

机器学习笔记(四):kNN算法

机器学习笔记(三):NumPy、Matplotlib、kNN算法

机器学习笔记(二):矩阵、环境搭建、NumPy

机器学习笔记(一):机器的学习定义、导数和最小二乘

Kafka从上手到实践 - 实践真知:搭建Kafka相关的UI工具

Kafka从上手到实践 - Kafka集群:启动Kafka集群

Kafka从上手到实践 - Kafka集群:Kafka Listeners

长按扫描二维码关注凌云时刻

每日收获前沿技术与科技洞见

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值