机器学习实战:线性回归模型

公众号:尤而小屋
作者:Peter
编辑:Peter

大家好,我是Peter~

今天带来的是机器学习的一篇实战文章:利用机器学习库scikit-learn实战线性回归模型。

机器学习实战—线性回归

在理想的状态下,任何非线性的东西都是可以通过线性的东西来拟合的(参考泰勒公式)。而且线性模型本质上是均值预测,而大部分事物的变化都只是围绕着均值来波动(参考大数定理),所以线性模型能够模拟绝大部分的现象。

网络图

文章目录

image

基本形式

基本表达

假设x是由d个属性来描述:x={x_1,x_2,......,x_d};其中x_i表示第i个属性上的取值。线性模型是通过各个属性之间的组合来得到一个进行预测的函数,可表示为:

f(x) = w_1x_1+ w_2x_2 + ... + w_dx_d + b

如果用向量表示为:

f(x) = w^Tx+b

其中w=(w_1,w_2,...,w_d)称之为权重,b称之为偏置


不同形式

不同尺度下的线性函数f(x):

  • f(x)取离散的值:线性多分类模型
  • f(x)取实数域上实值函数:线性回归模型
  • f(x)为对数:对数线性模式
  • f(x)进行sigmoid非线性变换:对数几率回归

本文中重点讲解的是线性回归问题,参考资料:《周志华-机器学习》和李航《统计学习方法》,还有datawhale的《南瓜书》公式部分。

线性回归

给定数据集D = {(x_1,y_1),(x_2,y_2),...,(x_m,y_m)},y_i \in R

线性回归linear regression试图学得一个线性模型,尽可能使得预测值f(x)和实际值y_i之间的差别最小

衡量方法

使用均方误差来衡量:找到合适的w和b,满足 \min _{(w,b)} \sum ^m _{i=1} (f(x_i) - y_i)^2

均方误差对应的就是常用的欧几里得距离(欧式距离)。基于均方误差最小化来进行模型求解的方法称之为:最小二乘法

在线性回归模型中,最小二乘法就是试图找到一条直线,使得所有样本到直线上的欧氏距离之和最小

参数求解

求解w和b使E(w,b)=\sum ^m _{i=1}(y_i-wx_i-b)^2达到最小,这个过程称之为最小二乘法的参数估计

E(w,b)对w和b单独求导的过程,具体推导过程参考:https://datawhalechina.github.io/pumpkin-book/#/chapter3/chapter3

image
image

令上面的两个求导出来的结果等于0,我们可以得到w和b的两个结果:

image
image

sklearn实战线性回归

我们通过网上的一个公开的数据集,来实现如何利用机器学习库sklearn进行线性回归学习线性回归问题。

  • 数据来源

  • 数据探索

  • 数据处理

  • 运行sklearn的线性模型

  • 模型评估

  • 模型优化

  • 可视化展示结果

数据来源

1、数据的介绍看这里: http://archive.ics.uci.edu/ml/datasets/Combined+Cycle+Power+Plant

2、数据的下载地址请移步 http://archive.ics.uci.edu/ml/machine-learning-databases/00294/

数据中有4个字段属性用来描述发电厂的输出电力,最后一个是真实的输出电力值。

我们现在需要做的是利用线性回归模型找到4个因素对输出电力的影响,来预测后期的发电力。

数据探索

import pandas as pd
import numpy  as np
from sklearn import datasets, linear_model
from sklearn.linear_model import LinearRegression  # 导入线性回归模型

import matplotlib.pyplot as plt
%matplotlib inline 

1、读取数据

image

2、数据信息查看

image

3、数据统计信息查看

image

数据处理

1、选择需要的样本数据X,也就是前4个字段的信息

image

2、选择我们的样本输出标签数据y,也就是最后一个属性字段的数据

image

数据集划分

数据集的划分:一部分变成训练集,另一部分划分成测试集

from sklearn.model_selection import train_test_split  # 从模型选择模块中导入训练、测试集模块

X_train,X_test,y_train,y_test = train_test_split(X, y, random_state=1)

X_train   # 7176条数据训练数据
image

测试集的数据是2392条:

image

样本的输出值的行记录是和对应的X相同的;同时我们也发现:本次案例有75%的数据作为了训练集,25%作为了测试集

image

拟合实例化对象

