Ransac算法,也称为随机抽样一致性算法,是一种迭代方法,用于从一组包含噪声或异常值的数据中估计数学模型。Ransac算法特别适用于线性回归问题,因为它能够处理包含异常值的数据集,并能够估计出最佳的线性模型。
1 简介
在数据分析和机器学习的领域中,线性回归是一种广泛使用的预测模型。然而,当数据集中包含异常值或噪声时,传统的线性回归方法可能会受到严重影响。为了解决这一问题,Ransac线性回归算法提供了一种稳健的方法来估计线性模型参数。
Ransac算法的核心思想是从数据集中随机选择一个子集作为基础样本,并使用这个子集估计线性模型的参数。然后,它会计算所有数据点到这个模型的误差,并根据一个预设的阈值来判断该模型是否可以接受。如果模型被接受,Ransac算法会继续优化模型参数;否则,它会选择另一个子集并重复这个过程。
在Ransac线性回归中,算法的基本步骤如下:
- 随机选择数据集中的子集作为模型的基础样本。基础样本的大小通常由用户设定,通常为数据集大小的一定比例。
- 使用基础样本估计线性模型的参数,如斜率和截距。
- 计算模型误差,即数据集中每个点与模型预测值之间的距离。
- 判断是否满足停止准则,即是否找到了一个足够好的模型。如果满足,则退出算法;否则,继续迭代。
- 在数据集中选择与当前模型最不一致的点作为异常值,将其从数据集中移除。
- 重复步骤1-5,直到找到一个足够好的模型或者达到最大迭代次数。
Ransac算法的优点在于它能够处理包含异常值的数据集,并能够估计出最佳的线性模型。它的缺点是迭代次数可能较多,计算复杂度较高。另外,Ransac算法对于数据的分布假设敏感,如果数据分布不符合假设,可能会导致算法性能下降。
2 Python代码
# -*- coding: utf-8 -*-
"""
@Time : 2023/10/17 14:13
@Auth : RS迷途小书童
@File :Ransac线性回归.py
@IDE :PyCharm
"""
import numpy as np # 导入numpy库,用于进行数值计算和处理数组
import matplotlib.pyplot as plt # 导入matplotlib库的pyplot模块,用于绘制图形
import random # 导入random库,用于生成随机数
# 定义生成数据集的参数
SIZE = 500 # 数据点的总数
OUT = 230 # 数据的上限
X = np.linspace(0, 100, SIZE) # 生成从0到100,共SIZE个数据点的等差数列
Y = [] # 创建一个空列表,用于存储所有的数据值
# 对于X中的每一个元素,执行以下操作
for i in X:
# 生成一个0到10之间的随机整数,如果这个数大于5,执行下面的if语句,否则执行else语句
if random.randint(0, 10) > 5:
# 从0到OUT之间随机生成一个整数,并添加到Y列表中
Y.append(random.randint(0, OUT))
else:
# 再次生成一个0到10之间的随机整数,如果这个数大于5,执行下面的if语句,否则执行else语句
if random.randint(0, 10) > 5:
# 根据当前元素i和随机生成的数值计算出一个新的y值,并添加到Y列表中
Y.append(3 * i + 10 + 3 * random.random())
else:
Y.append(3 * i + 10 - 3 * random.random()) # 同上,只是计算公式略有不同
list_x = np.array(X) # 将X转换为numpy数组,方便后续的数据处理和计算
list_y = np.array(Y) # 将Y转换为numpy数组,方便后续的数据处理和计算
# 使用matplotlib库绘制原始数据点的散点图
plt.scatter(list_x, list_y) # 在二维平面上绘制原始数据点,使用散点图展示
plt.show() # 显示绘制的图形
def linear_regression(list_x, list_y):
# 进行迭代操作,寻找最佳的线性回归模型参数a和b
iters = 10000 # 迭代次数
epsilon = 3 # 内点的误差阈值
threshold = (SIZE - OUT) / SIZE + 0.01 # 阈值,用于控制早停(early stopping)策略
best_a, best_b = 0, 0 # 最佳线性回归模型的参数,初始值为0
pre_total = 0 # 内点数量的初始值,初始为0
# 进行迭代操作,寻找最佳的线性回归模型参数a和b
for i in range(iters):
# 从SIZE个数据点中随机选择两个点,索引存储在sample_index中
sample_index = random.sample(range(SIZE), 2)
x_1 = list_x[sample_index[0]] # 获取第一个点的x值
x_2 = list_x[sample_index[1]] # 获取第二个点的x值
y_1 = list_y[sample_index[0]] # 获取第一个点的y值
y_2 = list_y[sample_index[1]] # 获取第二个点的y值
# 根据两个点的坐标计算出线性回归模型的斜率a和截距b
a = (y_2 - y_1) / (x_2 - x_1) # 计算斜率a
b = y_1 - a * x_1 # 计算截距b
total_in = 0 # 内点计数器,初始值为0
# 对于每一个数据点,计算其对应的预测值,并与真实值进行比较,如果误差小于epsilon,则认为此点为内点,计数器加1
for index in range(SIZE):
y_estimate = a * list_x[index] + b # 根据线性回归模型计算出预测值
if abs(y_estimate - list_y[index]) < epsilon: # 判断预测值与真实值的误差是否小于epsilon
total_in += 1 # 如果小于epsilon,则此点为内点,计数器加1
# 如果当前的内点数量大于之前所有的内点数量,则更新最佳参数a和b,以及内点数量pre_total
if total_in > pre_total: # 记录最大内点数与对应的参数
pre_total = total_in
best_a = a
best_b = b
# 如果当前的内点数量大于设定的阈值所对应的人数,则跳出循环,不再进行迭代
if total_in > SIZE * threshold: # 如果当前内点数量大于阈值所设定的人数,则跳出循环
break # 跳出循环
print("迭代{}次,a = {}, b = {}".format(i, best_a, best_b)) # 输出当前迭代的次数,以及对应的线性回归模型参数a和b
x_line = list_x # 获取x轴的数据
y_line = best_a * x_line + best_b # 根据最佳线性回归模型计算出y轴的数据
plt.plot(x_line, y_line, c='r') # 使用matplotlib库绘制出线性回归模型的直线图,并用红色表示
plt.scatter(list_x, list_y) # 使用matplotlib库绘制出原始数据的散点图,并用其他颜色表示
plt.show() # 显示绘制的图形
linear_regression(list_x, list_y)
3 总结
Ransac线性回归是一种强大的线性回归方法,尤其适用于处理包含异常值和噪声的数据集。通过随机抽样一致性原则,Ransac算法能够从数据中筛选出可靠的基础样本,并基于此估计线性模型的参数。与传统的线性回归相比,Ransac算法具有更好的鲁棒性、灵活性、计算效率和可解释性。在实际应用中,Ransac线性回归已被广泛应用于各种领域,如回归预测、特征选择和异常检测等。通过与其他技术和方法的结合,Ransac线性回归还有望在未来进一步扩展其应用范围和性能。总之,Ransac线性回归是一种值得深入研究和应用的线性回归方法。