前面系列文章講過各種知識(shí),包括繪制曲線、散點(diǎn)圖、冪分布等,而如何在在散點(diǎn)圖一堆點(diǎn)中擬合一條直線,也變得非常重要。這篇文章主要講述調(diào)用Scipy擴(kuò)展包的curve_fit函數(shù)實(shí)現(xiàn)曲線擬合,同時(shí)計(jì)算出擬合的函數(shù)、參數(shù)等。希望文章對(duì)你有所幫助,如果文章中存在錯(cuò)誤或不足之處,還請(qǐng)海涵~ 前文推薦: 【Python數(shù)據(jù)挖掘課程】一.安裝Python及爬蟲入門介紹 【Python數(shù)據(jù)挖掘課程】二.Kmeans聚類數(shù)據(jù)分析及Anaconda介紹 【Python數(shù)據(jù)挖掘課程】三.Kmeans聚類代碼實(shí)現(xiàn)、作業(yè)及優(yōu)化 【Python數(shù)據(jù)挖掘課程】四.決策樹DTC數(shù)據(jù)分析及鳶尾數(shù)據(jù)集分析 【Python數(shù)據(jù)挖掘課程】五.線性回歸知識(shí)及預(yù)測(cè)糖尿病實(shí)例 【Python數(shù)據(jù)挖掘課程】六.Numpy、Pandas和Matplotlib包基礎(chǔ)知識(shí) 【Python數(shù)據(jù)挖掘課程】七.PCA降維操作及subplot子圖繪制 【Python數(shù)據(jù)挖掘課程】八.關(guān)聯(lián)規(guī)則挖掘及Apriori實(shí)現(xiàn)購物推薦 【Python數(shù)據(jù)挖掘課程】九.回歸模型LinearRegression簡(jiǎn)單分析氧化物數(shù)據(jù) 【python數(shù)據(jù)挖掘課程】十.Pandas、Matplotlib、PCA繪圖實(shí)用代碼補(bǔ)充 【python數(shù)據(jù)挖掘課程】十一.Pandas、Matplotlib結(jié)合SQL語句可視化分析 【python數(shù)據(jù)挖掘課程】十二.Pandas、Matplotlib結(jié)合SQL語句對(duì)比圖分析 【python數(shù)據(jù)挖掘課程】十三.WordCloud詞云配置過程及詞頻分析
一. Scipy介紹 SciPy (pronounced "Sigh Pie") 是一個(gè)開源的數(shù)學(xué)、科學(xué)和工程計(jì)算包。它是一款方便、易于使用、專為科學(xué)和工程設(shè)計(jì)的Python工具包,包括統(tǒng)計(jì)、優(yōu)化、整合、線性代數(shù)模塊、傅里葉變換、信號(hào)和圖像處理、常微分方程求解器等等。 官方地址:https://www./
Scipy常用的模塊及功能如下圖所示: 強(qiáng)烈推薦劉神的文章:Scipy高端科學(xué)計(jì)算 - 劉一痕 Scipy優(yōu)化和擬合采用的是optimize模塊,該模塊提供了函數(shù)最小值(標(biāo)量或多維)、曲線擬合和尋找等式的根的有用算法。
官方介紹:scipy.optimize.curve_fit 下面將從實(shí)例進(jìn)行詳細(xì)介紹,包括: 1.調(diào)用 numpy.polyfit() 函數(shù)實(shí)現(xiàn)一次二次多項(xiàng)式擬合; 2.Pandas導(dǎo)入數(shù)據(jù)后,調(diào)用Scipy實(shí)現(xiàn)次方擬合; 3.實(shí)現(xiàn)np.exp()形式e的次方擬合; 4.實(shí)現(xiàn)三個(gè)參數(shù)的形式擬合; 5.最后通過冪率圖形分析介紹自己的一些想法和問題。
二. 曲線擬合 1.多項(xiàng)式擬合
首先通過numpy.arange定義x、y坐標(biāo),然后調(diào)用polyfit()函數(shù)進(jìn)行3次多項(xiàng)式擬合,最后調(diào)用Matplotlib函數(shù)進(jìn)行散點(diǎn)圖繪制(x,y)坐標(biāo),并繪制預(yù)測(cè)的曲線。 完整代碼:
import matplotlib.pyplot as plt num = [4.00, 5.20, 5.900, 6.80, 7.34, 8.57, 9.86, 10.12, 12.56, 14.32, 15.42, 16.50, 18.92, 19.58, 20.00] #也可使用yvals=np.polyval(f1, x) plot1 = plt.plot(x, y, 's',label='original values') plot2 = plt.plot(x, yvals, 'r',label='polyfit values') plt.legend(loc=4) #指定legend的位置右下角
輸出結(jié)果如下圖所示,包括藍(lán)色的正方形散點(diǎn)和紅色的擬合曲線。 多項(xiàng)式函數(shù)為: y=-0.004669 x3 + 0.1392 x2 + 0.04214 x + 4.313 補(bǔ)充:給出函數(shù),可以用 Origin 進(jìn)行繪圖的,也比較方便。
2.e的b/x次方擬合 下面采用Scipy的curve_fit()對(duì)上面的數(shù)據(jù)進(jìn)行e的b/x次方擬合。數(shù)據(jù)集如下:
num = [4.00, 5.20, 5.900, 6.80, 7.34, 8.57, 9.86, 10.12, 12.56, 14.32, 15.42, 16.50, 18.92, 19.58, 20.00]
其中,x坐標(biāo)從1到15,y對(duì)應(yīng)Num數(shù)組,比如第一個(gè)點(diǎn)(1, 4.00)、最后一個(gè)點(diǎn)(15, 20.00)。 然后調(diào)用curve_fit()函數(shù),核心步驟: (1) 定義需要擬合的函數(shù)類型,如: def func(x, a, b): return a*np.exp(b/x) (2) 調(diào)用 popt, pcov = curve_fit(func, x, y) 函數(shù)進(jìn)行擬合,并將擬合系數(shù)存儲(chǔ)在popt中,a=popt[0]、b=popt[1]進(jìn)行調(diào)用; (3) 調(diào)用func(x, a, b)函數(shù),其中x表示橫軸表,a、b表示對(duì)應(yīng)的參數(shù)。 完整代碼如下:
import matplotlib.pyplot as plt from scipy.optimize import curve_fit num = [4.00, 5.20, 5.900, 6.80, 7.34, 8.57, 9.86, 10.12, 12.56, 14.32, 15.42, 16.50, 18.92, 19.58, 20.00] popt, pcov = curve_fit(func, x, y) yvals = func(x,a,b) #擬合y值 plot1 = plt.plot(x, y, 's',label='original values') plot2 = plt.plot(x, yvals, 'r',label='polyfit values') plt.legend(loc=4) #指定legend的位置右下角
繪制的圖形如下所示,擬合效果沒有多項(xiàng)式的好。
3.aX的b次方擬合 第三種方法是通過Pandas導(dǎo)入數(shù)據(jù),因?yàn)橥ǔ?shù)據(jù)都會(huì)存儲(chǔ)在csv、excel或數(shù)據(jù)庫中,所以這里結(jié)合讀寫數(shù)據(jù)繪制a*x的b次方形式。 假設(shè)本地存在一個(gè)data.csv文件,數(shù)據(jù)集如下圖所示:
然后調(diào)用Pandas擴(kuò)展包讀取數(shù)據(jù),并獲取x、y值顯示,這段代碼如下:
#導(dǎo)入數(shù)據(jù)及x、y散點(diǎn)坐標(biāo) data = pd.read_csv("data.csv") print(data.head(5)) #顯示前5行數(shù)據(jù)
比如 print y 輸出結(jié)果:
最后完整的擬合代碼如下所示:
import matplotlib.pyplot as plt from scipy.optimize import curve_fit #導(dǎo)入數(shù)據(jù)及x、y散點(diǎn)坐標(biāo) data = pd.read_csv("data.csv") print(data.head(5)) #顯示前5行數(shù)據(jù) popt, pcov = curve_fit(func, x, y) yvals = func(x,a,b) #擬合y值 plot1 = plt.plot(x, y, 's',label='original values') plot2 = plt.plot(x, yvals, 'r',label='polyfit values') plt.legend(loc=4) #指定legend的位置右下角
輸出結(jié)果如下圖所示:
4.三個(gè)參數(shù)擬合 最后介紹官方給出的實(shí)例,講述傳遞三個(gè)參數(shù),通常為 a*e(b/x)+c形式。
import matplotlib.pyplot as plt from scipy.optimize import curve_fit return a * np.exp(-b * x) + c # define the data to be fit with some noise xdata = np.linspace(0, 4, 50) y = func(xdata, 2.5, 1.3, 0.5) y_noise = 0.2 * np.random.normal(size=xdata.size) plt.plot(xdata, ydata, 'b-', label='data') # Fit for the parameters a, b, c of the function `func` popt, pcov = curve_fit(func, xdata, ydata) plt.plot(xdata, func(xdata, *popt), 'r-', label='fit') # Constrain the optimization to the region of ``0 < a < 3``, ``0 < b < 2`` popt, pcov = curve_fit(func, xdata, ydata, bounds=(0, [3., 2., 1.])) plt.plot(xdata, func(xdata, *popt), 'g--', label='fit-with-bounds')
輸出結(jié)果如下圖所示:
三. 冪律分布擬合及疑問 下面是我冪率分布的實(shí)驗(yàn),因?yàn)樯婕暗奖C埽灾惶岢鰩讉€(gè)問題。 圖1是多項(xiàng)式的擬合結(jié)果,基本符合圖形趨勢(shì)。 圖2是冪指數(shù)擬合結(jié)果,冪指數(shù)為-1.18也符合人類的基本活動(dòng)規(guī)律。
問題: 1.為什么冪律分布擬合的圖形不太好,而指數(shù)卻很好; 2.計(jì)算冪指數(shù)及擬合是否只對(duì)中間那部分效果好的進(jìn)行擬合; 3.e的b/x次方、多項(xiàng)方程、x的b次方哪個(gè)效果好?
最后希望這篇文章對(duì)你有所幫助,尤其是我的學(xué)生和接觸數(shù)據(jù)挖掘、機(jī)器學(xué)習(xí)的博友。這篇文字主要是介紹擬合,記錄一些代碼片段,作為在線筆記,也希望對(duì)你有所幫助。同時(shí),后面論文寫完會(huì)opensource系列文章。 一醉一輕舞,一夢(mèng)一輪回。一曲一人生,一世一心愿。 (By:Eastmount 2017-05-07 下午3點(diǎn)半 http://blog.csdn.net/eastmount/ )
|