惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

N
News | PayPal Newsroom
P
Proofpoint News Feed
Cyberwarzone
Cyberwarzone
C
Cisco Blogs
SecWiki News
SecWiki News
Know Your Adversary
Know Your Adversary
cs.AI updates on arXiv.org
cs.AI updates on arXiv.org
Vercel News
Vercel News
freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More
罗磊的独立博客
NISL@THU
NISL@THU
WordPress大学
WordPress大学
Hacker News - Newest:
Hacker News - Newest: "LLM"
T
Threat Research - Cisco Blogs
AI
AI
Simon Willison's Weblog
Simon Willison's Weblog
Security Archives - TechRepublic
Security Archives - TechRepublic
有赞技术团队
有赞技术团队
L
LINUX DO - 热门话题
Hacker News: Ask HN
Hacker News: Ask HN
V
V2EX
G
GRAHAM CLULEY
TaoSecurity Blog
TaoSecurity Blog
Hugging Face - Blog
Hugging Face - Blog
D
Darknet – Hacking Tools, Hacker News & Cyber Security
F
Fortinet All Blogs
博客园 - 叶小钗
博客园 - 三生石上(FineUI控件)
云风的 BLOG
云风的 BLOG
Recorded Future
Recorded Future
Latest news
Latest news
The Hacker News
The Hacker News
aimingoo的专栏
aimingoo的专栏
T
Troy Hunt's Blog
S
Schneier on Security
I
Intezer
Google DeepMind News
Google DeepMind News
A
Arctic Wolf
Apple Machine Learning Research
Apple Machine Learning Research
Threat Intelligence Blog | Flashpoint
Threat Intelligence Blog | Flashpoint
T
Threatpost
爱范儿
爱范儿
The Register - Security
The Register - Security
S
SegmentFault 最新的问题
Blog — PlanetScale
Blog — PlanetScale
博客园 - 聂微东
宝玉的分享
宝玉的分享
Recent Commits to openclaw:main
Recent Commits to openclaw:main
美团技术团队
B
Blog RSS Feed

少数派

