最小二乘法以及RANSAC(随机采样一致性)思想及实现

线性回归–最小二乘法(Least Square Method)

线性回归:

什么是线性回归?
举个例子,某商品的利润在售价为2元、5元、10元时分别为4元、10元、20元, 我们很容易得出商品的利润与售价的关系符合直线:y=2x. 在上面这个简单的一元线性回归方程中,我们称“2”为回归系数,即斜率为其回归系数。 回归系数表示商品的售价(x)每变动一个单位,其利润(y)与之对应的变动关系。
在这里插入图片描述
线性回归表示这些离散的点总体上“最逼近”哪条直线。
实现方法:
• 它通过最小化误差的平方和,寻找数据的最佳函数匹配。
• 利用最小二乘法可以简便地求得未知的数据,并使得这些求得的数据与实际数据之间误差的平方 和为最小。
• 假设我们现在有一系列的数据点(xi,yi) (i=1,…,m),那么由我们给出的拟合函数h(x)得到的估计量就 是h(xi)
• 残差:ri = h(xi) – yi

最小二乘法(Least Square Method)的概念

• 残差:ri = h(xi) – yi
• 三种范数:
1.∞-范数:残差绝对值的最大值,即所有数据点中残差距离的最大值:
在这里插入图片描述
2. 1-范数:绝对残差和,即所有数据点残差距离之和:
在这里插入图片描述
3. 2-范数:残差平方和:
在这里插入图片描述
• 拟合程度,用通俗的话来讲,就是我们的拟合函数h(x)与待求解的函数y之间的相似性。那么 2-范数越小,自然相似性就比较高了。

最小二乘法的定义:

由此,我们可以写出最小二乘法的定义了:
在这里插入图片描述
这是一个无约束的最优化问题,分别对k和b求偏导,然后令偏导数为0,即可获得极值点。在这里插入图片描述

最小二乘法的代码实现:

import pandas as pdsales=pd.read_csv('train_data.csv',sep='\s*,\s*',engine='python')  #读取CSV
X=sales['X'].values    #存csv的第一列
Y=sales['Y'].values    #存csv的第二列#初始化赋值
s1 = 0     
s2 = 0
s3 = 0     
s4 = 0
n = 4       ####你需要根据的数据量进行修改#循环累加
for i in range(n):s1 = s1 + X[i]*Y[i]     #X*Y,求和s2 = s2 + X[i]          #X的和s3 = s3 + Y[i]          #Y的和s4 = s4 + X[i]*X[i]     #X**2,求和#计算斜率和截距
k = (s2*s3-n*s1)/(s2*s2-s4*n)
b = (s3 - k*s2)/n
print("Coeff: {} Intercept: {}".format(k, b))

实验结果:

输入:
在这里插入图片描述
输出:
无

RANSAC(随机采样一致性)

RANSAC与最小二乘法

• 生产实践中的数据往往会有一定的偏差。
• 例如我们知道两个变量X与Y之间呈线性关系,Y=aX+b,我们想确定参数a与b的具体值。通过实验, 可以得到一组X与Y的测试值。虽然理论上两个未知数的方程只需要两组值即可确认,但由于系统误 差的原因,任意取两点算出的a与b的值都不尽相同。我们希望的是,最后计算得出的理论模型与测 试值的误差最小。
• 最小二乘法:通过计算最小均方差关于参数a、b的偏导数为零时的值。事实上,很多情况下,最小 二乘法都是线性回归的代名词。
• 遗憾的是,最小二乘法只适合于误差较小的情况。
• 在模型确定以及最大迭代次数允许的情况下,RANSAC总是能找到最优解。(对于包含80%误差的数 据集,RANSAC的效果远优于直接的最小二乘法。)
• 由于一张图片中像素点数量大,采用最小二乘法运算量大,计算速度慢。
在这里插入图片描述
比如说:上图,通过肉眼很明显可以看出来拟合的线应该是蓝色的,然而经过最小二乘法后得到的是红色的线。

RANSAC的步骤:

RANSAC算法的输入:

  1. 一组观测数据(往往含有较大的噪声或无效点),
  2. 一个用于解释观测数据的参数化模型
  3. 一些可信的参数。
    RANSAC算法的实现:
  4. 在数据中随机选择几个点设定为内群
  5. 计算适合内群的模型
  6. 把其它刚才没选到的点带入刚才建立的模型中,计算是否为内群
  7. 记下内群数量
  8. 重复以上步骤
  9. 比较哪次计算中内群数量最多,内群最多的那次所建的模型就是我们所要求的解
    注意:不同问题对应的数学模型不同,因此在计算模型参数时方法必定不同,RANSAC的作用不在于计 算模型参数,而是提供更好的输入数据(样本)。(这导致ransac的缺点在于要求数学模型已知)

