在上一篇文章中我们对一元线性回归模型和方程的原理及公式进行了推导,本篇文章将根据实际数据建立一个一元回归模型,代码基于Python

建模应用

首先导入需要用到的Python库:

#一元线性回归
import matplotlib.pyplot as plt #画图库
import pandas as pd
import numpy as np
from sklearn.linear_model import LinearRegression #线性回归库

原始数据为工作时间与收入表,对应有两列数据:工作时间(年)和工资(千),导入数据并查看前10列数据。

#读取数据,
df = pd.read_excel(r"C:\Downloads\工作时间与收入表.xlsx")
df.head(10)


将所有数据绘制散点图,看一下数据的分布

# 绘制散点图
plt.rcParams['font.family'] = 'KaiTi'
plt.scatter(df['工龄'], df['薪水(K)'], c='blue') # 添加标签和标题
plt.xlabel('workyear')
plt.ylabel('salary')
plt.title('workyear to salary') # 添加图例
plt.legend() # 显示图形
plt.show()


从图中可以看出数据是具有线性趋势的,所以考虑使用线性回归模型找出对应关系。这里我们先按照之前说过的原理来自己计算一下回归方程的参数。
首先是最小二乘法:

# 更新k,b(最小二乘法)
k = np.sum(df['薪水(K)'] * (df['工龄'] - df['工龄'].mean())) / (np.sum(df['工龄'] ** 2) - np.sum(df['工龄']) ** 2 / len(df))
b = df['薪水(K)'].mean() - k * df['工龄'].mean() print(k, b)

首先是计算协方差和方差估计参数:

cov_xy = np.sum((df['工龄'] - df['工龄'].mean()) * (df['薪水(K)'] - df['薪水(K)'].mean()))
var_x = np.sum((df['工龄'] - df['工龄'].mean())**2) # 计算k和b
k = cov_xy / var_x
b = df['薪水(K)'].mean() - k * df['工龄'].mean() print(k, b)

实际计算后两种方法得到的参数结果是一致的,将回归方程与数据作图展示一下:

# 绘制散点图
plt.rcParams['font.family'] = 'KaiTi'
plt.scatter(df['工龄'], df['薪水(K)'], c = 'blue', label = 'data') # 生成一些x值
x_line = np.linspace(0, 5, 100) # 根据直线方程计算对应的y值
k = np.sum(df['薪水(K)'] * (df['工龄'] - df['工龄'].mean())) / (np.sum(df['工龄'] ** 2) - np.sum(df['工龄']) ** 2 / len(df))
b = df['薪水(K)'].mean() - k * df['工龄'].mean()
y_line = k * x_line + b # 绘制直线图
plt.plot(x_line, y_line, label = f' y = {k:.2f}x + {b:.2f}', c = 'red') # 添加标签和标题
plt.xlabel('Workyear')
plt.ylabel('Salary')
plt.title('Workyear to salary') # 添加图例
plt.legend() # 显示图形
plt.show()


这样我们就得到了一个一元回归模型的结果,当然我们也可以直接用Python库内置的模型直接建模

#直接通过内置库建模

X = df[['工龄']]  #这里的自变量必须写成二维形式,一个因变量可能对应多个自变量
Y = df['薪水(K)'] # 模型搭建
model = LinearRegression()
model.fit(X,Y) # 模型可视化
plt.scatter(X,Y)
plt.plot(X,model.predict(X),color='red')
plt.xlabel('Workyear')
plt.ylabel('Salary')
plt.show() #查看系数,截距:线性回归方程构造
model.coef_,model.intercept_

可以得到相同的结果

模型的评价

评价指标

之前通过观察数据分布我们猜测数据符合一元线性回归模型并计算得到回归方程,之后还需要对得到的回归模型进行评估,这里主要以3个值作为评判标准:
R-squared(即统计学中的R方)、Adj.R-squared(即调整后R方)、P值。

其中R-squared和Adj.R-squared用来衡量线性拟合的优劣,P值用来衡量特征变量的显著性。

R-squared和Adj.R-squared的取值范围为0~1,它们的值越接近1,则模型的拟合程度越高;一般情况下R-squared和Adj.R-squared大于0.7表示模型拟合程度很好,R-squared和Adj.R-squared在0.4到0.7之间表示模型拟合程度一般。

P值在本质上是个概率值,其取值范围也为0~1,P值越接近0,则特征变量的显著性越高,即该特征变量真的和目标变量具有更高的相关性,一般当P值小于0.05时,就认为特征变量与目标变量有显著相关性。

R方(R-squared)

R-squared即R方,可记为

R

2

R^2

R2,

R

s

q

R_{sq}

