一元一階線性擬合:
假設存在一條線性函數盡量能滿足所有的點:y=ax+b .對所有點的的公式為:

殘差值β = 實際值y - 估計值y,β 應盡量小,當 β = 0 時,則完全符合一元線性方程:y=ax+b

通過最小二乘法計算殘差和最小:

根據微積分,當 Q 對 a、b 的一階偏導數為了0時,Q 達到最小。

解方程組,求 a、b 的值:


示例:

如客戶的貸款金額及還款金額情況,設 x 為貸款金額,預測Y為還款金額。(也可以當做收入與消費的情況)
通過公式計算相應的值:

解得:
a = 655131.86/2194469.14 = 0.2985
b = 172.64-a*598.24 = -5.93464
即得回歸方程為: Ÿ = 0.2985*x - 5.93464
回歸方程驗證:

Y 的第 i 個觀察值與樣本值的離差 ,點與回歸線在 Y 軸上的距離。總離差分解為兩部分為:

實際觀測值與回歸擬合值之差,為回歸直線不能解釋的部分:

樣本回歸擬合值與觀測值的平均值之差,為回歸直線可解釋的部分:

其中,設總體平方和為:

即得 回歸平方和為:

殘差平方和為:

即: TSS=ESS+RSS
樣本中,TSS不變, 如果實際觀測點離樣本回歸線越近,則ESS在TSS中占的比重越大.
擬合優度:

R2 為(樣本)可決系數/判定系數(coefficient of determination),取值范圍:[0,1]。R2越接近1,說明實際觀測點離樣本線越近,擬合優度越高。一般地要求R2≥0.7。

計算結果;
R2 = 1 - 72279.48 / 267861.07 = 0.73016
python 方法實現:
#-*- coding: utf-8 -*- # python 3.5.0 import numpy as np import pandas as pd import matplotlib.pyplot as plt from sklearn.linear_model import LinearRegression df = pd.read_table('D:/Python35/mypy/test.txt') x = np.asarray(df[['x']]) y = np.asarray(df[['y']]) reg = LinearRegression().fit(x, y) print("一元回歸方程為: Y = %.5fX + (%.5f)" % (reg.coef_[0][0], reg.intercept_[0])) print("R平方為: %s" % reg.score(x, y)) plt.scatter(x, y, color='black') plt.plot(x, reg.predict(x), color='red', linewidth=1) plt.show()


一元多階線性擬合(多項式擬合):
假設存在一個函數,只有一個自變量,即只有一個特征屬性,滿足多項式函數如下:

損失函數:損失函數越小,就代表模型擬合的越好。

通過對損失函數偏導為0時,得到最終解方程的函數:

公式推導參考:
https://www.zhihu.com/question/23483726
http://blog.csdn.net/xiaolewennofollow/article/details/46757657
https://wenku.baidu.com/view/f20f3e0da8956bec0875e343.html?from=search
python numpy.polyfit 實現:(此處 x 只有一個特征,屬於一元多階函數)
假設因變量 y 剛好符合該公式。
import numpy as np import matplotlib.pyplot as plt x = np.array([-4,-3,-2,-1,0,1,2,3,4,5,6,7,8,9,10]) y = np.array(2*(x**4) + x**2 + 9*x + 2) #假設因變量y剛好符合該公式 #y = np.array([300,500,0,-10,0,20,200,300,1000,800,4000,5000,10000,9000,22000]) # coef 為系數,poly_fit 擬合函數 coef1 = np.polyfit(x,y, 1) poly_fit1 = np.poly1d(coef1) plt.plot(x, poly_fit1(x), 'g',label="一階擬合") print(poly_fit1) coef2 = np.polyfit(x,y, 2) poly_fit2 = np.poly1d(coef2) plt.plot(x, poly_fit2(x), 'b',label="二階擬合") print(poly_fit2) coef3 = np.polyfit(x,y, 3) poly_fit3 = np.poly1d(coef3) plt.plot(x, poly_fit3(x), 'y',label="三階擬合") print(poly_fit3) coef4 = np.polyfit(x,y, 4) poly_fit4 = np.poly1d(coef4) plt.plot(x, poly_fit4(x), 'k',label="四階擬合") print(poly_fit4) coef5 = np.polyfit(x,y, 5) poly_fit5 = np.poly1d(coef5) plt.plot(x, poly_fit5(x), 'r:',label="五階擬合") print(poly_fit5) plt.scatter(x, y, color='black') plt.legend(loc=2) plt.show()

其中5個函數擬合如下:

可以看到,只要最高階為4階以上,如 四階擬合 和 五階擬合,擬合函數近乎完全是符合原函數 y = 2*(x**4) + x**2 + 9*x + 2,擬合是最好的,幾乎沒有產生震盪,沒有過擬合。
當將因變量 y 更換如下:
x = np.array([-4,-3,-2,-1,0,1,2,3,4,5,6,7,8,9,10])
y = np.array([300,500,0,-10,0,20,200,300,1000,800,4000,5000,10000,9000,22000])

結果發現,四階及以上擬合程度較高。當設置階數越高,震盪越明顯,也就過度擬合了。怎樣確定擬合函數或者最高階呢? 參考:Python 確定多項式擬合/回歸的階數
