最近接到一个问题:

线性拟合是怎么实现的
线性拟合怎么优化

当时一时兴起的我就马上跑去百度谷歌了一番,发现似乎并没有想象的这么简单,于是先简单总结一下:

线性拟合是什么?

线性拟合是曲线拟合的一种形式。设x和y都是被观测的量,且y是x的函数:y=f(x; b),曲线拟合就是通过x,y的观测值来寻求参数b的最佳估计值,及寻求最佳的理论曲线y=f(x; b)。当函数y=f(x; b)为关于b的i线性函数时,称这种曲线拟合为线性拟合。(摘自百度百科)

说白了,就是将一堆包含x,y值的坐标点放在一个二维平面,然后用尽可能接近每个点的一条曲线去描述它,鉴于问题太多,我这里就先讲讲直线的拟合叭

作为一组数据(x,y各一组应该是两组才对),应该有自己的想法,自己上二维数组的画板才对了呀(python可以用matplotlib.pyplot里的方法简易实现)

好的那么它上去了,我们继续。

线性拟合怎么实现?

这是个好问题,我们想将数据拟合成一条直线,如果是用纸笔我们会怎么做呢
“哎,这么简单,不就是用尺子量到差不多然后画一笔就好了嘛”
“像这样是吧,那我要怎么判断这条线是不是拟合的线呢?”


“你看一哈子不就好咯”

好啦,言归正传,要将这个直线画出来呢,我们都知道一条直线可以用方程表述出来,也就是y = kx + b;其中呢,k 为直线的斜率,b 就是这条直线的 y 截距啦(没别的,就y = kx + b)

最小二乘法

作为一条直线,最重要的就是斜率和截距,作为一个耿直boy,那就直一点,直接将直线的斜率和截距求出来,这时候我们就用到了最小二乘法,而它是干嘛的呢:

最小二乘法(又称最小平方法)是一种数学优化技术。它通过最小化误差的平方和寻找数据的最佳函数匹配。利用最小二乘法可以简便地求得未知的数据,并使得这些求得的数据与实际数据之间误差的平方和为最小。最小二乘法还可用于曲线拟合。其他一些优化问题也可通过最小化能量或最大化熵用最小二乘法来表达。(摘自百度百科)

简单的说,就是求点到直线的垂直距离,根据横坐标来计算点到直线上垂直距离的差值。对这个点的值和拟合直线的距离求和,然后分别对k和b求导的方法来算出k和b的值。具体的求解过程可以看另一篇文章:

文章链接,还没有写,写后修改

距离图就如下啦

#python代码如下:传入x和y两个数组,就会通过求平方和的方式得出结果,b,k的算法原理我会写在最小二乘法的原理上
def linefit(x,y):N=int(len(x))sumx,sumy,sumx2,sumxy=0,0,0,0for i in range(0,N): sumx+=x[i]sumy+=y[i]sumx2+=x[i]**2sumxy+=x[i]*y[i]b=(sumy*sumx2-sumx*sumxy)/(N*sumx2-sumx**2) k=(N*sumxy-sumx*sumy)/(N*sumx2-sumx**2) return b,k

梯度下降法

首先呢,我先来介绍一下梯度下降法:

如果有一个人想下山(没有很多鲁迅走过所成的路),那么怎样才会是下山最快的路呢?
首先,考虑一步能跨多远的距离,也就是步长
其次,我们要考虑向下走,那么我们就牵扯到向量了,将山的高度视为 y 轴,那么向下走最快的当然是走在一步以内能走到的距离内 y 减小的最多的那一步
然后我们每一步都这么考虑,直到到达最底下,于是我们的每一步都是下山相对减少最多的那一步
这样一次次迭代直到最后的极小值便是梯度下降法的结果,而过程则是梯度下降法

再来贴一贴百度百科的,是不是就能看懂了:

梯度下降法(英语:Gradient descent)是一个一阶最优化算法。 要使用梯度下降法找到一个函数的局部极小值,必须向函数上当前点对应梯度(或者是近似梯度)的反方向的规定步长距离点进行迭代搜索。