Rsq​。要想理解R-squared,得先了解3组概念:
整体平方和TSS(Total Sum of Squares):数据实际值与整个样本均值的差距平方和,可以理解为我们直接用均值作了一个简单粗暴的模型,作为一个基准线
**残差平方和RSS/SSE (Residual Sum of Squares) **:数据实际值与回归曲线得到的值差距平方和,是由误差导致的真实值和估计值之间的偏差平方和(Sum Of Squares Due To Error,SSE),代表的是我们建立的回归模型没有解释的残差部分
**解释平方和ESS/SSR(Explained Sum of Squares) **:整个样本均值与回归曲线得到的值差距平方和,代表的是我们建立的回归模型可以解释的部分(Sum Of Squares Due To Regression,SSR),可以理解为详细建模之后比上面说的简单粗暴的模型更好的部分有多少
它们的关系如下图所示,其中Actual

Y

i

Y_i

Yi​为实际值,

Y

f

i

t

t

e

d

Y_{fitted}

Yfitted​为预测值,

Y

m

e

a

n

Y_{mean}

Ymean​为所有散点平均值。

R方的计算公式为:

R

2

=

1

R

S

S

T

S

S

R^2=1-\frac{RSS}{TSS}

R2=1−TSSRSS​
所以模型不可以解释的部分RSS越少,也就说明回归方程得到的预测值在每个点都更靠近真实值,回归模型也就越好,反映到R方上就是越靠近1.

调整后R方(Adj.R-squared)

上面说到R方越接近1,模型的拟合程度越高。不过拟合程度也不是越高越好,拟合程度过高可能会导致过拟合现象。

所谓过度拟合(简称过拟合),是指模型在训练样本中拟合程度过高,虽然它很好地贴合了训练集数据,但是却丧失了泛化能力,模型不具有推广性,导致在新的数据集中表现不佳。

过拟合相对的则是欠拟合,欠拟合是指模型拟合程度不高,数据距离拟合曲线较远,或指模型没有很好地捕捉到数据特征,不能够很好地拟合数据

调整后R方是R方的改进版,其目的是为了防止选取的特征变量过多而导致虚高的R方。每新增一个特征变量,线性回归背后的数学原理都会导致R-squared增加,但是这个新增的特征变量可能对模型并没有什么帮助。为了限制过多的特征变量,引入了调整后R方的概念,它在R方的基础上额外考虑了特征变量的数量这一因素,其公式如下。

R

2

=

1

(

1

R

2

)

(

n

1

)

n

k

1

\overline {R^2}=1-\frac{(1-R^2)(n-1)}{n-k-1}

R2=1−n−k−1(1−R2)(n−1)​
其中n为样本数量,k为特征变量数量,可以看到当特征变量数量k越多的时候会对调整后R方产生负影响,从而告告诉我们不要为了追求高R方值而添加过多的特征变量。对于特征变量数量不同的模型之间的比较,调整后R方能更准确地反映线性模型的好坏。

P值

P值涉及统计学里假设检验中的概念,判断特征变量与预测变量有无显著相关性,如果有显著的相关性那么说明对应的特征变量更适合放到回归方程中作为自变量。其原假设为特征变量与预测变量无显著相关性,那么P值就是当原假设为真时当前实际得到的样本结果出现的概率。通常来说,我们会以0.05为阈值,当P值小于0.05时,就认为该特征变量与预测变量显著相关。

评价指标代码

利用statsmodels库可直接输出常用的评价指标

#线性回归模型评估
import statsmodels.api as sm # add_constant()函数给原来的特征变量X添加常数项,并赋给X2,这样才有y=ax+b中的常数项,即截距b
X2 = sm.add_constant(X)
# 用OLS()和fit()函数对Y和X2进行线性回归方程搭建
est = sm.OLS(Y,X).fit()
est.summary()


可以看到上述建立的模型R方和调整后R方为0.78左右,P值小于0.05,说明这个模型的拟合程度很好。当然在实际应用中,这些评价指标一般不会像这个例子这么理想,需要更加综合的判断。、

