通俗易懂之最小二乘法(附matlab和python例子實(shí)現(xiàn))

前言
最小二乘法也稱最小平方法,是一種數(shù)學(xué)優(yōu)化技術(shù),通過最小化誤差的平方和來尋找數(shù)據(jù)的最佳函數(shù)匹配。
感謝各友的鼓勵與支持??????,往期文章都在最后梳理出來了(●'?'●)
??????????????????????????????????????????????????????????????????
線性函數(shù)模型
典型的一類函數(shù)模型是線性函數(shù)模型。最簡單的線性式是y=b0x+b1寫成矩陣形式為:

直接給出該式的參數(shù)解:


其中:

為x的算術(shù)平均值,也可解得如下形式:

最小二乘法原理
假設(shè)結(jié)果y與m個(gè)因素x[i]有關(guān),且為線性關(guān)系,即:
y?=?k[0]?+?k[1]?*?x[1]?+?k[2]?*?x[2]?+?...?+?k[m]?*?x[m]經(jīng)過測量,現(xiàn)有n組數(shù)據(jù)(n >= m),求合適的k[i],使得上述表達(dá)式與測量結(jié)果盡可能的相符。
最小二乘法的做法很簡單,讓所有殘差的平方和最小即可,設(shè)p[i]表示第i組測試數(shù)據(jù),把k[i]看成未知數(shù),最小化f:
f?=?(p[1]?-?y[1])?^?2?+?(p[2]?-?y[2])?^?2?+?...?+?(p[n]?-?y[n])?^?2實(shí)例分析
這里舉個(gè)簡單例子說明最小二乘法的過程。現(xiàn)要用錢去買游戲幣,售幣處貼出公示如下:
10元 —— 11個(gè)游戲幣20元?——?23個(gè)游戲幣50元?——?58個(gè)游戲幣100元?——?123個(gè)游戲幣
顯然,付的錢數(shù)與得到的游戲幣存在某種線性關(guān)系,設(shè)有:y = ax + b,代入以上數(shù)據(jù)得:
10a + b = 1120a + b = 2350a + b = 58100a + b = 123
構(gòu)造殘差函數(shù)
f = (10a + b - 11) ^ 2 + (20a + b - 23) ^ 2 + (50a + b - 58) ^ 2 + (100a + b - 123) ^ 2
分別對a, b求偏導(dǎo),并令其等于0,才能使f取得最值。
20(10a + b - 11) + 40(20a + b - 23) + 100(50a + b - 58) + 200(100a + b - 123) = 0?2(10a?+?b?-?11)?+??2(20a?+?b?-?23)?+???2(50a?+?b?-?58)?+???2(100a?+?b?-?123)?=?0
解出結(jié)果:a = 1.2439, b = -2.2245,從而關(guān)系式為:y = 1.2439x - 2.2245。
有了該表達(dá)式,現(xiàn)在可以對未知點(diǎn)進(jìn)行預(yù)測了,例如80塊錢,大約可以買97個(gè)游戲幣,而125元錢大約可以買153個(gè)。
python實(shí)現(xiàn)
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)
運(yùn)行結(jié)果:

解出k=1.24388, b=-2.2245,與上面手算的一致。可以通過pyplot將數(shù)據(jù)以圖的形式直觀的展現(xiàn)出來。
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()
運(yùn)行結(jié)果:

matlab實(shí)現(xiàn)例子
在matlab中,有現(xiàn)成的曲線擬合函數(shù)polyfit,其也是基于最小二乘原理實(shí)現(xiàn)的,具體用法為:
ans=polyfit(x,y,n). 其中x,y為待擬合點(diǎn)的坐標(biāo)向量,n為多項(xiàng)式的階數(shù)。下面代碼是用polyfit函數(shù)來做曲線擬合:
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矩陣存儲每次求得的方程系數(shù),按列存儲answer(i,n)=ANSS(i);endx0=0:0.01:17;y0=ANSS(1)*x0.^n ; %根據(jù)求得的系數(shù)初始化并構(gòu)造多項(xiàng)式方程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('不同次數(shù)方程曲線擬合結(jié)果,從1到9階')

在分析時(shí)間與溫度關(guān)系時(shí),也會用到最小二乘法對其進(jìn)行擬合。具體事例如下:
例如:對某日隔兩小時(shí)測一次氣溫。設(shè)時(shí)間為ti,氣溫為Ci,i = 0,2 ,4,…,24。數(shù)據(jù)如下:
表2 溫度(Ci)隨時(shí)間(ti)變化關(guān)系-----------------------------------------------------------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是個(gè)多項(xiàng)式的系數(shù)% 即擬合的曲線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坐標(biāo)軸范圍設(shè)置xlabel('溫度(度)');ylabel('時(shí)間(點(diǎn))');title('溫度變化圖','position',?[18,10])??
運(yùn)行結(jié)果:

「?? 感謝大家」
如果你覺得這篇內(nèi)容對你挺有有幫助的話:
- 點(diǎn)贊支持下吧,讓更多的人也能看到這篇內(nèi)容(收藏不點(diǎn)贊,都是耍流氓 -_-)
- 歡迎在留言區(qū)與我分享你的想法,也歡迎你在留言區(qū)記錄你的思考過程。
- 覺得不錯(cuò)的話,也可以閱讀近期梳理的文章(感謝鼓勵與支持??????):
- 編程中的惰性思想、
- PyMySQL數(shù)據(jù)庫搭建
- 看到這些代碼,我自嘆不如?。?!
- GitHub 太慢?9 種方案可提速!
- 圖像技術(shù)-人像動漫化
- 提高你的Python編碼效率
- 0.052秒打開100GB數(shù)據(jù),這個(gè)Python開源庫火爆了!
- 小程序云開發(fā)資源的管理
- 教你用python進(jìn)行數(shù)字化妝,可愛至極
- 加速Python列表和字典,讓你代碼更加高效
- 匯總超全的Matplotlib可視化最有價(jià)值的 50 個(gè)圖表(附完整 Python 源代碼)(三)
- 匯總超全的Matplotlib可視化最有價(jià)值的 50 個(gè)圖表(附完整 Python 源代碼)(二)
- 匯總超全的Matplotlib可視化最有價(jià)值的 50 個(gè)圖表(附完整 Python 源代碼)(一)
- 教你用Python制作實(shí)現(xiàn)自定義字符大小的簡易小說閱讀器?
- 「查缺補(bǔ)漏」鞏固你對算法復(fù)雜度的理解
- 匯總了32個(gè)為開發(fā)者提供的免費(fèi)工具
- 教你通過python利用近鄰法實(shí)現(xiàn)圖片縮小后變成另一張圖(類似幻影坦克)
- 30 行代碼實(shí)現(xiàn)螞蟻森林自動收能量
老鐵,三連支持一下,好嗎?↓↓↓

歡迎大家加入到知識星球這個(gè)大家庭,這里一定有與你志同道合的小伙伴,在這里大家可以一起交流,一起學(xué)習(xí),一同吹逼,一同玩耍。。。
長按按鈕? “識別二維碼”?關(guān)注我更多精彩內(nèi)容等著你哦


點(diǎn)分享

點(diǎn)點(diǎn)贊

點(diǎn)在
