2017-06-07 1 views
0

私は高さの密度変化のリストであるデータにガウス曲線を当てようとしていますが、生成された曲線のプロットは常にオフです過大評価される)。ここに私のコードは次のとおりです。ガウス分布がデータに正しく当てはまらない

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

#Gaussian function 
def gauss_function(x, a, x0, sigma): 
    return a*np.exp(-(x-x0)**2/float((2*sigma**2))) 

x = heights5 
y = demeans5 #density values at each height 

amp = max(y) 
center = x[np.argmax(y)] 
width = 20 #eye-balled estimate 


#p0 = amp, width, center 
popt, pcov = curve_fit(gauss_function, x, y, p0 = [amp, width, center]) 

#plot 
dataplot = plt.scatter(x, y, marker = '.', label = 'Observations') 
gausplot = plt.plot(x,gauss_function(x, *popt), color='red', label ='Gaussian fit') 

string = 'fwhm = ' + str(2.355*popt[2]) + '\npeak = ' + str(popt[0]) + '\nmean = ' + str(popt[1]) + '\nsigma = ' + str(popt[2]) 

#plot labels etc. 
plt.xlabel("Height[km]") 
plt.ylabel("Density") 
plt.legend([dataplot, gausplot], labels = ['fit', 'Observations']) 
plt.text(130, 2000, string) 
plt.show() 

これは、それが生成するプロットである:

poor fit

私はより正確に曲線をフィットする方法は?また、データの幅を見積もる方法はありますか?

+3

あなたは何を期待していますか?あなたのデータは正規分布していません(ピークが2つあります;バイモーダルです)。そのフィッティングは、配布についてのあなたの前提を考えれば、私にとっては間違って見えません。もちろん、あなたはGaussiansのMixtureを使うことができますが、それはあなたが望むものかどうかは分かりません。 – sascha

+0

あなたはガウスの人口から実際にはサンプリングされなかったことを意味するたくさんのデータポイントを持っているようです。 –

+0

3つのディストリビューションが混在しているというヒントがあります。ガウスの仮定の理論的根拠はありますか? –

答えて

0

さらに正確にフィットさせるために、scipy.interpolateモジュールを調べることができます。そこの関数は、補間とフィッティングに関してはうまく機能します。良い仕事を行うことができ

他フィッティング技術は、次のとおり A)CSTS B)BSplines C)多項式補間

scipyのダウンロードもBSplinesの実装を有しています。他の2つは、あなた自身を実装する必要があります。

関連する問題