【问题标题】:What is the problem of Gaussianmixture in the sklearn package in Python?Python中sklearn包中的Gaussianmixture有什么问题?
【发布时间】:2019-04-25 21:49:08
【问题描述】:

我在 python 中使用 sklearn 的 Gaussianmixture (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()

是否应该对GM进行另一次调整?

【问题讨论】:

    标签: python scikit-learn


    【解决方案1】:

    TLDR:每次运行时获得的适合度都会发生变化,尝试几次并保持最佳状态(最低的hcgmm.bic())。您的数据似乎具有三个维度,我猜这另一个维度正在扔掉东西(包括链接或绘制它会有所帮助)。

    如果有人想要一个更长的例子,这里有一个 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 的东西:

    然后我可以像 OP 那样安装 GMM

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

    并绘制结果:

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

    但大多数情况下,我的身体都非常糟糕。但是运行几次后,我得到了这个:

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

    如果我使用上述随机数据运行 fit 1000 次,我可以生成一个看起来像这样的 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)])
    

    然后绘制结果分布:

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

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

    它再次严重失败(ARI

    【讨论】:

    • 感谢 Sam 并为丢失数据感到抱歉,this my data。我不是 python 专家,但我会测试你的建议。
    • 对于文件名冲突,我深表歉意。文件名已更正,现在上面的链接处于活动状态。亲爱的 Sam,据我所知,您的 python 知识比我好,如果您用您的代码检查我的数据,我会非常高兴。
    猜你喜欢
    • 1970-01-01
    • 2021-06-23
    • 1970-01-01
    • 1970-01-01
    • 2021-10-03
    • 2018-08-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多