【发布时间】:2018-04-17 00:58:23
【问题描述】:
我试图在双峰分布data 上拟合两个高斯分布,但大多数优化器总是根据如下开始猜测给我错误的结果
我还从scikit-learn 尝试了GMM,但没有多大帮助。我想知道我可能做错了什么以及更好的方法,以便我们可以测试和拟合双峰数据。使用curve_fit和data的示例代码之一如下
import numpy as np
import matplotlib.pyplot as plt
from scipy.optimize import curve_fit
def gauss(x,mu,sigma,A):
return A*np.exp(-(x-mu)**2/2/sigma**2)
def bimodal(x,mu1,sigma1,A1,mu2,sigma2,A2):
return gauss(x,mu1,sigma1,A1)+gauss(x,mu2,sigma2,A2)
def rmse(p0):
mu1,sigma1,A1,mu2,sigma2,A2 =p0
y_sim = bimodal(x,mu1,sigma1,A1,mu2,sigma2,A2)
rms = np.sqrt((y-y_sim)**2/len(y))
data = pd.read_csv('data.csv')
x, y = data.index, data['24hr'].values
expected=(400,720,500,700,774,150)
params,cov=curve_fit(bimodal,x,y,expected, maxfev=100000)
sigma=np.sqrt(np.diag(cov))
plt.plot(x,bimodal(x,*params),color='red',lw=3,label='model')
plt.plot(x,y,label='data')
plt.legend()
print(params,'\n',sigma)
【问题讨论】:
-
你为什么使用高斯函数?大山峰高度倾斜,看起来几乎是三角形。
-
我使用了高斯分布,因为后面阶段的数据会扩散到松散的双峰,看起来像高斯分布。我想保持拟合参数一致,以便在后期进行数据间比较。
-
我没有尝试运行你的代码,但是从结果来看,你可能没有做错任何事情。假设其中一种模式与右侧的小峰很好地对齐。然后另一个高斯模式必须以某种方式适应大的、倾斜的、非高斯峰值,如果没有相当高的 RMS 误差,它就无法做到这一点。尽管不能很好地拟合小峰值,但将两种模式组合在一起以降低匹配大峰值所需的误差时,总体误差可能会小得多。
-
感谢您指出这个方向。那么可能我需要更改双峰分布函数中的分布类型。我会调查的。
-
我有一个使用 scipy 的 scipy.optimize.differential_evolution 遗传算法来确定初始参数的示例,用于将双洛伦兹峰方程拟合到碳纳米管的拉曼光谱数据bitbucket.org/zunzuncode/RamanSpectroscopyFit - 替换方程和数据用你自己的,你应该完成。
标签: python python-3.x scipy scikit-learn curve-fitting