Ajustement gaussien pour Python
Je suis en train de l'ajustement d'une Gaussienne pour mes données (ce qui est déjà un accidenté de la gaussienne). J'ai déjà pris l'avis de ceux qui sont ici et essayé curve_fit
et leastsq
mais je pense que je suis absent quelque chose de plus fondamental (que je n'ai aucune idée de comment utiliser la commande).
Voici le script que j'ai jusqu'à présent
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()
Ce que je reçois de ce est une gaussienne-ish forme qui est l'original de mes données, et une ligne droite horizontale.
Aussi, j'aimerais parcelle de mon graphique à l'aide de points, au lieu d'avoir le contact.
Toute entrée est appréciée!
source d'informationauteur Richard Hsia
Vous devez vous connecter pour publier un commentaire.
Voici code corrigé:
résultat:
Explication
Vous avez besoin de bon de commencer par des valeurs telles que la
curve_fit
fonction converge à un "bon" valeurs". Je ne peux pas vraiment dire pourquoi votre modèle ne converge pas (même si la définition de votre moyenne est étrange - voir ci-dessous), mais je vais vous donner une stratégie qui fonctionne pour les non-normalisé de Gauss-fonctions comme le votre.Exemple
Les paramètres estimés devraient être au plus près des valeurs (utiliser le pondérée de la moyenne arithmétique - diviser par la somme de toutes les valeurs):
Personnellement, je préfère utiliser numpy.
Commentaire sur la définition de la moyenne (y compris les Développeurs de réponse)
Depuis les évaluateurs n'aime pas mon edit sur #Développeur du codeje vais vous expliquer pour ce cas, je voudrais suggérer une amélioration du code. La moyenne de développeur ne correspondent pas à l'un de la normale définitions de la moyenne.
Votre définition retourne:
Du développeur définition retourne:
La moyenne arithmétique pondérée:
De même, vous pouvez comparer les définitions de l'écart-type (
sigma
). Comparer avec la figure de l'résultant de l'ajustement:Commentaire pour Python 2.utilisateurs de x
En Python 2.x vous devez en outre utiliser la nouvelle division à n'exécuter pas à des résultats bizarres ou à convertir le les chiffres avant la division explicitement:
ou, par exemple,
Vous obtenez une ligne droite horizontale, car elle ne converge pas.
Meilleure convergence est atteinte si le premier paramètre de la ferrure (p0) est mis comme max(y), 5 dans l'exemple, au lieu de 1.
Après avoir perdu des heures à essayer de trouver mon erreur, le problème est votre formule:
sigma = sum(y*(x-moyenne)**2)/n c'est faux, la formule correcte est la racine carrée de ce!;
sqrt(sum(y*(x-moyenne)**2)/n)
Espère que cette aide
Il y a une autre façon de procéder à l'ajustement, qui est à l'aide de la 'lmfit' paquet. Il utilise essentiellement le cuve_fit mais il est beaucoup mieux dans le montage et offre complexe de montage.
Détaillée, étape par étape les instructions sont données dans le lien ci-dessous.
http://cars9.uchicago.edu/software/python/lmfit/model.html#model.best_fit
devrait être