web-dev-qa-db-ja.com

Pythonの最小二乗法?

私はこれらの値を持っています:

_T_values = (222, 284, 308.5, 333, 358, 411, 477, 518, 880, 1080, 1259) (x values)
_
_C/(3Nk)_values = (0.1282, 0.2308, 0.2650, 0.3120 , 0.3547, 0.4530, 0.5556, 0.6154, 0.8932, 0.9103, 0.9316) (y values)
_

私は彼らがモデルに従っていることを知っています:

_C/(3Nk)=(h*w/(k*T))**2*(exp(h*w/(k*T)))/(exp(h*w/(k*T)-1))**2
_

k=1.38*10**(-23)h=6.626*10**(-34)も知っています。測定データを最もよく表すwを見つけなければなりません。 Pythonで最小二乗法を使用してこれを解決したいのですが、これがどのように機能するのか本当にわかりません。誰か助けてもらえますか?

5
Philipp

この回答では、Pythonを使用して一般的な指数パターンのフィッティングパラメーターを決定する方法について説明します。

データのクリーニング

最初に、サンプリングデータをnumpy配列として入力して整理します。これは、後で計算と明確化に役立ちます。

import matplotlib.pyplot as plt
import scipy.optimize as opt
import numpy as np

#% matplotlib inline

# DATA ------------------------------------------------------------------------
T_values = np.array([222, 284, 308.5, 333, 358, 411, 477, 518, 880, 1080, 1259])
C_values = np.array([0.1282, 0.2308, 0.2650, 0.3120 , 0.3547, 0.4530, 0.5556, 0.6154, 0.8932, 0.9103, 0.9316])

x_samp = T_values
y_samp = C_values    

Scipyとnumpyには多くの カーブフィッティング 関数があり、それぞれ使用方法が異なります。 scipy.optimize.leastsq および scipy.optimize.least_squares 。簡単にするために、 scipy.optimize.curve_fit 、しかし妥当な開始パラメータの選択なしで最適化された回帰曲線を見つけることは困難です。開始パラメーターの選択に関する簡単な手法については後で説明します。

レビュー

最初に、OPは予想されるフィッティング方程式を提供しましたが、指数関数の一般方程式を確認することにより、Pythonを使用してカーブフィットする問題に取り組みます。

enter image description here

次に、この一般的な関数を作成します。これは数回使用されます。

# GENERAL EQUATION ------------------------------------------------------------
def func(x, A, c, d):
    return A*np.exp(c*x) + d

トレンド

  • amplitude:小さいAは小さい振幅を与えます
  • shape:小さいcは、曲線の「膝」を平坦化することによって形状を制御します
  • positiondはy切片を設定します
  • orientation:負のAは、水平軸を横切って曲線を反転します。負のcは、縦軸を横切って曲線を反転します

後者の傾向を以下に示し、さまざまなパラメーターを持つ線(赤い線)と比較して、コントロール(黒い線)を強調しています。

enter image description here

enter image description here

初期パラメータの選択

後者の傾向を使用して、次にデータを見て、これらのパラメーターを調整して曲線をエミュレートしてみましょう。デモのために、データに対していくつかの試行方程式をプロットします。

# SURVEY ----------------------------------------------------------------------
# Plotting Sampling Data
plt.plot(x_samp, y_samp, "ko", label="Data")

x_lin = np.linspace(0, x_samp.max(), 50)                   # a number line, 50 evenly spaced digits between 0 and max

# Trials
A, c, d = -1, -1e-2, 1
y_trial1 = func(x_lin,  A,     c, d)
y_trial2 = func(x_lin, -1, -1e-3, 1)
y_trial3 = func(x_lin, -1, -3e-3, 1)

plt.plot(x_lin, y_trial1, "--", label="Trial 1")
plt.plot(x_lin, y_trial2, "--", label="Trial 2")
plt.plot(x_lin, y_trial3, "--", label="Trial 3")
plt.legend()

enter image description here

単純な試行錯誤から、曲線の形状、振幅、位置、および方向をより適切に近似できます。たとえば、最初の2つのパラメーター(Aおよびc)は負でなければならないことがわかっています。 cの大きさのオーダーについても妥当な推測があります。

推定パラメーターの計算

ここで、最初の推測に最適な試行のパラメーターを使用します。

# REGRESSION ------------------------------------------------------------------
p0 = [-1, -3e-3, 1]                                        # guessed params
w, _ = opt.curve_fit(func, x_samp, y_samp, p0=p0)     
print("Estimated Parameters", w)  

# Model
y_model = func(x_lin, *w)

# PLOT ------------------------------------------------------------------------
# Visualize data and fitted curves
plt.plot(x_samp, y_samp, "ko", label="Data")
plt.plot(x_lin, y_model, "k--", label="Fit")
plt.title("Least squares regression")
plt.legend(loc="upper left")

# Estimated Parameters [-1.66301087 -0.0026884   1.00995394]

enter image description here

これはどのように作動しますか?

curve_fitは、scipyが提供する多くの 最適化関数 の1つです。初期値を指定すると、結果の推定パラメーターは反復的に調整され、結果の曲線は残差、または近似された線とサンプリングデータの差を最小化します。より良い推測は、反復回数を減らし、結果を高速化します。近似曲線のこれらの推定パラメーターを使用して、特定の方程式の特定の係数を計算できます(最後の演習はOPに任されています)。

9
pylang

scipyを使用したい:

import scipy.optimize.curve_fit

def my_model(T,w):
    return (hw/(kT))**2*(exp(hw/(kT)))/(exp(hw/(kT)-1))**2
w= 0 #initial guess
popt, pcov = curve_fit(my_model, T_values, C_values,p0=[w])      
1
Mohammad Athar