如何将一维向量表示为 scipy/numpy 的高斯曲线之和?
How to represent 1D vector as sum of Gaussian curves with scipy/numpy?
更新:谢谢,它有效。
我有一个表示直方图的一维向量。它看起来像几个高斯函数的总和:
我在 SO 上找到了 curve_fit
示例代码,但不知道如何修改它以接收更多高斯元组 (mu, sigma)。我听说 'curve_fit' 只优化了一个函数(在本例中是一条高斯曲线)。
import numpy as np
from scipy.optimize import curve_fit
import matplotlib.pyplot as plt
def estimate_sigma(hist):
bin_edges = np.arange(len(hist))
bin_centres = bin_edges + 0.5
# 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')
print 'Fitted mean = ', coeff[1]
coeff2 =coeff[2]
print 'Fitted standard deviation = ', coeff2
plt.show()
此函数找到一条高斯曲线,而视觉上有 3 或 4 条:
拜托,你能建议一些numpy/scipy函数来实现([m1, sigma1],[m2, sigma2],..,[mN,sigmaN])
形式的1D vector
的gmm表示吗?
按照 tBuLi 的建议,我将额外的高斯曲线系数传递给 gauss
以及 curve_fit
。
现在拟合曲线看起来是这样的:
更新代码:
def estimate_sigma(hist):
bin_edges = np.arange(len(hist))
bin_centres = bin_edges + 0.5
# Define model function to be used to fit to the data above:
def gauss(x, *gparams):
g_count = len(gparams)/3
def gauss_impl(x, A, mu, sigma):
return A*numpy.exp(-(x-mu)**2/(2.*sigma**2))
res = np.zeros(len(x))
for gi in range(g_count):
res += gauss_impl(x, gparams[gi*3], gparams[gi*3+1], gparams[gi*3+2])
return res
# p0 is the initial guess for the fitting coefficients (A, mu and sigma above)
curves_count = 4
p0 = np.tile([1., 0., 1.], curves_count)
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 coeff
plt.show()
更新:谢谢,它有效。
我有一个表示直方图的一维向量。它看起来像几个高斯函数的总和:
我在 SO 上找到了 curve_fit
示例代码,但不知道如何修改它以接收更多高斯元组 (mu, sigma)。我听说 'curve_fit' 只优化了一个函数(在本例中是一条高斯曲线)。
import numpy as np
from scipy.optimize import curve_fit
import matplotlib.pyplot as plt
def estimate_sigma(hist):
bin_edges = np.arange(len(hist))
bin_centres = bin_edges + 0.5
# 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')
print 'Fitted mean = ', coeff[1]
coeff2 =coeff[2]
print 'Fitted standard deviation = ', coeff2
plt.show()
此函数找到一条高斯曲线,而视觉上有 3 或 4 条:
拜托,你能建议一些numpy/scipy函数来实现([m1, sigma1],[m2, sigma2],..,[mN,sigmaN])
形式的1D vector
的gmm表示吗?
按照 tBuLi 的建议,我将额外的高斯曲线系数传递给 gauss
以及 curve_fit
。
现在拟合曲线看起来是这样的:
更新代码:
def estimate_sigma(hist):
bin_edges = np.arange(len(hist))
bin_centres = bin_edges + 0.5
# Define model function to be used to fit to the data above:
def gauss(x, *gparams):
g_count = len(gparams)/3
def gauss_impl(x, A, mu, sigma):
return A*numpy.exp(-(x-mu)**2/(2.*sigma**2))
res = np.zeros(len(x))
for gi in range(g_count):
res += gauss_impl(x, gparams[gi*3], gparams[gi*3+1], gparams[gi*3+2])
return res
# p0 is the initial guess for the fitting coefficients (A, mu and sigma above)
curves_count = 4
p0 = np.tile([1., 0., 1.], curves_count)
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 coeff
plt.show()