Python 多項式擬合(一元回歸)


一元一階線性擬合:

假設存在一條線性函數盡量能滿足所有的點: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 確定多項式擬合/回歸的階數

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM