欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  科技

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

程序员文章站 2022-06-26 17:58:09
sk-learn机器学习 线性回归 多元线性回归 两个评价指标...



多元线性回归

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

可以看看我的这篇文章:

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

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

scikit-learn机器学习(再谈线性回归)
所以预测函数的实质就是构建一个这样的多项式——也就是找到所有特征对应的参数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

scikit-learn机器学习(再谈线性回归)
我们将所有的误差平方和除以样本数,得到我们的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() 

绘制的图形如下:
scikit-learn机器学习(再谈线性回归)
我们可以看到两条直线拟合的还算是非常好的,前面几乎是重合在一起的,从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左右,说明我们的模型对信息的拟合还算可以的

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

本文地址:https://blog.csdn.net/Enternalwiser/article/details/108257085