RANSAC的参数确定:

这里有几个问题:

  1. 一开始的时候我们要随机选择多少点(n)
  2. 以及要重复做多少次(k)

• 假设每个点是真正内群的概率为 w: w = 内群的数目/(内群数目+外群数目)
• 通常我们不知道 w 是多少, w^n是所选择的n个点都是内群的机率, 1-w^n 是所选择的n个点至少有一个 不是内群的机率, (1 − wn)k 是表示重复 k 次都没有全部的n个点都是内群的机率, 假设算法跑 k 次以后 成功的机率是p,那么, 1 − p = (1 − wn)k p = 1 − (1 − wn)k
• 我们可以通过P反算得到抽取次数K,K=log(1-P)/log(1-w^n)
• 所以如果希望成功机率高:
• 当n不变时,k越大,则p越大; 当w不变时,n越大,所需的k就越大。
• 通常w未知,所以n 选小一点比较好。

RANSAC的代码实现:

import numpy as np
import scipy as sp
import scipy.linalg as sldef ransac(data, model, n, k, t, d, debug = False, return_all = False):"""输入:data - 样本点model - 假设模型:事先自己确定n - 生成模型所需的最少样本点k - 最大迭代次数t - 阈值:作为判断点满足模型的条件d - 拟合较好时,需要的样本点最少的个数,当做阈值看待输出:bestfit - 最优拟合解(返回nil,如果未找到)iterations = 0bestfit = nil #后面更新besterr = something really large #后期更新besterr = thiserrwhile iterations < k {maybeinliers = 从样本中随机选取n个,不一定全是局内点,甚至全部为局外点maybemodel = n个maybeinliers 拟合出来的可能符合要求的模型alsoinliers = emptyset #满足误差要求的样本点,开始置空for (每一个不是maybeinliers的样本点){if 满足maybemodel即error < t将点加入alsoinliers }if (alsoinliers样本点数目 > d) {%有了较好的模型,测试模型符合度bettermodel = 利用所有的maybeinliers 和 alsoinliers 重新生成更好的模型thiserr = 所有的maybeinliers 和 alsoinliers 样本点的误差度量if thiserr < besterr{bestfit = bettermodelbesterr = thiserr}}iterations++}return bestfit"""iterations = 0bestfit = Nonebesterr = np.inf #设置默认值best_inlier_idxs = Nonewhile iterations < k:maybe_idxs, test_idxs = random_partition(n, data.shape[0])print ('test_idxs = ', test_idxs)maybe_inliers = data[maybe_idxs, :] #获取size(maybe_idxs)行数据(Xi,Yi)test_points = data[test_idxs] #若干行(Xi,Yi)数据点maybemodel = model.fit(maybe_inliers) #拟合模型test_err = model.get_error(test_points, maybemodel) #计算误差:平方和最小print('test_err = ', test_err <t)also_idxs = test_idxs[test_err < t]print ('also_idxs = ', also_idxs)also_inliers = data[also_idxs,:]if debug:print ('test_err.min()',test_err.min())print ('test_err.max()',test_err.max())print ('numpy.mean(test_err)',numpy.mean(test_err))print ('iteration %d:len(alsoinliers) = %d' %(iterations, len(also_inliers)) )# if len(also_inliers > d):print('d = ', d)if (len(also_inliers) > d):betterdata = np.concatenate( (maybe_inliers, also_inliers) ) #样本连接bettermodel = model.fit(betterdata)better_errs = model.get_error(betterdata, bettermodel)thiserr = np.mean(better_errs) #平均误差作为新的误差if thiserr < besterr:bestfit = bettermodelbesterr = thiserrbest_inlier_idxs = np.concatenate( (maybe_idxs, also_idxs) ) #更新局内点,将新点加入iterations += 1if bestfit is None:raise ValueError("did't meet fit acceptance criteria")if return_all:return bestfit,{'inliers':best_inlier_idxs}else:return bestfitdef random_partition(n, n_data):"""return n random rows of data and the other len(data) - n rows"""all_idxs = np.arange(n_data) #获取n_data下标索引np.random.shuffle(all_idxs) #打乱下标索引idxs1 = all_idxs[:n]idxs2 = all_idxs[n:]return idxs1, idxs2class LinearLeastSquareModel:#最小二乘求线性解,用于RANSAC的输入模型    def __init__(self, input_columns, output_columns, debug = False):self.input_columns = input_columnsself.output_columns = output_columnsself.debug = debugdef fit(self, data):#np.vstack按垂直方向(行顺序)堆叠数组构成一个新的数组A = np.vstack( [data[:,i] for i in self.input_columns] ).T #第一列Xi-->行XiB = np.vstack( [data[:,i] for i in self.output_columns] ).T #第二列Yi-->行Yix, resids, rank, s = sl.lstsq(A, B) #residues:残差和return x #返回最小平方和向量   def get_error(self, data, model):A = np.vstack( [data[:,i] for i in self.input_columns] ).T #第一列Xi-->行XiB = np.vstack( [data[:,i] for i in self.output_columns] ).T #第二列Yi-->行YiB_fit = sp.dot(A, model) #计算的y值,B_fit = model.k*A + model.berr_per_point = np.sum( (B - B_fit) ** 2, axis = 1 ) #sum squared error per rowreturn err_per_pointdef test():#生成理想数据n_samples = 500 #样本个数n_inputs = 1 #输入变量个数n_outputs = 1 #输出变量个数A_exact = 20 * np.random.random((n_samples, n_inputs))#随机生成0-20之间的500个数据:行向量perfect_fit = 60 * np.random.normal( size = (n_inputs, n_outputs) ) #随机线性度,即随机生成一个斜率B_exact = sp.dot(A_exact, perfect_fit) # y = x * k#加入高斯噪声,最小二乘能很好的处理A_noisy = A_exact + np.random.normal( size = A_exact.shape ) #500 * 1行向量,代表XiB_noisy = B_exact + np.random.normal( size = B_exact.shape ) #500 * 1行向量,代表Yiif 1:#添加"局外点"n_outliers = 100all_idxs = np.arange( A_noisy.shape[0] ) #获取索引0-499np.random.shuffle(all_idxs) #将all_idxs打乱outlier_idxs = all_idxs[:n_outliers] #100个0-500的随机局外点A_noisy[outlier_idxs] = 20 * np.random.random( (n_outliers, n_inputs) ) #加入噪声和局外点的XiB_noisy[outlier_idxs] = 50 * np.random.normal( size = (n_outliers, n_outputs)) #加入噪声和局外点的Yi#setup model all_data = np.hstack( (A_noisy, B_noisy) ) #形式([Xi,Yi]....) shape:(500,2)500行2列input_columns = range(n_inputs)  #数组的第一列x:0output_columns = [n_inputs + i for i in range(n_outputs)] #数组最后一列y:1debug = Falsemodel = LinearLeastSquareModel(input_columns, output_columns, debug = debug) #类的实例化:用最小二乘生成已知模型linear_fit,resids,rank,s = sp.linalg.lstsq(all_data[:,input_columns], all_data[:,output_columns])#run RANSAC 算法ransac_fit, ransac_data = ransac(all_data, model, 50, 1000, 7e3, 300, debug = debug, return_all = True)if 1:import pylabsort_idxs = np.argsort(A_exact[:,0])A_col0_sorted = A_exact[sort_idxs] #秩为2的数组if 1:pylab.plot( A_noisy[:,0], B_noisy[:,0], 'k.', label = 'data' ) #散点图pylab.plot( A_noisy[ransac_data['inliers'], 0], B_noisy[ransac_data['inliers'], 0], 'bx', label = "RANSAC data" )else:pylab.plot( A_noisy[non_outlier_idxs,0], B_noisy[non_outlier_idxs,0], 'k.', label='noisy data' )pylab.plot( A_noisy[outlier_idxs,0], B_noisy[outlier_idxs,0], 'r.', label='outlier data' )pylab.plot( A_col0_sorted[:,0],np.dot(A_col0_sorted,ransac_fit)[:,0],label='RANSAC fit' )pylab.plot( A_col0_sorted[:,0],np.dot(A_col0_sorted,perfect_fit)[:,0],label='exact system' )pylab.plot( A_col0_sorted[:,0],np.dot(A_col0_sorted,linear_fit)[:,0],label='linear fit' )pylab.legend()pylab.show()if __name__ == "__main__":test()

