scikit-learn机器学习十一 (再谈线性回归)

多元线性回归

在前面的文章中提过简单的线性回归,并且使用线性回归预测了pizza的价格

可以看看我的这篇文章:

scikit-learn机器学习二 (简单线性回归、K-临近算法-分类和回归、特征缩放)

对于一个有n个特征的样本来说,多元线性回归的结果就是一个这样的多项式:

在这里插入图片描述
所以预测函数的实质就是构建一个这样的多项式——也就是找到所有特征对应的参数w

损失函数

对于多元线性回归来说,它的损失函数就是每个真实标签和预测值的差的平方和,也叫SSE(误差平方和),或者RSS(残差平方和)

我们一般称之为RSS残差平方和

linear_model.LinearRession

我们可以看看这个类的原型:

class sklearn.linear_model.LinearRegression 
(fit_intercept=True, normalize=False, copy_X=True, n_jobs=None)

一般这四个参数我们都不用填

  • 第一个参数:是否计算截距,默认是
  • 第二个参数:是否标准化, 默认否
  • 第三个参数:是否创建副本,默认是
  • 第四个参数:计算的作业数,默认None

探索load_boston数据集

这里我们使用Boston房价的数据集来进行线性回归的探索

from sklearn.linear_model import LinearRegression as LR # 线性回归类
from sklearn.model_selection import train_test_split # 划分训练集和测试集
from sklearn.model_selection import cross_val_score # 交叉验证
from sklearn.datasets import load_boston # Boston房价数据集
import pandas as pd

data = load_boston() # 导入

x = pd.DataFrame(data.data)  # 使用pandas中的dataframe
print(x)
y = data.target

输出结果:

          0     1      2    3      4   ...   8      9     10      11    12
0    0.00632  18.0   2.31  0.0  0.538  ...  1.0  296.0  15.3  396.90  4.98
1    0.02731   0.0   7.07  0.0  0.469  ...  2.0  242.0  17.8  396.90  9.14
2    0.02729   0.0   7.07  0.0  0.469  ...  2.0  242.0  17.8  392.83  4.03
3    0.03237   0.0   2.18  0.0  0.458  ...  3.0  222.0  18.7  394.63  2.94
4    0.06905   0.0   2.18  0.0  0.458  ...  3.0  222.0  18.7  396.90  5.33
……

接着我们返回数据集的shape和特征的含义

print(x.shape) # 返回数据集的大小

x.columns = data.feature_names # 返回十三个特征的含义

print(x.columns)
(506, 13)

Index(['CRIM', 'ZN', 'INDUS', 'CHAS', 'NOX', 'RM', 'AGE', 'DIS', 'RAD', 'TAX',
    'PTRATIO', 'B', 'LSTAT'],
      dtype='object')

线性回归实例

然后我们将该数据集用于线性回归

x_train, x_test, y_train, y_test = train_test_split(x, y, test_size=0.3, random_state=200)
# 划分测试集和训练集

reg = LR().fit(x_train, y_train)  # LR中不需要填参数

y_pred = reg.predict(x_test) # 预测值

print([*zip(x_train.columns, reg.coef_)]) # 组合输出每个特征对应的参数w

print(reg.intercept_) # 输出截距

输出结果:

[('CRIM', -0.058376767641541226), ('ZN', 0.03568524088301603), 
('INDUS', -0.025588257810322246), ('CHAS', 2.3000486379053795),
 ('NOX', -14.337361073174005), ('RM', 3.725345361239569),
  ('AGE', -0.008587766478136496), ('DIS', -1.2927481612970984), 
  ('RAD', 0.25684883924075746), ('TAX', -0.012186338054641026), 
  ('PTRATIO', -0.8928588296406447), ('B', 0.009748098650749316), 
  ('LSTAT', -0.4905439832694449)]
# 返回每个特征对应的w参数大小
  
33.984121388310506 # 截距

这样我们就完成了线性回归模型的建立,我们应该怎么评估我们模型的好坏呢?

线性回归模型的评估

一方面,我们通过找真实值和预测值之间的差异来评估我们的模型,差异越小模型的拟合效果越好,另一方面我们还需要看我们是否拟合到了足够多的信息

正确预测数值

我们知道RSS残差平方和,本质是我们预测值与真实值之间的差异,RSS既是我们的损失函数,也是评价指标之一

一般我们使用均方误差MSE来衡量真实值和预测值的差异

我们可以从metrics或者从交叉验证的参数scoring来调用MSE

在这里插入图片描述
我们将所有的误差平方和除以样本数,得到我们的MSE

# 评估模型
from sklearn.metrics import mean_squared_error as MSE

print(MSE(y_pred, y_test)) # 打印均方误差

print(cross_val_score(reg, x, y, cv=10, scoring="neg_mean_squared_error"))

最后一行是交叉验证的代码

第一个参数是实例化的模型,第二个参数是原始的数据集的特征,第三个参数是标签,第四个参数是交叉验证的次数,最后一个是评分标准

29.84924566934878 # 均方误差

[  -9.28694671  -14.15128316  -14.07360615  -35.20692433  -31.88511666
  -19.83587796   -9.94726918 -168.37537954  -33.32974507  -10.96041068]

这里肯定有读者会疑惑了,均方误差不应该是非负数吗?

为什么在交叉验证里面,十个均方误差都是负数呢?

我们可以看到参数在写的时候前面加了三个字母:neg,表示最后的结果全部取了负数来表示这是一种损失——真实值和测试值的误差造成的损失

拟合足够的信息

然后我们看看第二个衡量指标:是否拟合了足够的信息

我们可以先通过matplotlib来可视化我们的预测值和真实值

import matplotlib.pyplot as plt

sorted(y_test)

plt.plot(range(len(y_test)), sorted(y_test), c="blue", label="Data")
plt.plot(range(len(y_pred)), sorted(y_pred), c="red", label="Predict")
plt.legend()
plt.show()

绘制的图形如下:

我们可以看到两条直线拟合的还算是非常好的,前面几乎是重合在一起的,从120开始,后面的信息拟合不足,但是只从均方误差中我们并不能知道我们的误差来自哪里,因为最后我们除以了样本数量,前面的误差很小,后面的误差就算很大,但是平摊到每一个样本身上时,总的均方误差还是小的,但是我们可以预想如果曲线再往后画,误差可能会越来越大

所以我们引入了第二个衡量标准:是否拟合了足够的信息

我们要使用的是R²和EVS(可解释性方差分数)来帮我们衡量模型对数据的信息捕捉

简单来说当R²和EVS的值越接近1则说明捕捉的信息量越多

from sklearn.metrics import r2_score

# 两种方式调用R²
r2 = reg.score(x_test, y_test)
print(r2)
print(r2_score(y_test, y_pred)) # 一定要注意参数的顺序!!!
# 或者你也可以指定参数,就不必在意顺序了
# r2_score(y_true = y_test,y_pred = y_pred)
print("\n")
# 调用EVS的两种方法
from sklearn.metrics import explained_variance_score as EVS

print(EVS(y_test, y_pred))
print(cross_val_score(reg, x, y, cv=10, scoring="explained_variance"))

输出结果:

0.7275131045619103 # R²的值
0.7275131045619103

0.7336202735115658 # EVS的值
[ 0.74784412  0.5381936  -0.80757662  0.66844779  0.5586898   0.74128804
  0.41981565 -0.11666214 -0.44561819  0.42197365] # 十次交叉验证的EVS的值

最后的结果在0.73左右,说明我们的模型对信息的拟合还算可以的

感谢您的耐心阅读!向着变成更好的自己的目标出发吧!

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

国家一级假勤奋研究牲

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值