RANSAC随机采样一致性算法
RANSAC算法的输入是一组观测数据(往往含有较大的噪声或无效点),它是一种重采样技术(resampling technique),通过估计模型参数所需的最小的样本点数,来得到备选模型集合,然后在不断的对集合进行扩充,其算法步骤为:
- 随机的选择估计模型参数所需的最少的样本点。
- 估计出模型的参数。
- 找出在误差 ϵϵ 内,有多少点适合当前这个模型,并将这些点标记为模型内点
- 如果内点的数目占总样本点的比例达到了事先设定的阈值 ττ,那么基于这些内点重新估计模型的参数,并以此为最终模型, 终止程序。
- 否则重复执行1到4步。
RANSAC算法是从输入样本集合的内点的随机子集中学习模型。
RANSAC算法是一个非确定性算法(non-deterministic algorithm),这个算法只能得以一定的概率得到一个还不错的结果,在基本模型已定的情况下,结果的好坏程度主要取决于算法最大的迭代次数。
RANSAC算法在线性和非线性回归中都得到了广泛的应用,而其最典型也是最成功的应用,莫过于在图像处理中处理图像拼接问题,这部分在Opencv中有相关的实现。
从总体上来讲,RANSAC算法将输入样本分成了两个大的子集:内点(inliers)和外点(outliers)。其中内点的数据分布会受到噪声的影响;而外点主要来自于错误的测量手段或者是对数据错误的假设。而RANSAC算法最终的结果是基于算法所确定的内点集合得到的。
下面这份代码是RANSAC的适用实例:
# -*- coding: utf-8 -*-
"""
author : duanxxnj@163.com
time : 2016-07-07-15-36
"""
import numpy as np
import time
from sklearn import linear_model,datasets
import matplotlib.pyplot as plt
# 产生数据样本点集合
# 样本点的特征X维度为1维,输出y的维度也为1维
# 输出是在输入的基础上加入了高斯噪声N(0,10)
# 产生的样本点数目为1000个
n_samples = 1000
X, y, coef = datasets.make_regression(n_samples=n_samples,
n_features=1,
n_informative=1,
noise=10,
coef=True,
random_state=0)
# 将上面产生的样本点中的前50个设为异常点(外点)
# 即:让前50个点偏离原来的位置,模拟错误的测量带来的误差
n_outliers = 50
np.random.seed(int(time.time()) % 100)
X[:n_outliers] = 3 + 0.5 * np.random.normal(size=(n_outliers, 1))
y[:n_outliers] = -3 + 0.5 * np.random.normal(size=n_outliers)
# 用普通线性模型拟合X,y
model = linear_model.LinearRegression()
model.fit(X, y)
# 使用RANSAC算法拟合X,y
model_ransac = linear_model.RANSACRegressor(linear_model.LinearRegression())
model_ransac.fit(X, y)
inlier_mask = model_ransac.inlier_mask_
outlier_mask = np.logical_not(inlier_mask)
# 使用一般回归模型和RANSAC算法分别对测试数据做预测
line_X = np.arange(-5, 5)
line_y = model.predict(line_X[:, np.newaxis])
line_y_ransac = model_ransac.predict(line_X[:, np.newaxis])
print "真实数据参数:", coef
print "线性回归模型参数:", model.coef_
print "RANSAC算法参数: ", model_ransac.estimator_.coef_
plt.plot(X[inlier_mask], y[inlier_mask], '.g', label='Inliers')
plt.plot(X[outlier_mask], y[outlier_mask], '.r', label='Outliers')
plt.plot(line_X, line_y, '-k', label='Linear Regression')
plt.plot(line_X, line_y_ransac, '-b', label="RANSAC Regression")
plt.legend(loc='upper left')
plt.show()
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 48
- 49
- 50
- 51
- 52
- 53
- 54
- 55
- 56
- 57
- 58
- 59
- 60
- 61
- 62
运行结果为:
真实数据参数: 82.1903908408
线性回归模型参数: [ 55.19291974]
RANSAC算法参数: [ 82.08533159]