Python的sklearn包中的Gaussianmixture有什么问题?

时间:2019-04-25 11:11:51

标签: python scikit-learn

我正在python中使用sklearn的高斯混合(GM)来识别星团的成员。 GM调整有两个组件,其他组件是默认设置。如图所示,看到的显然不是簇成员的一颗恒星(带有红点)显示为成员。中间图中聚集的红点很可能是我的成员。但是,其左上角的单个红点不应成为成员。因为距离这个中间群体不够近。

My cluster image

我的python代码是

import numpy as np
from numpy import array
import pandas as pd
from sklearn.mixture import GaussianMixture

import matplotlib.pyplot as plt
from matplotlib import style
import matplotlib.colors as mtcolor

style.use("seaborn-white")
clist = ["gray", "red"]
cmap = mtcolor.ListedColormap(clist)

eX = pd.read_csv("mysatrs.csv", usecols=['col1', 'col2', 'col3']).values

col0m = (eX[:,0] >= -5) & (eX[:,0] <= 5)
col1m = (eX[:,1] >= -5) & (eX[:,1] <= 5)
col2m = (eX[:,2] > 0)

X = eX[col0m & col1m & col2m]

plt.figure(figsize=(6,6))

hcgmm = GaussianMixture(n_components=2)
gmmfit = hcgmm.fit(X)
gmmprd = gmmfit.predict(X)
hcprobs = gmmfit.predict_proba(X)
hcmns = hcgmm.means_

plt.scatter(X[:,0], X[:,1], c=gmmprd, s=3, cmap=cmap)
plt.show()

是否应该对通用汽车进行其他调整?

1 个答案:

答案 0 :(得分:2)

TLDR:每次运行它都会改变您的适应性,尝试几次并保持最佳(最低hcgmm.bic())。您的数据似乎有3个维度,我想这是另外3个维度(包括链接或进行绘制会有所帮助)。

如果有人想要更长的例子,这是MWE。首先,我们提取软件包并生成一些数据:

import numpy as np
import matplotlib.pyplot as plt
from sklearn.mixture import GaussianMixture

background = np.random.randn(50,2) * 5
cluster = np.random.randn(50,2)

plt.scatter(background[:,0], background[:,1])
plt.scatter(cluster[:,0], cluster[:,1])

这给出了类似于OP的内容:

random draw

然后,我可以像OP那样适合GMM

gmm = GaussianMixture(n_components=2)
fit = gmm.fit(X)

并使用以下结果绘制结果:

plt.scatter(X[:,0], X[:,1], c=fit.predict(X))

但大多数情况下,我的情况都很糟糕。但是运行几次之后,我得到了:

fit with bic 993.5

这表明我们可以(至少有时)恢复合理的分区。这种拟合的BIC是993.5,而我经常看到的> 1000看起来很糟糕。

如果使用上述随机数据运行fit 1000次,我可以生成一个CDF,看起来像:

flipped CDF

(x / y轴绕错了方向,x是概率,y是BIC值),表示将在大约10%的时间内恢复良好的分区。尝试其他随机抽奖会说这有所不同,但我的成功率还没有超过40%。

鉴于您只有几个要点和组成部分,您可以尝试一种计算量更大的方法。我希望贝叶斯MCMC混合模型在这里能做的更好。

我刚刚记得Rand index是检查分区准确性的简便方法。我们可以生成大量测试数据,进行拟合,并通过以下操作获得BIC和Rand指数:

from sklearn.metrics import adjusted_rand_score

true_labels = (np.random.random(100) < 0.5).astype(int)
ix_a, = np.nonzero(true_labels == 0)
ix_b, = np.nonzero(true_labels == 1)

gmm = GaussianMixture(n_components=2)

def test():
    X = np.empty((len(true_labels), 2), float)
    X[ix_a,:] = np.random.randn(len(ix_a), 2) * 5
    X[ix_b,:] = np.random.randn(len(ix_b), 2)

    fit = gmm.fit(X)
    ari = adjusted_rand_score(true_labels, fit.predict(X))
    return fit.bic(X), ari

fits = np.array([test() for _ in range(1000)])

,然后绘制结果分布:

plot of fits from above

这表明76%的时间我们没有得到任何有用的信息。如果我们有1000个数据点(即X有1000行),那么它通常会恢复合理的分区。但是,如果我从“ Uniform(-10,10)”分布中绘制background,例如与:

background = np.random.rand(500,2) * 20 - 10
cluster = np.random.randn(500,2)

它再次严重失败(ARI <0.5〜99.5%)。基本上,GM模型似乎很难处理非高斯数据。