Wie finde ich die Mitte aus einem cluster von Daten-Punkten?
Sagen wir mal ich aufgetragen, der die position des Hubschraubers jeden Tag für das vergangene Jahr und kam mit der folgenden Karte:
Jedem menschlichen Blick auf diese in der Lage wäre, mir zu sagen, dass dieser Hubschrauber ist aus Chicago.
Wie finde ich das gleiche Ergebnis in code?
Ich bin auf der Suche nach so etwas wie dieses:
$geoCodeArray = array([GET=http://pastebin.com/grVsbgL9]);
function findHome($geoCodeArray) {
//magic
return $geoCode;
}
Letztlich generieren, so etwas wie dieses:
UPDATE: Beispieldatensatz
Hier ist eine Karte mit einem Beispieldatensatz: http://batchgeo.com/map/c3676fe29985f00e1605cd4f86920179
Hier ist ein pastebin von 150 Geo: http://pastebin.com/grVsbgL9
Den oben enthält 150 Geo-Codes. Die ersten 50 sind in wenigen Clustern der Nähe von Chicago. Die übrigen sind verstreut im ganzen Land, darunter auch einige kleine Cluster in New York, Los Angeles und San Francisco.
Ich haben über eine million (ernst) Datensätze wie diese, die ich werde brauchen zu Durchlaufen und zu identifizieren, die am ehesten "zu Hause". Ihre Hilfe wird sehr geschätzt.
UPDATE 2: Flugzeug eingeschaltet, um Hubschrauber
Dem Flugzeug wurde das Konzept-Zeichnung zu viel Aufmerksamkeit auf körperliche Flughäfen. Die Koordinaten können Sie überall in der Welt, nicht nur Flughäfen. Nehmen wir an, es ist ein super Hubschrauber nicht an die Physik gebunden, Kraftstoff, oder irgendetwas anderes. Es kann landen, wo er will. 😉
- Können Sie teilen sich ein link mit solchen Daten?
- Sicher. Karte: batchgeo.com/map/c3676fe29985f00e1605cd4f86920179 und Geo-Codes: pastebin.com/grVsbgL9
- Blick auf die Karte bin ich nicht in der Lage zu beurteilen, ob das Flugzeug mit Sitz in Chicago oder in San Francisco. Ich erwarte nicht, dass ein Algorithmus besser zu sein als mich auf diese.
- Nun gibt es 50 Punkte, in der Nähe von Chicago und nur 20 oder so in der Nähe von San Francisco. Es scheint nicht abwegig, dass ein Algorithmus sollte in der Lage sein zu entdecken, in Chicago als wahrscheinlicher cluster zu konzentrieren. Aber ich bin offen für Korrektur.
- Auch die nächsten beiden Daten-Punkte sind nur einige Meter voneinander entfernt in Central Park, NYC. Ich warf diejenigen, die in es, um sicherzustellen, dass wir nicht zählen auf der nächsten Strecke zu fahren, den rest in den Fokus.
- das problem liegt in den Worten "Nähe". Trotzdem, tolle Idee, zu werfen und diese Punkte in. Die max-von-Summen der inverse-Quadrat-Distanzen gab mir nur die Antwort, die Sie erwartet 😉
- nun, das hinzufügen eines "slack", 20 Nm, mein Algorithmus scheint zu funktionieren, der Suche nach einer Stelle in der Nähe von Chicago, aber mit einer "lockeren" 10 Nm "sieht" zwei Cluster über Chicago und eine in der Nähe, und wählt einen Punkt im zweiten cluster. Die Frage ist, ist ein Durchmesser von 40 Nm immer noch "Nähe"?
- Sie sollten erkennen, dass ein Teil der Grund, warum die Menschen identifizieren können, die Ebene der Heimatbasis Chicago und nicht sagen, Joliet, ist, weil die Leute wissen, dass es ist ein wichtiger Flughafen in Chicago.
- Siehe unten für ein f-code-Beispiel, das in der Tat ergibt Flughafen von Chicago.
- Oh, wow, danke Ryan!!! Ich wirklich zu schätzen.
- Jeder Mensch würde in der Lage sein zu sagen, dass Hubschrauber hat die 20-fache der Reichweite von allen bekannten Hubschrauber.
Du musst angemeldet sein, um einen Kommentar abzugeben.
Folgende Lösung funktioniert auch, wenn die Punkte sind überall auf der Erde, durch die Umwandlung von Längen-und Breitengrad zu kartesischen Koordinaten. Es funktioniert eine Art von KDE (kernel density estimation), aber in einem ersten Durchlauf die Summe der Kerne ausgewertet wird nur die Daten-Punkte. Der kernel sollte so gewählt werden, passen Sie das problem. Im code unten ist es das, was ich mir scherzhaft/überheblich nennen eine Trossian, d.h., 2-d2/h2 für d≤h und h2/d2 für d>h (wobei d der euklidische Abstand und h ist die "Bandbreite"
$global_kernel_radius
), aber es könnte auch eine Gauß - (e-d2/2h2), ein Epanechnikov-kernel (1-d2/h2 für d<h, 0 sonst), oder einen anderen kernel. Eine optionale zweite Durchlauf verfeinert die Suche, lokal, entweder durch addieren einer unabhängigen kernel auf einem lokalen Netz, oder durch die Berechnung der Schwerpunkt, in beiden Fällen in eine Umgebung definiert, die von$local_grid_radius
.Im wesentlichen, jeder Punkt Summen all die Punkte, die es hat, um mit sich selbst, wiegt Sie mehr, wenn Sie näher (durch die bell-Kurve), und auch Wiegen, die Ihnen durch die optional Gewicht array
$w_arr
. Der Gewinner ist der Punkt mit der maximalen Summe. Nachdem der Sieger gefunden wurde, wird die "home" suchen wir für die gefunden werden können, wiederholen Sie den gleichen Prozess lokal um den Gewinner (mit einem anderen bell-Kurve), oder es kann geschätzt werden, werden die "center of mass" aller Punkte innerhalb eines bestimmten radius um den Gewinner, wobei der radius null werden kann.Muss der Algorithmus angepasst werden, um das problem, indem Sie die entsprechenden Kernel, indem Sie, wie um die Suche zu verfeinern lokal, und durch einstellen der Parameter. Für das Beispiel-dataset, das Trossian kernel für den ersten pass, und der Epanechnikov-kernel für den zweiten pass, alle 3 Radien auf 30 mi und grid step 1 mi könnte ein guter Ausgangspunkt, aber nur, wenn die beiden sub-Clustern von Chicago sollte gesehen werden als eine große Gruppe. Ansonsten kleinere Radien müssen so gewählt werden.
Die Tatsache, dass Entfernungen entsprechen der euklidischen und nicht groß-Kreis sollte nur vernachlässigbare Auswirkungen für die Aufgabe zur hand. Die Berechnung der great-circle Entfernungen wäre viel umständlicher und würde nur dazu führen das Gewicht sehr weit Punkte werden deutlich geringer - aber diese Punkte haben schon einen sehr niedrigen Gewicht. Im Prinzip der gleiche Effekt könnte erzielt werden, indem ein anderer kernel. Kerne, die haben eine komplette cut-off-jenseits einiger Entfernung, wie der Epanechnikov-kernel, haben dieses problem nicht bei allen (in der Praxis).
Die Umrechnung zwischen lat,lng und x,y,z für das WGS84 datum exakt angegeben (allerdings ohne Gewährleistung der numerischen Stabilität) mehr als eine Referenz ist, als durch eine echte Notwendigkeit. Wenn die Höhe berücksichtigt werden, oder wenn eine schnellere back-Konvertierung erforderlich ist, entnehmen Sie bitte der Wikipedia-Artikel.
Den Epanechnikov-kernel, abgesehen davon, dass "mehr lokales" als die Gauß-und Trossian-Kernel, hat den Vorteil, dass das Schnellste für die zweite Schleife ist O(ng), wobei g die Anzahl der Punkte, die von dem lokalen Netz, und kann auch eingesetzt werden, in die erste Schleife ist O(n2), wenn n groß ist.
Dieses Problem kann gelöst werden, indem Sie eine Gefahr Oberfläche. Sehen Rossmo Formel.
Dies ist die predator problem. Da eine Reihe von geografisch-liegt Kadaver, wo ist das Versteck der Räuber? Rossmo-Formel löst dieses problem.
Finden Sie den Punkt mit der größte Dichte Schätzung.
Sein sollte ziemlich einfach. Verwenden Sie einen kernel-radius, der etwa deckt einen großen Flughafen im Durchmesser. Einen 2D-GAUSS-oder Epanechnikov-kernel sollte in Ordnung sein.
http://en.wikipedia.org/wiki/Multivariate_kernel_density_estimation
Dies ist ähnlich wie die Berechnung einer Heap-Karte: http://en.wikipedia.org/wiki/Heat_map
und dann das finden der hellsten Stelle. Außer es berechnet die Helligkeit sofort.
For fun habe ich gelesen, eine 1% - Stichprobe der geografischen Koordinaten von DBpedia (z.B. Wikipedia) in ELKI, projiziert es in den 3D-Raum und aktiviert die Dichte Schätzung overlay (versteckt in den Visualisierungen scatterplot-Menü). Sie können sehen, es ist ein hotspot in Europa, und in geringerem Ausmaß in den USA. Der hotspot in Europa ist Polen, glaube ich. Zuletzt habe ich geprüft, jemand hatte offenbar erstellt einen Wikipedia-Artikel mit geografischen Koordinaten für so ziemlich jede Stadt in Polen. Die ELKI-visualizer, leider, weder können Sie Zoomen, drehen, oder reduzieren Sie die kernel-Bandbreite optisch finden die meisten dichten Punkt. Aber es ist einfach zu implementieren Sie sich selbst; Sie wahrscheinlich auch nicht brauchen, um in den 3D-Raum, kann aber nur verwenden breiten-und Längengrade.
Kernel-Dichte-Schätzung sollte in Tonnen von Anwendungen. Die eins in R ist wahrscheinlich viel stärker. Ich habe vor kurzem entdeckt, diese heatmap im ELKI, so dass ich wusste, wie schnell darauf zugreifen. Siehe z.B. http://stat.ethz.ch/R-manual/R-devel/library/stats/html/density.html für einen zugehörigen R-Funktion.
Auf Ihre Daten, R, versuchen Sie es zum Beispiel:
dies sollte zeigen eine starke Präferenz für Chicago.
Erträge
[1] 42.14697 -88.09508
- das ist weniger als 10 Meilen vom Flughafen von Chicago.Besser koordiniert versuchen:
dpik
in der Astrophysik nutzen wir so genannte "half-mass radius". Gegeben eine Verteilung, und Ihr Zentrum, die Hälfte der Masse-radius ist der Krümmungsradius von einem Kreis mit der Hälfte der Punkte der Verteilung.
Diese Menge ist eine charakteristische Länge der Verteilung der Punkte.
Wenn Sie wollen, dass die Heimat der Hubschrauber ist, wo die Punkte sind maximal konzentriert, so dass es ist der Punkt, der mindestens die Hälfte der Masse-radius!
Mein Algorithmus ist wie folgt: für jeden Punkt, den Sie berechnen diese die Hälfte der Masse-radius-Zentrierung der distribution in der aktuellen Punkt. Die "home" - der Helikopter wird der Punkt sein, mit der mindestens die Hälfte der Masse-radius.
Habe ich durchgeführt, und die berechneten center ist
42.149994 -88.133698
(in Chicago)Ich habe auch verwendet, die 0,2 der gesamten Masse anstelle von 0,5(die Hälfte) in der Regel verwendet in der Astrophysik.
Dies ist meine (in python) alghorithm, der findet die Heimat der Hubschrauber:
def inside...
Linien? Ich bin mit der Umsetzung dieses auf PHP und haben eine harte Zeit zu verstehen, dass ein Teil. Funktioniert das nur zurückgeben der Anzahl der Punkte innerhalb des radius?cos(radians($long2) - radians($long2))
die null. BTW deine Vermutung überdef inside
ist richtig, es gibt die Punkte innerhalb eines bestimmten Kreises von radiusradius
und zentriert aufcenter
.long1-long2
oderlong2-long1
). Vielen Dank für das heads-up. Ich war vor allem verwirrt über die Schleifen in Ihrem python-code. Ich verstehe nicht, wo das Schleifen-start und-Ende, so dass ich verwirrt war, dass es sich um PHP. Jede weitere Hilfe ist willkommen.long1-long2
oderlong2-long1
weil diecos
Funktion ist auch. In der Tatcos(x)=cos(-x)
und socos(x-y)=cos(y-x)
. Der code scheint ok, mir geht es nicht funktioniert?if(ninside>=npoints*0.2):
dann wird die Schleife beendet. Dies scheint nicht richtig zu mir.$coordinateArr[$centroidKey][0] . ',' . $coordinateArr[$centroidKey][1]
. Aber es ist etwas unheimlich, beängstigend in deinem code: Du hast multipied die$distance
durch3959
(ich Schätze der Erde radius in [mi]), in diesem Falldeltar=0.1
ist zu klein! Das ist mein code funktioniert: codepad.org/9Ro4lcQQ . BTW: ich habe gewählt die Erde radius gleich 1 in meinem code. Über den Zyklus: Es Stoppt aufif(ninside>=npoints*0.2):
weil die 0,2 Masse-radius gefunden wird, und der code nur für die Suche mindestens eine.1
,$deltar=0.1
ist zu groß, wenn ich verstehe, was der code tut. @Ryan: versuchen Sie, mit$deltar=$r_increment_in_miles/3959
$deltar
ist der Betrag, um den die vorläufige Hälfte der Masse-radius erhöht bei jedem Schritt. Wenn$r_increment_in_miles
ist die echte gewünschte Inkrement, das ist gleich$deltar
wenn das 3959 Faktor ist in der Ferne-Funktion. Wenn auf der anderen Seite der Erde radius auf 1 gesetzt ist und keine Skalierungsfaktor erscheint in der Ferne-Funktion$deltar=$r_increment_in_miles/3959
.Können Sie DBSCAN für diese Aufgabe.
DBSCAN ist ein Dichte-basiertes clustering mit einer Vorstellung von Lärm. Sie benötigen zwei Parameter:
Zunächst die Anzahl der Punkte zu einem cluster sollte mindestens
"minpoints"
.Und zweitens, ein Nachbarschafts-parameter genannt
"epsilon"
setzt einen Abstand Schwelle zu den umliegenden Punkte, die enthalten sein sollten in Ihrem cluster.Den gesamten Algorithmus funktioniert wie folgt:
Es ist wirklich einfach umzusetzen und es gibt viele frameworks, die Unterstützung dieser Algorithmus bereits. Zu finden, den Mittelwert des Clusters sind, können Sie nehmen Sie einfach der Mittelwert aller zugeordneten Punkte aus Ihrer Nachbarschaft.
Jedoch, im Gegensatz zu der Methode, die @TylerDurden schlägt vor, dies braucht eine Parametrisierung - also müssen Sie etwas finden, von hand gestimmt Parameter passend zu Ihrem problem.
In Ihrem Fall können Sie versuchen die minpoints zu 10% eurer gesamten Punkte, wenn das Flugzeug wird voraussichtlich bleiben 10% der Zeit, die Sie verfolgen auf einem Flughafen. Die Dichte-parameter epsilon, hängt von der Auflösung Ihres geografischen sensor und die Distanz-Metrik, die Sie verwenden - ich würde vorschlagen, die haversine Entfernung für geographische Daten.
Wie etwa teilen Sie die Karte in viele Zonen und dann finden Sie die Mitte der Ebene, in der zone mit den meisten Flugzeug. Der Algorithmus wird so etwas wie dieses
Alle, die ich auf dieser Maschine ist ein Alter compiler, also machte ich eine ASCII-version von diesem. Es "zieht" (in ASCII) eine Karte - Punkte sind Punkte, X ist, wo die wirkliche Quelle ist, G ist, wo die vermutete Quelle ist. Wenn die beiden sich überschneiden, nur X angezeigt.
Beispiele (SCHWIERIGKEIT 1,5 und 3 entsprechend):
Die Punkte erzeugt werden, durch die Auswahl von einem zufälligen Punkt als Quelle, dann nach dem Zufallsprinzip verteilen Punkte, so dass Sie eher näher an der Quelle.
DIFFICULTY
ist eine floating-point-Konstanten regelt, dass der Ausgangspunkt generation - wie viel eher die Punkte, um näher an die Quelle - wenn es 1 oder weniger, das Programm sollte in der Lage sein, zu erraten, die genaue Quelle, oder ganz in der Nähe. Bei 2,5, sollte es immer noch ziemlich anständig. Bei 4+, wird es beginnen, zu erraten, noch schlimmer, aber ich denke, dass es immer noch Vermutungen besser als ein Mensch.Könnte es sein, optimiert durch die Verwendung von binären Suche über die X -, dann Y - dies würde die Vermutung schlimmer, wäre aber viel, viel schneller. Oder beginnen Sie mit größeren Blöcken, dann die Spaltung der beste block weiter (oder der beste block und die 8 umgebenden). Für eine höhere Auflösung-system, für die diese erforderlich wären. Dies ist ein ziemlich naiver Ansatz, obwohl, aber es scheint zu funktionieren gut in einem 80x24-system. 😀
Virtual earth hat eine sehr gute Erklärung, wie kann man es relativ schnell. Sie haben auch code-Beispiele. Bitte haben Sie einen Blick auf http://soulsolutions.com.au/Articles/ClusteringVirtualEarthPart1.aspx
Einer einfachen Mischung aus Modell scheint zu funktionieren ziemlich gut für dieses problem.
Im Allgemeinen, um einen Punkt minimiert, dass der Abstand zu allen anderen Punkten in einem Datensatz, können Sie einfach den Mittelwert. In diesem Fall, werden Sie wollen, um einen Punkt zu finden, minimiert die Distanz von a Teilmenge der Punkte konzentriert. Wenn Sie postulieren, dass ein Punkt kommen entweder aus der konzentrierten Menge der Punkte von Interesse oder aus einer diffusen Satz von hintergrund-Punkte, dann ergibt dies eine Mischung Modell.
Ich habe einige python-code unten. Die konzentrierten Bereich wird modelliert, indem eine hoch-Präzisions-normal-Verteilung und der hintergrund Punkt modelliert werden, indem entweder eine niedrige Genauigkeit Normalverteilung oder eine Gleichverteilung über eine bounding-box, die auf den Datensatz (es ist eine code-Zeile, die auskommentiert werden können, um wechseln Sie zwischen diesen Optionen). Auch, Mischung Modelle können etwas instabil, so läuft der EM-Algorithmus ein paar mal mit zufälligen Anfangsbedingungen und die Wahl der Lauf mit dem höchsten log-likelihood bessere Ergebnisse liefert.
Wenn Sie eigentlich auf der Suche bei Flugzeugen, dann hinzufügen irgendeine Art von zeitabhängigen Dynamik wird wahrscheinlich verbessern Sie Ihre Fähigkeit zu schließen, die home base immens.
Ich würde auch vorsichtig sein, Rossimo Formel, denn es enthält einige ziemlich starke Annahmen über Kriminalität-Distributionen.
Können Sie leicht anpassen, Rossmo-Formel, zitiert nach Tyler Durden, um Ihren Fall mit paar einfache Hinweise:
Die Formel :
Diese Formel geben, die so etwas wie eine Wahrscheinlichkeit des Vorhandenseins der Basis-operation für ein raubtier oder ein Serienkiller ist. In Ihrem Fall könnte es geben, die Wahrscheinlichkeit einer base in einem bestimmten Punkt. Ich werde später erklären, wie es zu benutzen. U können, schreiben Sie es auf diese Weise :
Proba(Basis auf Punkt A)= Sum{auf allen Flecken} ( Phi/(dist^f)+(1-Phi)(B*(g-f))/(2B-dist)^g )
Mit euklidische Distanz
Möchten Sie zu einem euklidischen Abstand und nicht die Manhattan ein, weil ein Flugzeug oder Hubschrauber ist nicht gebunden an die Straße/Straßen. So verwenden euklidische Abstand ist der richtige Weg, wenn Sie tracking ein Flugzeug & nicht ein Serienmörder. So "dist" in der Formel ist der euklidische Abstand zwischen dem Punkt ur das testen und die Stelle, als
Angemessene variable B
Variable B wurde zur Darstellung der Regel "halbwegs intelligenten killer nicht seinen Nachbar töten". In Ihrem Fall wird ebenfalls angewendet werden, weil niemand Sie benutzen ein Flugzeug/roflcopter zu bekommen, um die nächste Straßenecke. wir können annehmen, dass die minimale Reise ist zum Beispiel 10 km oder etwas sinnvolles, wenn Sie angewendet werden, um Ihren Fall.
Exponentielle Faktor f
Faktor f wird verwendet, um ein Gewicht auf die Entfernung. Zum Beispiel, wenn alle die spots sind in einem kleinen Bereich, der Sie wollen könnte ein großer Faktor f, weil die Wahrscheinlichkeit des airport/base/HQ abnehmen wird schnell, wenn alle Ihre Datenpunkt sind in der gleichen Branche. g arbeitet in einer ähnlichen Weise, zu ermöglichen, wählen Sie die Größe der "Basis ist unwahrscheinlich, dass direkt neben dem spot" - Bereich
Faktor Phi :
Wieder dieser Faktor festgelegt werden, mit Ihrem wissen von dem problem. Es ermöglicht zu wählen, die möglichst genaue Faktor zwischen "Basis ist in der Nähe spots" und "ich werde nicht verwenden Sie die Ebene, um 5 m", beispielsweise, wenn u denken, dass der zweite fast spielen keine Rolle Sie können Phi 0,95
(0<Phi<1)
Wenn beide interessant sind phi wird etwa 0,5, Wie es zu implementieren als etwas nützliches :
Ersten, die Sie teilen möchten, Ihre Karte in kleine Quadrate unterteilt wird : Vernetzung der Karte ( genau wie invisal habe) (je kleiner die Quadrate ,desto genauer das Ergebnis (in general)), dann mit Hilfe der Formel zu finden, die mehr wahrscheinliche Lage. In der Tat, das Netz ist nur ein array mit allen möglichen Orten. (wenn u wollen, um genau zu sein erhöhen Sie die Anzahl der möglichen stellen, aber es erfordert mehr Rechenzeit und PhP ist nicht bekannt für seine erstaunliche Geschwindigkeit)
Algorithmus :
Hoffe, dass es Ihnen helfen
Zuerst möchte ich sagen, dass ich mit Vorliebe deine Methode illustrieren und erklären das problem ..
Wenn ich in deinen Schuhen wäre, würde ich gehen für einen Dichte-basierter Algorithmus wie DBSCAN
und dann nach der Clusterbildung werden die Gebiete und die Beseitigung der Lärm Punkte wenige Bereiche (Auswahl) bleiben .. dann werde ich den cluster mit der höchsten Dichte der Punkte und Berechnung der durchschnittlichen Punkt und finden Sie die nächste wirkliche Punkt zu . getan, den Platz gefunden! :).
Grüße,
Warum nicht so etwas wie dieses:
Summe vielleicht nicht die beste Metrik zu verwenden. Möglicherweise ist der Punkt mit den meisten "kleinen Strecken"?
Summe über die Distanzen. Nehmen Sie den Punkt mit der kleinsten summiert Entfernung.
Können Sie einen minimum spanning tree zu entfernen und den längsten Kanten. Die kleineren Bäume geben Sie die centeroid nachschlagen. Der name des Algorithmus single-link-k-clustering. Es gibt einen Beitrag hier: https://stats.stackexchange.com/questions/1475/visualization-software-for-clustering.