line.fit(X_train,y_train)
LinearRegression()

查看我们模拟出来的系数:

print(line.intercept_)  # 相当于是d;类似于截距
print(line.coef_)   # 相当于是每个w的取值
[460.05727267]
[[-1.96865472 -0.2392946   0.0568509  -0.15861467]]

到这里,我们就已经模拟出来了线性回归的表达式:也就是PE和前面4个变量之间的关系式子:

PE = -1.96865472*AT -0.2392946*V + 0.0568509*AP -0.15861467*PH + 460.05727267

模型评价

通过训练集的数据我们得到了线性回归的表达式,现在我们通过该表达式来模拟我们之前产生的测试集数据。

一个模型的评估,对于线性回归通常就是用上面我们介绍的均方差(Mean Squared Error, MSE)或者均方根差(Root Mean Squared Error, RMSE)在测试集上的表现来评价模型的好坏。下面通过代码来进行测试:

y_pred = line.predict(X_test)  # 对测试集数据进行预测

y_pred
array([[457.26722361],
       [466.70748375],
       [440.33763981],
       ...,
       [457.39596168],
       [429.37990249],
       [438.16837983]])
len(y_pred)
2392

预测到结果之后,我们将预测值和实际值进行比较:

from sklearn import metrics  # 对比模块
# 输出MSE

print("MSE:",metrics.mean_squared_error(y_test,y_pred)) 
MSE: 20.837191547220346
# 输出RMSE:MSE开根号的结果

print("RMSE: ",np.sqrt(metrics.mean_squared_error(y_test,y_pred)))
RMSE:  4.564777272465804

使用交叉验证优化模型

交叉验证法:将全部的数据样本D划分成k个大小相似的互斥子集。每个子集尽量保持数据分布的一致性。然后用用k-1个子集作为训练集,剩下的那个作为测试集。

这样就可以获取k组训练集/测试集,从而进行k次的训练和测试,最终返回k次训练的均值。

我们可以使用sklearn中自带的交叉验证方法来优化我们得到的模型,下面的例子中,采用的10折交叉验证:

line
LinearRegression()
from sklearn.model_selection import cross_val_predict  # 导入交叉验证模块

y_predicted = cross_val_predict(line,X,y,cv=10) 
y_predicted  # 通过交叉验证得到的预测值
array([[467.24487977],
       [444.06421837],
       [483.53893768],
       ...,
       [432.47556666],
       [443.07355843],
       [449.74395838]])
len(y_predicted)
9568

通过交叉验证得到的预测值predicted和真实值求MSE和RMSE:

# 输出MSE

print("MSE:",metrics.mean_squared_error(y,y_predicted)) 
MSE: 20.79367250985753
print("RMSE: ",np.sqrt(metrics.mean_squared_error(y,y_predicted)))
RMSE:  4.560007950635342

我们发现:通过使用交叉验证后的均方误差优于未使用情况下的误差

绘图

最后,我们画出真实的样本值和预测值之间的图形,当点距离中间y=x的值越近,说明预测损失越低。

下面是使用matplotlib绘图的代码和效果:

fig, ax = plt.subplots()

ax.scatter(y, y_predicted)

ax.plot([y.min(), y.max()], [y.min(), y.max()], 'k--', lw=3)

ax.set_xlabel('Measured')  # 真实值
ax.set_ylabel('Predicted') # 预测值

plt.show()
image

我把数据用Plotly_express重新绘制了一遍,看看效果:

data = pd.concat([pd.DataFrame(y),pd.DataFrame(y_predicted)],axis=1)
data.columns = ["Measured", "Predicted"]
data
image
import plotly_express as px

fig = px.scatter(data,
                 x="Measured",  # 真实值
                 y="Predicted",  # 预测值
                 trendline="ols",  # 趋势线
                 trendline_color_override="red" # 颜色
                )

fig.show()
image
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 159,015评论 4 362
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,262评论 1 292
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 108,727评论 0 243
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 43,986评论 0 205
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,363评论 3 287
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,610评论 1 219
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,871评论 2 312
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,582评论 0 198
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,297评论 1 242
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,551评论 2 246
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,053评论 1 260
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,385评论 2 253
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,035评论 3 236
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,079评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,841评论 0 195
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,648评论 2 274
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,550评论 2 270

推荐阅读更多精彩内容