sklearn GMM分类预测(组件分配)顺序

时间:2016-05-03 15:42:36

标签: python scikit-learn

我试图将细胞分类为群体。当我使用时:

gmix = mixture.GMM(n_components=3, covariance_type='full') gmix.fit(samples)

以下代码中的均值输出按顺序变化,除非我设置:  np.radom.seed(0)

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/5/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 ("\n\nori gmix.weights \n", gmix.weights_)
    w = np.split(gmix.weights_,3)
    w = np.asarray(w)
    w = np.ravel(w[order,:])
    gmix.weights_ = w

3 个答案:

答案 0 :(得分:1)

我一直在寻找相同的功能。这是我的解决方案,基于@ 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

答案 1 :(得分:0)

这基本上是矩阵/向量索引问题。我在这里可能过于冗长,但对你的矩阵进行排序应该只有两行。

一般情况下,聚类算法(在您的情况下为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]])

如果你看到,行和列会根据我们的新订单重新排列。

你有它,你的手段和协方差排序。

您可能还需要重新标记原始标签,您可以在此处使用答案:Fast replacement of values in a numpy array

答案 2 :(得分:0)

由于scikit-learn版本为0.23.1,正确的方法是也重新排序 precisions _ precisions_cholesky _ 。此外, covars _ 现在是 covariances _ 。 因此,对于一维版本,您应该这样做:

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]