web-dev-qa-db-ja.com

Pythonでガウス曲線をフィットするにはどうすればよいですか?

配列が与えられ、それをプロットすると、ノイズのあるガウス形状が得られます。ガウスに適合させたい。これは私がすでに持っているものですが、これをプロットすると、フィットしたガウス分布が得られず、代わりに直線が得られます。これまでさまざまな方法を試しましたが、理解できません。

random_sample=norm.rvs(h)

parameters = norm.fit(h)

fitted_pdf = norm.pdf(f, loc = parameters[0], scale = parameters[1])

normal_pdf = norm.pdf(f)

plt.plot(f,fitted_pdf,"green")
plt.plot(f, normal_pdf, "red")
plt.plot(f,h)
plt.show()

click for image

12
P. Kaur

次のように scipy.stats.norm からfitを使用できます。

import numpy as np
from scipy.stats import norm
import matplotlib.pyplot as plt

data = np.random.normal(loc=5.0, scale=2.0, size=1000)
mean,std=norm.fit(data)

norm.fitは、データに基づいて正規分布のパラメーターの適合を試みます。実際、上記の例では、meanは約2で、stdは約5です。

プロットするには、次のことができます。

plt.hist(data, bins=30, normed=True)
xmin, xmax = plt.xlim()
x = np.linspace(xmin, xmax, 100)
y = norm.pdf(x, mean, std)
plt.plot(x, y)
plt.show()

enter image description here

青いボックスはデータのヒストグラムであり、緑の線は適合パラメーターをもつガウス分布です。

11
Miriam Farber

ガウス関数をデータセットに適合させる方法は多数あります。データのフィッティングにはしばしばアストロピーを使用するため、これを追加の回答として追加したいと考えました。

ノイズのあるガウスをシミュレートするデータセットを使用します。

import numpy as np
from astropy import modeling

m = modeling.models.Gaussian1D(amplitude=10, mean=30, stddev=5)
x = np.linspace(0, 100, 2000)
data = m(x)
data = data + np.sqrt(data) * np.random.random(x.size) - 0.5
data -= data.min()
plt.plot(x, data)

enter image description here

その後、フィッティングは実際には非常に簡単です。データとフィッターにフィットするモデルを指定します。

fitter = modeling.fitting.LevMarLSQFitter()
model = modeling.models.Gaussian1D()   # depending on the data you need to give some initial values
fitted_model = fitter(model, x, data)

そしてプロット:

plt.plot(x, data)
plt.plot(x, fitted_model(x))

enter image description here


ただし、Scipyのみを使用することもできますが、自分で関数を定義する必要があります。

from scipy import optimize

def gaussian(x, amplitude, mean, stddev):
    return amplitude * np.exp(-((x - mean) / 4 / stddev)**2)

popt, _ = optimize.curve_fit(gaussian, x, data)

これにより、近似の最適な引数が返され、次のようにプロットできます。

plt.plot(x, data)
plt.plot(x, gaussian(x, *popt))

enter image description here

5
MSeifert

Scipy.optimize()のcurve_fitを使用してガウス関数を近似することもできます。この場合、独自のカスタマイズされた関数を定義できます。ここでは、ガウスカーブフィッティングの例を示します。たとえば、2つの配列xyがある場合。

from scipy.optimize import curve_fit
from scipy import asarray as ar,exp

x = ar(range(10))
y = ar([0,1,2,3,4,5,4,3,2,1])

n = len(x)                          #the number of data
mean = sum(x*y)/n                   #note this correction
sigma = sum(y*(x-mean)**2)/n        #note this correction

def gaus(x,a,x0,sigma):
    return a*exp(-(x-x0)**2/(2*sigma**2))

popt,pcov = curve_fit(gaus,x,y,p0=[1,mean,sigma])

plt.plot(x,y,'b+:',label='data')
plt.plot(x,gaus(x,*popt),'ro:',label='fit')
plt.legend()

Curve_fit関数は、3つの引数で呼び出す必要があります:フィットする関数(この場合はgaus())、独立変数の値(この場合はx)、および依存変数の値(この場合はケーシー)。 curve_fit関数は、(最小二乗の意味での)最適なパラメーターの配列と、最適なパラメーターの共分散を含む2番目の配列(詳細は後述)を返します。

以下は、近似の出力です。

enter image description here

2
Pankaj

これにはlmfitが便利かもしれません。ガウス近似の組み込みメソッドと、曲線近似問題の多くの便利なオプションがあります。見る
https://lmfit.github.io/lmfit-py/builtin_models.html#example-1-fit-peaked-data-to-gaussian-lorentzian-and-voigt-profiles =

0
M Newville