派早报:Google 发布 Fitbit Air 等 - 少数派 「新人报到」確認需求,再開始 - 少数派 从 SOLO 独立开发者社区,我看到了越来越多开发者开始做自己的产品 - 少数派 我怎么管理那些"不常做,但总会忘"的生活事项 - 少数派 人形机器人量产元年,数据才是具身智能的“生死线” - 少数派 BuhoLaunchpad 高度还原 Mac 启动台:开发历程与思考 - 少数派 五年陪伴依然不舍,DIY 换壳后让罗技 MX Master 3 继续服役 - 少数派 新玩意 240|少数派的编辑们最近买了啥? - 少数派 一日一技|为什么你应该关闭 iOS 的键盘声音 - 少数派 我做了个插件和 Skills,一键提取任何网站的设计规范 Design.md - 少数派 住在三四线城市的你,该开始录播客了 - 少数派 甘南秘境,大白高国 - 少数派 AI的审美:谁让把我变成川内倫子 - 少数派 返工怎能不烦恼,打工人片单总有一部是你的「嘴替」 - 少数派 为了让「上厕所」更健康,我做了一个小工具 - 少数派 AI + Skill,能够让生成的文章去除 AI 味吗? - 少数派 新玩意|韶音OpenDots ONE 耳夹式耳机 - 少数派 《美满》| 在每一个春天的晚上相爱(362) - 少数派 新玩意|优篮子 PS01 MagSnap 磁吸支架 - 少数派 自我整合手记 | 我开始早睡了:用稳定规则,为自由托底 - 少数派 用龙虾(OpenClaw)两个多月,我最深的12个体会 - 少数派 听歌时间到,12 张你可能错过的 2025 华语乐坛好专辑 - 少数派 承诺能追吗 - 少数派 macOS 26启动台没了? 我做了个不一样的App启动器 - Keboard - 少数派 《四海为家的人》| INTJ对话INTJ(361) - 少数派 你发过的那些黑历史,是时候一次清干净了 - 少数派 新玩意:安安静静玩,越玩越专注:计客密码机 - 少数派 iPad 用户首次体验 Android 平板:vivo Pad6 Pro - 少数派 数据逻辑强 - 少数派 极北行+ | 一路向北,探访日本至北之地 | 001 - 少数派 万字剖析:千问App深度体验报告(2026) - 少数派 在2026年,如何真正防止别人抄袭你的作品 - 少数派 怎么用 50 块搭个 AI 语音助手?我踩了 3 天坑 - 少数派 YeeroAI:让 AI 对话真正成为知识管理的一部分 - 少数派 爬泰山 - 少数派 「旅图显影」 App 更新:这次,我们补上了一点「手感」 - 少数派 假期出门太折磨?我的 23 条经验帮你规划惬意旅行 - 少数派 工作流会变吗 - 少数派 Claude Opus 4.6 怎么用最省钱?我测了 5 种方案 - 少数派 GPT Image 2 让图文并茂不再稀罕 - 少数派 用户侧出发——什么是AI,我要不要学习? - 少数派 找片、转存、整理、播放一条龙!让你的付费网盘值回票价 - 少数派 欢迎试用!日课一问2.0插件 - 少数派 自己做的MDeditor,原本想购买 Typora 试了两次支付不成功,干脆自己做一个 - 少数派 vibe coding了一个 3MB 的小工具,让 ~/Downloads 彻底告别混乱 - 少数派 因为受不了 Mac 的风扇策略,我做了一个风扇控制工具 - 少数派 别只怪模型 - 少数派 Warp 终端的 AI 功能怎么用?我测了一周的体验 - 少数派 AI 写代码老是出 bug?这 5 个配置我后悔没早知道 - 少数派 「新玩意」苹果出相机可能就这样:Sigma BF + 45mm F2.8 DG Contemporary - 少数派 一个面向2030年的AI操作系统是什么样子的:浅谈cola这款有灵魂的Agent - 少数派 别只看写代码 - 少数派 每天解决10个问题,还是一口气攻坚解决400个? - 少数派 AI 交易机器人怎么搭?我用 Claude 跑了一周实盘 - 少数派 Maptoposter Online:把你爱的城市画成艺术海报 - 少数派 Function Calling 怎么用?我测了 3 个模型发现差距真大 - 少数派 Legend Talk:我做了个 AI 圆桌,让 160 位思想家围着你的问题转 - 少数派 如何找到自己的蓝方?在小县城寻找压力测试 - 少数派 语音输入与软件接口|2026年聊AI时,我们都聊些什么(上) - 少数派 混动已经卖爆,纯电又来补刀——钛7闪充版简直“不讲武德” - 少数派 本月玩什么|朋友收藏、识质存在、沙罗周期 - 少数派 为什么要每天坚持输出? - 少数派 Claude API 挂了好几个小时,你的项目有备用方案吗? - 少数派 Function Calling 没你想的复杂——我用它做了个有点用的工具 - 少数派 登录系统立即播放视频或者图片音乐的软件 - 少数派 我为什么创建 FlipHTML5 下载工具 - 少数派 残局没电?多品牌外设电量统一管理软件EasyBluetooth已支持RTSS游戏内显示以及AIDA64 - 少数派 前往通义路的路 - 少数派 太好看了,媲美Sun的个人导航页,NAS部署星云门户 - 少数派 乌黑嘴唇“一键检测”上线了 - 少数派 派早报:Claude AI 接入多个创意软件生态、FILCO 生产方接手品牌等 - 少数派 【更新】BearCLI、Claude 连接器与 MCP 服务器 - 少数派 记了上千条流水,还是看不懂财务?我做了一个让 AI 读懂账本的工作台 - 少数派 MINI R56 升级原厂 Sport 模式 - 少数派 新玩意 | 一棵柠檬树(仿真版) - 少数派 Momenta的“物理AI”野望,需迈过“含摩量”这道关 - 少数派 网页直接投屏控制手机!NAS一键部署PandaScrcpy,流畅丝滑可远程。 - 少数派 众测|邀你一同探索随身 AI 硬件入口 YoooClaw C·ONE - 少数派 2050大会:分享时间是真诚 参会记 - 少数派 iPad 赋能电影创作:国内首部宣纸手绘长片《燃比娃》的幕后故事 - 少数派 AI的审美:我用 8 个大模型给 100 张旅行照片打分 - 少数派 普通人如何破圈?去参加一个本地协会 - 少数派 把极空间的图标全换了,主题DIY全攻略打造你的专属NAS桌面 - 少数派 电子便签墙,帮你实现便签自由 - 少数派 我如何用三个 CLI 工具取代文档创建需求 - 少数派 原来真的有人可以玩一辈子 - 少数派 社区速递 139 | 派友热议三月买了啥、复古单反尼康 Df 体验 - 少数派 06 作品的赏析与评价 - 少数派 TDS REVIEW|索尼 WF-1000XM6 降噪真无线耳机体验 - 少数派 35.98万起售的第二代腾势D9,我看重的不是堆料,而是不凑合 - 少数派 鼠须管 Squirrel 皮肤配置指北 - 少数派 从watch ultra2换到redmi watch6 - 少数派 派早报:阿里巴巴发布视频生成模型 HappyHorse 1.0 等 - 少数派 别迷信1M - 少数派 家人们天塌了!网盘“大封杀”,多个渠道多条路,NAS部署PanHub - 少数派 AI与人勾心斗角!NAS一键部署AI狼人杀,假日休闲必备。 - 少数派 电商必备!Comfyui工作流批量生图插件,一次生成12张!支持Nano banana pro模型 - 少数派 Comfyui工作流配置Gpt-image-2模型教程,0.03/张 - 少数派 OpenClaw第三方APi怎么配置?可使用Gpt-image-2模型 - 少数派 会员社区话题精选 Ep. 103 - 少数派
如何用Python检验线性回归的假设是否满足 - 少数派
2021-11-07 · via 少数派

