好的,所以我当前的曲线拟合代码有一个步骤,使用scipy.stats根据数据确定正确的分布,
distributions = [st.laplace, st.norm, st.expon, st.dweibull, st.invweibull, st.lognorm, st.uniform]
mles = []
for distribution in distributions:
pars = distribution.fit(data)
mle = distribution.nnlf(pars, data)
mles.append(mle)
results = [(distribution.name, mle) for distribution, mle in zip(distributions, mles)]
for dist in sorted(zip(distributions, mles), key=lambda d: d[1]):
print dist
best_fit = sorted(zip(distributions, mles), key=lambda d: d[1])[0]
print 'Best fit reached using {}, MLE value: {}'.format(best_fit[0].name, best_fit[1])
print [mod[0].name for mod in sorted(zip(distributions, mles), key=lambda d: d[1])]
数据是数值列表 . 到目前为止,这对于拟合单峰分布非常有效,在脚本中确认,该脚本随机生成随机分布的值并使用curve_fit重新确定参数 .
现在我想使代码能够处理双峰分布,如下例所示:
是否有可能从scipy.stats获取一对模型的MLE,以确定特定的一对分布是否适合数据?,类似于
distributions = [st.laplace, st.norm, st.expon, st.dweibull, st.invweibull, st.lognorm, st.uniform]
distributionPairs = [[modelA.name, modelB.name] for modelA in distributions for modelB in distributions]
并使用这些对来获得适合数据的那对分布的MLE值?
1 回答
这不是一个完整的答案,但它可以帮助您解决您的问题 . 假设您知道您的问题是由两个密度产生的 . 解决方案是使用 k-mean or EM algorithm.
Initalization . 您可以通过将每个观察值影响到一个或另一个密度来初始化算法 . 并初始化两个密度(初始化密度的参数,你的情况中的一个参数是“高斯”,“拉普拉”等等...迭代 . 然后,迭代,你运行以下两个步骤:
Step 1. 优化参数,假设每个点的影响是正确的 . 您现在可以使用任何优化求解器 . 此步骤为您提供适合您数据的最佳两个密度(使用给定参数)的估计 .
Step 2. 您可以根据最大可能性将每个观察分类为一个密度或另一个密度 .
你重复直到收敛 .
这个网页很好地解释了https://people.duke.edu/~ccc14/sta-663/EMAlgorithm.html
如果您不知道有多少密度生成了您的数据,则问题就更加困难了 . 你必须处理惩罚性的分类问题,这有点难 .
以下是一个简单的编码示例:您知道您的数据来自2个不同的高斯(您不知道每个密度生成了多少变量) . 在您的情况下,您可以调整此代码以循环每个可能的密度对(计算更长,但我会根据经验工作)
希望能帮助到你 .