我必须找到参数theta,以便:
其中r是已知向量,phi是使用前一次迭代中的参数的函数。如何在Python中实现该优化?
import numpy as np
import scipy.optimize as optimize
# Gaussian function
def gaussian(x, mu, sig):
return (1/(sig*np.sqrt(2*np.pi)))*np.exp(-np.power(x - mu, 2.) / (2 * np.power(sig, 2.)))
# My observed data is a sum of two gaussians
step = 0.005
numSignals = 2
x = np.arange(0, 3+step, step)
w = np.array([0.4,0.8])
mean = np.array([0.5,0.9])
sigma = np.array([0.1,0.2])
noise = 0.05*np.random.normal(0,1,len(x))
y = w[0]*gaussian(x, mean[0], sigma[0]) + w[1]*gaussian(x, mean[1], sigma[1])
#Initialization, I assume my model is a sum of weighted gaussians and it is empty at the beginning
model = 0
i = 0
_mean = np.zeros(numSignals)
_sigma = np.zeros(numSignals)
_w = np.zeros(numSignals)
while i<numSignals:
r = y - model
# Optimization step
J = lambda c: -abs(np.dot(r,gaussian(x,c[0],c[1])))**2
res = optimize.minimize(J, (0.2, 0.5), method='TNC', tol=1e-6)
_mean[i] = res.x[0]
_sigma[i] = res.x[1]
_w[i] = np.dot(gaussian(x,_mean[i],_sigma[i]),r)/np.dot(gaussian(x,_mean[i],_sigma[i]),gaussian(x,_mean[i],_sigma[i]))
model = model + _w[i]*gaussian(x,_mean[i],_sigma[i])
print _w[i],_mean[i],_sigma[i]
i += 1
这是一种初始化算法,用于查找信号的均值,西格玛和权重的值,即两个高斯函数的和。在初始化之后,我使用了另一种有效的算法,但是这个算法得到了错误的值(即使使用初始值来优化实际值而不是0.2和0.5,我得到0.51和0.54表示平均值,2.2e-6和2.4e-6表示西格马)。
我尝试优化残差(r)和基函数(高斯函数)之间的相关性,以找出估计值(_w,_mean,_sigma)
编辑1:我只是试图找到最大化上面表达式的参数(w,mean和sigma)(或者最小化我的代码中的负数),所以我找到了初始化另一个算法的估计。但是尽管在scipy的最小化方法中使用实际值作为初始值,我得到了平均值和sigma的错误值。
编辑2:高斯函数完美运作...所以在评论之前,测试你所引用的代码,不要试图羞辱人
答案 0 :(得分:0)
我认为你的方法存在一个概念上与SciPy无关的问题。如果我理解正确,您的代码中有数据(y
)可以解释为两个(未知)高斯的总和。 (即,mean
和sigma
仅在此处给出,因为您为了示例而计算y
。通常,y
将是某些度量的结果。)
您现在尝试通过首先将一个高斯拟合到数据,然后将另一个高斯拟合到第一个拟合与数据之间的差异(残差,在您的代码r
中来找到两个高斯的参数在第二次迭代中)。如果其中一个显然支配数据,这可能会给你基本的高斯。但是,在您提供的数据中,两个基础高斯的影响都具有相似的数量级。
因此,在第一次迭代中,您将得到一个高斯,它最接近数据。因为它必须覆盖&#39; 两个基础高斯组合的效果,它不能太相似于它们中的一个。然后试图用另一个(也就是不同的)高斯来估计残差,不会从中拯救你。
如果你想获得令人满意的结果,你必须一次性拟合你的双高斯模型的所有参数。