如何用Python检验线性回归的假设是否满足

文章目录

提示:该系列文章侧重代码编程实践,不涉及理论基础。如代码无法正常运行或有任何疑问,请告诉我,我将设法解答。


线性回归作为数据分析的基础方法之一被广泛应用,但回归结果是否能够满足有效(effective)、无偏(unbiased)和一致性(consistent)呢?这篇文章将逐步详细介绍如何用Python(Jupyter Notebook)来检验我们的多元线性回归是否满足五大假设的要求。

   点此下载文章数据    提取码:0001
   若超链接不可用,请复制以下地址:
链接:https://pan.baidu.com/s/1Mv0TJ4GL2dehytFmbfzmog
提取码:0001

   做好准备,我们现在开始🚀

一、导入数据

   本文以受教育年限对个人工资这一经典研究问题为例进行讲解。为保证示例简明,线性回归仅适用了数据中的部分连续数据变量。

#导入数据 请预先下载好数据并上传至Jupyter Notebook
data=pd.read_csv('train.csv')
#检查一下数据吧,显示数据里的前4行
train.head()

    运行后,以看到数据如下
 

在这里插入图片描述

   接着我们定义定义自变量和因变量

#定义自变量集X包含educ(受教育年限)、hours(工作小时数)、IQ(智商得分)以及exper(工作总年限)四个变量
X = train[['educ','hours', 'IQ','exper']]
#看一下我们的自变量吧
X.head()
#定义因变量y是lwage(小时工资的对数)
y = pd.Series(train.lwage)

     我们可以看到在17个变量里,我们只选用了其中的四个作为自变量
 

在这里插入图片描述

二、进行线性回归

   Python里线性回归的方法不止一种,我们用以下方式进行:

import statsmodels.api as sm
from statsmodels.formula.api import ols

lin_reg = ols('y~educ+hours+IQ+exper', data=train).fit()
lin_reg.summary()

我们得到如下结果:

在这里插入图片描述


   对于结果的解释,此处不是重点。我们现在就可以开始对于假设条件是否满足的检验了👇

