webentwicklung-frage-antwort-db.com.de

Passen Sie eine Gaußsche Funktion an

Ich habe ein Histogramm (siehe unten) und versuche, den Mittelwert und die Standardabweichung zusammen mit dem Code zu finden, der eine Kurve an mein Histogramm anpasst. Ich denke, es gibt etwas in SciPy oder Matplotlib, das helfen kann, aber jedes Beispiel, das ich versucht habe, funktioniert nicht. 

import matplotlib.pyplot as plt
import numpy as np

with open('gau_b_g_s.csv') as f:
    v = np.loadtxt(f, delimiter= ',', dtype="float", skiprows=1, usecols=None)

fig, ax = plt.subplots()

plt.hist(v, bins=500, color='#7F38EC', histtype='step')

plt.title("Gaussian")
plt.axis([-1, 2, 0, 20000])

plt.show()
20
user1496646

Werfen Sie einen Blick auf diese Antwort , um beliebige Daten an die Daten anzupassen. Grundsätzlich können Sie scipy.optimize.curve_fit verwenden, um jede gewünschte Funktion an Ihre Daten anzupassen. Der folgende Code zeigt, wie Sie einen Gaussian an einige zufällige Daten anpassen können (Kredit an this SciPy-User-Mailinglisten-Post).

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

# Define some test data which is close to Gaussian
data = numpy.random.normal(size=10000)

hist, bin_edges = numpy.histogram(data, density=True)
bin_centres = (bin_edges[:-1] + bin_edges[1:])/2

# Define model function to be used to fit to the data above:
def gauss(x, *p):
    A, mu, sigma = p
    return A*numpy.exp(-(x-mu)**2/(2.*sigma**2))

# p0 is the initial guess for the fitting coefficients (A, mu and sigma above)
p0 = [1., 0., 1.]

coeff, var_matrix = curve_fit(gauss, bin_centres, hist, p0=p0)

# Get the fitted curve
hist_fit = gauss(bin_centres, *coeff)

plt.plot(bin_centres, hist, label='Test data')
plt.plot(bin_centres, hist_fit, label='Fitted data')

# Finally, lets get the fitting parameters, i.e. the mean and standard deviation:
print 'Fitted mean = ', coeff[1]
print 'Fitted standard deviation = ', coeff[2]

plt.show()
35
Chris

Sie können die Schätzung für das Gaußsche Gemisch von sklearn wie folgt versuchen:

import numpy as np
import sklearn.mixture

gmm = sklearn.mixture.GMM()

# sample data
a = np.random.randn(1000)

# result
r = gmm.fit(a[:, np.newaxis]) # GMM requires 2D data as of sklearn version 0.16
print("mean : %f, var : %f" % (r.means_[0, 0], r.covars_[0, 0]))

Referenz: http://scikit-learn.org/stable/modules/mixture.html#mixture

Beachten Sie, dass Sie auf diese Weise Ihre Stichprobenverteilung nicht mit einem Histogramm schätzen müssen.

13
Nicolas Barbey

Eine alte Frage, aber für jeden, der nur eine Dichte für eine Serie darstellen möchte, könnte man die .plot(kind='kde') von matplotlib ausprobieren. Dokumente hier .

Beispiel mit Pandas:

mydf.x.plot(kind='kde')
2
misterte

Ich bin nicht sicher, was Ihre Eingabe ist, aber möglicherweise ist Ihre y-Achsenskala zu groß (20000). Versuchen Sie, diese Zahl zu reduzieren. Der folgende Code funktioniert für mich:

import matplotlib.pyplot as plt
import numpy as np

#created my variable
v = np.random.normal(0,1,1000)


fig, ax = plt.subplots()


plt.hist(v, bins=500, normed=1, color='#7F38EC', histtype='step')

#plot
plt.title("Gaussian")
plt.axis([-1, 2, 0, 1]) #changed 20000 to 1

plt.show()

Bearbeiten:

Wenn Sie die tatsächliche Anzahl der Werte auf der y-Achse festlegen möchten, können Sie normed=0 einstellen. Und würde einfach die plt.axis([-1, 2, 0, 1]) loswerden.

import matplotlib.pyplot as plt
import numpy as np

#function
v = np.random.normal(0,1,500000)


fig, ax = plt.subplots()

# changed normed=1 to normed=0
plt.hist(v, bins=500, normed=0, color='#7F38EC', histtype='step')

#plot
plt.title("Gaussian")
#plt.axis([-1, 2, 0, 20000]) 

plt.show()
0
Akavall