线性回归原理推导与应用(二):Python一元线性回归实战的更多相关文章

  1. R语言解读一元线性回归模型

    转载自:http://blog.fens.me/r-linear-regression/ 前言 在我们的日常生活中,存在大量的具有相关性的事件,比如大气压和海拔高度,海拔越高大气压强越小:人的身高和体 ...

  2. Python实现——一元线性回归(梯度下降法)

    2019/3/25 一元线性回归--梯度下降/最小二乘法_又名:一两位小数点的悲剧_ 感觉这个才是真正的重头戏,毕竟前两者都是更倾向于直接使用公式,而不是让计算机一步步去接近真相,而这个梯度下降就不一 ...

  3. Python实现——一元线性回归(最小二乘法)

    2019/3/24 线性回归--最小二乘法公式法 暂时用python成功做出来了图像,但是其中涉及到的公式还是更多的来自于网络,尤其是最小二乘法公式中的两个系数的求解,不过目前看了下书高数也会马上提及 ...

  4. 梯度下降法及一元线性回归的python实现

    梯度下降法及一元线性回归的python实现 一.梯度下降法形象解释 设想我们处在一座山的半山腰的位置,现在我们需要找到一条最快的下山路径,请问应该怎么走?根据生活经验,我们会用一种十分贪心的策略,即在 ...

  5. Python回归分析五部曲(二)—多重线性回归

    基础铺垫 多重线性回归(Multiple Linear Regression) 研究一个因变量与多个自变量间线性关系的方法 在实际工作中,因变量的变化往往受几个重要因素的影响,此时就需要用2个或2个以 ...

  6. 回归分析法&一元线性回归操作和解释

    用Excel做回归分析的详细步骤 一.什么是回归分析法 "回归分析"是解析"注目变量"和"因于变量"并明确两者关系的统计方法.此时,我们把因 ...

  7. python机器学习——线性回归方法

    背景与原理: 线性回归是机器学习建模中最为简单的模型,也是计算起来最为直观的模型 所谓线性回归,我们要建立的是这样的模型:对一组数据,每组数据形如$(x_{1},...,x_{n},y)$,我们希望构 ...

  8. machine learning 之 导论 一元线性回归

    整理自Andrew Ng 的 machine learnig 课程 week1. 目录: 什么是机器学习 监督学习 非监督学习 一元线性回归 模型表示 损失函数 梯度下降算法 1.什么是机器学习 Ar ...

  9. 十二. Python基础(12)--生成器

    十二. Python基础(12)--生成器 1 ● 可迭代对象(iterable) An object capable of returning its members one at a time. ...

  10. 机器学习经典算法具体解释及Python实现--线性回归(Linear Regression)算法

    (一)认识回归 回归是统计学中最有力的工具之中的一个. 机器学习监督学习算法分为分类算法和回归算法两种,事实上就是依据类别标签分布类型为离散型.连续性而定义的. 顾名思义.分类算法用于离散型分布预測, ...

随机推荐

  1. 移除任务栏右端"显示桌面"按钮-AutoIt

    核心代码 $hwnd = WinGetHandle("[CLASS:Shell_TrayWnd]", "") ControlHide($hwnd, " ...

  2. 适合Java程序员的Go入门笔记

    0.背景 3年java开发背景(因此这篇文章的特点是:比较适合java程序员doge),业余时间有了解过一些go,如今加入字节团队主要技术栈是go,此篇主要结合go语言圣经和团队内go项目,总结一些基 ...

  3. 在 MySQL 中建索引时需要注意哪些事项?

    在 MySQL 中建索引时需要注意哪些事项 索引在 MySQL 中是提升查询性能的关键,但不当的索引设计可能会导致性能下降或资源浪费.因此,在建索引时需要综合考虑性能.存储成本和业务需求. 1. 确定 ...

  4. C#基础——超级方便的ExpandoObject类别

    这东西是.NET Framework 4.5 的新东西..发现这个,大概就跟发现新大陆一样的兴奋,让我再次赞叹Anders Hejlsberg 之神.. 这边有MSDN : http://msdn.m ...

  5. Java 线程的常用操作方法

    目录 线程命名和取得 线程的休眠 线程优先级(priority) 线程命名和取得 如果想要进行线程名称的操作,可以使用Thread类的如下方法: 构造方法:public Thread(Runnable ...

  6. SpringBoot文件上传--转载

    转载地址:https://www.jianshu.com/p/85017f5ecba1

  7. kubeadm部署高可用master

    准备阶段 master1  master2  master3 node1 关闭selinux,firewall setenforce  0 sed -i 's/SELINUX=enforcing/SE ...

  8. 用JavaScript打造全新编程语言:从无到有的完整实践指南

    @charset "UTF-8"; .markdown-body { line-height: 1.75; font-weight: 400; font-size: 15px; o ...

  9. 极简版秒表(java GUI)

    package javaPractice; import javax.swing.*; import java.text.*; import java.util.*; import java.awt. ...

  10. [RCTF2015]EasySQL 报错注入与二次注入

    [RCTF2015]EasySQL 报错注入与二次注入 二次注入,可以概括为以下两步: 第一步:插入恶意数据 进行数据库插入数据时,对其中的特殊字符进行了转义处理,在写入数据库的时候又保留了原来的数据 ...