三、假设检验

   在你们的计量课程中,应该已经学过BLUE。什么意思呢?也就是说根据高斯-马尔可夫(Gauss-Markov )定理,在线性回归模型中,普通最小二乘 (OLS)估计 是最佳线性无偏估计 (BLUE),但前提是满足经典线性回归假设:

  1. 所有参数均为常数且满足线性关系
  2. 误差项(errors)的期望均值为0,且与自变量无关
  3. 因变量不能有完全共线性
  4. 误差项是同方差(homoscedasticity of errors),也即误差项的方差不受到自变量的影响,是一个固定不变的值

   此外,与其他无偏线性估计量相比,BLUE 中的“最佳”意味着估计量的方差最小。

假设1:线性假设(Linearity of the model)

   在线性回归中因变量y是自变量X的线性方程,因此我们的参数(parameters)必须是线性的。如果我们用线性模型去拟合非线性的数据,那么就会造成很严重的预测误差。

   那么,我们可以用两张图来检查是否符合线性:(1)实际值与预测值;(2)残差与预测值。如果在第一张图中,所有的点都围绕对角线对称分布;或者第二张途中所有的点都成水平线对称分布,那么我们认为是符合线性假设的。
为了检测非线性,可以检查观察值与预测值或残差与预测值的图。 期望的结果是点在前一个图中围绕对角线对称分布,在后一个图中围绕水平线对称分布。 在这两种情况下,方差大致恒定。

%matplotlib inline
%config InlineBackend.figure_format ='retina'
import seaborn as sns 
import matplotlib.pyplot as plt
import statsmodels.stats.api as sms
sns.set_style('darkgrid')
sns.mpl.rcParams['figure.figsize'] = (15.0, 9.0)
#在这里定义了一个名为linearity_test的函数用来检验线性假设,如果做了不止一线性回归,只要运行这部分代码一次,后面直接可以调用,不必重复写代码
def linearity_test(model, y):
    '''
    Function for visually inspecting the assumption of linearity in a linear regression model.
    It plots observed vs. predicted values and residuals vs. predicted values.
    
    Args:
    * model - fitted OLS model from statsmodels
    * y - observed values
    '''
    fitted_vals = model.predict()
    resids = model.resid

    fig, ax = plt.subplots(1,2)
    
    sns.regplot(x=fitted_vals, y=y, lowess=True, ax=ax[0], line_kws={'color': 'red'})
    ax[0].set_title('Observed vs. Predicted Values', fontsize=16)
    ax[0].set(xlabel='Predicted', ylabel='Observed')

    sns.regplot(x=fitted_vals, y=resids, lowess=True, ax=ax[1], line_kws={'color': 'red'})
    ax[1].set_title('Residuals vs. Predicted Values', fontsize=16)
    ax[1].set(xlabel='Predicted', ylabel='Residuals')

##到这里我们对 linearity_test 这个函数的设定就完成啦,以后每次只需要输入下面这一行,把y前面替换成你所回归的模型的名称就大功告成!
linearity_test(lin_reg, y) 
在这里插入图片描述


   我们发现在本示例中,所有点都大致围绕对角线均匀分布,在残差-预测值图中,所有点大致均匀分布在水平线两侧,因此,我们认为大致符合线性假设。

假设2:误差项(errors)的期望均值为0

   这个检验异常轻松,代码如下:

#是的,就这一句!
lin_reg.resid.mean()

我们得到的结果:

-4.901604968612456e-15

残差的均值非常的小近乎为0。

假设3:无(完全)多重共线性假设

   如果模型中自变量之间存在精确相关关系或者高度相关,那么模型就会难以准确估计。比如,有X1和X2两个自变量,如果X1 = 2 + 3 * X2,那么X1和X2就是精确相关,从而违反假定。

   当然了,一定程度的多重共线性是可以存在于模型中,只要它不是“完美的”。 在前一种情况下,估计效率较低,估计将不那么精确并且对特定数据集高度敏感,但仍然无偏。

   我们可以使用方差膨胀因子 (VIF) 检测多重共线性。 如果变量完全没有线性关系, VIF 的值将为 1。也即VIF值越接近于1,多重共线性越轻,反之越重。

