2016-04-19 9 views
1

Ein Modell, das ich konstruiert habe, produziert Ausgabe, die die Form von drei normalen Verteilungen annimmt.erkennen separate Normalverteilungen in einem Datensatz

import numpy as np 
d1 = [np.random.normal(2,.1) for _ in range(100)] 
d2 = [np.random.normal(2.5,.1) for _ in range(100)] 
d3 = [np.random.normal(3,.1) for _ in range(100)] 
sudo_model_output = d1 + d2 + d3 
np.random.shuffle(sudo_model_output) 

enter image description here

Was ist ein pythonic Weg, um die Normalverteilung Mittelwert und Standardabweichung bei jeder Normalverteilung zugeordnet zu finden? Ich kann eine Schätzung, wo die Verteilungen beginnen und enden, nicht fest codieren (~ 2,25 und 2,75 hier), da sich der Wert mit jeder Iteration meiner Simulation ändert.

+1

Sie können versuchen, die Summe von drei Normalverteilungen mit jeweils eigener Mitte und Breite anzupassen, die 6 Variablen ergeben würden. Wenn die Breiten ähnlich sind, könnten Sie mit 4 Variablen (centre1, ctr2, ctr3, width) davonkommen. – roadrunner66

+0

Dazu müsste ich irgendwie die Daten richtig trennen? – kilojoules

+0

Nein, Sie können nicht wissen, ob ein bestimmter Wert zu einer gegebenen Verteilung gehört, wenn sie sehr nahe beieinander liegen. Sie passen einfach die Summe an, siehe unten. – roadrunner66

Antwort

1

angepasst ich die Passform aus: Fitting a histogram with python

from scipy.optimize import leastsq 
import numpy as np 
import matplotlib.pyplot as p 
%matplotlib inline 

d1 = [np.random.normal(2,.1) for _ in range(1000)] 
d2 = [np.random.normal(2.5,.1) for _ in range(1000)] 
d3 = [np.random.normal(3,.1) for _ in range(1000)] 
sum1 = d1 + d2 + d3 
bins=np.arange(0,4,0.01) 
a=np.histogram(sum1,bins=bins) 

fitfunc = lambda p, x: p[0]*exp(-0.5*((x-p[1])/p[2])**2) +\ 
     p[3]*exp(-0.5*((x-p[4])/p[5])**2) +\ 
     p[6]*exp(-0.5*((x-p[7])/p[8])**2) 

errfunc = lambda p, x, y: (y - fitfunc(p, x)) 

xdata,ydata=bins[:-1],a[0] 
p.plot(xdata,ydata) 

init = [40, 2.1, 0.1,40, 2.4, 0.1,40, 3.1, 0.1 ] 

out = leastsq(errfunc, init, args=(xdata, ydata)) 
c = out[0] 
print c 

enter image description here

Jetzt, fit ziemlich gut aussieht, aber ich kam ganz in der Nähe mit den inital Schätzwerte für die Amplitude, Mitte und Breite (init sehen) von diesen 9 Variablen. Wenn Sie wüssten, dass sie alle die gleiche Höhe oder Breite haben und daher die Anzahl der Variablen verringern könnten, würde es die Anpassung erleichtern.

Verwandte Themen