通俗易懂之最小二乘法(附matlab和python例子实现)

前言
最小二乘法也称最小平方法,是一种数学优化技术,通过最小化误差的平方和来寻找数据的最佳函数匹配。
感谢各友的鼓励与支持🌹🌹🌹,往期文章都在最后梳理出来了(●'◡'●)
👇👇👇👇👇👇👇👇👇👇👇👇👇👇👇👇👇👇👇👇👇👇👇👇👇👇👇👇👇👇👇👇👇
线性函数模型
典型的一类函数模型是线性函数模型。最简单的线性式是y=b0x+b1写成矩阵形式为:

直接给出该式的参数解:


其中:

为x的算术平均值,也可解得如下形式:

最小二乘法原理
假设结果y与m个因素x[i]有关,且为线性关系,即:
y = k[0] + k[1] * x[1] + k[2] * x[2] + ... + k[m] * x[m]经过测量,现有n组数据(n >= m),求合适的k[i],使得上述表达式与测量结果尽可能的相符。
最小二乘法的做法很简单,让所有残差的平方和最小即可,设p[i]表示第i组测试数据,把k[i]看成未知数,最小化f:
f = (p[1] - y[1]) ^ 2 + (p[2] - y[2]) ^ 2 + ... + (p[n] - y[n]) ^ 2实例分析
这里举个简单例子说明最小二乘法的过程。现要用钱去买游戏币,售币处贴出公示如下:
10元 —— 11个游戏币20元 —— 23个游戏币50元 —— 58个游戏币100元 —— 123个游戏币
显然,付的钱数与得到的游戏币存在某种线性关系,设有:y = ax + b,代入以上数据得:
10a + b = 1120a + b = 2350a + b = 58100a + b = 123
构造残差函数
f = (10a + b - 11) ^ 2 + (20a + b - 23) ^ 2 + (50a + b - 58) ^ 2 + (100a + b - 123) ^ 2
分别对a, b求偏导,并令其等于0,才能使f取得最值。
20(10a + b - 11) + 40(20a + b - 23) + 100(50a + b - 58) + 200(100a + b - 123) = 02(10a + b - 11) + 2(20a + b - 23) + 2(50a + b - 58) + 2(100a + b - 123) = 0
解出结果:a = 1.2439, b = -2.2245,从而关系式为:y = 1.2439x - 2.2245。
有了该表达式,现在可以对未知点进行预测了,例如80块钱,大约可以买97个游戏币,而125元钱大约可以买153个。
python实现
import numpy as npfrom scipy.optimize import leastsqdef func(p, x):k, b = preturn k * x + bdef error(p, x, y):return func(p, x) - yX = np.array([10, 20, 50, 100])Y = np.array([11, 23, 58, 123])P = (0, 0)ret = leastsq(error, P, args=(X, Y))k, b = ret[0]print(k, b)
运行结果:

解出k=1.24388, b=-2.2245,与上面手算的一致。可以通过pyplot将数据以图的形式直观的展现出来。
import numpy as npfrom scipy.optimize import leastsqimport matplotlib.pyplot as pltdef func(p, x):k, b = preturn k * x + bdef error(p, x, y):return func(p, x) - yX = np.array([10, 20, 50, 100])Y = np.array([11, 23, 58, 123])P = (0, 0)ret = leastsq(error, P, args=(X, Y))k, b = ret[0]print(k, b)plt.figure()plt.scatter(X, Y, color='red')x = np.linspace(0, 200, 200)y = k * x + bplt.plot(x, y)plt.show()
运行结果:

