505 Stimmen

Finden Sie die Ähnlichkeitsmetrik zwischen zwei Zeichenfolgen

Wie bekomme ich die Wahrscheinlichkeit, dass ein String in Python einem anderen String ähnlich ist?

Ich möchte einen Dezimalwert wie 0.9 (was 90% bedeutet usw.) erhalten. Bevorzugt mit Standard-Python und Bibliothek.

zum Beispiel.

ähnlich("Apfel", "Apel") # hätte eine hohe Wahrscheinlichkeit.

ähnlich("Apfel", "Mango") # hätte eine niedrigere Wahrscheinlichkeit.

6voto

DRV Punkte 526

Textentfernung:

TextDistance - Python-Bibliothek zum Vergleich der Entfernung zwischen zwei oder mehr Sequenzen durch viele Algorithmen. Es hat Textentfernung

  • 30+ Algorithmen
  • Reine Python-Implementierung
  • Einfache Verwendung
  • Vergleich von mehr als zwei Sequenzen
  • Einige Algorithmen haben mehr als eine Implementierung in einer Klasse.
  • Optionale Verwendung von numpy für maximale Geschwindigkeit.

Beispiel1:

import textdistance
textdistance.hamming('test', 'text')

Ausgang:

1

Beispiel2:

import textdistance

textdistance.hamming.normalized_similarity('test', 'text')

Ausgang:

0,75

Danke und Prost!!!

4voto

George Pipis Punkte 1044

Es gibt viele Metriken zur Definition von Ähnlichkeit und Distanz zwischen Strings, wie oben erwähnt. Ich werde mein 5 Cent geben, indem ich ein Beispiel für Jaccard-Ähnlichkeit mit Q-Grammen und ein Beispiel mit Edit-Distanz zeige.

Die Bibliotheken

from nltk.metrics.distance import jaccard_distance
from nltk.util import ngrams
from nltk.metrics.distance  import edit_distance

Jaccard-Ähnlichkeit

1-jaccard_distance(set(ngrams('Apple', 2)), set(ngrams('Appel', 2)))

und wir erhalten:

0.33333333333333337

Und für Apple und Mango

1-jaccard_distance(set(ngrams('Apple', 2)), set(ngrams('Mango', 2)))

und wir erhalten:

0.0

Edit-Distanz

edit_distance('Apple', 'Appel')

und wir erhalten:

2

Und schließlich,

edit_distance('Apple', 'Mango')

und wir erhalten:

5

Kosinus-Ähnlichkeit auf Q-Grammen (q=2)

Eine weitere Lösung besteht darin, mit der textdistance-Bibliothek zu arbeiten. Ich werde ein Beispiel für Kosinus-Ähnlichkeit geben

import textdistance
1-textdistance.Cosine(qval=2).distance('Apple', 'Appel')

und wir erhalten:

0.5

3voto

Alex Punnen Punkte 3960

Füge die Spacy NLP-Bibliothek auch hinzu;

@profile
def main():
    str1= "31. März 09:08:41 Die Welt ist schön"
    str2= "31. März 19:08:42 Schön ist die Welt"
    print("NLP-Ähnlichkeit=",nlp(str1).similarity(nlp(str2)))
    print("Diff-Bibliotheksähnlichkeit", SequenceMatcher(None, str1, str2).ratio()) 
    print("Jellyfish-Bibliotheksähnlichkeit", jellyfish.jaro_distance(str1, str2))

if __name__ == '__main__':

    #python3 -m spacy download en_core_web_sm
    #nlp = spacy.load("en_core_web_sm")
    nlp = spacy.load("en_core_web_md")
    main()

Führe mit Robert Kerns line_profiler aus

kernprof -l -v ./python/loganalysis/testspacy.py

NLP-Ähnlichkeit= 0,9999999821467294
Diff-Bibliotheksähnlichkeit 0,5897435897435898
Jellyfish-Bibliotheksähnlichkeit 0,8561253561253562

Die Zeiten jedoch offenbaren

