我的直方图显示了两个峰。但是,当用双高斯曲线拟合它时,它只显示一个峰值。几乎跟随stackoverflow中显示的每个答案。但未能得到正确的结果。它以前是由我在Fortran的老师完成的,他有两个高峰。
我在一次试验中使用了leastsq
的{{1}} scipy.optimize
。我也应该提供我的数据吗?
这是我的代码。
binss = (max(x) - min(x))/0.05 #0.05 is my bin width
n, bins, patches = plt.hist(x, binss, color = 'grey') #gives the histogram
x_a = []
for item in range(len(bins)-1):
b = (bins[item]+bins[item+1])/2
x_a.append(b)
x_avg = np.array(x_a)
y_real = n
def gauss(x, A, mu, sigma):
gaus = []
for item in range(len(x)):
gaus.append(A*e**(-(x[item]-mu)**2./(2.*sigma**2)))
return np.array(gaus)
A1, A2, m1, m2, sd1, sd2 = [25, 30, 0.3, 0.6, -0.9, -0.9]
#Initial guesses for leastsq
p = [A1, A2, m1, m2, sd1, sd2]
y_init = gauss(x_avg, A1, m1, sd1) + gauss(x_avg, A2, m2, sd2) #initially guessed y
def residual(p, x, y):
A1, A2, m1, m2, sd1, sd2 = p
y_fit = gauss(x, A1, m1, sd1) + gauss(x, A2, m2, sd2)
err = y - y_fit
return err
sf = leastsq(residual, p, args = (x_avg , y_real))
y_fitted1 = gauss(x_avg, sf[0][0], sf[0][2], sf[0][4])
y_fitted2 = gauss(x_avg, sf[0][1], sf[0][3], sf[0][5])
y_fitted = y_fitted1 + y_fitted2
plt.plot(x_avg, y_init, 'b', label='Starting Guess')
plt.plot(x_avg, y_fitted, color = 'red', label = 'Fitted Data')
plt.plot(x_avg, y_fitted1, color= 'black', label = 'Fitted1 Data')
plt.plot(x_avg, y_fitted2, color = 'green', label = 'Fitted2 Data')
即使我得到的数字也不顺利。 x_avg
只有54分。请帮忙。甚至不能在这里发布这个数字。
在MATLAB上绘图时,获得了正确的结果。原因: MATLAB使用Trust Region算法代替Levenberg-Marquardt算法 这不适合约束。
只有在显示为3的总和时才会出现正确的结果 个别高斯人,而不是2。
如何决定使用哪个算法以及何时使用?
答案 0 :(得分:7)
您的问题似乎是mixtures of Gaussian
,也称为Gaussian mixture model
。有几种实现方式。 sklearn
值得考虑。
import numpy as np
from sklearn import mixture
import matplotlib.pyplot as plt
comp0 = np.random.randn(1000) - 5 # samples of the 1st component
comp1 = np.random.randn(1000) + 5 # samples of the 2nd component
x = np.hstack((comp0, comp1)) # merge them
gmm = mixture.GMM(n_components=2) # gmm for two components
gmm.fit(x) # train it!
linspace = np.linspace(-10, 10, 1000)
fig, ax1 = plt.subplots()
ax2 = ax1.twinx()
ax1.hist(x, 100) # draw samples
ax2.plot(linspace, np.exp(gmm.score_samples(linspace)[0]), 'r') # draw GMM
plt.show()
输出是
答案 1 :(得分:2)
我添加了另一个高斯术语。所以p
共计9个参数。因此
p = [A1, A2, A3, m1, m2, m3, sd1, sd2, sd3]
然后定义了另一个词y_fitted3
并将其添加到y_fitted
。然后它给出了两个完美拟合的正确图形,除了曲线根本不光滑的事实!然后在stackoverflow中搜索使我使用spline
。即。
from scipy.interpolate import spline
然后在最后,
x_new = np.linspace(x_avg.min(),x_avg.max(),30000)
ysmooth = spline(x_avg, y_fitted, x_new)
plt.plot(x_new, ysmooth)
然后就是那样。
签入维基百科,它说python中的L-M
也使用T-R
。所以再次尝试leastsq
给出了结果。
但是,我仍然不清楚MATLAB
中显示的差异。额外的输入将不胜感激!谢谢。