我正在python中使用sklearn的高斯混合(GM)来识别星团的成员。 GM调整有两个组件,其他组件是默认设置。如图所示,看到的显然不是簇成员的一颗恒星(带有红点)显示为成员。中间图中聚集的红点很可能是我的成员。但是,其左上角的单个红点不应成为成员。因为距离这个中间群体不够近。
我的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()
是否应该对通用汽车进行其他调整?
答案 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的内容:
然后,我可以像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 <0.5〜99.5%)。基本上,GM模型似乎很难处理非高斯数据。