線性擬合是數據處理中一種比較常用的方式。但是擬合的方法也又好幾種。 1、第一版代碼(網上學習別人的,感覺用的是平均數方法,最小二乘法自己處理的感覺) #! /usr/bin/env python # -*- coding: utf-8 -*- import numpy as np ###使用的數學模塊 from matplotlib import pylab as pl # 定義要分析的數據,自己處理時候,可以開放接口去讀取相應文件中的內容 x = np.array([6,7.8,3.7,4.8,3.5]) y = np.array([14.2,24.3,18.6,17.8,27.9]) # 回歸方程求取函數 def fit(x,y): if len(x) != len(y): return ###先判斷一下這個數據逆否可以擬合,主要是讀取其他文件數據的時候可能出錯 numerator = 0.0 denominator = 0.0 x_mean = np.mean(x) y_mean = np.mean(y) for i in range(len(x)): numerator += (x[i]-x_mean)*(y[i]-y_mean) denominator += np.square((x[i]-x_mean)) print('numerator:',numerator,'denominator:',denominator) b0 = numerator/denominator b1 = y_mean - b0*x_mean return b0,b1 # 定義預測函數 def predit(x,b0,b1): return b0*x + b1 # 求取回歸方程 b0,b1 = fit(x,y) print('Line is:y = %2.0fx + %2.0f'%(b0,b1)) # 預測 x_test = np.array([0.5,1.5,2.5,3,4]) y_test = np.zeros((1,len(x_test))) for i in range(len(x_test)): y_test[0][i] = predit(x_test[i],b0,b1) # 繪制圖像 xx = np.linspace(0, 5) yy = b0*xx + b1 pl.plot(xx,yy,'k-') pl.scatter(x,y,cmap=pl.cm.Paired) pl.scatter(x_test,y_test[0],cmap=pl.cm.Paired) pl.show() 2、感覺使用了最下二乘法但是代碼不太看得懂 #! /usr/bin/env python # -*- coding: utf-8 -*- ###最小二乘法試驗### import numpy as np from scipy.optimize import leastsq from matplotlib import pylab as pl import matplotlib.pyplot as plt # 定義訓練數據 x = np.array([6,7.8,3.7,4.8,3.5]) y = np.array([14.2,24.3,18.6,17.8,27.9]) ###需要擬合的函數func及誤差error### def func(p,x): k,b=p return k*x+b def error(p,x,y,s): print s return func(p,x)-y #x、y都是列表,故返回值也是個列表 #TEST p0=[100,2] ###主函數從此開始### s="Test the number of iteration" #試驗最小二乘法函數leastsq得調用幾次error函數才能找到使得均方誤差之和最小的k、b Para=leastsq(error,p0,args=(x,y,s)) #把error函數中除了p以外的參數打包到args中 k,b=Para[0] print"k=",k,'\n',"b=",b plt.figure(figsize=(8,6)) plt.scatter(x,y,color="red",label="Sample Point",linewidth=3) #畫樣本點 x=np.linspace(0,10,1000) y=k*x+b plt.plot(x,y,color="orange",label="Fitting Line",linewidth=2) #畫擬合直線 plt.legend() plt.show() https://www.bilibili.com/read/cv4971766/
