用 RANSAC 从含异常点的数据中恢复线性关系

原文:The scikit-learn developers,Robust linear model estimation using RANSAC。中文翻译与技术整理:未完纪。代码 BSD-3-Clause;2026-10-05 核对 stable 文档(页面标示 1.9.1)。

RANSAC流程图:合成1000条数据并修改50条,普通回归使用全部样本,RANSAC通过候选一致性集合拟合,再比较系数和内点掩码。
图:两种拟合路径的概念示意,未完纪原创;不是本轮运行输出或拟合结果截图。

少量偏离主趋势的观测,就可能明显改变普通线性回归的拟合方向。本例用完全合成的数据演示 RANSAC(随机采样一致性)如何估计一个更稳健的线性关系:普通回归使用所有点,RANSAC 则识别内点与外点,并用识别出的内点拟合最终模型。这里的“外点”是相对于模型假设而言,不是对数据真实性的判决。

本文依据 scikit-learn 官方完整示例翻译整理。全部代码和原文输出仅作静态核对;没有在本轮执行,不能据此宣称复现成功。

生成已知答案的数据

示例用 make_regression 生成 1,000 条观测,只含一个特征与一个有效特征,噪声参数为 10。coef=True 让函数同时返回生成数据的真实系数,便于随后比较估计值。random_state=0 固定此数据生成步骤的随机性。接下来不是简单在既有目标上加一点噪声,而是直接替换前 50 条记录的 X 与 y:输入集中在 3 附近,目标集中在 -3 附近,因此形成偏离主关系的一组观测。

拟合、检查掩码并画出两条线

下面保留源文的完整计算流程与参数,只将解释性注释译为中文。它需要 NumPy、Matplotlib 与 scikit-learn;应在自己管理的隔离项目环境中使用相容版本。源示例没有读取本地数据、下载样本或访问网络。

# Authors: The scikit-learn developers
# SPDX-License-Identifier: BSD-3-Clause
# 中文注释由未完纪整理;计算逻辑与源示例一致。
import numpy as np
from matplotlib import pyplot as plt
from sklearn import datasets, linear_model

n_samples = 1000
n_outliers = 50

X, y, coef = datasets.make_regression(
    n_samples=n_samples,
    n_features=1,
    n_informative=1,
    noise=10,
    coef=True,
    random_state=0,
)

# 注入偏离主趋势的观测
np.random.seed(0)
X[:n_outliers] = 3 + 0.5 * np.random.normal(size=(n_outliers, 1))
y[:n_outliers] = -3 + 10 * np.random.normal(size=n_outliers)

# 普通回归:使用全部样本
lr = linear_model.LinearRegression()
lr.fit(X, y)

# RANSAC:估计一致性集合并拟合稳健模型
ransac = linear_model.RANSACRegressor()
ransac.fit(X, y)
inlier_mask = ransac.inlier_mask_
outlier_mask = np.logical_not(inlier_mask)

# 生成用于展示拟合直线的横坐标
line_X = np.arange(X.min(), X.max())[:, np.newaxis]
line_y = lr.predict(line_X)
line_y_ransac = ransac.predict(line_X)

print("Estimated coefficients (true, linear regression, RANSAC):")
print(coef, lr.coef_, ransac.estimator_.coef_)

lw = 2
plt.scatter(
    X[inlier_mask], y[inlier_mask],
    color="yellowgreen", marker=".", label="Inliers",
)
plt.scatter(
    X[outlier_mask], y[outlier_mask],
    color="gold", marker=".", label="Outliers",
)
plt.plot(line_X, line_y, color="navy", linewidth=lw, label="Linear regressor")
plt.plot(
    line_X, line_y_ransac,
    color="cornflowerblue", linewidth=lw, label="RANSAC regressor",
)
plt.legend(loc="lower right")
plt.xlabel("Input")
plt.ylabel("Response")
plt.show()

inlier_mask_ 是与样本位置对应的布尔数组。将它用于 X 和 y 的同一行,才能在图中正确区分内点与外点。np.logical_not 得到其补集。不要把“注入了 50 个异常点”理解成 RANSAC 必然恰好排除这 50 个点;模型按自身残差准则判断,分类结果可能与人工注入位置不同。

lr.coef_ 来自普通线性回归;ransac.estimator_.coef_ 来自 RANSAC 最终拟合的基础回归器。两者与数据生成函数返回的 coef 比较,展示的是在这个构造场景中恢复主线性关系的能力。line_X 使用 np.arange,步长默认为 1;它只是画线用的横坐标集合,并不是新采集的验证样本。

如何阅读原站给出的结果

原站RANSAC拟合图:黄绿色内点沿主趋势排列,金色外点位于右侧;浅蓝RANSAC斜率比海军蓝普通回归更陡。
原站示例拟合结果,© 2007–2026 The scikit-learn developers;原图转载,非本文执行或泛化评估。

源页面展示的系数依次为真实值 82.1903908407869、普通回归约 54.17236387、RANSAC 约 82.08533159。它们说明在原作者这一轮运行中,普通最小二乘被异常观测拉偏,而 RANSAC 的斜率更接近已知真值。这些数字属于原站示例输出,本轮没有重算;页面所列 0.095 秒运行时间也不是本文的性能测试。

图上黄绿色与金色分别表示模型判为内点与外点的样本,海军蓝与浅蓝线分别表示普通回归与 RANSAC。颜色编码所表达的是模型处理结果,不是一个独立标注数据集的分类准确率。原文没有训练集与测试集拆分,因此这张拟合图也不能充当泛化评估。

静态审核与迁移边界

本例未发现硬编码凭证、外部命令调用、文件删除、动态执行或网络注入入口。np.random.seed(0) 修改的是 NumPy 的进程级随机状态;放入较大程序时可能影响其他随机流程。源文没有给 RANSACRegressor 单独传入 random_state,它的可复现性依赖运行上下文。若改成 RANSACRegressor(random_state=0),这是一个明确的编辑修改:它固定估计器自己的随机入口,但也可能改变原站数值,不能继续把上述系数当作保证输出。

迁移到真实问题时,需要根据量纲和业务允许的误差检查残差阈值、采样次数和基础模型是否合适。离群数据可能代表错误,也可能代表第二种有效机制。先保存被排除样本供核查,再决定是否采用结果;不要仅因掩码为 False 就删除业务记录。

署名与许可:© 2007–2026 The scikit-learn developers。示例代码标记 BSD-3-Clause;完整许可附于本文末尾,并可查阅官方许可。中文翻译、技术说明和原创示意图由未完纪整理。中文翻译及编辑标注日期:2026-10-05。

版权与许可全文

以下保留本页涉及的来源材料或示例代码的版权、许可条件与免责声明;各自适用范围依原声明。中文翻译及编辑标注:未完纪,2026-10-05。

LICENSE-source.txt

BSD 3-Clause License

Copyright (c) 2007-2026 The scikit-learn developers.
All rights reserved.

Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:

* Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
* Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
© 版权声明
THE END
喜欢就支持一下吧
点赞0 分享
评论 抢沙发

请登录后发表评论

    暂无评论内容