33

私は自分のデータにガウスを当てはめようとしています(これはすでに大まかなガウスです)。私はすでにここにいる人のアドバイスを受けて試しましたが、もっと基本的なものが欠けているcurve_fitleastsq思います (コマンドの使い方がわからないという点で)。ここに私がこれまでに持っているスクリプトを見てください

import pylab as plb
import matplotlib.pyplot as plt

# Read in data -- first 2 rows are header in this example. 
data = plb.loadtxt('part 2.csv', skiprows=2, delimiter=',')

x = data[:,2]
y = data[:,3]
mean = sum(x*y)
sigma = sum(y*(x - mean)**2)

def gauss_function(x, a, x0, sigma):
    return a*np.exp(-(x-x0)**2/(2*sigma**2))
popt, pcov = curve_fit(gauss_function, x, y, p0 = [1, mean, sigma])
plt.plot(x, gauss_function(x, *popt), label='fit')

# plot data

plt.plot(x, y,'b')

# Add some axis labels

plt.legend()
plt.title('Fig. 3 - Fit for Time Constant')
plt.xlabel('Time (s)')
plt.ylabel('Voltage (V)')
plt.show()

これから得られるのは、元のデータであるガウス風の形状と、まっすぐな水平線です。

ここに画像の説明を入力

また、ポイントを接続するのではなく、ポイントを使用してグラフをプロットしたいと思います。どんな入力でも大歓迎です!

4

8 に答える 8

24

説明

curve_fit関数が「適切な」値に収束するように、適切な開始値が必要です。あなたのフィットが収束しなかった理由を本当に言うことはできません(平均の定義が奇妙ですが、以下を確認してください)が、あなたのような正規化されていないガウス関数で機能する戦略を提供します。

推定されたパラメータは最終値に近いはずです (加重算術平均を使用し、すべての値の合計で割ります)。

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

x = np.arange(10)
y = np.array([0, 1, 2, 3, 4, 5, 4, 3, 2, 1])

# weighted arithmetic mean (corrected - check the section below)
mean = sum(x * y) / sum(y)
sigma = np.sqrt(sum(y * (x - mean)**2) / sum(y))

def Gauss(x, a, x0, sigma):
    return a * np.exp(-(x - x0)**2 / (2 * sigma**2))

popt,pcov = curve_fit(Gauss, x, y, p0=[max(y), mean, sigma])

plt.plot(x, y, 'b+:', label='data')
plt.plot(x, Gauss(x, *popt), 'r-', label='fit')
plt.legend()
plt.title('Fig. 3 - Fit for Time Constant')
plt.xlabel('Time (s)')
plt.ylabel('Voltage (V)')
plt.show()

私は個人的にnumpyを使用することを好みます。

平均の定義に関するコメント (開発者の回答を含む)

レビュアーは#Developer のコードに対する私の編集を気に入らなかったので、改善されたコードを提案するケースについて説明します。開発者の平均は、平均の通常の定義のいずれにも対応していません。

あなたの定義は以下を返します:

>>> sum(x * y)
125

開発者の定義は次を返します。

>>> sum(x * y) / len(x)
12.5 #for Python 3.x

加重算術平均:

>>> sum(x * y) / sum(y)
5.0

同様に、標準偏差 ( ) の定義を比較できますsigma。結果の近似の図と比較します。

結果の適合

Python 2.x ユーザーへのコメント

Python 2.x では、奇妙な結果に遭遇したり、除算前の数値を明示的に変換したりしないように、新しい除算を追加で使用する必要があります。

from __future__ import division

または例

sum(x * y) * 1. / sum(y)
于 2016-07-18T08:05:11.643 に答える
4

私のエラーを見つけようとして何時間も失った後、問題はあなたの式です:

sigma = sum(y*(x-mean)**2)/n

この前の式は間違っています。正しい式はこれの平方根です!;

sqrt(sum(y*(x-mean)**2)/n)

お役に立てれば

于 2014-05-10T17:10:43.370 に答える
1

フィットを実行する別の方法があります。それは、'lmfit' パッケージを使用することです。基本的には cuve_fit を使用しますが、フィッティングがはるかに優れており、複雑なフィッティングも提供します。詳細なステップバイステップの手順は、以下のリンクに記載されています。 http://cars9.uchicago.edu/software/python/lmfit/model.html#model.best_fit

于 2015-11-25T23:35:01.797 に答える
1
sigma = sum(y*(x - mean)**2)

する必要があります

sigma = np.sqrt(sum(y*(x - mean)**2))
于 2016-01-09T10:57:00.217 に答える
0

この質問はここでも回答されています: How can I fit a gaussian curve in python?

MSeifert による回答では、astropy パッケージを使用した簡単なガウス モデリングについても言及されています。

于 2022-01-03T10:56:51.173 に答える