我正在尝试将细胞分类为群体。当我使用:
gmix = mixture.GMM(n_components=3, covariance_type='full')
gmix.fit(samples)
以下代码的平均值输出按顺序变化,除非我设置:CCD_ 2。
print ("gmix.means n", gmix.means_)
colors = ['r' if i==0 else ('g' if i==1 else ('b' if i ==2 else 'm'))for i in gmix.predict(samples)]
我想要按X轴平均值排序的类(每个类的第一项),即:
[[ 3.25492404e+02 2.88403293e-02]
[ 3.73942908e+02 3.25283512e-02]
[ 5.92577646e+02 4.40595768e-02]]
因此,在上面的代码中,红色总是325,绿色372和蓝色592。目前,我认为没有任何东西可以对输出进行排序。
我试过了:
gmix.means_ = np.sort(gmix.means_, axis = 0)
但是,gmix.covars和gmix.weights也需要进行相应的排序,这就是我陷入困境的地方!
非常感谢!
编辑4/16/16:
谢谢你的帮助,指引我朝着正确的方向前进。这是我写得不好但工作的版本:
sort_indices = gmix.means_.argsort(axis = 0)
order = sort_indices[:, 0]
print('norder:', order)
gmix.means_ = gmix.means_[order,:]
gmix.covars_ = gmix.covars_[order, :]
print ("n sorted gmix.covars n", gmix.covars_)
print ("nnori gmix.weights n", gmix.weights_)
w = np.split(gmix.weights_,3)
w = np.asarray(w)
w = np.ravel(w[order,:])
gmix.weights_ = w
我在寻找相同的功能。这是我的解决方案,基于@ed3203代码:
def fit_predict_by(clf, X, order_function):
"""
Sort `clf.fit_predict` by given attribute.
It ensure that all calls to fit predict will return an array
sorted by the given attribute. In addition, the `clf` attributes
`means_`, `covars_`, and `weights_` are also sorted similarly.
## Usage
# Sort by cluster weights
y = fit_predict_by(clf, X, lambda clf: clf.weights_.argsort())
# or sort by the `x` value of the mean
y = fit_predict_by(clf, X, lambda clf: clf.means_.argsort()[:, 0])
"""
y = clf.fit_predict(X)
order = order_function(clf)
for attr in ('means_', 'covars_', 'weights_'):
sorted_attr = getattr(clf, attr)[order]
setattr(clf, attr, sorted_attr)
ensure_no_overlap = len(order)
for new_val, old_val in enumerate(order):
y[y == old_val] = new_val + ensure_no_overlap
return y - ensure_no_overlap
这基本上是一个矩阵/向量索引问题。我在这里可能太冗长了,但对矩阵进行排序应该只有两行。
一般的聚类算法(在您的情况下是GMM)不能保证每次都以相同的顺序标记聚类,也不能保证每次给您提供相同的聚类,除非您修复了初始条件。
如果你想让聚类按其均值的X坐标排序,你可能需要自己做这件事。这包括两个步骤,就像你在问题中提到的那样:
a) 对平均值进行排序并获取索引b) 使用索引提取您的平均收入
这可以简单地完成如下操作:
a) 在你的手段上做一个argsort
>>> means = np.array(np.mat('1, 2; 4, 3; 2, 6'))
>>> sort_indices = means.argsort(axis=0)
array([[0, 0],
[2, 1],
[1, 2]])
您的订单将是argsorted数组的第一列:
>>> order = sort_indices[:,0]
>>> order
array([0, 2, 1])
(b) 现在,我们将使用这个"订单"来重新排序您的收入。
>>> sorted_m = means[order,:]
>>> sorted_m
array([[1, 2],
[2, 6],
[4, 3]])
和你的协方差,让我们创建一个伪协方差矩阵:
>>> c = np.array(np.mat('9, 8, 7; 6, 5, 4; 3, 2, 1'))
>>> c
array([[9, 8, 7],
[6, 5, 4],
[3, 2, 1]])
现在,重新索引你的c,一个简单的方法就是重新索引:
>>> sorted_c = c[order,:][:, order]
>>> sorted_c
array([[9, 7, 8],
[3, 1, 2],
[6, 4, 5]])
如果你看到了,行和列是根据我们的新顺序重新排列的。
你有它,bot你的均值和协变排序。
您可能还需要重新标记原始标签,可以在此处使用答案:快速替换numpy数组中的值
由于scikit学习版本为0.23.1,正确的方法是重新排序精度_和精密度_cholesky_ovars_现在是协变s_order = best_gmm.means_.argsort(axis=0)[:, 0]
best_gmm.means_ = best_gmm.means_[order]
best_gmm.covariances_ = best_gmm.covariances_[order]
best_gmm.weights_ = best_gmm.weights_[order]
best_gmm.precisions_ = best_gmm.precisions_[order]
best_gmm.precisions_cholesky_ = best_gmm.precisions_cholesky_[order]