2016-12-13 2 views
4

Ich mache einige Clustering-Arbeit mit der Accord.net library. Letztendlich versuche ich, die optimale Anzahl von Clustern zu finden, die mit the elbow method verwendet werden können, was einige relativ einfache Berechnungen erfordert. Allerdings habe ich es schwer, die Werte zu bekommen, die ich brauche, um die beste Anzahl von K in meiner KMeans Modellierung zu verwenden.Entfernung von einem Datenpunkt zu seinem Schwerpunkt mit Accord.net

Ich habe einige Beispieldaten/code:

open Accord 
open Accord.Math 
open Accord.MachineLearning 
open Accord.Statistics 
open Accord.Statistics.Analysis 

let x = [| 
    [|4.0; 1.0; 1.0; 2.0|]; 
    [|2.0; 4.0; 1.0; 2.0|]; 
    [|2.0; 3.0; 1.0; 1.0|]; 
    [|3.0; 6.0; 2.0; 1.0|]; 
    [|4.0; 4.0; 1.0; 1.0|]; 
    [|5.0; 10.0; 1.0; 2.0|]; 
    [|7.0; 8.0; 1.0; 2.0|]; 
    [|6.0; 5.0; 1.0; 1.0|]; 
    [|7.0; 7.0; 2.0; 1.0|]; 
    [|5.0; 8.0; 1.0; 1.0|]; 
    [|4.0; 1.0; 1.0; 2.0|]; 
    [|3.0; 5.0; 0.0; 3.0|]; 
    [|1.0; 2.0; 0.0; 0.0|]; 
    [|4.0; 7.0; 1.0; 2.0|]; 
    [|5.0; 3.0; 2.0; 0.0|]; 
    [|4.0; 11.0; 0.0; 3.0|]; 
    [|8.0; 7.0; 2.0; 1.0|]; 
    [|5.0; 6.0; 0.0; 2.0|]; 
    [|8.0; 6.0; 3.0; 0.0|]; 
    [|4.0; 9.0; 0.0; 2.0|] 
    |] 

und ich kann den Cluster leicht genug, um mit

let kmeans = new KMeans 5 

let kmeansMod = kmeans.Learn x 
let clusters = kmeansMod.Decide x 

erzeugen, aber wie kann ich den Abstand von einem bestimmten Datenpunkt berechnen x es ist zugewiesener Cluster? Ich sehe nichts in der KMeans Cluster Collection class documentation, die darauf hindeutet, dass es bereits eine Methode für dieses Problem implementiert ist.

Es scheint, dass es relativ einfach sein sollte, diese Entfernung zu berechnen, aber ich bin ratlos. Wäre es so einfach, wie so etwas wie

let dataAndClusters = Array.zip clusters x 

let getCentroid (m: KMeansClusterCollection) (i: int) = 
    m.Centroids.[i] 

dataAndClusters 
|> Array.map (fun (c, d) -> (c, (getCentroid kmeansMod c) 
           |> Array.map2 (-) d 
           |> Array.sum)) 

zu tun, die zurück

val it : (int * float) [] = 
    [|(1, 0.8); (0, -1.5); (1, -0.2); (0, 1.5); (0, -0.5); (4, 0.0); (2, 1.4); 
    (2, -3.6); (2, 0.4); (3, 0.75); (1, 0.8); (0, 0.5); (1, -4.2); (3, -0.25); 
    (1, 2.8); (4, 0.0); (2, 1.4); (3, -1.25); (2, 0.4); (3, 0.75)|] 

Bin ich diese Distanz richtig Berechnung? Ich vermute nicht.

Wie schon erwähnt, ich bin auf der Suche nach der richtigen Anzahl von K in KMeans Clustering zu verwenden. Ich dachte nur, ich würde den einfachen Algorithmus verwenden, der in the second paragraph of this Stats.StackExchange.com answer ausgelegt ist. Bitte beachten Sie, dass ich nicht bin gegen die Verwendung der "Gap Statistic" am Ende der oberen Antwort verbunden ist.

+0

Sie sollten den Abstand zu seinem nächsten Cluster mit der Methode Scores() anstelle von Decide() berechnen können. – Cesar

Antwort

0

Stellt sich heraus, dass ich nicht Berechnung der Entfernungen korrekt war, aber ich war in der Nähe.

Doing mehr Graben, sah ich this similar question, but for the R language und brach den Prozess in dieser akzeptierten Antwort in meiner eigenen R Sitzung definiert.

Die Schritte scheinen ziemlich einfach zu sein:

1. From each data value, subtract the centroid values 
2. Sum the differences for a given data/centroid pair 
3. Square the differences 
4. Find the square root of the differences. 

Für mein Beispiel Daten über, würde es diese brechen:

let distances = 
    dataAndClusters 
    |> Array.map (fun (c, d) -> (c, ((getCentroid kmeansMod c) 
            |> Array.map2 (-) d 
            |> Array.sum 
            |> float) ** 2.0 
            |> sqrt)) 

Notiere die Addition von zwei Linien,

|> float) ** 2.0 wandelt den Wert in einen Gleitkommawert um, so dass er quadriert werden kann (z. B. x**y)

und

|> sqrt) die die Quadratwurzel des Wertes feststellt.

Es kann eine eingebaute Methode dafür sein, aber ich habe es noch nicht gefunden. Im Moment funktioniert das für mich.

Verwandte Themen