尧图网络科技YAOTU DIGITAL 获取报价
获取报价
首页 / 资讯中心 / 文章详情

稳健回归实战:用R语言rlm和lmrob处理离群值

发布时间:2026/9/27 6:03:45

资讯中心
01
ARTICLE

稳健回归实战:用R语言rlm和lmrob处理离群值

稳健回归实战:用R语言rlm和lmrob处理离群值
简介这款关于R语言稳健性估计的实例分析课件适合正在学习回归诊断、异常值处理的数据分析初学者与统计相关课程学生。内容以线性回归模型为切入点系统讲解残差、异常点、高杠杆点和强影响点的定义与区别并给出杠杆率、学生化残差、Cook距离的计算公式和判断阈值帮助读者理解远离主体的观测为何会扭曲最小二乘估计。课件结合R代码示例演示lm()拟合模型、plot()生成四幅诊断图、resid()提取残差、cooks.distance()计算库克距离并进一步介绍利用Huber和Bisquare权重的M估计实现稳健回归使读者在实际建模中能够识别可疑点并调整模型策略。压缩包内共1个PPT课件容量约716KB公式、图表与R命令集中呈现既便于课堂展示也适合自学复盘。该资源已有1129人浏览学习是一份简洁实用的R语言稳健性估计参考资料。1. 稳健性估计不是“删掉野值”的遮羞布R语言里值得认真跑的第二种回归你拿一份空气污染日浓度数据跑回归一两个极端天气日就能让系数翻两倍删掉这几个点结果变号不删又觉得结论悬。R语言里的稳健性估计robust estimation解决的就是这个问题它不是先主观删数据而是换一个对野值不敏感的损失函数让少数极端点“说了不算”。这套方法对应到 R 里最常用的就是MASS::rlm()和robustbase::lmrob()。适合正在写数据分析作业、做论文回归、或者被真实数据里的离群值反复折磨的人。只要你能接受“估计结果不再依赖个别样本”这件事稳健性估计值得你投入一晚上把它跑通。2. 从最小二乘到稳健估计一组野值就能让 lm() 集体翻车2.1 最小二乘的“一票否决”为什么 1% 的野值能改写你的结论普通线性回归的lm()估计的是min Σ(y_i - ŷ_i)²。这个目标函数里残差是平方的意味着一个残差为 10 的点对目标函数的贡献是残差为 1 的点的 100 倍。换句话说只要样本里混入哪怕一个极端值最小二乘的回归线就会被它“拉过去”。这不是数值 bug而是由损失函数的数学性质决定的——平方损失对极端残差没有上限单个点可以无限放大自己的影响力。我把这个现象叫“一票否决制”一个点的残差特别大时它基本拥有了修改整条回归线斜率的权力。更麻烦的是协变量里的高杠杆点。假设 x 本身也偏离主体很远那么这个点既在 x 方向有影响力又在 y 方向有异常残差二者叠加lm()的系数可以偏到完全脱离业务解释。很多人在这一步选择直接把点删掉但“删哪些、删多少”本身又带有主观性删完之后的显著性检验也不再严格。量化这个脆弱性统计上有个概念叫破坏点breakdown point估计量能容忍的野值比例上限。样本均值的破坏点是 0因为一个无穷大的观测就能把均值拉到无穷样本中位数的破坏点是 50%因为只有当超过一半的数据被污染时中位数才会失真。最小二乘回归的破坏点同样是 0也就是说理论上哪怕只有一个坏点系数就能被无限拉偏。稳健性估计的核心目标就是把破坏点从 0 提到一个可接受的 20%、30% 甚至接近 50%。2.2 稳健估计家族M估计、S估计、MM估计在 R 里的对应实现R 语言里最常见的稳健估计是 M估计Maximum-likelihood type estimate。它的思路是把平方损失换成更“温和”的 ρ 函数。Huber 提出的 ρ 函数在残差小于某个阈值 k 时按平方计算大于 k 时按线性增长相当于给大残差“封顶”。Tukey 的 bisquare双平方函数更狠残差超过阈值后权重逐渐降到 0极端点直接被无视。S估计走的是另一条路它不是直接修改残差损失而是最小化残差的稳健尺度通常用 MAD即绝对中位差因为尺度本身就不容易被野值带偏。S估计的破坏点可以做得很高代价是效率偏低数据干净时它的方差比最小二乘大不少。MM估计是两者的结合先用 S估计得到一个高破坏点的初值再在这个初值附近做一次 M估计既保住抗污染能力又恢复正态误差下的效率。这就是robustbase::lmrob()默认行为。方法核心思想R 函数破坏点数据干净时效率最小二乘平方损失lm()0%100%基准M估计对残差损失截断/降权MASS::rlm()取决于 ψ 函数和维度一般偏低约 95%选好 kS估计最小化残差稳健尺度robustbase::lmrob(methodS)可到 50%相对低MM估计S 初值 M 迭代robustbase::lmrob()理论接近 50%约 95%实际使用时我一般这样选数据量不大、野值比例不超过 15%、只想要一个“不容易被带偏的回归系数”用rlm()就够比例更高、或者野值和杠杆点同时存在直接上lmrob()它的默认 MM 估计比rlm()更耐污染。除此之外robust::covRob()可以处理多元协方差矩阵的稳健估计rrcov包里的PcaHubert()做稳健主成分这些在分析高维数据时同样值得跑一遍但本文主要围绕回归展开。3. 用 rlm() 跑通第一次稳健回归构造污染数据、建模与诊断3.1 构造一个带野值的数据集为什么模拟数据比直接跑“你的数据”更稳妥第一次接触稳健估计强烈建议先在模拟数据上跑通。原因很直接真实数据里你不知道真实系数模型估得对不对没有参照而模拟数据是你自己设定真值的能一眼看出lm()偏了多少、rlm()拉回来了多少。下面这段代码生成 120 个样本真实关系是y 2 1.5x ε然后随机污染其中 10 个样本的 y 值。# 固定随机种子保证结果可复现 set.seed(2024) n - 120 x - rnorm(n) eps - rnorm(n) y - 2 1.5 * x eps # 随机挑 10 个点把 y 拉离真实回归线 out_idx - sample(n, 10) y[out_idx] - y[out_idx] 15 # 看一眼污染后的分布 boxplot(y, main 污染后的 y)这里的关键参数是污染规模10 个点占总数约 8%已经足以让lm()的斜率明显失真。15是相对误差标准差约 1的 15 倍属于强野值。真实场景里你遇到的野值可能是传感器故障、极端天气事件或者录入错误量级不一定这么大但这套流程不受影响。如果你手头有标题里提到的配套数据资源只需要把read.csv的数据源替换成你的文件后面整个建模过程不变。3.2 对比 lm、rlm、lmrob系数、权重和残差谁更接近真相现在用三种方式拟合同一个模型普通最小二乘、Huber 型 M估计、MM 估计。rlm()默认使用psi.huber阈值 k 取 1.345lmrob()默认使用 MM 估计具体调参下一章展开。library(MASS) library(robustbase) # 普通最小二乘 fit_ols - lm(y ~ x) # Huber M估计 fit_huber - rlm(y ~ x, psi psi.huber, k 1.345) # MM估计 fit_mm - lmrob(y ~ x, setting KS2014) # 对比真实系数和三个模型的估计值 data.frame( truth c(2, 1.5), ols coef(fit_ols), huber coef(fit_huber), mm unname(coef(fit_mm)) )运行这段代码你会发现fit_ols的截距和斜率明显偏离 2 和 1.5而fit_huber、fit_mm基本能回到真值附近。原因在于lm()的平方损失被那 10 个大残差点主导而rlm()在 IRLS迭代重加权最小二乘过程中给大残差样本降权lmrob()更是通过 S估计先确定了抗污染的初值再精修。通俗讲普通回归在“照顾”野值稳健回归在“隔离”野值。接下来看每个样本的稳健权重。rlm()返回对象里的w分量是 IRLS 最后一轮迭代的权重数值越接近 0 说明这个样本对回归结果的影响越小。# 打印权重最低的 5 个样本 w - fit_huber$w tail(sort(w), 5) which(w 0.5)被污染样本通常会被压到 0.3 以下甚至接近 0。这一步的诊断价值在于权重图能告诉你模型“怀疑”哪些点而不是你主观判断哪些点像野值。如果后来发现某个样本业务上确实重要比如它是真实的高值客户、真实的极端天气事件那么你就要回到数据本身去确认它是记录错误还是真实信号——稳健估计只能帮你发现它不能替你做业务决策。3.3 用你自己的数据替换数据读取与资源的衔接模拟验证跑通了就该上真实数据。无论数据是 CSV、Excel 还是 RDS核心步骤都一样读入、检查类型、替换公式里的变量名、把lm()换成rlm()或lmrob()。# 假设你的数据文件是 data.csv路径换成实际下载到的地方 d - read.csv(data.csv, stringsAsFactors FALSE) str(d) # 确认每一列的类型 sum(is.na(d)) # 检查缺失值 # 用你的因变量 y_var 和自变量 x1, x2 替换下面的公式 fit_real - lmrob(y_var ~ x1 x2, data d, setting KS2014) summary(fit_real)一个容易被忽略的细节是缺失值和字符型变量。lmrob()对输入很敏感如果某列被读成 character模型会报错如果是NA稳健估计的初始化过程也可能不稳定。所以读入数据后先str()和summary()过一遍把数值型变量转成 numeric缺失值按你的业务规则处理再进入建模。标题里提到的“分析数据见资其它资源”如果你手头有对应的数据文件直接替换read.csv这一行即可后续流程完全一致。4. 稳健性估计必调参数psi函数、收敛阈值与标准误4.1 psi函数选型Huber 还是 bisquare效率与破坏点的取舍rlm()里最核心的参数是psi。Huber 的 psi 函数在残差较小时保持平方损失的行为残差超过阈值后线性增长所以它对“厚尾”数据很稳妥Tukey 的 bisquare 则在残差超过一定阈值后把权重完全压到 0对极端野值更强势。两者的默认参数都设计成“数据干净时效率约为 95%”Huber 的k 1.345bisquare 的c 4.685。选型没有唯一答案。我的习惯是如果数据是一堆小毛刺、整体呈厚尾分布用psi.huber如果存在明显的大野值比如强度高几个数量级用psi.bisquare更能把它们“请出”模型。真实项目里我通常两个都跑一遍——如果两种 psi 给出的系数差异很大说明数据里存在让方法敏感的极端结构这时候需要回到数据本身去看而不是继续纠结参数。# 用 bisquare 重新拟合对比 Huber 的结果 fit_bisq - rlm(y ~ x, psi psi.bisquare, c 4.685) coef(fit_bisq) coef(fit_huber) # 对比 Huber 的系数注意c和k不是随意调的。调小阈值会让估计更抗污染但数据干净时效率下降调大阈值则相反。除非你知道自己在做什么否则建议保持默认。需要解释给别人的时候用“效率”这个词比较准确默认参数下如果数据来自正态分布稳健估计的效率约为 95%意味着只损失 5% 的精度来换取对野值的抵抗力。4.2 收敛参数与尺度估计maxit、acc、nResample 在调什么rlm()使用 IRLS 迭代求解两个参数直接控制迭代行为maxit是最大迭代次数acc是收敛阈值。默认maxit 20在极端高杠杆情况下可能不够acc 1e-4表示两次迭代系数变化小于这个阈值就停止。lmrob()的初始化则依赖nResample它的含义是 S估计阶段随机子采样的次数默认 500。如果野值比例高或者变量之间存在强相关500 次采样可能找不到好的初值导致 S 估计失败。参数所属函数默认值作用什么时候调k/crlm()1.345 / 4.685psi 函数阈值需要调整抗污染力度时maxitrlm()20IRLS 最大迭代次数出现“迭代不收敛”警告时调大到 50accrlm()1e-4收敛阈值追求更精确的系数时调小nResamplelmrob()500S 估计初值采样次数报“S estimation failed”时调大到 2000settinglmrob()KS2014预设调参方案默认即可极少改尺度估计也要留意。rlm()的scale.est参数控制残差尺度的估计方式可选 MAD 或 Huber默认 MAD。MAD 本身就是稳健尺度比标准差稳定得多如果你换上 Huber 尺度野值对尺度的影响会大一些迭代路径也会跟着变。实际场景中我会保持默认除非我明确知道误差分布的形状。4.3 稳健回归不等于稳健标准误sandwich 包补上聚类标准误很多新手把“稳健回归”和“稳健标准误”混为一谈。前者是更换估计方法本身让系数不被野值带偏后者是在 OLS 或 GLM 估计完成后用三明治估计量修正标准误解决异方差和组内相关问题。这是两条赛道rlm()的系数估计虽然稳健但它返回的标准误并不一定适合你的面板数据或聚类抽样数据。如果你的诉求是“系数不被野值带偏同时标准误也不被组内相关欺骗”常见做法是用sandwich包配合lmtest对lm()的结果做修正。注意vcovHC()主要面向lm/glm对象不是rlm()。library(sandwich) library(lmtest) # 对 OLS 估计做异方差稳健标准误 fit_ols - lm(y ~ x) coeftest(fit_ols, vcov vcovHC(fit_ols, type HC1)) # 如果数据有组结构用聚类稳健标准误 # d$group 是你的聚类标签 coeftest(fit_ols, vcov vcovCL(fit_ols, cluster ~ group))参数上唯一需要决策的是typeHC0 是原始三明治HC1 加了小样本自由度校正HC2/ HC3 对杠杆点更敏感。一般我会优先 HC1样本量小或者存在高杠杆点时换成 HC3。这个组合很适合做论文里的稳健性检验主回归用lmrob()报告稳健系数再用lm()vcovCL()报告普通系数和聚类标准误审稿人看了挑不出毛病。5. 稳健估计常见问题排查与避坑记录5.1 rlm() 的 summary 没有 p 值不是 bug现象跑完rlm()后执行summary(fit)输出的表格里只有 Value、Std. Error、t value没有 Pr(|t|) 那一列新手容易以为自己哪里写错了。原因MASS::rlm()的 summary 默认不输出 p 值。稳健估计的系数在大样本下近似正态但有限样本的精确分布取决于误差分布和 psi 函数rlm()选择不给你一个“看似精确”的 p 值。解决把它当 z 值用正态近似手工计算 p 值。s - summary(fit_huber)$coefficients z - s[, t value] p_value - 2 * pnorm(abs(z), lower.tail FALSE) cbind(s, p_value)另一种做法是用lmrob()它的 summary 直接输出 p 值。所以如果你写报告时需要显著性检验列最省事的路径是直接上lmrob()。两种方法我都用过结论基本一致但lmrob()的输出对读者更友好。5.2 lmrob() 报 “S estimation failed”三个最常见触发点现象lmrob(y ~ x, setting KS2014)直接报错提示 S 估计阶段失败模型一个系数都没给出来。原因S 估计通过随机子采样寻找初值以下三种情况最容易失败——变量量纲差异过大比如一个变量在 0.001 量级、另一个在 10000 量级野值比例过高默认采样很难抽到干净子样本自变量之间存在强共线性或完全线性关系。解决先对数值型变量做标准化再提高nResample到 2000最后检查共线性。# 标准化数值变量 d_std - as.data.frame(scale(d[, c(x1, x2)])) d_std$y - d$y # 提高采样次数减少失败概率 fit_mm - lmrob(y ~ x1 x2, data d_std, setting KS2014, nResample 2000)标准化之后模型系数解释会变汇报时把系数换算回原始尺度即可。如果提高采样后依然失败你真正要处理的是共线性而不是稳健估计的参数。5.3 高杠杆点不等于坏点权重接近 0 也可能冤枉好数据现象检查rlm()的权重时发现某些点权重非常低把它们删掉后结果大变甚至方向改变。问题是这些点看起来并不像记录错误。原因稳健估计把对回归线影响大的点降权但“影响大”既可能是残差大也可能是杠杆高。一个位于 x 空间边缘但符合整体趋势的点杠杆很高虽然它不是野值也会被施加低权重。这是稳健方法的代价——它分不清“坏点”和“影响力大的好点”。解决结合 hatvalues 或马氏距离看杠杆手动区分两类点。# 给拟合对象计算杠杆值 hatv - hatvalues(fit_ols) par(mfrow c(1, 2)) plot(hatv, main 杠杆值) plot(fit_huber$w, main 稳健权重) # 同时杠杆高且权重低的点才是真正的强影响候选 suspect - which(hatv 2 * mean(hatv) fit_huber$w 0.5)真正需要警惕的是“高杠杆 低权重”的组合。如果杠杆高但权重正常说明这个点在 x 方向特殊、却和总体趋势一致应该保留。5.4 小样本下稳健估计更脆别指望 n20 时 rlm() 给你多少好处现象样本量只有几十个跑rlm()和lm()得到的系数差异不大但标准误反而更宽显著性更差。原因稳健估计的优良性质高破坏点、渐近正态、效率都是大样本结论。样本量小时IRLS 的权重估计本身就有较大波动稳健估计的方差可能大于lm()。这不算翻车而是统计理论的正常边界。解决n 小于 30 时我更倾向于做敏感性分析而不是只报一个稳健结果——把lm()、rlm()、lmrob()的系数都列出来看结论是否依赖方法选择。如果三种方法方向一致说明结论比较稳健如果差异巨大说明数据量不足以支撑稳定推断再多方法也救不了。这也是下一章用 bootstrap 验证的原因小样本下自助法比渐近近似更可信。6. 进阶验证用 bootstrap 给稳健估计补置信区间并快速检验野值比例的影响稳健估计的置信区间在理论上依赖渐近近似但样本量不够大时这个近似不一定可靠。更实用的做法是直接用boot包做自助法重抽样。library(boot) # 定义一个函数从数据集中抽取样本并返回 lmrob 的斜率 fit_mm_boot - function(d, i) { fit - lmrob(y ~ x, data d[i, ], setting KS2014) unname(coef(fit)[2]) } set.seed(42) boot_out - boot(d, fit_mm_boot, R 1000) boot.ci(boot_out, type perc)R 1000是经验值lmrob()每次都要做 S 估计和 IRLS重抽样次数太大耗时明显如果只想粗看区间500 次也够。这个方法的价值在于它把置信区间的构造从“假设理论分布”换成了“反复重抽样拟合”对野值比例较高或样本量较小的数据更诚实。另一个我有用的验证手段是模拟不同污染比例观察lm()和lmrob()的表现差异以此判断手头数据对稳健估计的需求有多强。prop - c(0, 0.05, 0.10, 0.20, 0.30) rmse_ols - rmse_rob - numeric(5) for (j in seq_along(prop)) { set.seed(j 1) # 污染比例 p生成一批污染数据 for (r in 1:20) { y2 - 2 1.5 * x rnorm(n) n_out - floor(prop[j] * n) out_idx2 - sample(n, n_out) y2[out_idx2] - y2[out_idx2] 15 d2 - data.frame(x x, y y2) rmse_ols[j] - rmse_ols[j] (coef(lm(y ~ x, d2))[2] - 1.5)^2 rmse_rob[j] - rmse_rob[j] (coef(lmrob(y ~ x, d2, setting KS2014))[2] - 1.5)^2 } }当污染比例达到 20% 以上时OLS 的斜率均方误差会明显放大而lmrob()基本保持稳定。这也是我现在的一个硬规矩任何回归报告先把野值比例估算一下低于 5% 用lm()就够了5% 到 15% 用rlm()超过 15% 或者有高杠杆嫌疑直接上lmrob()并把 bootstrap 区间一起报告。做数据分析这些年我被一组“看着人畜无害”的野值坑过太多次多留一条稳健路径总不会错。希望这些思路和代码能帮你在真实数据里少踩几个坑。本文还有配套的精品资源点击获取
02
RELATED NEWS

相关资讯

更多网站建设与数字化升级内容

03
WHY YAOTU

想打造同款高转化官网?

懂行业、懂生意,从建站到增长一站式陪跑

◈

场景化定制

不做模板站,围绕你的业务场景量身设计,小众不撞款。

◐

营销型架构

以转化目标组织内容与路径,让官网真正带来询盘。

▲

全周期服务

设计、开发、运营、运维一体,上线只是开始。

免费获取你的建站方案

留下需求,专属顾问 24 小时内为你输出方案建议。