实现结果:
在这里插入图片描述

注意:特别注意:这个算法应该数据是随机初始的,可能出现did't meet fit acceptance criteria的错误,多运行几次有几率解决。
结果很明显可以看出:ransac模型比linear模型更加接近exact system。

RANSAC的应用:

全景拼接:
流程:

  1. 针对某个场景拍摄多张/序列图像
  2. 通过匹配特征(sift匹配)计算下一张图像与上一张图像之间的变换结构。
  3. 图像映射,将下一张图像叠加到上一张图像的坐标系中
  4. 变换后的融合/合成
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述

RANSAC的优缺点:

优点:

  1. 它能鲁棒的估计模型参数。例如,它能从包含大量局外点的数据集中估计出高精度的参数。

缺点:

  1. 它计算参数的迭代次数没有上限;如果设置迭代次数的上限,得到的结果可能不是最优的结果,甚至可能得到错误的结果。
  2. RANSAC只有一定的概率得到可信的模型,概率与迭代次数成正比。
  3. 它要求设置跟问题相关的阀值。
  4. RANSAC只能从特定的数据集中估计出一个模型,如果存在两个(或多个)模型,RANSAC不能找到 别的模型。
  5. 要求数学模型已知(这个缺点最致命)

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/389512.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

软键盘弹起,导致底部被顶上去

