Python 実験データを自作関数にフィッティングする「scipy.optimize」

'24/05/06更新:コードの可読性向上のため、コード中のパラメータに説明を追記しました。
 本記事では、自作のガウス関数にフィッティングする例の雛形コードを載せました。下図は、本プログラム実行結果です。青点は実験データ(便宜上のサンプルデータ)で、赤線はフィッティング後の関数をプロットしている(ここではガウス関数)。

f:id:HK29:20180506212756p:plain

▼本プログラム
 フィッテイングはScipyのoptimizeを利用していて、得られる最適解は初期値の設定に依存します。

import numpy as np
import matplotlib.pyplot as plt
from scipy.optimize import curve_fit

# データの準備
x_data = np.linspace(5, 11, 30)
y_data = np.array([1.9e16, 2.2e16, 2.5e16, 2.1e16, 2.8e16, 2.9e16, 2.2e16, 2.6e16, 2.4e16, 3.6e16,
                  5.5e16, 9.2e16, 2.5e17, 1.1e18, 3.4e18, 5.5e18, 2.2e18, 5.1e17, 1.3e17, 5.4e16, 
                  8.9e16, 5.7e16, 2.5e16, 5.1e16, 5.6e16, 3.2e16, 3.0e16, 2.5e16, 2.1e16, 1.8e16])

# フィッティングする関数を定義
def gaussian_function(x, amplitude, mean, stddev, offset):
    """
    ガウス関数を表す関数

    Parameters:
        x (numpy.ndarray): 入力値
        amplitude (float): ガウス関数の振幅
        mean (float): ガウス関数の平均
        stddev (float): ガウス関数の標準偏差
        offset (float): ガウス関数のオフセット(定数項)

    Returns:
        numpy.ndarray: 入力値に対するガウス関数の値
    """
    return amplitude * np.exp(-(x - mean)**2 / (2 * stddev**2)) + offset

# 初期パラメータの設定
initial_params = np.array([1e18, 8, 3, 1e15])

# データのフィッティング
optimized_params, covariance = curve_fit(gaussian_function, x_data, y_data, p0=initial_params)

# フィッティング結果の表示
print("Optimized Parameters:", optimized_params)

# フィッティングされた関数の計算
y_fit = gaussian_function(x_data, *optimized_params)

# グラフのプロット
plt.scatter(x_data, y_data, c='blue', label='Raw Data')  # 生データのプロット
plt.plot(x_data, y_fit, 'r-', label='Fit: Amplitude=%2.2E, Mean=%3.2f, StdDev=%3.2f, Offset=%2.2E' % tuple(optimized_params))  # フィッティングされた関数のプロット

# グラフのオプション設定
plt.xlabel('x', fontsize=18)
plt.ylabel('y', fontsize=18)
plt.yscale("log")
plt.ylim([1e15, 1e20])
plt.grid(which="both")
plt.legend(loc='upper right')
plt.tight_layout()

# グラフの表示と保存
#plt.show()
plt.savefig("optimized_fit.png", bbox_inches="tight")

参考ページ
[1] scipyのoptimizeのcurve_fit
https://docs.scipy.org/doc/scipy/reference/generated/scipy.optimize.curve_fit.html#scipy.optimize.curve_fit

[2] 比例、1次関数、2次関数にフィッティングしたい場合
https://hk29.hatenablog.jp/entry/2020/02/15/230322
以上

<広告>