Python NLTK Dataframe Zeichenvergleich

Wenn du dir nicht sicher bist, in welchem der anderen Foren du die Frage stellen sollst, dann bist du hier im Forum für allgemeine Fragen sicher richtig.
Antworten
servus_97
User
Beiträge: 24
Registriert: Donnerstag 3. September 2020, 12:01

Hallo Leute!

Ich versuche mal schnell mein Problem zu beschreiben:

Ich habe eine Dataframe mit der Spalte "Name".
Manchmal schleichen sich Fehler in die Namen -- bspw.) Anstatt "Bosch" haben wir "Bosc h" oder "B0sch"

Jetzt will ich das Df einlesen, ein String als Input eingeben und es soll mir als Output den Spaltenwert geben, mit der höchsten Wahrscheinlichkeit.

Bspw)

(soll die Spalte 'Name' von dem DF sein)
Name: 'B0sch', 'Adidas', 'Bosch AG & CO' , 'Puma', ...

Input= 'Bosch'

Output: 'Mit x% Wahrscheinlichkeit ist dein gesuchtes Wort B0sch. (so in der Art)

Nun hatte ich schonmal eine ähnliche Frage gestellt und mir haben einige helfen können (danke an euch :) )

Code: Alles auswählen

from collections import defaultdict

import nltk
from nltk.util import ngrams

import pandas as pd 
import numpy as np 
from sklearn import feature_extraction, metrics
import io
from tqdm import tqdm

df = pd.read_excel('excel.xlsx')

df = df['Name'].to_string().splitlines()


txt = 'Nike


def extract_features(text):
    features = defaultdict(int)
    for count in range(1, 4):
        for ngram in ngrams(text, count):
            features[ngram] += 1
    return features
    
 
classifier = nltk.NaiveBayesClassifier.train((extract_features(line),line) for line in txt)

for line in df:
    classified = classifier.classify(extract_features(line))
    probdist = classifier.prob_classify(extract_features(line))
    print(f"{classified:10s} | {probdist.prob(classified):0.2f} | {line}")

Jedoch wird hier das String 'Nike' Buchstabe für Buchstabe mit den Spaltenwerten verglichen

AUSGABE:


k | 0.37 | 0 Bosch
i | 0.2 | 0 Pina
i | 0.14 | 0 Bid. A
....
rogerb
User
Beiträge: 878
Registriert: Dienstag 26. November 2019, 23:24

@servus_97,

Da gibt es leider noch einige Probleme:

Code: Alles auswählen

df = df['Name'].to_string().splitlines()
So hast du noch den index in deinen Daten enthalten. Das dürfte die Suche verfälschen.

Code: Alles auswählen

classifier = nltk.NaiveBayesClassifier.train((extract_features(line),line) for line in txt)
Das macht keinen Sinn, da du 'txt' wie eine Liste behandelst.
Ich kenne mich nicht sonderlich mit NLTK aus, aber einen Classifier mit nur einem Wort zu trainieren, dürfte auch nicht viel Sinn machen. Dazu können sich ja mal andere äußern, die mehr davon verstehen.

Statt dessen habe ich mal versucht den Classifier mit deinen Excel Daten zu trainieren und dann das eingegebene Wort an den Classifier übergegeben.

Code: Alles auswählen

from collections import defaultdict

import nltk
from nltk.util import ngrams

import pandas as pd 


df = pd.read_excel('excel.xlsx')
df = df['Name'].to_string(index=False).splitlines()

txt = 'Bach'


def extract_features(text):
    features = defaultdict(int)
    for count in range(1, 4):
        for ngram in ngrams(text, count):
            features[ngram] += 1
    return features
    

classifier = nltk.NaiveBayesClassifier.train((extract_features(line),line) for line in df)
best_guess = classifier.classify(extract_features(txt))
probdist = classifier.prob_classify(extract_features(txt))
prob = probdist.prob(best_guess)

print(f"Du sagtest '{txt}', aber ich bin mir zu {prob*100:5.2f}% sicher, dass du '{best_guess}' meintest")

"""
Ausgabe bei meinen Beispieldaten:
Du sagtest 'Bach', aber ich bin mir zu 83.81% sicher, dass du 'Bosch' meintest
"""

servus_97
User
Beiträge: 24
Registriert: Donnerstag 3. September 2020, 12:01

Hi,

danke dir. Es macht echt wenig Sinn, da hast du recht. Gerade, weil die Daten die trainiert werden sollen, eigentlich keine Fehler haben dürften ?

Ich habe mich jetzt doch für die Bibliothek fuzzywuzzy entschieden. Da läuft es über die Leventhstein Distanz ab. Ist auch viel schneller als der Classifier.

ODER
gibt es eine Möglichkeit den "train" Prozess nicht immer wiederholen zu müssen ? So was wie ein Memory, der die Daten speichert.
Ansonsten dauert der Vorgang oft sehr lange
rogerb
User
Beiträge: 878
Registriert: Dienstag 26. November 2019, 23:24

@servus_97,

wie lange kann das denn dauern und welcher Schritt dauert so lange?
Bei mir hat es bei 10000 Zeilen in der Excel-Tabelle eine Sekundenbruchteil gedauert. Wieviel Zeilen hast du denn in deinen Tabellen?

Man kann jedes Objekt - auch den classifier - als pickle speichern.
https://docs.python.org/3/library/pickl ... ule-pickle

Ich habe mit fuzzywuzzy noch nichts gemacht. Es scheint weniger Features zu haben. Aber wenn das genau die sind, die du brauchst, ist ja alles gut.
servus_97
User
Beiträge: 24
Registriert: Donnerstag 3. September 2020, 12:01

😅Hatte einen Fehler gemacht, deswegen auch die lange Dauerzeit.

Habe es jetzt mit Pickle hinbekommen :) Danke
LukeNukem
User
Beiträge: 232
Registriert: Mittwoch 19. Mai 2021, 03:40

servus_97 hat geschrieben: Mittwoch 28. Juli 2021, 19:49 😅Hatte einen Fehler gemacht, deswegen auch die lange Dauerzeit.

Habe es jetzt mit Pickle hinbekommen :) Danke
Anstelle des Moduls "pickle" bieten sich häufig auch die externe Bibliothek "dill" und, wenn es auf Performance ankommt, das externe Modul "quickle" an. Vor allem ""quickle" ist mit eigens definierten De- und Encodern sehr schnell und hat den angenehmen Nebeneffekt, daß die serialisierten Objekte hübsch klein sind.
Antworten