Funktion: main in Zeile 32

Zeile #      Aufrufe      Zeit  Pro Aufruf   % Zeit  Inhalt der Zeile
==============================================================
    32                                           @profile
    33                                           def main():
    34         1          1.0      1.0      0.0      str1= "31. März 09:08:41 Die Welt ist schön"
    35         1          0.0      0.0      0.0      str2= "31. März 19:08:42 Schön ist die Welt"
    36         1      43248.0  43248.0     99.1      print("NLP-Ähnlichkeit=",nlp(str1).similarity(nlp(str2)))
    37         1        375.0    375.0      0.9      print("Diff-Bibliotheksähnlichkeit", SequenceMatcher(None, str1, str2).ratio()) 
    38         1         30.0     30.0      0.1      print("Jellyfish-Bibliotheksähnlichkeit", jellyfish.jaro_distance(str1, str2))

0voto

David Emmanuel Punkte 1

Hier ist, was ich gedacht habe:

import string

def match(a,b):
    a,b = a.lower(), b.lower()
    error = 0
    for i in string.ascii_lowercase:
            error += abs(a.count(i) - b.count(i))
    total = len(a) + len(b)
    return (total-error)/total

if __name__ == "__main__":
    print(match("pple inc", "Apple Inc."))

0voto

Weilory Punkte 1697
  • Python3.6+=

  • Keine importierte Bibliothek

  • Funktioniert gut in den meisten Szenarien

Bei Stack Overflow werden alle relevanten Informationen angezeigt, wenn Sie versuchen, einen Tag hinzuzufügen oder eine Frage zu veröffentlichen. Dies ist sehr praktisch und genau der Algorithmus, den ich suche. Deshalb habe ich einen Abfragesatz-Ähnlichkeitsfilter kodiert.

def compare(qs, ip):
    al = 2
    v = 0
    for ii, letter in enumerate(ip):
        if letter == qs[ii]:
            v += al
        else:
            ac = 0
            for jj in range(al):
                if ii - jj < 0 or ii + jj > len(qs) - 1: 
                    break
                elif letter == qs[ii - jj] or letter == qs[ii + jj]:
                    ac += jj
                    break
            v += ac
    return v

def getSimilarQuerySet(queryset, inp, length):
    return [k for tt, (k, v) in enumerate(reversed(sorted({it: compare(it, inp) for it in queryset}.items(), key=lambda item: item[1])))][:length]

if __name__ == "__main__":
    print(compare('apple', 'mongo'))
    # 0
    print(compare('apple', 'apple'))
    # 10
    print(compare('apple', 'appel'))
    # 7
    print(compare('dude', 'ud'))
    # 1
    print(compare('dude', 'du'))
    # 4
    print(compare('dude', 'dud'))
    # 6

    print(compare('apple', 'mongo'))
    # 2
    print(compare('apple', 'appel'))
    # 8

    print(getSimilarQuerySet(
        [
            "java",
            "jquery",
            "javascript",
            "jude",
            "aja",
        ], 
        "ja",
        2,
    ))
    # ['javascript', 'java']

Erklärung

  • compare nimmt zwei Zeichenfolgen entgegen und gibt eine positive Ganzzahl zurück.
  • Sie können die erlaubte Variable al in compare bearbeiten, sie gibt an, wie groß der Bereich ist, den wir durchsuchen müssen. Die Funktion funktioniert folgendermaßen: Zwei Zeichenfolgen werden durchlaufen, wenn das gleiche Zeichen am gleichen Index gefunden wird, wird der Akkumulator dem größten Wert hinzugefügt. Dann suchen wir im Indexbereich des erlaubten, wenn Übereinstimmungen gefunden werden, wird der Akkumulator basierend darauf, wie weit der Buchstabe entfernt ist, hinzugefügt (je weiter, desto kleiner).
  • Länge gibt an, wie viele Elemente Sie als Ergebnis möchten, die dem Eingabestring am ähnlichsten sind.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X