2017-06-11 1 views
10

On me donne un tableau et quand je le trace je reçois une forme gaussienne avec du bruit. Je veux aller avec le gaussien. C'est ce que j'ai déjà, mais quand je trace cela, je ne reçois pas un gaussien ajusté, au lieu de cela, j'ai juste une ligne droite. J'ai essayé de nombreuses façons différentes et je n'arrive tout simplement pas à comprendre.Comment puis-je ajuster une courbe gaussienne en 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

Répondre

6

Vous pouvez utiliser fit de scipy.stats.norm comme suit:

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 tente d'adapter les paramètres d'une distribution normale sur la base des données. Et en effet, dans l'exemple ci-dessus mean est d'environ 2 et std est d'environ 5.

Pour tracer, vous pouvez le faire:

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

Les boîtes bleues sont l'histogramme de votre données, et la ligne verte est le Gaussien avec les paramètres ajustés.

+0

Et que ferais-je pour voir ce gaussien ajusté? –

+0

@ P.Kaur voir ma réponse mise à jour –

0

Vous pouvez également adapter une fonction gaussienne avec curve_fit de scipy.optimize() où vous pouvez définir votre propre fonction personnalisée. Ici, je donne un exemple pour un ajustement de courbe gaussienne. Par exemple, si vous avez deux tableaux x et y.

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() 

La fonction curve_fit doit être appelé avec trois arguments: la fonction que vous souhaitez adapter (Gaus() dans ce cas), les valeurs de la variable indépendante (dans notre cas x), et les valeurs de la variable dépendante (dans notre cas y). La fonction curve_fit renvoie un tableau avec les paramètres optimaux (au sens des moindres carrés) et un second tableau contenant la covariance des paramètres optimaux (plus de détails plus loin).

Voici la sortie de l'ajustement.

enter image description here

+0

Si j'utilise cette méthode mon gaussien ajusté est juste une ligne droite. –

+0

Êtes-vous sûr? J'ai inclus l'intrigue de sortie que je reçois. Il suffit de copier le code ci-dessus, vous obtiendrez la courbe gaussienne pour l'ajustement. – Pankaj

+0

Aussi cette méthode est supérieure à l'autre puisque vous pouvez adapter n'importe quelle fonction arbitraire en utilisant curve_fit(). – Pankaj

1

Vous trouverez peut-être lmfit utile pour cela. Il a des méthodes intégrées pour l'ajustement gaussien, et de nombreuses options pratiques pour les problèmes d'ajustement de courbe. Voir
https://lmfit.github.io/lmfit-py/builtin_models.html#example-1-fit-peaked-data-to-gaussian-lorentzian-and-voigt-profiles

+0

Cette méthode a bien fonctionné pour me donner les différents paramètres tels que sigma et la moyenne, mais comment puis-je tracer le guassian ajusté sur mes données d'origine? –

+0

avec 'out = model.fit (...)', le tableau du modèle best-fit est maintenu dans 'out.best_fit' - qui devrait être prêt pour le traçage avec les données. Il existe de nombreux exemples de scripts qui incluent le traçage dans le dossier docs and examples. –

0

Il existe plusieurs façons d'adapter une fonction gaussienne à un ensemble de données. J'utilise souvent l'astropie pour ajuster les données, c'est pourquoi je voulais ajouter ceci comme réponse supplémentaire.

J'utilise un certain ensemble de données qui doivent simuler une gaussienne avec un peu de bruit:

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

convenable Ensuite, il est en fait assez simple, vous spécifiez un modèle que vous souhaitez adapter aux données et un installateur:

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) 

et transcrites:

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

enter image description here


Cependant, vous pouvez également utiliser simplement Scipy mais vous devez définir la fonction vous:

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) 

Cela renvoie les arguments optimaux pour l'ajustement et vous pouvez tracer comme ça :

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

enter image description here