from statsmodels.stats.outliers_influence import variance_inflation_factor

vif_data = pd.DataFrame()
vif_data["feature"] = X.columns

vif_data["VIF"] = [variance_inflation_factor(X.values, i)
                          for i in range(len(X.columns))]
  
print(vif_data)

 结果如下:
 

在这里插入图片描述


   通常而言,我们以VIF=10(5也很常用)为判断标准,如果大于10则认为存在多重共线性,需要通过迭代删除VIF值高的变量。
   小贴士:可以通过相关系数矩阵去识别相关性。

假设4:异方差检验

   当残差呈现异方差时,会很难确定真实标准差,通常会导致置信区间过宽/过窄。例如,如果残差方差随时间而增大, 那么对于非样本数据预测的置信区间会窄得超乎寻常。 异方差的另一个影响也可能是在估计系数时对误差方差最大的数据赋予过多的权重。

   为了研究残差是否同方差,我们可以查看残差(或者标准差)与拟合值的关系图。 当残差随拟合值增长时,就可能存在异方差。此外,我们还可以采用Breusch-Pagan和Goldfeld-Quandt来进行检验。这两个检验的原假设都是同方差。

%matplotlib inline
%config InlineBackend.figure_format ='retina'


import statsmodels.stats.api as sms
import numpy as np

sns.set_style('darkgrid')
sns.mpl.rcParams['figure.figsize'] = (15.0, 9.0)

#类似的,我们从这里开始定义homoscedasticity_test这个函数用来检验异方差
def homoscedasticity_test(model):
    '''
    Function for testing the homoscedasticity of residuals in a linear regression model.
    It plots residuals and standardized residuals vs. fitted values and runs Breusch-Pagan and Goldfeld-Quandt tests.
    
    Args:
    * model - fitted OLS model from statsmodels
    '''
    fitted_vals = model.predict()
    resids = model.resid
    resids_standardized = model.get_influence().resid_studentized_internal

    fig, ax = plt.subplots(1,2)

    sns.regplot(x=fitted_vals, y=resids, lowess=True, ax=ax[0], line_kws={'color': 'red'})
    ax[0].set_title('Residuals vs Fitted', fontsize=16)
    ax[0].set(xlabel='Fitted Values', ylabel='Residuals')

    sns.regplot(x=fitted_vals, y=np.sqrt(np.abs(resids_standardized)), lowess=True, ax=ax[1], line_kws={'color': 'red'})
    ax[1].set_title('Scale-Location', fontsize=16)
    ax[1].set(xlabel='Fitted Values', ylabel='sqrt(abs(Residuals))')

    bp_test = pd.DataFrame(sms.het_breuschpagan(resids, model.model.exog), 
                           columns=['value'],
                           index=['Lagrange multiplier statistic', 'p-value', 'f-value', 'f p-value'])

    gq_test = pd.DataFrame(sms.het_goldfeldquandt(resids, model.model.exog)[:-1],
                           columns=['value'],
                           index=['F statistic', 'p-value'])

    print('\n Breusch-Pagan test ----')
    print(bp_test)
    print('\n Goldfeld-Quandt test ----')
    print(gq_test)
    print('\n Residuals plots ----')

#运行一次以后,直接调用就可以再次检验异方差啦
homoscedasticity_test(lin_reg)

结果如下:
 

在这里插入图片描述
在这里插入图片描述


   如果是同方差性,那么图中的点应该是随机没有特定趋势的,也就是说残差值不会随着拟合值增加或减少。 我们可以看到,我们的数据集并不完全如此,有一些波动,而且Breusch-Pagan检验也在1%显著性上拒绝原假设,所以该数据很可能存在异方差。

总结

   以上我们对线性假设、误差期望值为0、无多重共线性以及同方差的假设进行了检验。 如有任何问题,请跟我联系哦📧