Python一元和多元线性回归模型的原理及评估【附代码】
线性回归模型是利用线性拟合的方式来探寻数据背后的规律,如下图所示,就是通过搭建线性回归模型来寻找这些散点(也称样本点)背后的趋势线(也称回归曲线),而通过这个回归曲线我们就能进行一些简单的预测分析或因果关系分析。线性回归中,我们根据特征变量(也称自变量)来对反应变量(也称因变量)进行预测,根据特征变量的个数可将线性回归模型分为一元线性回归和多元线性回归。通过一个特征变量:工作年限对收入进行预测,就
目录
1.一元线性回归
(1)线性回归模型的定义
线性回归模型是利用线性拟合的方式来探寻数据背后的规律,如下图所示,就是通过搭建线性回归模型来寻找这些散点(也称样本点)背后的趋势线(也称回归曲线),而通过这个回归曲线我们就能进行一些简单的预测分析或因果关系分析。
线性回归中,我们根据特征变量(也称自变量)来对反应变量(也称因变量)进行预测,根据特征变量的个数可将线性回归模型分为一元线性回归和多元线性回归。通过一个特征变量:工作年限对收入进行预测,就属于一元线性回归;通过多个特征变量:工作年限、行业、所在城市等对收入进行预测,就属于多元线性回归。这一小节主要先讲解下一元线性回归模型。
(2)一元线性回归的数学原理
一元线性回归模型也称为简单线性回归模型,其形式可以通过如下公式表达:
其中y为因变量,x为自变量,a表示回归系数,b表示截距。其中为实际值,为预测值,一元线性回归的目的就是拟合出一条线来使得预测值和实际值尽可能的接近,如果大部分点都落在拟合出来的线上,那么该线性回归模型则拟合较好。
我们通过两者差值的平方和(该和也称为残差平方和)来进行衡量,公式如下,其中为∑为求和符号。此外,补充说明一句,在机器学习领域,该残差平方和也被称之为回归模型的损失函数。
显然我们希望这个和越小越好,这样实际值和预测值就更加接近,而数学上求最小值的方法为求导数,当导数为0时,该残差平方和最小。那么通过对残差平方和进行求导,然后令其导数为0便可以求得一元线性回归模型的系数a和截距b,这个便是一元线性回归的数学原理,学术上称其为最小二乘法。而在Python中就有专门的库来求解这里的系数a和截距b,而不需要我们去计算复杂的数学公式。
(3)一元线性回归的代码实现
1.绘制散点图
首先通过Matplotlib库先绘制几个散点,代码如下:
X=[[1],[2],[3],[4],[5]]
Y=[2,4,6,8]
其中自变量集合X需要写成二维结构形式,也即大列表里包含着小列表,这个其实是符合之后多元回归的逻辑,因为多元回归,一个因变量y可能对应着多个自变量x,比如对于三元线性回归(即有三个特征变量),此时的自变量集合X就需要写成类似如下形式:
X=[[1,2,3],[2,4,5],[4,6,8],[5,7,9]]
此时的散点如下图所示(附代码):
import matplotlib.pyplot as plt
X = [[1], [2], [4], [5]]
Y = [2, 4, 6, 8]
plt.scatter(X, Y)
plt.show()
2. 引入Scikit-learn库搭建模型
有了原始数据后,引入Scikit-learn库便可快速搭建线性回归模型,代码如下:
from sklearn.linear_model import LinearRegression
regr = LinearRegression()
regr.fit(X,Y)
3.模型预测
regr已经是搭建好的模型了,此时就可以通过该模型来预测数据了,比如自变量是数字1.5,那么通过predict()函数就能预测当自变量x=1.5时对应的因变量y了,代码如下:
y = regr.predict([[1.5]])
print(y)
注意这里的自变量还是得写成二维结构的形式,原理和之前绘制散点图时写成二维结构数据类似,此时获得的预测结果y如下所示,此时获得y为一个一维数组。
[2.9]
此外,如果想同时预测多个自变量,则可以使用如下代码:
y = regr.predict([[1.5], [2.5], [4.5]])
print(y)
此时的预测结果如下:
[2.9 4.3 7.1]
4.模型可视化
我们还可以将搭建好的模型可视化展示出来,代码如下:
plt.scatter(X, Y)
plt.plot(X, regr.predict(X))
plt.show()
5.线性回归方程构造
可以通过coef_和intercept_得到此时直线的系数及截距,代码如下:
print('系数a为:' + str(regr.coef_[0]))
print('截距b为:' + str(regr.intercept_))
运行结果如下:
系数a为:1.4000000000000004
截距b为:0.7999999999999989
那么此时的一元线性回归得到的线性回归方程就可以表示为如下形式:y = 1.4*x + 0.8
(4)案例:不同行业工作年限与收入的线性回归模型
1.案例背景
通常来说,收入都会随着工作年限的增长而增长,而在不同的行业中收入的增长速度都会有所不同,本小节就是来通过一元线性回归模型来探寻工作年限对收入的影响,也即搭建收入预测模型,同时比较多个行业的收入预测模型来分析各个行业的特点。
2.读取数据
这里我们首先以目前比较火的IT行业为例,这里选取的是北京地区的IT行业工龄分布于0-8年的100个IT工程师月工资情况,通过如下代码读取数据。
import pandas as pd
df = pd.read_excel('IT行业收入表.xlsx')
df.head()
使用.head()打印结果如下:
此时的工龄为自变量,薪水为因变量,通过如下代码进行自变量、因变量选取:
X = df[['工龄']]
Y = df['薪水']
通过如下代码可以将此时的散点图绘制出来:
from matplotlib import pyplot as plt
plt.rcParams['font.sans-serif'] = ['SimHei']
plt.scatter(X,Y)
plt.xlabel('工龄')
plt.ylabel('薪水')
plt.show()
最后运行效果如下图所示:
3.模型搭建
通过如下代码即可搭建线性回归模型:
from sklearn.linear_model import LinearRegression
regr = LinearRegression()
regr.fit(X,Y)
4.模型可视化
通过如下代码即可将线性回归模型可视化呈现:
plt.scatter(X,Y)
plt.plot(X, regr.predict(X), color='red')
plt.xlabel('工龄')
plt.ylabel('薪水')
plt.show()
此时运行效果如下图所示:
5.线性回归方程构造
我们还可以通过上一小节的知识点查看该直线的斜率系数a和截距b,代码如下:
print('系数a为:' + str(regr.coef_[0]))
print('截距b为:' + str(regr.intercept_))
运行结果如下:
系数a为:2497.1513476046866
截距b为:10143.131966873787
6.补充:一元多线性回归
如何通过代码的方式来搭建一个一元二次线性回归模型,首先通过如下代码生成二次项数据:
from sklearn.preprocessing import PolynomialFeatures
poly_reg = PolynomialFeatures(degree=2)
X_ = poly_reg.fit_transform(X)
生成完二次项数据后,就可以根据和之前一样的代码获得一元二次线性回归模型了:
regr = LinearRegression()
regr.fit(X_, Y)
然后通过和类似的代码就可以绘制上面的曲线图了,注意此时的predict()函数中填的是X_。
plt.scatter(X,Y)
plt.plot(X, regr.predict(X_), color='red')
plt.show()
通过类似的手段,我们可以获取此时的一元二次回归方程的系数a,b和常数项c,代码如下:
print(regr.coef_)
print(regr.intercept_)
结果如下:
[ 0. -743.68080444 400.80398224]
13988.159332096882
此时的系数项中为3个数,第一个0对应之前生成的X_常数项前面的系数,也对应之前说的X_的常数项不会产生影响;-743.68代表的X_一次项前面的系数,也即系数b;400.8代表的X_二次项前面的系数,也即系数a;而13988则代表常数项c,所以该一元二次线性回归方程为:
y = 400.8x^2 - 743.68x + 13988
用同样的方法,我们可以获取到金融行业、汽车制造行业、餐饮服务行业的工龄与薪酬的线性相关性,这四个行业的一元二次线性回归模型如下图所示:
2.线性回归模型评估
(1)模型评估的编程实现
模型搭建完成后,我们还需要对模型进行评估,这里我们主要以三个值作为评判标准:
1.R-squared(也即统计学中常说的R^2)
2.Adj. R-squared(也即Adjusted R^2)
3.P值
其中R-squared和Adj. R-squared用来衡量线性拟合的程度P值用来衡量特征变量的显著性。
在应用中,我们只需要记得R squared或者Adj. R-squared越高,那么模型的拟合程度越高;如果P值越低,那么该特征变量的显著性越高,也即真的和预测变量有相关性。R-squared 和 Adj. R-squared的取值范围为0-1,P值本质是个概率值,其取值范围也为0-1。
在Python中,通过如下代码即可查看这三个参数:
import statsmodels.api as sm
X2 = sm.add_constant(X)
est = sm.OLS(Y, X2).fit()
est.summary()
打印est.summary():
(2)模型评估的数学原理
1.R-squared的理解
首先来看R-squared,要想理解R-squared,得先了解三个新的概念:
1.整体平方和 TSS(Total Sum of Squares)
2.残差平方和 RSS(Residual Sum of Squares)
3.解释平方和 ESS(Explained Sum of Squares)
相关内容解释都绘制在下图中:其中Yi为实际值,Yfitted为预测值,Ymean为所有散点平均值:
R-squared的公式为=
当RSS趋向于0的时候,说明实际值基本都落在了拟合曲线上,其拟合程度非常高,那么此时R-squared趋向于1,所以在实战当中,R-squared越大(越接近1),其拟合程度越高。不过也不是拟合程度越高越好,当拟合程度过高的时候,可能会导致过拟合的现象。
2.Adj. R-squared的理解(过拟合与欠拟合)
所谓过度拟合(简称过拟合),是指模型在训练样本中拟合程度过高,虽然它很好地贴合了训练集数据,但是却丧失了泛化能力,模型不具有推广性,导致在新的数据集中表现不佳。过拟合相对的则是欠拟合,欠拟合是指模型拟合程度不高,数据距离拟合曲线较远,或指模型没有很好地捕捉到数据特征,不能够很好地拟合数据。Adj. R-squared是R-squared的改进版,其目的是为了防止选取的特征变量过多,而导致虚高的R-squared,每当新增一个特征变量的时候,因为线性回归背后的数学原理,都会导致R-squared增加,但是可能这个新增的特征变量可能对模型并没有什么帮助,为了限制过多的特征变量,所以引入了Adj. R-squared的概念,Adj. R-squared会在原来R-squared的基础上额外考虑到特征变量数目这一值,其公式如下:
其中n为样本数量,k为特征变量数量,可以看到当特征变量数量k越多的时候,其实会对Adj. R-squared产生负影响,因此不要为了一味地追求高R-squared而过多的添加特征变量。
可以看到对于完全拟合的线性方程Adj. R-squared和R-squared是一致的,都为数字1。倘若不是完全拟合,例如此时的R-squared为0.9,那么此时Adj. R-squared的计算过程与结果如下所示:
3.P值的理解
P值涉及统计学里假设检验中的概念,其原假设为特征变量与预测变量无显著相关性,P值是当原假设为真时所得到的样本观察结果或更极端结果出现的概率。通常来说,我们会以0.05为阈值,当P值小于0.05时,就认为该特征变量与预测变量显著相关。
3.多元线性回归
(1)多元线性回归的数学原理和代码实现
多元线性回归模型的原理其实和一元线性回归的原理类似,其形式可以用如下公式表达:
其中:x1、x2、x3……为不同特征变量,
k1、k2、k3……则为这些特征变量前的系数,
k0为常数项
多元线性回归模型的搭建也是通过数学计算来获取合适的系数,使得下图所示的残差平方和最小,其中为实际值,为预测值。
其核心代码和一元线性回归其实是一致的,代码如下:
from sklearn.linear_model import LinearRegression
regr = LinearRegression()
regr.fit(X,Y)
(2)案例:客户价值预测模型
1.案例背景
这里以信用卡客户的客户价值来解释下客户价值预测的具体含义:客户价值预测就是指客户未来一段时间能带来多少利润,其利润的来源可能来自于信用卡的年费、取现手续费、分期手续费、境外交易手续费用等。而分析出客户的价值后,在进行营销、电话接听、催收、产品咨询等各项服务时,就可以针对高价值的客户进行区别于普通客户的服务,有助于进一步挖掘这些高价值客户的价值,并提高这些高价值客户的忠诚度。
2.读取数据
通过如下代码读取相关数据,这里共选取了100多组已有的客户价值数据,其中一些数据已经经过一些简单预处理了。
import pandas as pd
df = pd.read_excel('客户价值数据表.xlsx')
df.head()
其中客户价值为1年的客户价值,即在1年里能给银行带来的收益;学历已经进行数据的预处理,其中2表示高中学历,3表示本科学历,4表示研究生学历;性别中0表示女,1表示男。
此时的后5列为自变量 ,“客户价值”为因变量,通过如下代码进行自变量、因变量选取:
X = df[['历史贷款金额', '贷款次数', '学历', '月收入', '性别']]
Y = df['客户价值']
自变量X同样必须写成二维数据结构,因变量Y写成一维的数据结构即可。
3.模型搭建
通过如下代码即可搭建线性回归模型:
from sklearn.linear_model import LinearRegression
regr = LinearRegression()
regr.fit(X,Y)
4.线性回归方程构造
看该直线的斜率系数a和截距b,代码如下:
print('各系数为:' + str(regr.coef_))
print('常数项系数k0为:' + str(regr.intercept_))
运行结果如下:
各系数为:[5.71421731e-02 9.61723492e+01 1.13452022e+02 5.61326459e-02
1.97874093e+00]
常数项系数k0为:-208.42004079958383
5.模型评估
利用模型评估的方法我们也可以对多元线性回归进行模型评估,代码如下:
import statsmodels.api as sm
X2 = sm.add_constant(X)
est = sm.OLS(Y, X2).fit()
est.summary()
开放原子开发者工作坊旨在鼓励更多人参与开源活动,与志同道合的开发者们相互交流开发经验、分享开发心得、获取前沿技术趋势。工作坊有多种形式的开发者活动,如meetup、训练营等,主打技术交流,干货满满,真诚地邀请各位开发者共同参与!
更多推荐
所有评论(0)