2017-12-09 9 views
0

Ich schreibe einen Algorithmus, der überprüft, wie viel eine Zeichenfolge gleich einer anderen Zeichenfolge ist. Ich verwende Sklearn Cosinus-Ähnlichkeit.Sklearn Kosinusähnlichkeit für Strings, Python

Mein Code ist:

from sklearn.feature_extraction.text import TfidfVectorizer 
from sklearn.metrics.pairwise import cosine_similarity 

example_1 = ("I am okey", "I am okeu") 
example_2 = ("I am okey", "I am crazy") 

tfidf_vectorizer = TfidfVectorizer() 
tfidf_matrix = tfidf_vectorizer.fit_transform(example_1) 
result_cos = cosine_similarity(tfidf_matrix[0:1], tfidf_matrix) 
print(result_cos[0][1]) 

Ausführen dieses Code für example_1, druckt ,336096927276. Wenn Sie es für Beispiel 2 ausführen, wird dasselbe Ergebnis ausgegeben. Das Ergebnis ist in beiden Fällen dasselbe, weil nur ein anderes Wort existiert.

Was ich will, ist eine höhere Punktzahl für Beispiel_1 zu bekommen, weil die verschiedenen Wörter "okey vs okeu" nur einen anderen Buchstaben haben. Im Gegensatz dazu gibt es in example_2 zwei völlig unterschiedliche Wörter "okey vs crazy".

Wie kann mein Code berücksichtigen, dass in einigen Fällen die verschiedenen Wörter nicht völlig verschieden sind?

Antwort

2

Für kurze Strings wird Levenshtein distance wahrscheinlich bessere Ergebnisse als Kosinusähnlichkeit basierend auf Wörtern ergeben. Der folgende Algorithmus ist von Wikibooks angepasst. Da dies eine Abstandsmetrik ist, ist eine kleinere Punktzahl besser.

def levenshtein(s1, s2): 
    if len(s1) < len(s2): 
     s1, s2 = s2, s1 

    if len(s2) == 0: 
     return len(s1) 

    previous_row = range(len(s2) + 1) 
    for i, c1 in enumerate(s1): 
     current_row = [i + 1] 
     for j, c2 in enumerate(s2): 
      insertions = previous_row[j + 1] + 1 
      deletions = current_row[j] + 1 
      substitutions = previous_row[j] + (c1 != c2) 
      current_row.append(min(insertions, deletions, substitutions)) 
     previous_row = current_row 

    return previous_row[-1]/float(len(s1)) 

example_1 = ("I am okey", "I am okeu") 
example_2 = ("I am okey", "I am crazy") 

print(levenshtein(*example_1)) 
print(levenshtein(*example_2))         
+0

Guter Vorschlag, aber 'von leven Import Levenshtein' wäre einfacher. – FTP

+0

Meine Saiten sind Produkttitel. Ich versuche, 3 verschiedene Metriken zu kombinieren. Levenshtein, Cosine und Jaro Winkler, ich berechne den Mittelwert dieser 3 Metriken. – nesi