计算出可视界面的高度&#xff0c;当软键盘弹起时让底部元素隐藏掉&#xff0c;当键盘收起时再让它显示&#xff0c;实在没办法时这种方法也不失为一种方法1 var hdocument.documentElement.clientHeight; 2 $(window).resize(function(){ 3 let heightdocument.documentEl…

关于LaaS,PaaS,SaaS一些个人的理解

关于LaaS,PaaS,SaaS一些个人的理解 关于LaaS,PaaS,SaaS一些个人的理解 其实如果从整个程序运营的角度来考虑比较好 第一个LaaS 这个也叫做Haas 就是硬件或者基础设置即服务 比如现在的 aws azure 阿里云 腾讯云 百度云 都是提供服务器基础设置服务的 包括服务器的硬件…

糖药病数据集分类_使用optuna和mlflow进行心脏病分类器调整

糖药病数据集分类背景 (Background) Data science should be an enjoyable process focused on delivering insights and real benefits. However, that enjoyment can sometimes get lost in tools and processes. Nowadays it is important for an applied data scientist to…

Android MVP 框架

为什么80%的码农都做不了架构师&#xff1f;>>> 前言 根据网络上的MVP套路写了一个辣鸡MVP DEMO 用到的 android studio MVPHelper插件,方便自动生成框架代码rxjavaretrofit什么是MVP MVP就是英文的Model View Presenter&#xff0c;然而实际分包并不是只有这三个包…

相似图像搜索的哈希算法思想及实现(差值哈希算法和均值哈希算法)

图像相似度比较哈希算法: 什么是哈希&#xff08;Hash&#xff09;&#xff1f; • 散列函数&#xff08;或散列算法&#xff0c;又称哈希函数&#xff0c;英语&#xff1a;Hash Function&#xff09;是一种从任何一种数据中创建小 的数字“指纹”的方法。散列函数把消息或数…

腾讯云AI应用产品总监王磊:AI 在传统产业的最佳实践

欢迎大家前往腾讯云社区&#xff0c;获取更多腾讯海量技术实践干货哦~ 背景&#xff1a;5月23-24日&#xff0c;以“焕启”为主题的腾讯“云未来”峰会在广州召开&#xff0c;广东省各级政府机构领导、海内外业内学术专家、行业大咖及技术大牛等在现场共议云计算与数字化产业创…

标准化(Normalization)和归一化实现

概念&#xff1a; 原因&#xff1a; 由于进行分类器或模型的建立与训练时&#xff0c;输入的数据范围可能比较大&#xff0c;同时样本中各数据可 能量纲不一致&#xff0c;这样的数据容易对模型训练或分类器的构建结果产生影响&#xff0c;因此需要对其进行标准 化处理&#x…

Toast源码深度分析

目录介绍 1.最简单的创建方法 1.1 Toast构造方法1.2 最简单的创建1.3 简单改造避免重复创建1.4 为何会出现内存泄漏1.5 吐司是系统级别的 2.源码分析 2.1 Toast(Context context)构造方法源码分析2.2 show()方法源码分析2.3 mParams.token windowToken是干什么用的2.4 schedul…

