回归数据有极端目标值怎么办?用 HuberRegressor 与普通线性回归对照

在固定模拟数据中只污染训练目标,用 HuberRegressor 和普通线性回归对照干净测试集误差,核对残差标记并说明高杠杆特征的边界。

回归训练表里少数目标值明显偏离多数样本时,可以保留普通线性回归作为基线,再用 HuberRegressor 做同条件对照。Huber 对较小残差使用平方损失,对较大残差使用绝对值损失,减轻极端目标值的影响,同时仍保留这些样本参与拟合。先回查异常值来源,再决定是否采用更稳健的损失;模型标记不能替代数据审核。

本例人为生成 300 行单特征数据,真实关系为 y=3x+2 加小幅随机噪声;先保留 100 行干净测试数据,再把训练集中的 20 个目标值上移 45。这是受控模拟,已在 Windows、Python 3.11.15、scikit-learn 1.9.1、NumPy 2.4.6 的 CPU 环境运行,没有真实业务样本,也不声称 Huber 在任何数据上都优于普通线性回归。

回归数据有极端目标值怎么办?用 HuberRegressor 与普通线性回归对照

两种回归方法怎样处理较大的残差

LinearRegression 官方文档说明,普通最小二乘拟合会最小化观测目标和预测值之间的残差平方和。残差平方会让极端偏差对目标函数贡献很大,因此这类污染可能拉动斜率与截距。

HuberRegressor 官方文档给出的切换依据是 |y-Xw-c|/scale与 epsilon 的关系;这里的系数 w、截距 c 和尺度 scale 都由拟合得到。它并非按 y 的绝对大小判异常,也不会自动删除超出阈值的行。

配置或属性 本例用途 应怎样解读
epsilon=1.35 确定标准化残差的损失切换 是训练配置,不是业务误差容限
alpha=0.0 关闭本例 Huber 的系数正则项 便于和普通最小二乘对照
scale_ 拟合得到的残差尺度 不等于目标列的标准差
outliers_ 训练样本残差标记 反映模型拟合后的残差,不证明原记录错误

先建立独立环境,以下固定为本文运行版本。macOS/Linux 激活环境使用 source .venv/bin/activate。

python -m venv .venv
.venv\Scripts\activate
python -m pip install scikit-learn==1.9.1 numpy==2.4.6

先划分,再污染训练目标并做对照

把代码保存为 huber_demo.py,运行 python huber_demo.py。两个模型使用完全相同的训练特征、污染后的训练目标和干净测试集;测试目标保持原值,没有用于挑选 epsilon。检查误差时同时输出斜率与截距,便于看到拟合线是否偏离已知生成关系。

import numpy as np
from sklearn.linear_model import HuberRegressor, LinearRegression
from sklearn.metrics import mean_absolute_error, root_mean_squared_error
from sklearn.model_selection import train_test_split

rng = np.random.default_rng(42)
X = rng.uniform(-3, 3, size=(300, 1))
y_clean = 3 * X[:, 0] + 2 + rng.normal(0, 0.3, size=300)
X_train, X_test, y_train_clean, y_test = train_test_split(
    X, y_clean, test_size=100, random_state=42)
y_train = y_train_clean.copy()
contaminated = rng.choice(len(y_train), size=20, replace=False)
y_train[contaminated] += 45
assert len(X_train) == 200 and len(X_test) == 100
assert np.sum(y_train != y_train_clean) == 20
assert np.isfinite(X_train).all() and np.isfinite(y_train).all()
models = {
    'ordinary': LinearRegression(),
    'huber': HuberRegressor(epsilon=1.35, alpha=0.0, max_iter=1000)
}
print('train_test_rows:', len(X_train), len(X_test))
print('contaminated_training_targets:', len(contaminated))
for name, model in models.items():
    model.fit(X_train, y_train)
    pred = model.predict(X_test)
    assert pred.shape == y_test.shape and np.isfinite(pred).all()
    print(name, 'coef:', round(float(model.coef_[0]), 6),
          'intercept:', round(float(model.intercept_), 6),
          'clean_test_MAE:', round(float(mean_absolute_error(y_test, pred)), 6),
          'clean_test_RMSE:', round(float(root_mean_squared_error(y_test, pred)), 6))
