2016-05-03 1 views
1

Ich versuche, Zellen in Populationen zu klassifizieren. Wenn ich benutze:sklearn GMM Klassifizierung Vorhersage (Komponentenzuordnung) Auftrag

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

Das bedeutet Ausgang, aus dem Code unten, Änderungen in Ordnung, wenn ich nicht gesetzt: 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)]

Ich mag die von der X sortierten Klassen Achse bedeutet (erstes Element jeder Klasse) zB:

[[ 3.25492404e+02 2.88403293e-02] 
[ 3.73942908e+02 3.25283512e-02] 
[ 5.92577646e+02 4.40595768e-02]] 

So in dem obigen Code rot immer 325 sein würde, grün 372 und blue 592. Im Moment glaube ich nicht, dass irgendetwas den Output sortiert.

Ich habe versucht:

gmix.means_ = np.sort(gmix.means_, axis = 0) 

Aber dann die gmix.covars_ und gmix.weights_ müssen auch entsprechend sortiert werden, was ist, wo ich bin stecken!

Vielen Dank!

bearbeitet 4/5/16:

Danke für die Hilfe und Lenkung mich in der richtigen Richtung. Hier ist meine schlecht geschriebene, aber funktionierende Version:

Antwort

0

Dies ist im Grunde ein Matrix/Vektor-Indexierungsproblem. Ich bin hier wahrscheinlich zu ausführlich, aber es sollten nur zwei Zeilen sein, um Ihre Matrizen zu sortieren.

Clustering-Algorithmen im Allgemeinen (GMM in Ihrem Fall) sind nicht garantiert, die Cluster in der gleichen Reihenfolge jedes Mal zu beschriften, noch sind sie Ihnen garantiert die gleichen Cluster jedes Mal, wenn Sie die Anfangsbedingungen beheben.

Wenn Sie möchten, dass die Cluster nach ihrer X-Koordinate sortiert werden, müssen Sie dies möglicherweise selbst tun. Dies beinhaltet zwei Schritte, wie Sie in Ihrer Frage erwähnt:

a) die Mittel, sortieren und die Indizes erhalten b) die Indizes können Sie Ihre Mittel extrahieren

Dies kann einfach durchgeführt werden, wie folgt:

a) Führen Sie eine argsort auf Ihrem Mittel

>>> means = np.array(np.mat('1, 2; 4, 3; 2, 6')) 
>>> sort_indices = means.argsort(axis=0) 
array([[0, 0], 
     [2, 1], 
     [1, 2]]) 

Ihre Bestellung die erste Spalte der argsorted Array wäre:

>>> order = sort_indices[:,0] 
>>> order 
array([0, 2, 1]) 

(b) Jetzt werden wir diese 'Bestellung' verwenden, um Ihre Mittel neu zu ordnen.

>>> sorted_m = means[order,:] 
>>> sorted_m 

array([[1, 2], 
     [2, 6], 
     [4, 3]]) 

und Ihre Kovarianzen, lassen Sie uns eine Dummy-Kovarianzmatrix erstellen:

>>> 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]]) 

Jetzt indizieren Ihre c, und eine einfache Möglichkeit ist, einfach reindex:

>>> sorted_c = c[order,:][:, order] 
>>> sorted_c 
array([[9, 7, 8], 
     [3, 1, 2], 
     [6, 4, 5]]) 

Wenn Sie Sehen Sie, die Zeilen und Spalten werden gemäß unserer neuen Reihenfolge neu angeordnet.

Da haben Sie es, bot Ihre Mittel und Kovarien sortiert.

Möglicherweise müssen Sie Ihre Original-Etiketten als auch auf neu kennzeichnen, für die Sie die Antwort hier verwenden können: Fast replacement of values in a numpy array

+0

Danke für die Hilfe und Lenk mich in die richtige Richtung. Hier ist meine schlecht geschrieben, aber funktionierende Version: ' sort_indices = gmix.means_.argsort (Achse = 0) order = sort_indices [:, 0] print ('\ Norder:' Reihenfolge) gmix.means_ = gmix .means_ [order ,:] gmix.covars_ = gmix.covars_ [Ordnung:] print ("\ n \ n gmix.covars sortiert", gmix.covars_) print ("\ n \ Nori gmix. Gewichte \ n ", gmix.weights_) w = np.split (gmix.weights_, 3) w = np.asarray (w) w = np.ravel (w [order ,:]) gmix.weights_ = w –

1

Ich war für die gleiche Funktion suchen. Hier ist meine Lösung, basierend auf @ ed3203 code:

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