wake-up-neo.com

Fuzzy-String-Vergleich

Was ich anstrebe, ist ein Programm, das eine Datei einliest und jeden Satz gemäß dem ursprünglichen Satz vergleicht. Der Satz, der perfekt mit dem Original übereinstimmt, erhält eine Punktzahl von 1 und ein Satz, der dem Gegenteil entspricht, erhält eine 0. Alle anderen unscharfen Sätze erhalten eine Note zwischen 1 und 0. 

Ich bin nicht sicher, welche Operation ich verwenden soll, um dies in Python 3 abzuschließen. 

Ich habe den Beispieltext eingefügt, in dem der Text 1 das Original ist und die anderen vorhergehenden Zeichenfolgen die Vergleiche sind. 

Text: Probe

Text 1: Es war eine dunkle und stürmische Nacht. Ich saß ganz alleine auf einem roten Stuhl. Ich war nicht ganz alleine, da ich drei Katzen hatte.

Text 20: Es war eine düstere und stürmische Nacht. Ich saß ganz alleine auf einem purpurroten Stuhl. Ich war nicht völlig alleine, da ich drei Katzen hatte// Sollte einen Höhepunkt erzielen, aber nicht 1

Text 21: Es war eine düstere und stürmische Nacht. Ich saß ganz alleine auf einer roten Kathedra. Ich war nicht völlig alleine, da ich drei Katzen hatte// Sollte unter 20 liegen

Text 22: Ich saß ganz alleine auf einer hochroten Kathedra. Ich war nicht völlig alleine, da ich drei Katzen hatte. Es war eine düstere und stürmische Nacht ... // // Sollte weniger als Text 21, aber NICHT 0 sein

Text 24: Es war eine dunkle und stürmische Nacht. Ich war nicht alleine Ich saß nicht auf einem roten Stuhl. Ich hatte drei Katzen. // // sollte eine 0 erzielen!

53
jacksonstephenc

Es gibt ein Paket namens fuzzywuzzy . Per pip installieren:

pip install fuzzywuzzy

Einfache Verwendung:

>>> from fuzzywuzzy import fuzz
>>> fuzz.ratio("this is a test", "this is a test!")
    96

Das Paket ist auf difflib aufgebaut. Warum benutzen Sie das nicht einfach? Abgesehen davon, dass es etwas einfacher ist, gibt es eine Reihe verschiedener Übereinstimmungsmethoden (z. B. Token Order Insensitivity, partielles String-Matching), die es in der Praxis leistungsfähiger machen. Die process.extract-Funktionen sind besonders nützlich: Finden Sie die am besten passenden Zeichenfolgen und Verhältnisse aus einem Satz. Aus ihrem Readme:

Teilverhältnis

>>> fuzz.partial_ratio("this is a test", "this is a test!")
    100

Token-Sortierverhältnis

>>> fuzz.ratio("fuzzy wuzzy was a bear", "wuzzy fuzzy was a bear")
    90
>>> fuzz.token_sort_ratio("fuzzy wuzzy was a bear", "wuzzy fuzzy was a bear")
    100

Token-Set-Verhältnis

>>> fuzz.token_sort_ratio("fuzzy was a bear", "fuzzy fuzzy was a bear")
    84
>>> fuzz.token_set_ratio("fuzzy was a bear", "fuzzy fuzzy was a bear")
    100

Verarbeiten

>>> choices = ["Atlanta Falcons", "New York Jets", "New York Giants", "Dallas Cowboys"]
>>> process.extract("new york jets", choices, limit=2)
    [('New York Jets', 100), ('New York Giants', 78)]
>>> process.extractOne("cowboys", choices)
    ("Dallas Cowboys", 90)
87
congusbongus

In der Standardbibliothek ( difflib ) gibt es ein Modul, das Zeichenfolgen vergleichen und basierend auf ihrer Ähnlichkeit eine Bewertung zurückgeben kann. Die SequenceMatcher -Klasse sollte das tun, wonach Sie suchen.

EDIT: Kleines Beispiel aus der Python-Eingabeaufforderung:

>>> from difflib import SequenceMatcher as SM
>>> s1 = ' It was a dark and stormy night. I was all alone sitting on a red chair. I was not completely alone as I had three cats.'
>>> s2 = ' It was a murky and stormy night. I was all alone sitting on a crimson chair. I was not completely alone as I had three felines.'
>>> SM(None, s1, s2).ratio()
0.9112903225806451

HTH!

75
mac

fuzzyset ist viel schneller als fuzzywuzzy (difflib) sowohl für die Indizierung als auch für die Suche.

from fuzzyset import FuzzySet
corpus = """It was a murky and stormy night. I was all alone sitting on a crimson chair. I was not completely alone as I had three felines
    It was a murky and tempestuous night. I was all alone sitting on a crimson cathedra. I was not completely alone as I had three felines
    I was all alone sitting on a crimson cathedra. I was not completely alone as I had three felines. It was a murky and tempestuous night.
    It was a dark and stormy night. I was not alone. I was not sitting on a red chair. I had three cats."""
corpus = [line.lstrip() for line in corpus.split("\n")]
fs = FuzzySet(corpus)
query = "It was a dark and stormy night. I was all alone sitting on a red chair. I was not completely alone as I had three cats."
fs.get(query)
# [(0.873015873015873, 'It was a murky and stormy night. I was all alone sitting on a crimson chair. I was not completely alone as I had three felines')]

Warnung: Seien Sie vorsichtig, dass Sie nicht unicode und bytes in Ihrem Fuzzyset mischen.

13
hobs

Die Aufgabe heißt Paraphrase Identification ist ein aktives Forschungsgebiet in der Verarbeitung natürlicher Sprachen. Ich habe mehrere aktuelle Veröffentlichungen verlinkt, für die Sie Open Source-Code auf GitHub finden können.

Beachten Sie, dass alle beantworteten Fragen davon ausgehen, dass zwischen den beiden Sätzen eine gewisse Ähnlichkeit zwischen Zeichenfolgen und Flächen besteht, während in Wirklichkeit zwei Sätze mit geringer Zeichenfolgenähnlichkeit semantisch ähnlich sein können.

Wenn Sie sich für diese Art von Ähnlichkeit interessieren, können Sie Skip-Thoughts ..__ verwenden. Installieren Sie die Software gemäß den GitHub-Handbüchern und gehen Sie in der Readme-Datei zum Abschnitt zur Erkennung von Paraphrasen:

import skipthoughts
model = skipthoughts.load_model()
vectors = skipthoughts.encode(model, X_sentences)

Dies konvertiert Ihre Sätze (X_sententien) in Vektoren. Später können Sie die Ähnlichkeit zweier Vektoren anhand folgender Kriterien ermitteln:

similarity = 1 - scipy.spatial.distance.cosine(vectors[0], vectors[1])

dabei gehen wir davon aus, dass Vektor [0] und Vektor 1 der entsprechende Vektor zu X_sentences [0], X_sentences 1 sind, den Sie nach ihren Bewertungen suchen wollten.

Es gibt andere Modelle, um einen Satz in einen Vektor umzuwandeln, den Sie hier finden können.

Sobald Sie Ihre Sätze in Vektoren umgewandelt haben, ist die Ähnlichkeit nur eine Frage des Findens der Kosinusähnlichkeit zwischen diesen Vektoren.

1
Ash