Notebook ini menyajikan cara menyesuaikan model non linier pada kumpulan data menggunakan python. Dua jenis algoritma akan disajikan. Pertama, pendekatan kuadrat terkecil standar menggunakan fungsi def f_model(x, a, c): return pd.np.log((a + x)**2 / (x - c)**2) _1 dari def f_model(x, a, c): return pd.np.log((a + x)**2 / (x - c)**2) 2 di mana kita akan mempertimbangkan ketidakpastian respons, yaitu y. Kedua cocok dengan regresi jarak ortogonal (ODR) menggunakan def f_model(x, a, c): return pd.np.log((a + x)**2 / (x - c)**2) 3 di mana kita akan memperhitungkan ketidakpastian pada x dan y
Piton disiapkan
# manage data and fit import pandas as pd import numpy as np # first part with least squares from scipy.optimize import curve_fit # second part about ODR from scipy.odr import ODR, Model, Data, RealData # style and notebook integration of the plots import seaborn as sns %matplotlib inline sns.set(style="whitegrid")
Membaca dan memplot data
Baca data dari file csv dengan panda
df = pd.read_csv("donnees_exo9.csv", sep=";") df.head(8) # first 8 lines _
xyDy001. 371300-0. 021016110. 747050-0. 089438220. 5875800. 017098330. 5101100. 089353440. 4245610. 083885550. 3949600. 121319660. 157880-0. 152851770. 223860-0. 016393
Plot data dengan bilah kesalahan
ax = df.plot( x="x", y="y", kind="line", yerr="Dy", title="Some experimental data", linestyle="", marker=".", capthick=1, ecolor="gray", linewidth=1 )
Paskan model pada data
Kami ingin menyesuaikan model berikut, dengan parameter, $a$ dan $b$, pada data di atas
$$f(x) = \ln \dfrac{(a + x)^2}{(x-c)^2}$$
Langkah pertama. fungsi
Pertama, kami mendefinisikan fungsi yang sesuai dengan model
def f_model(x, a, c): return pd.np.log((a + x)**2 / (x - c)**2)
Tahap kedua. inisialisasi parameter
Hitung nilai y untuk model dengan perkiraan
df["model"] = f_model(df["x"], 3, -2) df.head(8)
xyDymodel001. 371300-0. 0210160. 810930110. 747050-0. 0894380. 575364220. 5875800. 0170980. 446287330. 5101100. 0893530. 364643440. 4245610. 0838850. 308301550. 3949600. 1213190. 267063660. 157880-0. 1528510. 235566770. 223860-0. 0163930. 210721
Sekarang plot perkiraan pertama Anda tentang model tersebut
ax = df.plot( x="x", y="y", kind="line", yerr="Dy", title="Some experimetal data", linestyle="", marker=".", capthick=1, ecolor="gray", linewidth=1 ) ax = df.plot( x="x", y="model", kind="line", ax=ax, linewidth=1 ) _
Langkah ketiga. Lakukan yang cocok
Sekarang kami secara eksplisit melakukan penyesuaian dengan def f_model(x, a, c): return pd.np.log((a + x)**2 / (x - c)**2) _1 menggunakan fungsi def f_model(x, a, c): return pd.np.log((a + x)**2 / (x - c)**2) 5 kami dan tebakan awal untuk parameter. Jalankan def f_model(x, a, c): return pd.np.log((a + x)**2 / (x - c)**2) _6 dan baca dokumentasi tentang fungsi tersebut. def f_model(x, a, c): return pd.np.log((a + x)**2 / (x - c)**2) 1 mengikuti pendekatan kuadrat terkecil dan akan meminimalkan
$$\sum_k \dfrac{\left(f(\text{xdata}_k, \texttt{*popt}) - \text{ydata}_k\right)^2}{\sigma_k^2}$$
help(curve_fit)
popt, pcov = curve_fit( f=f_model, # model function xdata=df["x"], # x data ydata=df["y"], # y data p0=(3, -2), # initial value of the parameters sigma=df["Dy"] # uncertainties on y )
print(popt)
[ 2.01673012 -1.01484118]Itu dia
Langkah keempat. Hasil pas
Parameter ada di def f_model(x, a, c): return pd.np.log((a + x)**2 / (x - c)**2) 8
df = pd.read_csv("donnees_exo9.csv", sep=";") df.head(8) # first 8 lines _0
Anda dapat menghitung kesalahan standar deviasi dari def f_model(x, a, c): return pd.np.log((a + x)**2 / (x - c)**2) 9
df = pd.read_csv("donnees_exo9.csv", sep=";") df.head(8) # first 8 lines _2
df = pd.read_csv("donnees_exo9.csv", sep=";") df.head(8) # first 8 lines _3Anda dapat menghitung koefisien determinasi dengan
\begin{equation} R^2 = \frac{\sum_k (y^{calc}_k - \overline{y})^2}{\sum_k (y_k - \overline{y})^2} \end{equation
df = pd.read_csv("donnees_exo9.csv", sep=";") df.head(8) # first 8 lines _4
df = pd.read_csv("donnees_exo9.csv", sep=";") df.head(8) # first 8 lines _5Buat plot
Sekarang, lihat hasilnya di plot
df = pd.read_csv("donnees_exo9.csv", sep=";") df.head(8) # first 8 lines _6
xyDymodel001. 371300-0. 0210161. 373491110. 747050-0. 0894380. 807266220. 5875800. 0170980. 573842330. 5101100. 0893530. 445561440. 4245610. 0838850. 364284
ax = df.plot( x="x", y="y", kind="line", yerr="Dy", title="Some experimetal data", linestyle="", marker=".", capthick=1, ecolor="gray", linewidth=1 ) ax = df.plot( x="x", y="model", kind="line", ax=ax, linewidth=1 ) _
Atau menggunakan lebih banyak nilai x untuk model, agar mendapatkan kurva yang lebih mulus
df = pd.read_csv("donnees_exo9.csv", sep=";") df.head(8) # first 8 lines _8
Ketidakpastian pada x dan y
x dan y masing-masing disebut variabel independen (atau penjelas) dan dependen (respons). Seperti pada contoh di atas, ketidakpastian seringkali hanya memperhitungkan variabel respon (y). Di sini, kita akan melakukan fit yang sama tetapi dengan ketidakpastian pada variabel x dan y
Dalam pendekatan kuadrat terkecil, untuk setiap nilai x, jarak antara respons model dan data diminimalkan. Saat Anda melakukan ini untuk setiap nilai x tertentu, Anda tidak dapat memasukkan x ketidakpastian. Untuk memasukkannya, kami akan menggunakan pendekatan regresi jarak ortogonal (ODR). Lihatlah dari mana berikut ini ditulis
Tambahkan x ketidakpastian
Tambahkan, secara artifisial, ketidakpastian normal acak pada x
df = pd.read_csv("donnees_exo9.csv", sep=";") df.head(8) # first 8 lines _9
xyDyDx001. 371300-0. 0210160. 091596110. 747050-0. 089438-0. 015025220. 5875800. 0170980. 230026330. 5101100. 089353-0. 113324440. 4245610. 0838850. 232209
ax = df.plot( x="x", y="y", kind="line", yerr="Dy", title="Some experimental data", linestyle="", marker=".", capthick=1, ecolor="gray", linewidth=1 ) 0
Buat yang cocok
1) Tentukan modelnya
Fungsi model harus didefinisikan dengan cara yang sedikit berbeda. Argumen pertama (disebut df["model"] = f_model(df["x"], 3, -2) df.head(8) _0 di sini) harus berupa daftar parameter
ax = df.plot( x="x", y="y", kind="line", yerr="Dy", title="Some experimental data", linestyle="", marker=".", capthick=1, ecolor="gray", linewidth=1 ) 1
Tentukan data dan modelnya
ax = df.plot( x="x", y="y", kind="line", yerr="Dy", title="Some experimental data", linestyle="", marker=".", capthick=1, ecolor="gray", linewidth=1 ) 2
2) Jalankan algoritma
Dua perhitungan akan dilakukan
- df["model"] = f_model(df["x"], 3, -2) df.head(8) 1 adalah pendekatan kuadrat terkecil dan hanya mempertimbangkan y ketidakpastian
- df["model"] = f_model(df["x"], 3, -2) df.head(8) 2 ODR eksplisit
Untuk setiap perhitungan, kami membuat iterasi pertama dan memeriksa apakah konvergensi tercapai dengan df["model"] = f_model(df["x"], 3, -2) df.head(8) 3. Jika tidak, kami menjalankan paling banyak 100 kali lagi algoritma sementara konvergensi tidak tercapai
Pertama, Anda dapat melihat bahwa pendekatan kuadrat terkecil memberikan hasil yang sama dengan fungsi def f_model(x, a, c): return pd.np.log((a + x)**2 / (x - c)**2) 1 yang digunakan di atas