梯度下降法是一种迭代的思路求最优解,相对应的,我们在计算时,也要收集点到直线的距离,但是与最小二乘法不同的是,我们不需要通过计算直角三角形来得出斜率,因为在每一次迭代的时候我们就可以得出一条拟合的直线,迭代时的拟合直线为 y = ki x +bi
此时提一下损失函数,也就是说,每一个点都不一定完全符合这个拟合的直线,肯定会有差值,这个差值就记为一个名为”损失“的值里,损失函数 Q 就是由每一个点到直线的距离的平方加起来的(是不是有点像最小二乘法,也就是Q = ∑i=1m\sum_{i=1}^m∑i=1m​(yi - (ki x + bi) )2
那么我们要在何时停止呢,就可以设定一个停止的值,当再往下迭代,其损失函数的变化比约定的值小时,即判为梯度下降收敛了,即往下运算的性价比不高了,便可以退出
以下便是大致迭代过程

 epsilon = 0.01  #迭代伐值alpha = 0.001 #迭代速率theta0 = 0 #截距theta1 = 0 #斜率error1 = 0 #当前迭代的损失error0 = 0 #上一次迭代的损失while True:sum0 = 0 sum1 = 0cnt = cnt + 1for i in range(0, len(x)):#计算是线高了还是低了,低了会变成负值diff =y[i] - (theta0 + theta1 * x[i])sum0 = sum0 + diffsum1 = sum1 + diff * x[i]theta0 = theta0 + alpha * sum0 / len(x)#在这次迭代的变化theta1 = theta1 + alpha * sum1 / len(x)#在这次迭代的变化error1 = 0 #重置此次迭代的损失for i in range(0, len(x)):error1 = error1 + (y[i] - (theta0 + theta1 * x[i] )) ** 2 #计算损失if abs(error1 - error0) < epsilon:#损失小于约定值breakelse:error0 = error1

线性拟合的优化

线性拟合的思路我们讲清楚了,那么我们该怎么优化呢?
首先,我们可以分为两个部分:

1:对数据进行筛选
2.:对函数进行优化
3:对函数的结果进行优化

筛选数据

想要使直线尽可能拟合成一个更正确的直线,我们可以舍弃掉一部分特别偏的点

比如这里就出现了一个跟直线打着八竿子远的点,当然,这么远的点对我们的直线拟合的速度肯定是有影响的,我们就应该将这个数据排除在外,筛选出一定范围内拟合直线的点,可以提高对数据的运算速度。
那么我们该怎么筛选出这些点呢?

首先介绍最常用的一种方式:标准偏差筛选法

我们都知道,数据筛选是将相对较远的无用的数据给筛出,那么怎样的距离才算较远呢?如果自定一个常数那么也不能适应所有数据情况,所以这个值我们应该从数据中得出,于是我们想到了标准偏差。
标准偏差很好求,也就是平均方差开方,而平均方差也就是方差和然后除以样本数量求平均值
Avg = 1m\frac{1}{m}m1​∑i=1m\sum_{i=1}^m∑i=1m​(xi-x‾\overline{x}x)2
然后呢,我们以三倍标准方差为阈值,当一个点的标准差大于三倍标准偏差,那么我们就可以认定它为无用值,将其排除。
这种做法的好处就是将一些太偏的数据给除掉,在梯度下降中可以使迭代次数减少

函数优化

以梯度下降为例,之前提到过,我们梯度下降法可以看成是一步一步下山的方法,那么我们该选取怎样的步长则是优化点之一,太长了,我们一不小心就从这座山跨过去了跨到另一座山上;太短了,又要走很多次,导致结果变慢(如图就太长了要反复横跳)

所以说确定步长也是算法中的一个优化点,当然也有公式可以求得最优步长(详情可见armijo算法,太复杂不解释)
然后第二个就是减少参与运算的数据
首先我来介绍三种梯度下降的算法:
1.批量梯度下降法
2.随机梯度下降法
3.小批量梯度下降法

首先是批量梯度下降法,也就是之前的使用所有数据来进行更新,比如我有m个样本,就将所有m个样本用于更新算法,因为是用所有样本,所以当数据量特别大的时候运算速度还是很慢的

第二个就是随机梯度下降法,与批量梯度下降法是两个极端,为了改变批量梯度下降法的缺点,我们每次迭代时都只随机选取一个作为样本,迭代速度就快很多,也就是有m个样本,但是每次更新只选用1个,优点是运算较快,但缺点也显而易见,就是收敛的时候梯度方向变化很大,不容易达到收敛的局部最优解

第三个就是小批量梯度下降法,吸收了批量梯度和随机梯度的优点,我们从m个样本中选若干个(一般选10个)作为样本进行迭代,相比于大量的m来说,小批量的10个运算速度还是非常快的,相比于收敛梯度方向不稳定的随机梯度下降法来说10个样本同时运算的收敛方向变化不算太大,结合了两者的优点

函数结果优化

基于梯度下降来说,梯度下降法找的是损失函数最小的那个值,但是如果所寻找的局部最优值不是全局最优值呢?那么我们最后得到的结果就不一定是最满意的结果,所以我们本应该继续迭代寻找全局最优值
那咋办呢,看到这个坑就想往里跳,跳了还懒得出去。这时候我们就要催一催这个函数继续往前探索一段路,如果在前边找到了比局部最优还好的解,那就替换掉,如果在一定路程还没找到的,那就回去吧。
于是,模拟退火算法就出现啦。

模拟退火算法从某一较高初温出发,伴随温度参数的不断下降,结合概率突跳特性在解空间中随机寻找目标函数的全局最优解,即在局部最优解能概率性地跳出并最终趋于全局最优。(摘自百度百科)

简单地说,在打铁退火就像是往前探索,横坐标即是温度,纵坐标便是铁的柔软程度,在打铁的时候,随着温度下降,铁的柔软程度会逐渐变化,而我们要做的就是在温度区间内找到最坚硬的部分(值最低)
而在解决问题时,横坐标即是问题的迭代次数,纵坐标即是所求的最小值(损失函数最小值),我们要求的就是在规定迭代区间内找出其最小值。

模拟退火的基本思想:
(1) 初始化:初始温度T(充分大),初始解状态S(是算法迭代的起点),每个T值的迭代次数L
(2) 对k=1, …, L做第(3)至第6步:
(3) 产生新解S′
(4) 计算增量ΔT=C(S′)-C(S),其中C(S)为评价函数
(5) 若ΔT<0则接受S′作为新的当前解,否则以概率exp(-ΔT/T)接受S′作为新的当前解.
(6) 如果满足终止条件则输出当前解作为最优解,结束程序。
终止条件通常取为连续若干个新解都没有被接受时终止算法。
(7) T逐渐减少,且T->0,然后转第2步。

然后我再来贴一下“人话”

模拟退火算法:
退火算法是一种贪心算法,但是引入了随机因素,以一种随机概率接收比当前解要差的结果
其中,概率可以根据当前温度以及解的最优程度决定:

概率P、能量差dE、温度T、自然对数e dE = Enew - Eold //新的值减去旧的值
其中dE的值分两种情况:
若dE<0,也就是新的能量值小于旧的能量值,也就是得到趋向于最小值的一个值时,则必定接受 此时的P(dE)将直接为1

若dE>0,也就是新的能量值大于旧的能量值,此时就要考虑是否将这个值采纳,则使用公式:

P(dE) = e(-(dE/T))

其中:T为迭代时的温度,随着迭代次数的增加,T的值将会减小(也就是退火的过程,温度逐渐降低)
随着T降低,dE/T会增大,所以e(-(dE/T))将会趋近于0,所以温度越低,被接受的概率也会随之降低

于是在循环中,我们只需要将温度设置为循环结束条件即可,每次循环将温度递减

/*
T:当前温度
T_min:温度下限
newState:新的状态
oldState:旧的状态
nextState:循环的下一个状态
dE:两个状态的能量差
P(dE):接收新状态的概率
getLow:接受新状态的最低接收值
r:温度递减系数
*/void SA()
{while(T > T_min){dE = E( newState ) - E( oldState );if(dE >= 0){oldState = newState;}else{if( P(dE) > getLow){oldState = newState;}}T = r * T;nextState;}
}

在线性拟合中呢,我们需要找的最小值就是在梯度下降法中有提到过的损失函数Q,当Q最小时,也就是所有点到直线距离都为最短,那么这条直线就是我们要求的直线。
在模拟退火算法中呢,有关键的点,就是初始温度T、结束温度T_min和接受的概率P(dE),其中呢P(dE)是根据温度和前后两种情况的差值决定的,温度越低,取值的概率越低。

数据线性拟合优化之路相关推荐

  1. 基于matlab数据线性拟合回归

    1 选题背景及意义 在统计学中,线性回归是利用称为线性回归方程的最小平方函数对一个或多个自变量和因变量之间关系进行建模的一种回归分析.这种函数是一个或多个称为回归系数的模型参数的线性组合.只有一个自变 ...

  2. python曲线拟合_python如何实现数据的线性拟合

    实验室老师让给数据画一张线性拟合图.不会matlab,就琢磨着用python.参照了网上的一些文章,查看了帮助文档,成功的写了出来 这里用到了三个库 import numpy as np import ...

  3. python数据拟合怎么做的,python如何实现数据的线性拟合

    实验室老师让给数据画一张线性拟合图.不会matlab,就琢磨着用python.参照了网上的一些文章,查看了帮助文档,成功的写了出来 这里用到了三个库 import numpy as np import ...

  4. Python实现部分地区男人身高/体重数据的线性拟合

    # Python实现部分地区男人身高/体重数据的线性拟合 import numpy as np import matplotlib.pyplot as plt from scipy import op ...

  5. python 物理实验_基于Python和梯度下降算法的物理实验数据一元线性拟合方法

    基于 Python 和梯度下降算法的物理实验数据一元线性拟 合方法 关毅铬 ; 程敏熙 [期刊名称] < <物理通报> > [年 ( 卷 ), 期] 2019(000)010 ...

  6. python线性拟合怎么做_python如何实现数据的线性拟合

    实验室老师让给数据画一张线性拟合图.不会matlab,就琢磨着用python.参照了网上的一些文章,查看了帮助文档,成功的写了出来 这里用到了三个库 import numpy as np import ...

  7. Python实现数据的线性拟合

    Python实现对实验数据的函数拟合 数据拟合会涉及到多种拟合方法,本文旨在把本人可能使用到的做一个总结 持续更新ing 1. List item # 线性拟合from scipy import op ...

  8. 100000行级别数据的 Excel 导入优化之路

    大家好,我是不才陈某~ 今天分享一篇大数据量Excel导入如何优化的文章,非常不错. 需求说明 项目中有一个 Excel 导入的需求:缴费记录导入 由实施 / 用户 将别的系统的数据填入我们系统中的 ...

  9. 100000 行级别数据的 Excel 导入优化之路

    点击蓝色"架构文摘"关注我哟 加个"星标",每天上午 09:25,干货推送! 作者: 后青春期的Keats 博客园: cnblogs.com/keatsCode ...

  10. 使用Origin根据数据的二维图(单x,单y)进行线性拟合

    1.对上周画的二维图进行线性拟合,如下gif所示 2.修改拟合后的图像 3.对参数进行解释 第一行 Equation y=a+bx:          拟合的方程的形式是一元一次方程 第二行 Plot ...

最新文章

  1. spring in action小结4.1
  2. BloomFilter算法概述
  3. java学习(100):集合类简介
  4. 定位到元素后获取其属性_Selenium界面自动化测试(4)(Python):元素定位及操作...
  5. LeetCode MySQL 574. 当选者
  6. v-model 维护组件内外数据双向同步
  7. obs命令行工具obsutil的使用测试
  8. Windows10 查看电脑关机时间(提交忘记打卡申请必备)
  9. python绘图颜色代码_Python绘图的颜色设置
  10. 信息系统集成监理费收取标准_信息工程监理取费参考标准.doc
  11. 职业发展的明线与暗线
  12. 德歌:阿里云RDS PG最佳实践
  13. Windows 提示“缺少所需的 CD/DVD 驱动器设备驱动程序”
  14. Room的基本使用(一)
  15. nginx负载均衡(权重)
  16. 数值型数据的表示(1.0)
  17. 梅科尔工作室-江凌宇-鸿蒙笔记3
  18. Windows系统的消息
  19. Kotlin Jetpack Compose remember 给Icon添加透明度 remember 添加参数来记录其位置
  20. 在Word2010中给首字设置下沉

热门文章

  1. PDMS二次开发(十三)——Pipeline Tool升级到E3D版本
  2. Android 语音助手
  3. 555低电平出发定时器
  4. win10下u盘检测的到,但是盘符不显示
  5. Flask - Jinjia2
  6. java中Joiner的使用笔记
  7. SpringBoot整合mybatis一直失败差不到数据,解决方案
  8. C#——NPOI对Excel的操作、导入导出时异常处理(二)
  9. 球面坐标系与指标坐标系转换
  10. 儿研所 计算机训练,金博智慧:注意缺陷、多动障碍儿童计算机认知训练(工作记忆训练)研究...