我尝试从高斯混合模型中进行抽样。我有一个非常简单的例子,实际上只有一个成分(所以,实际上不是一个混合)。然后我用标准正态数据对其进行拟合。然而,该混合的权重对于一个混合成分来说最终大于1,导致错误:
import numpy as npfrom sklearn.mixture import GaussianMixturedataset = np.random.standard_normal(10).reshape(-1, 1)mixture = GaussianMixture(n_components=1)mixture.fit(dataset)mixture.sample(10)
ValueError: pvals < 0, pvals > 1 or pvals contains NaNs
显然,这由第一个成分的权重大于1引起:
> print(mixture.weights_[0])1.0000000000000002
这看起来像是一个bug。但也许是我在这里做错了什么?
回答:
尽管从技术上讲,这确实似乎是一个bug,但事实是,正如另一个答案中已经解释的那样,真正的原因是请求一个高斯混合模型的n_components=1
从建模的角度来看是没有意义的;有人可能会争辩说,应该更早地引发一个异常(或者至少是一个警告),即每当请求GaussianMixture(n_components=1)
时。我猜这可能是一个设计选择,但无论如何,这可能是scikit-learn Github仓库中作为可能的问题进行讨论的内容,而不是在这里。
话虽如此,这里有一个简单的解决方法:在n_components=1
的特殊情况下,强制 mixture.weights_[0]
等于1.0:
import numpy as npfrom sklearn.mixture import GaussianMixturedataset = np.random.standard_normal(10).reshape(-1, 1)mixture = GaussianMixture(n_components=1)mixture.fit(dataset)mixture.weights_[0]# 1.0000000000000002mixture.sample(10)# ValueError: pvals < 0, pvals > 1 or pvals contains NaNs# 强制权重为1.0:mixture.weights_[0] = 1.mixture.sample(10)# 结果:(array([[ 0.51371178], [ 0.1530927 ], [-0.56327362], [-1.22308348], [ 1.26889771], [ 1.11849849], [-1.47091749], [-0.41259178], [ 1.93872769], [ 0.26282224]]), array([0, 0, 0, 0, 0, 0, 0, 0, 0, 0]))
显然,这里不应该有任何理论上的担忧,因为根据定义,高斯混合中单个成分的权重是1.0;只是,正如另一个答案中所展示的,在可用的样本数量很少的情况下,GMM算法未能在可用的机器精度内给出恰好为1.0的权重。