【发布时间】:2017-06-14 22:59:39
【问题描述】:
我正在尝试使用 scikit-learn 拟合高斯总和,因为 scikit-learn GaussianMixture 似乎比使用 curve_fit 更强大。
问题:即使是单个高斯峰的截断部分,它也不能很好地拟合:
from sklearn import mixture
import matplotlib.pyplot
import matplotlib.mlab
import numpy as np
clf = mixture.GaussianMixture(n_components=1, covariance_type='full')
data = np.random.randn(10000)
data = [[x] for x in data]
clf.fit(data)
data = [item for sublist in data for item in sublist]
rangeMin = int(np.floor(np.min(data)))
rangeMax = int(np.ceil(np.max(data)))
h = matplotlib.pyplot.hist(data, range=(rangeMin, rangeMax), normed=True);
plt.plot(np.linspace(rangeMin, rangeMax),
mlab.normpdf(np.linspace(rangeMin, rangeMax),
clf.means_, np.sqrt(clf.covariances_[0]))[0])
给予
现在将 data = [[x] for x in data] 更改为 data = [[x] for x in data if x <0] 以截断分布返回
任何想法如何正确安装截断?
注意:分布不一定在中间被截断,可能会剩下完整分布的 50% 到 100% 之间的任何值。
如果有人能指出我的替代包,我也会很高兴。我只尝试了curve_fit,但一旦涉及两个以上的峰值,就无法让它做任何有用的事情。
【问题讨论】:
-
您期待什么?高斯的一半不是高斯,所以一个简单的高斯的所有拟合都不能产生好的结果。当您尝试高斯混合时,您可以使用 mixtures。但是对于多个高斯的混合,您需要的不仅仅是
n_components=1。这就是整个想法。 -
不确定这是真的。如果您使用 curve_fit 对单个高斯进行拟合,则效果非常好。只是这对于一个以上的峰值不能有效地工作。另外,为简单起见,
n_components=1... -
scipy stats 模块具有名为 truncnorm 的截断高斯数据的特定统计分布,当我尝试它时,它符合您的示例截断数据。如果您可以使用它,请参阅 truncnorm 的 scipy 文档:docs.scipy.org/doc/scipy/reference/generated/…
-
究竟是什么导致您在使用
curve_fit方法时遇到问题?您是否尝试过scipy.optimize的其他最小化方法?这是一个非常强大的工具箱,我认为不应轻易放弃。 -
我的数据非常嘈杂,用眼睛判断 GMM 通常会找到好的结果——除非部分数据被截断。我认为 GMM 的优势在于为拟合找到好的种子,这对于curve_fit 很难实现。当使用 curve_fit 一半的时间时,拟合甚至不会收敛。在这个问题上没有尝试过任何其他优化例程,但根据我的经验,它们都非常依赖于初始值。
标签: numpy scipy scikit-learn curve-fitting gaussian