2016-10-28 1 views
1

Ich habe zwei Vektoren, von denen jeder eine Reihe von Strings enthält. Zum BeispielFuzzy Matching zwei Saiten uring r

V1=c("pen", "document folder", "warn") 
V2=c("pens", "copy folder", "warning") 

Ich muss herausfinden, welche zwei am besten übereinstimmen. Ich benutze direkt Levenshtein Entfernung. Aber es ist nicht gut genug. In meinem Fall sollten Stift und Stifte dasselbe bedeuten. Dokumentenordner und Kopierordner sind wahrscheinlich das Gleiche. Warnung und Warnung sind eigentlich gleich. Ich versuche die Pakete wie tm zu benutzen. Aber ich bin mir nicht sicher, welche Funktionen dafür geeignet sind. Kann mir jemand davon erzählen?

+0

Sie müssen sich 'stringdist' anschauen. –

+0

wahrscheinlich müssen Sie ein benutzerdefiniertes Wörterbuch der Art machen. [Dieses Beispiel mit Wordnet] (http://stackoverflow.com/questions/7512472/extracting-synonym-terms-from-wordnet-using-synonym) kann hilfreich sein – Aramis7d

+0

Lesen Sie auf Levenshtein Entfernung. Es ist im Grunde - wie viele "single move" Änderungen vorgenommen werden müssen, um Strings zu entsprechen. Am besten wäre es, diesen Wert zu minimieren. '? adist' –

Antwort

1

Hier ist Wiki für Levenshtein distance. Es misst, wie viele Lösch-, Änderungs- und Einfügeaktionen ausgeführt werden müssen, um Strings zu transformieren. Und einer der Ansätze für die Fuzzy-Anpassung besteht darin, diesen Wert zu minimieren.

Hier ist ein Beispiel. I gemischt, um ein wenig, damit es weniger langweilig:

V1 <- c("pen", "document folder", "warn") 
V2 <- c("copy folder", "warning", "pens") 

apply(adist(x = V1, y = V2), 1, which.min) 
[1] 3 1 2 

Ausgabemittel, die Positionen von V2 am nächsten Transformation von V1 entsprechen, in der Reihenfolge von V1.

data.frame(string_to_match = V1, 
      closest_match = V2[apply(adist(x = V1, y = V2), 1, which.min)]) 
    string_to_match closest_match 
1    pen   pens 
2 document folder copy folder 
3   warn  warning 
1

Nach meiner Erfahrung des Cosinus Spiel ist gut für diese Art eines Jobs:

V1 <- c("pen", "document folder", "warn") 
V2 <- c("copy folder", "warning", "pens") 
result <- sapply(V1, function(x) stringdist(x, V2, method = 'cosine', q = 1)) 
rownames(result) <- V2 
result 
        pen document folder  warn 
copy folder 0.6797437  0.2132042 0.8613250 
warning  0.6150998  0.7817821 0.1666667 
pens  0.1339746  0.6726732 0.7500000 

Sie haben eine abgeschnitten zu definieren, wenn der Abstand nahe genug ist, wie der Abstand senken, wie besser passen sie zusammen. Sie können auch mit dem Q-Parameter spielen, der angibt, wie viele Buchstabenkombinationen miteinander verglichen werden sollen. Zum Beispiel:

result <- sapply(V1, function(x) stringdist(x, V2, method = 'cosine', q = 3)) 
rownames(result) <- V2 
result 
        pen document folder  warn 
copy folder 1.0000000  0.5377498 1.0000000 
warning  1.0000000  1.0000000 0.3675445 
pens  0.2928932  1.0000000 1.0000000 
+0

Vielen Dank für euch alle! Ich werde diese Methoden ausprobieren. Nur eins bin ich mir nicht sicher: Meine Saiten sind eigentlich viel komplexer als dieses Beispiel. Eine Zeichenfolge könnte wie "Dienstag KFC Warnungen Stifte Dokument Ordner 13 * 15 zwei von ihnen sein". Es bedeutet, dass es einige unbrauchbare Sub-Strings und einige Zeichen gibt. Ich fürchte, dass in diesem Fall die direkte Verwendung dieser Distanzfunktion nicht sehr geeignet ist. Also denke ich über die Verwendung von TM-Paket zuerst für die Vorverarbeitung? Irgendwelche Vorschläge? –

+0

Das tm-Paket ist ein wirklich gutes für die Vorverarbeitung. Dieser Link könnte Ihnen bei der Vorverarbeitung der Daten helfen: https://rstudio-pubs-static.s3.amazonaws.com/31867_8236987cf0a8444e962ccd2aec46d9c3.html –