matlab实现例子
在matlab中,有现成的曲线拟合函数polyfit,其也是基于最小二乘原理实现的,具体用法为:
ans=polyfit(x,y,n). 其中x,y为待拟合点的坐标向量,n为多项式的阶数。下面代码是用polyfit函数来做曲线拟合:
clearclcx=[2,4,5,6,6.8,7.5,9,12,13.3,15];[~,k]=size(x);y=[-10,-6.9,-4.2,-2,0,2.1,3,5.2,6.4,4.5];for n=1:9ANSS=polyfit(x,y,n); %用polyfit拟合曲线for i=1:n+1 %answer矩阵存储每次求得的方程系数,按列存储answer(i,n)=ANSS(i);endx0=0:0.01:17;y0=ANSS(1)*x0.^n ; %根据求得的系数初始化并构造多项式方程for num=2:1:n+1y0=y0+ANSS(num)*x0.^(n+1-num);endsubplot(3,3,n)plot(x,y,'*')hold onplot(x0,y0)endsuptitle('不同次数方程曲线拟合结果,从1到9阶')

在分析时间与温度关系时,也会用到最小二乘法对其进行拟合。具体事例如下:
例如:对某日隔两小时测一次气温。设时间为ti,气温为Ci,i = 0,2 ,4,…,24。数据如下:
表2 温度(Ci)随时间(ti)变化关系-----------------------------------------------------------ti 0 2 4 6 8 10 12 14 16 18 20 22 24-----------------------------------------------------------ci 15 14 14 16 20 23 28 27 26 25 22 18 16-----------------------------------------------------------
x = [0 2 4 6 8 10 12 14 16 18 20 22 24]y = [15 14 14 16 20 23 26 27 26 25 22 18 16]plot(x,y,'o')grid onhold on% 三阶拟合 得到的 p = -0.0061 0.1474 -0.0246 13.7390是个多项式的系数% 即拟合的曲线y = -0.0061*x3 + 0.1474*x2 - 0.0246*x + 13.7390 (其中x3表示x的3次方,x2同理)p = polyfit(x,y,3)x1 = 0:0.01:24y1 = polyval(p,x1)plot(x1,y1,'r')axis([0 24 12 28]) % axis坐标轴范围设置xlabel('温度(度)');ylabel('时间(点)');title('温度变化图','position', [18,10])
运行结果:

「❤️ 感谢大家」
如果你觉得这篇内容对你挺有有帮助的话:
- 点赞支持下吧,让更多的人也能看到这篇内容(收藏不点赞,都是耍流氓 -_-)
 - 欢迎在留言区与我分享你的想法,也欢迎你在留言区记录你的思考过程。
 - 觉得不错的话,也可以阅读近期梳理的文章(感谢鼓励与支持🌹🌹🌹):
 
- 编程中的惰性思想、
 - PyMySQL数据库搭建
 - 看到这些代码,我自叹不如!!!
 - GitHub 太慢?9 种方案可提速!
 - 图像技术-人像动漫化
 - 提高你的Python编码效率
 - 0.052秒打开100GB数据,这个Python开源库火爆了!
 - 小程序云开发资源的管理
 - 教你用python进行数字化妆,可爱至极
 - 加速Python列表和字典,让你代码更加高效
 - 汇总超全的Matplotlib可视化最有价值的 50 个图表(附完整 Python 源代码)(三)
 - 汇总超全的Matplotlib可视化最有价值的 50 个图表(附完整 Python 源代码)(二)
 - 汇总超全的Matplotlib可视化最有价值的 50 个图表(附完整 Python 源代码)(一)
 - 教你用Python制作实现自定义字符大小的简易小说阅读器
 - 「查缺补漏」巩固你对算法复杂度的理解
 - 汇总了32个为开发者提供的免费工具
 - 教你通过python利用近邻法实现图片缩小后变成另一张图(类似幻影坦克)
 - 30 行代码实现蚂蚁森林自动收能量
 
老铁,三连支持一下,好吗?↓↓↓

欢迎大家加入到知识星球这个大家庭,这里一定有与你志同道合的小伙伴,在这里大家可以一起交流,一起学习,一同吹逼,一同玩耍。。。
长按按钮 “识别二维码” 关注我更多精彩内容等着你哦


点分享

点点赞

点在
