相補誤差関数でフィットしたい(scipy.special.erfc

 1import pandas as pd
 2import numpy as np
 3from scipy.optimize import curve_fit
 4from scipy.special import erfc
 5
 6def erfc_function(x, amp, mu, sigma, offset):
 7    """相補誤差補正関数
 8    Args:
 9        x(array-like): 測定データ
10        amp(float): 振幅
11        mu(float): 平均
12        sigma(float): 標準偏差
13        offset(float): 切片
14    Returns:
15        f(array-like): 誤差補正関数
16    """
17    f = amp * erfc((x - mu) / sigma) + offset
18    return f
19
20def fit(data: pd.DataFrame, x: str, y: str):
21    """
22    Args:
23        data(pd.DataFrame): 測定データ
24        x(str): X軸のカラム名
25        y(str): Y軸のカラム名
26    Returns:
27        popt(array_like): フィット値
28        perr(array_like): フィット値の誤差
29        x_fit(array_like): フィットした結果のX軸の値
30        y_fit(array_like): フィットした結果のY軸の値
31    """
32
33    copied = data.copy()
34    func = erfc_function
35    x_data = copied[x]
36    y_data = copied[y]
37    p_init = [初期パラメータ]
38
39    popt, pcov = curve_fit(func, x_data, y_data, p_init)
40    perr = np.sqrt(np.diag(pcov))
41
42    xmin = x_data.min()
43    xmax = x_data.max()
44
45    amp, mu, sigma, offset = popt
46    amp_e, mu_e, sigma_e, offset_e = perr
47
48    print(f"Amplitute: {amp} +/- {amp_e}")
49    print(f"Mean: {mu} +/- {mu_e}")
50    print(f"Sigma: {sigma} +/- {sigma_e}")
51    print(f"Offset: {offset} +/- {offset_e}")
52
53    x_fit = np.arange(xmin, xmax, 0.1)
54    y_fit = func(x_fit, amp, mu, sigma, offset)
55
56    return popt, perr, x_fit, y_fit

宇宙線測定時のスレッショルドを決定したときのサンプルです。 スレッショルド値をスライドさせ、得られた検出率の曲線に対して、 相補誤差関数でフィッティングしました。

誤差関数

\[\text{erf}(x) = \frac{2}{\sqrt(\pi)} \int_{t=0}^{x} \exp(-t^{2}) \text{d}t \]

誤差関数は、ガウス分布(正規分布)の累積分布関数です。 宇宙線測定時の信号に乗るノイズはガウス分布にしたがうと仮定できます。 あるスレッショルド値 \(T\) に対して、信号の大きさ \(x\)\(x < T\)\(T\)より小さい)となる確率を算出できます。

相補誤差関数

\[\text{erfc}(x) = 1 - \text{erf}(x) \]

あるスレッショルド値 \(T\) に対して、信号の大きさ \(x\)\(T < x\)\(T\)より大きい)となる確率を算出できます。

リファレンス