K-means ist ein standardmäßiger unbeaufsichtigter Clustering-Algorithmus, der bei einer Menge von "Punkten" und einer Anzahl von Clustern K jeden "Punkt" einem von K Clustern zuweist.
Pseudocode von K-Mitteln
Beachten Sie, dass es viele Varianten von K-Mitteln gibt. Sie müssen den unten beschriebenen Algorithmus implementieren. Möglicherweise haben Sie einige Variationen des Algorithmus oder verwenden integrierte Funktionen, solange Sie bei gleichen Anfangspunkten das gleiche Ergebnis wie bei diesem Algorithmus erzielen.
Bei dieser Herausforderung sind alle Eingaben Punkte in der 2D-Ebene (jeder Punkt wird durch seine Koordinaten in x und y dargestellt).
Inputs: K, the number of clusters
P, the set of points
Choose K points of P uniformly at random
Each chosen point is the initial centroid of its cluster
Loop:
For each point in P:
Assign to the cluster whose centroid is the nearest (Euclidean distance)
In case of a tie, any of the tied cluster can be chosen
Recompute the centroid of each cluster:
Its x coordinate is the average of all x's of the points in the cluster
Its y coordinate is the average of all y's of the points in the cluster
Until the clusters don't change from one iteration to the next
Output: the set of clusters
Eingänge und Ausgänge
- Sie können K und P durch
STDIN
oder als Funktionsargument usw. führen. - P und die Punkte in P können mit einer beliebigen Struktur dargestellt werden, die für Mengen / Listen in der Sprache Ihrer Wahl natürlich ist.
- K ist eine streng positive ganze Zahl.
- Sie können davon ausgehen, dass Eingaben gültig sind.
- Es wird immer mindestens K Punkte in P geben.
- Sie können die Cluster an ausgeben
STDOUT
, sie von einer Funktion zurückgeben usw. - Die Reihenfolge der Cluster und die Reihenfolge innerhalb der Cluster ist unwichtig. - Sie können entweder Punktgruppen zurückgeben, um Cluster darzustellen, oder jeden Punkt mit einer Kennung für den Cluster (z. B. einer Ganzzahl) kennzeichnen.
Testfälle
Da die resultierenden Cluster davon abhängen, welche Punkte ursprünglich ausgewählt wurden, erhalten Sie möglicherweise nicht alle dieselben Ergebnisse (oder jedes Mal dasselbe Ergebnis, wenn Sie Ihren Code ausführen).
Nehmen Sie daher nur die Ausgabe als Beispielausgabe.
Input:
K = 1
P = [[1,2.5]]
Output:
[[[1,2.5]]]
Input:
K = 3
P = [[4,8], [15,16], [23,42], [-13.37,-12.1], [666,-666]]
Output:
[[[666,-666]],[[-13.37,-12.1],[4,8]],[[15,16],[23,42]]]
Input:
K = 2
P = [[1,1], [1,1], [1,1]]
Output:
[[[1,1]],[[1,1],[1,1]]]
Wertung
Dies ist Code-Golf , daher gewinnt die kürzeste Antwort in Bytes.
quelle
1
, alle Punkte des zweiten Clusters haben Beschriftung2
usw.)K=2, P = [[1,1], [1,1], [1,1]]
.Antworten:
Matlab, 25 Bytes
Bei einer gegebenen
n x 2
Matrix (z. B. eine Zeile pro Punkt[[4,8]; [15,16]; [23,42]; [-13.37,-12.1]; [666,-666]]
) gibt diese Funktion eine Liste von Beschriftungen für jeden Eingabepunkt zurück.quelle
C ++,
479474 BytesNur ~ 20x so viel wie Matlab!
Golf gespielt
Die Eingabe / Ausgabe in den Algorithmus ist eine Menge von Punkten (
struct P
) mitx
undy
; und die Ausgabe ist dieselbe Menge, wobei ihrei
Menge den Index des Ausgabeclusters angibt, in dem der Punkt endet.Dieses Extra
i
wird auch verwendet, um die Cluster zu identifizieren. In der Hauptschleife wird der nächstgelegene Schwerpunkt zu jedem Punkt gefunden, indem eine Kopie der aktuellen Schwerpunkte nach der Nähe zu diesem Punkt sortiert wird.Dies behandelt entartete Fälle (leere Cluster), indem die vorherige Position der entsprechenden Schwerpunkte beibehalten wird (siehe Definition von
P::n
, die auch den Abstand zum vorherigen Schwerpunkt zurückgibt). Ein paar Zeichen könnten gespart werden, wenn angenommen wird, dass diese nicht auftauchen.Ungolfed, mit Haupt
quelle
#define R p){return
und das zweite Argument vonl
in ändern ,p
damit Sie es insgesamt dreimal verwenden können?J,
6054 BytesDefiniert ein Hilfsverb,
p
das eine Liste von Punkten und Schwerpunkten erstellt und jeden Punkt anhand des Index des nächsten Schwerpunkts klassifiziert. Anschließend wird der Vorgang der Auswahl eines neuen Schwerpunkts wiederholt, indem die Durchschnittswerte der Punkte in jedem Cluster bis zur Konvergenz ermittelt und anschließend die Punkte für die Ausgabe aufgeteilt werden.Verwendungszweck
Der Wert von k wird als Ganzzahl in der LHS angegeben. Die Liste der Punkte wird als 2d-Array auf der rechten Seite angegeben. Hier wird es als eine Liste von Punkten angegeben, die in ein 2d-Array von 5 x 2 umgeformt wird. Die Ausgabe ist die Bezeichnung, für die jeder Punkt in derselben Reihenfolge wie die Eingabe zum Cluster gehört.
Wenn Sie einen festen Samen für reproduzierbare Ergebnisse verwenden möchten, ersetzen Sie den
?
durch einen?.
at(?#)
.Erläuterung
quelle
CJam (60 Bytes)
Dies ist eine Funktion, die ihre Eingabe in der Form
k p
auf dem Stapel übernimmt . Es wird davon ausgegangen, dass die Punkte mit Doppel und nicht mit Int dargestellt werden. Es wird nicht implizit etwas über die Dimension der Punkte angenommen, daher würde es sich im euklidischen 6-D-Raum genauso gut gruppieren wie im angegebenen 2-D-Raum.Online-Demo
quelle
Mathematica
1412 BytesDa Einbauten erlaubt sind, sollte dies der Fall sein.
Beispiel
{{{4, 8}, {-13.37, -12.1}}, {{15, 16}, {23, 42}}, {{666, -666}}}
quelle
f = FindClusters
,f[something]
.Gelee , 24 Bytes
Probieren Sie es online aus!
Verwendet Funktionen, die implementiert wurden, nachdem diese Herausforderung veröffentlicht wurde. Angeblich ist dies nicht mehr konkurrierend .
Erläuterung
quelle
R , 273 Bytes
Probieren Sie es online aus!
Nimmt
P
als Matrix mitx
undy
Koordinaten in der ersten bzw. zweiten Spalte. GibtP
eine erste Spalte zurück, die den Clusterindex (Ganzzahl) angibt.Ich musste neu definieren,
w
indem ich die Quelle von kopiertennet::which.is.max
, um der Anforderung zu entsprechen, dass der Cluster bei Bindungen zufällig ausgewählt wird. Ansonsten würde ichwhich.min
abbase
für insgesamt 210 Bytes verwenden. Es gibt immer noch Platz zum Golfen, aber ich wollte es nicht zu sehr verschleiern, um anderen die Möglichkeit zu geben, mögliche Probleme in meinem Code zu erkennen.quelle
Julia 213 Bytes
Gibt ein Array mit der gleichen Länge wie zurück
p
, wobei Ganzzahlen angeben, zu welchem Cluster das entsprechende Elementp
gehört.Ich denke, es gibt noch einiges an Spielraum, um den Countdown der Charaktere zu optimieren.
(Natürlich könnte ich einfach das Paket Clustering.jl verwenden, um es trivial zu machen)
quelle