Ich suche nach einem Algorithmus zur Ähnlichkeit von Zeichenfolgen, der bei Zeichenfolgen mit variabler Länge bessere Ergebnisse liefert als die normalerweise vorgeschlagenen (Levenshtein-Abstand, Soundex usw.).
Beispielsweise,
Gegebene Zeichenfolge A: "Robert",
Dann String B: "Amy Robertson"
wäre ein besseres Spiel als
String C: "Richard"
Außerdem sollte dieser Algorithmus vorzugsweise sprachunabhängig sein (funktioniert auch in anderen Sprachen als Englisch).
string-matching
ranking
similarity
fuzzy-search
marzagao
quelle
quelle
Antworten:
Simon White von Catalysoft hat einen Artikel über einen sehr cleveren Algorithmus geschrieben, der benachbarte Zeichenpaare vergleicht und für meine Zwecke sehr gut funktioniert:
http://www.catalysoft.com/articles/StrikeAMatch.html
Simon hat eine Java-Version des Algorithmus und unten habe ich eine PL / Ruby-Version davon geschrieben (entnommen aus der einfachen Ruby-Version, die im zugehörigen Forumeintragskommentar von Mark Wong-VanHaren erstellt wurde), damit ich sie in meinen PostgreSQL-Abfragen verwenden kann:
Klappt wunderbar!
quelle
string_similarity("vitamin B", "vitamin C") #=> 1
es eine einfache Möglichkeit, diese Art von Verhalten zu verhindern?marzagaos antwort ist großartig. Ich habe es in C # konvertiert und dachte, ich würde es hier posten:
Pastebin Link
quelle
(2.0 * intersection) / union
- Ich bekomme Double.NaN, wenn ich zwei leere Zeichenfolgen vergleiche.Hier ist eine andere Version von Marzagaos Antwort, die in Python geschrieben wurde:
quelle
Hier ist meine PHP-Implementierung des vorgeschlagenen StrikeAMatch-Algorithmus von Simon White. Die Vorteile (wie im Link angegeben) sind:
Eine echte Widerspiegelung der lexikalischen Ähnlichkeit - Zeichenfolgen mit kleinen Unterschieden sollten als ähnlich erkannt werden. Insbesondere sollte eine signifikante Teilüberlappung der Teilzeichenfolgen auf ein hohes Maß an Ähnlichkeit zwischen den Zeichenfolgen hinweisen.
Eine Robustheit gegenüber Änderungen der Wortreihenfolge - zwei Zeichenfolgen, die dieselben Wörter enthalten, jedoch in einer anderen Reihenfolge, sollten als ähnlich erkannt werden. Wenn andererseits eine Zeichenfolge nur ein zufälliges Anagramm der in der anderen enthaltenen Zeichen ist, sollte sie (normalerweise) als unähnlich erkannt werden.
Sprachunabhängigkeit - Der Algorithmus sollte nicht nur in Englisch, sondern in vielen verschiedenen Sprachen funktionieren.
quelle
Eine kürzere Version von John Rutledge's Antwort:
quelle
intersection
Variable ist eine Zeilenverschwendung.Diese Diskussion war wirklich hilfreich, danke. Ich habe den Algorithmus zur Verwendung mit Excel in VBA konvertiert und einige Versionen einer Arbeitsblattfunktion geschrieben, eine zum einfachen Vergleich eines Zeichenfolgenpaars, die andere zum Vergleichen einer Zeichenfolge mit einem Bereich / Array von Zeichenfolgen. Die strSimLookup-Version gibt entweder die zuletzt beste Übereinstimmung als Zeichenfolge, Array-Index oder Ähnlichkeitsmetrik zurück.
Diese Implementierung führt zu denselben Ergebnissen, die im Amazon-Beispiel auf der Website von Simon White aufgeführt sind, mit wenigen geringfügigen Ausnahmen bei Spielen mit geringer Punktzahl. Ich bin mir nicht sicher, wo sich der Unterschied einschleicht, könnte die Split-Funktion von VBA sein, aber ich habe nicht untersucht, da sie für meine Zwecke gut funktioniert.
quelle
Es tut mir leid, die Antwort wurde nicht vom Autor erfunden. Dies ist ein bekannter Algorithmus, der erstmals von der Digital Equipment Corporation vorgestellt wurde und häufig als Schindel bezeichnet wird.
http://www.hpl.hp.com/techreports/Compaq-DEC/SRC-TN-1997-015.pdf
quelle
Ich habe den Algorithmus von Simon White in PL / pgSQL übersetzt. Das ist mein Beitrag.
quelle
String-Ähnlichkeitsmetriken enthalten eine Übersicht über viele verschiedene Metriken, die beim String-Vergleich verwendet werden ( Wikipedia hat auch eine Übersicht). Ein Großteil dieser Metriken ist in einer Bibliothek implementiert .
Ein weiteres Beispiel für eine Metrik, die in der angegebenen Übersicht nicht enthalten ist, ist beispielsweise der Komprimierungsabstand (der versucht, die Komplexität von Kolmogorov zu approximieren ), der für etwas längere Texte als den von Ihnen vorgestellten verwendet werden kann.
Sie können sich auch ein viel umfassenderes Thema der Verarbeitung natürlicher Sprache ansehen . Mit diesen R-Paketen können Sie schnell loslegen (oder zumindest einige Ideen geben).
Und noch eine letzte Änderung - suchen Sie die anderen Fragen zu diesem Thema bei SO, es gibt einige verwandte Fragen.
quelle
Eine schnellere PHP-Version des Algorithmus:
Für die Daten, die ich hatte (ca. 2300 Vergleiche), hatte ich eine Laufzeit von 0,58 Sekunden mit Igal Alkon- Lösung gegenüber 0,35 Sekunden mit meiner.
quelle
Eine Version in der schönen Scala:
quelle
Hier ist die R-Version:
quelle
Posting Marzagão Antwort in C99, inspiriert von diesen Algorithmen
Einige Tests basierend auf dem Originalartikel :
quelle
Aufbauend auf Michael La Voies fantastischer C # -Version, gemäß der Aufforderung, sie zu einer Erweiterungsmethode zu machen, habe ich mir Folgendes ausgedacht. Der Hauptvorteil dieser Vorgehensweise besteht darin, dass Sie eine generische Liste nach der prozentualen Übereinstimmung sortieren können. Angenommen, Sie haben ein Zeichenfolgenfeld mit dem Namen "Stadt" in Ihrem Objekt. Ein Benutzer sucht nach "Chester" und Sie möchten die Ergebnisse in absteigender Reihenfolge der Übereinstimmung zurückgeben. Zum Beispiel möchten Sie, dass buchstäbliche Übereinstimmungen von Chester vor Rochester angezeigt werden. Fügen Sie dazu Ihrem Objekt zwei neue Eigenschaften hinzu:
Stellen Sie dann für jedes Objekt den SearchText auf das ein, wonach der Benutzer gesucht hat. Dann können Sie es einfach mit etwas wie sortieren:
Hier ist die geringfügige Änderung, um es zu einer Erweiterungsmethode zu machen:
quelle
Meine JavaScript-Implementierung verwendet eine Zeichenfolge oder ein Array von Zeichenfolgen sowie eine optionale Etage (die Standardetage ist 0,5). Wenn Sie eine Zeichenfolge übergeben, wird true oder false zurückgegeben, je nachdem, ob die Ähnlichkeitsbewertung der Zeichenfolge größer oder gleich dem Floor ist. Wenn Sie ihm ein Array von Zeichenfolgen übergeben, wird ein Array der Zeichenfolgen zurückgegeben, deren Ähnlichkeitsbewertung größer oder gleich der Etage ist, sortiert nach Bewertung.
Beispiele:
Hier ist es:
quelle
for(var j = 0; j < pairs1.length; j++){
sollte seinfor(var j = 0; j < pairs2.length; j++){
Der Würfelkoeffizientenalgorithmus (Antwort von Simon White / marzagao) ist in Ruby in der Methode pair_distance_similar im Edelstein amatch implementiert
https://github.com/flori/amatch
Dieses Juwel enthält auch Implementierungen einer Reihe von ungefähren Matching- und String-Vergleichsalgorithmen: Levenshtein-Editierentfernung, Verkäufer-Editierentfernung, Hamming-Distanz, längste gemeinsame Teilsequenzlänge, längste gemeinsame Teilstringlänge, Paarentfernungsmetrik, Jaro-Winkler-Metrik .
quelle
Eine Haskell-Version - Sie können gerne Änderungen vorschlagen, da ich nicht viel Haskell gemacht habe.
quelle
Clojure:
quelle
Was ist mit der Levenshtein-Distanz, geteilt durch die Länge der ersten Saite (oder alternativ geteilt durch meine min / max / avg-Länge beider Saiten)? Das hat bei mir bisher funktioniert.
quelle
Hey Leute, ich habe es in Javascript versucht, aber ich bin neu darin. Weiß jemand, wie man es schneller macht?
quelle
x
und zu deklariereny
, und Sie sollten Schleifen nicht mit einerfor..in..
Schleife durchlaufen (for(..;..;..)
stattdessen verwenden).Hier ist eine andere Version von Ähnlichkeit, die auf dem Sørensen-Dice-Index basiert (Marzagaos Antwort), diese in C ++ 11 geschrieben:
quelle
Ich suchte nach einer reinen Ruby-Implementierung des Algorithmus, der durch die Antwort von @ marzagao angezeigt wird. Leider ist der von @marzagao angegebene Link defekt. In der Antwort von @ s01ipsist gab er Ruby Gem Amatch an, bei dem die Implementierung nicht in reinem Ruby erfolgt. So searchd ich ein wenig und Juwel gefunden fuzzy_match die reine Ruby - Implementierung hat (obwohl dieses Juwel Einsatz
amatch
) an hier . Ich hoffe das hilft jemandem wie mir.quelle