什麼是擬合 (fitting)?
當我們執行完一組實驗後,會將兩個物理量分別設成 x 座標和 y 座標,然後將數據點畫成散佈圖 (scatter diagram)。然而,只有數據的圖還不夠完整,還需要確認數據和理論解釋是否吻合,而比較的方式之一,就是以理論函數擬合 (fitting) 數據。
四步驟撰寫擬合程式
如果過去沒有寫程式的經驗,或是打算接觸新語言時,建議先用一組已知趨勢的函數當作數據(如: $\sin(x)$ 或 $\cos(x)$ 函數)來練習擬合,等到熟悉整組程式的運作和調整方式,再來擬合實驗數據。
撰寫擬合程式碼,通常會直接呼叫已經建好的函式或套件包 (package),而不同程式語言只差在語法不同,但邏輯是共通的。
以下列出我所知的程式語言中,各個擬合步驟常使用的函式名稱,有需要的話可以進一步閱讀各函式的官方文件來深入理解。
Python | Mathematica | |
---|---|---|
載入實驗數據檔 (e.g. txt, csv, xlsx) | pd.read |
Import |
定義擬合函數 | def func() |
Function |
程式執行擬合 | curve_fit |
Findfit |
畫擬合結果 | plt.plot |
Plot |
程式中的行、列和陣列
在 Excel 介面中,可以很清楚的看到一橫列 (row) 和一直行 (column) 的樣子,但在寫程式碼的時候,尤其是 Mathematica,會需要自行想像變數內儲存的資料是列還是行,我曾經因為這樣收穫不少次執行失敗。
動手前的工具選擇
我會用免費和需不需要碰程式碼來大致分類,因為大多數學校提供微軟 Office 的授權,所以我直接分到免費類,有些單位會提供付費軟體的授權,以下表格除了Origin和Excel提供直覺的表格操作以外,其他會需要跟文字為主的程式碼介面互動,所以如果需求不複雜,建議可以從Excel開始嘗試,Origin則需要看所屬單位有無自行購買而且我沒用過,所以這裡補個問號。
免費 | 付費 | |
---|---|---|
要碰程式碼 | Python | Matlab, Mathematica |
不需程式碼 | Excel | Origin (?) |
所以這篇文章以 Python 展示擬合數據的原因,除了因為常用好上手,重點是完全免費 (大概)!
Python 的語法相對易學易懂,背後有龐大社群在提供各式套件,現在常應用於機器學習或資料科學領域。不負責任觀察到這個語言有導入到各校課程規劃的趨勢。
撰寫擬合程式時,通常會運用 Python 的幾個知名套件,包含處理數據計算的 numpy、科學計算見長的 scipy、畫圖用的 matplotlib 和讀數據檔的 pandas。我是下載 Anaconda 這個組合包來一次取得這些套件,當然這些套件能做到的事情不僅擬合而已,若想繼續探索,可以多看其他人撰寫的程式,或是官方提供的文件。
Python的註解用#
來標示,而接下來的程式碼是在 Spyder 這個 IDE 中撰寫,#%%
寫法是 Spyder 提供的 cell 功能,讓程式碼可以像在 Jupyter notebook 一樣可以分區執行。另外,寫 Python 時務必注意縮排問題。
練習:$\sin (x)$ 擬合
在這個部分,我們可以完成第一個擬合程式,用 $y=\rm{sin}(0.8x)$ 的函數數值當成待擬合數據,$y=\rm{sin}(kx)$則當成擬合函數,我們會從擬合結果得知未知數 k 的數值,最後將數據和擬合函數值畫在同一張圖上比較。
1. 引入套件與函式
1 | #%% 引入套件 |
2. 設定練習用數據
1 | #%% 設定數據&畫圖觀察趨勢 |
1 | # ============畫散布圖============== |
3. 定義用來擬合的數學函數
1 | #%% curve fitting |
4. 執行擬合
1 | # ============conduct fitting============= |
5. 繪製數據和擬合結果圖
1 | #%% 讓座標軸刻度全部朝圖表中心,個人偏好 |
執行程式碼後可以得到下面這張圖,藍色圓點為原始數據,紅色實線為擬合結果。圖例中印出參數 a 經擬合後的值為 0.8,和設定數據時一致;從圖表上看來也相當符合,擬合得不錯。
進階:與 Exp 函數擬合
在此會練習到載入數據檔的語法,以及多個參數的擬合,會用到自然指數函數 $y=a \times e^{-bx}+c$ 來擬合,a、b 和 c 由擬合決定。
這裡的原始數據檔是我在 Excel 中製作,並儲存成 csv 格式,x 介於 1 到 20,y 為 x 代入 $y=e^{-2x}$ 的值,用 python 的 pandas 套件讀入檔案後,會將檔案內的數據存成 dataframe 格式,每個 column 的名稱就會直接沿用 (1,1) 和 (1,2) 的設定。
- 原始數據檔一角
- python 讀檔結果,可以發現 x 和 y 直接當成 column 名稱
1 | #%% 引入套件 |
:::
- ppot中的參數擬合結果
- 程式畫出的數據和理論比較圖,得到a=1,b=2和c趨近於0的結果,符合原先數據設定。