序列化框架MJExtension详解 + iOS ORM框架

当开发中你的模型中属性名称和 字典(JSON/XML) 中的key 不能一一对应时, 或者当字典中嵌套了多层字典数组时..., 以及教你如何用 MJExtension 配置类来统一管理你的模型配置, 下面罗列了开发中常见的一些特殊情况, 请参考!(MJExtension/github) 最基本用法: // 将字典转为模型 …

运行keras出现 FutureWarning: Passing (type, 1) or ‘1type‘ as a synonym of type is deprecated解决办法

运行keras出现 FutureWarning: Passing (type, 1) or ‘1type’ as a synonym of type is deprecated; in a future version of numpy, 原则来说&#xff0c;没啥影响&#xff0c;还是能运行&#xff0c;但是看着难受 解决办法&#xff1a; 点击蓝色的链接&#xff1a; 进入 …

RedirectToAction()转移方式及参数传递

今天在做一个功能的时&#xff0c;使用RedirectToAction()需要从这里传几个参数&#xff0c;从网上查了一下&#xff0c;这样解决。真好。 Return RedirectToAction("Index","ManageInfo",new{type0,page1});转载于:https://www.cnblogs.com/ZaraNet/p/978…

软件项目风险管理

近几年来软件开发技术、工具都有了很大的进步&#xff0c;但是软件项目开发超时、超支、甚至不能满足用户需求而根本没有得到实际使用的情况仍然比比皆是。软件项目开发和管理中一直存在着种种不确定性&#xff0c;严重影响着项目的顺利完成和提交。但这些软件风险并未得到充分…

mongdb 群集_群集文档的文本摘要

mongdb 群集This is a part 2 of the series analyzing healthcare chart notes using Natural Language Processing (NLP)这是使用自然语言处理(NLP)分析医疗保健图表笔记的系列文章的第2部分。 In the first part, we talked about cleaning the text and extracting sectio…

keras框架实现手写数字识别

详细细节可学习从零开始神经网络&#xff1a;keras框架实现数字图像识别详解&#xff01; 代码实现&#xff1a; [1]将训练数据和检测数据加载到内存中(第一次运行需要下载数据&#xff0c;会比较慢): &#xff08;mnist是手写数据集&#xff09; train_images是用于训练系统…

gdal进行遥感影像读写_如何使用遥感影像进行矿物勘探

gdal进行遥感影像读写Meet Jose Manuel Lattus, a geologist from Chile. In the latest Soar Cast, he discusses his work in mineral exploration and environmental studies, and explains how he makes a living by creating valuable information products based on diff…

从零开始神经网络:keras框架实现数字图像识别详解!

接口实现可参考&#xff1a;keras框架实现手写数字识别 思路&#xff1a; 我们的代码要导出三个接口&#xff0c;分别完成以下功能&#xff1a; 初始化initialisation&#xff0c;设置输入层&#xff0c;中间层&#xff0c;和输出层的节点数。训练train:根据训练数据不断的更…

大数据学习第一贴

搞了这么久的开发&#xff0c;一直没有养成发博客的习惯&#xff0c;今天开始对大数据所需内容进行总结性记录&#xff0c;并对以后遇到的问题形成一个自己的知识库。就这些&#xff01;转载于:https://blog.51cto.com/13921538/2299765

推荐算法的先验算法的连接_数据挖掘专注于先验算法

推荐算法的先验算法的连接So here we are diving into the world of data mining this time, let’s begin with a small but informative definition;因此&#xff0c;这一次我们将进入数据挖掘的世界&#xff0c;让我们从一个小的但内容丰富的定义开始&#xff1b; 什么是数…

Android 页面多状态布局管理

一、现状 页面多状态布局是开发中常见的需求&#xff0c;即页面在不同状态需要显示不同的布局&#xff0c;实现的方式也比较多&#xff0c;最简单粗暴的方式就是在 XML 中先将不同状态对应的布局隐藏起来&#xff0c;根据需要改变其可见状态&#xff0c;如果多个界面公用相同的…

Tensorflow入门神经网络代码框架

Tensorflow—基本用法 使用图 (graph) 来表示计算任务.在被称之为 会话 (Session) 的上下文 (context) 中执行图.使用 tensor 表示数据.通过 变量 (Variable) 维护状态.使用 feed 和 fetch 可以为任意的操作(arbitrary operation)赋值或者从其中获取数据。 • TensorFlow 是一…