huber = models['huber']
normalized_residual = np.abs(y_train - huber.predict(X_train)) / huber.scale_
assert np.array_equal(huber.outliers_, normalized_residual > huber.epsilon)
assert huber.outliers_.shape == (200,)
print('huber_scale:', round(float(huber.scale_), 6))
print('huber_flagged_training_rows:', int(huber.outliers_.sum()))
print('injected_targets_flagged:', int(huber.outliers_[contaminated].sum()))
print('fitted_training_rows:', len(huber.outliers_))

怎样读这个模拟实验的结果

本例实际输出如下。200 行参与训练,100 行保留测试,只有 20 个训练目标被人为改动。

train_test_rows: 200 100
contaminated_training_targets: 20
ordinary coef: 2.183498 intercept: 6.431025 clean_test_MAE: 4.503111 clean_test_RMSE: 4.726193
huber coef: 2.983838 intercept: 2.039493 clean_test_MAE: 0.249959 clean_test_RMSE: 0.318851
huber_scale: 0.214742
huber_flagged_training_rows: 75
injected_targets_flagged: 20
fitted_training_rows: 200

普通回归的斜率约 2.1835、截距约 6.4310,干净测试集 MAE 约 4.5031;Huber 的斜率约 2.9838、截距约 2.0395,MAE 约 0.2500。生成关系的斜率为 3、截距为 2,这次对照中 Huber 更接近它。RMSE 同时给出较大误差的影响,两种模型都在同一测试集计算。

Huber 标记了 75 个训练样本,其中包含全部 20 个被注入污染的目标,也包括其他 55 个样本。75 个标记不等于 75 条错数据;自然噪声和拟合尺度也会影响残差阈值。代码用 abs(y_train-predict)/scale_ > epsilon回算布尔标记,并与 outliers_ 逐条比较。最后 fitted_training_rows 仍为 200,说明被标记样本并没有从这次拟合中删除。

复制运行后,先核对划分数量和污染数量,再看输出是否全部为有限数、回算标记是否与 outliers_ 一致。本文没有用测试集选模型配置;真实任务中应在训练阶段的验证数据上比较候选 epsilon 和正则项,最终测试集留给一次独立评测。

换成真实回归数据时,先查这三个问题

  1. 极端目标是错误还是合法尾部?先回查单位、导出格式、录入来源和标签时间。合法的大额、高值或罕见事件可能正是目标任务的重要部分,不能因为模型残差大就删除。
  2. 特征 X 是否也存在极端值?Huber 针对响应残差减轻影响,但对极端特征形成的高杠杆点并没有自动的全面保护。高杠杆样本可能改变拟合线、甚至留下较小残差;需要结合特征范围、散点图与具体业务规则核查。
  3. 测试数据代表哪种分布?本例故意保留干净测试集,回答“训练目标污染对干净预测的影响”。如果真实使用场景含有合法的极端目标,应保留它们并单独报告尾部误差,不能只展示中间范围的平均分数。

多列特征的量纲差异还要另行处理。Huber 的 scale 作用于残差,不会自动逐列标准化 X;需要缩放时,只在训练数据拟合缩放器。若关系本身强烈非线性、存在分组差异或标签定义混乱,换损失函数不能代替修正模型与数据契约。

epsilon 越小越好吗?

较小 epsilon 会让更多标准化残差进入绝对值损失区域,但可能牺牲一部分对正常噪声的拟合。不要把 outliers_ 标记数量越多当成效果越好,也不要在最终测试集上反复调它。先定义真实错误成本,再用训练阶段的验证集和分组错例比较候选设置。

Ai菜鸟网。发布者:AI小管家,转载请注明出处:https://www.alyyhw.com/30593.html

赞 (0)
AI小管家的头像AI小管家
推荐系统怎么入门?用用户评分建立物品协同过滤示例
上一篇 11小时前
Pipeline 参数怎么设置?用双下划线修改嵌套模型并核对生效
下一篇 11小时前

相关推荐

联系我们

联系我们

1

在线咨询: QQ交谈

邮件:admin@example.com

工作时间:周一至周五,9:30-18:30,节假日休息

关注微信
关注微信
分享本页
返回顶部