Zestaw narzędzi języka naturalnego - klasyfikacja tekstu
Co to jest klasyfikacja tekstu?
Klasyfikacja tekstu, jak sama nazwa wskazuje, jest sposobem klasyfikowania fragmentów tekstu lub dokumentów. Ale tutaj pojawia się pytanie, dlaczego musimy używać klasyfikatorów tekstu? Po zbadaniu użycia słowa w dokumencie lub fragmencie tekstu, klasyfikatorzy będą mogli zdecydować, jaką etykietę klasy należy mu przypisać.
Klasyfikator binarny
Jak sama nazwa wskazuje, klasyfikator binarny zdecyduje między dwiema etykietami. Na przykład pozytywne lub negatywne. W tym przypadku fragment tekstu lub dokumentu może być jedną lub drugą etykietą, ale nie obydwoma.
Klasyfikator z wieloma etykietami
W przeciwieństwie do klasyfikatora binarnego, klasyfikator z wieloma etykietami może przypisać jedną lub więcej etykiet do fragmentu tekstu lub dokumentu.
Zestaw funkcji Labeled Vs Unlabeled
Mapowanie klucz-wartość nazw cech do wartości cech nazywa się zestawem funkcji. Oznaczone zestawy funkcji lub dane szkoleniowe są bardzo ważne dla uczenia klasyfikacji, aby później można było sklasyfikować zestaw funkcji bez etykiety.
Zestaw funkcji oznaczonych | Zestaw funkcji bez etykiety |
---|---|
Jest to krotka, która wygląda jak (wyczyn, etykieta). | To samo w sobie wyczyn. |
Jest to instancja ze znaną etykietą klasy. | Bez skojarzonej etykiety możemy to nazwać instancją. |
Służy do uczenia algorytmu klasyfikacji. | Po przeszkoleniu algorytm klasyfikacji może sklasyfikować zestaw funkcji bez etykiety. |
Wyodrębnianie cech tekstu
Wyodrębnianie cech tekstu, jak sama nazwa wskazuje, jest procesem przekształcania listy słów w zestaw funkcji, których może używać klasyfikator. Musimy przekształcić nasz tekst w‘dict’ style, ponieważ oczekuje się zestawu narzędzi języka naturalnego (NLTK) ‘dict’ zestawy funkcji stylu.
Model Bag of Words (BoW)
BoW, jeden z najprostszych modeli w NLP, służy do wyodrębniania cech z fragmentu tekstu lub dokumentu, tak aby można go było wykorzystać w modelowaniu w algorytmach ML. Zasadniczo konstruuje zestaw funkcji obecności słów ze wszystkich słów instancji. Koncepcja tej metody polega na tym, że nie dba o to, ile razy występuje słowo lub kolejność słów, dba tylko o to, czy słowo jest obecne na liście słów, czy nie.
Przykład
W tym przykładzie zdefiniujemy funkcję o nazwie bow () -
def bow(words):
return dict([(word, True) for word in words])
A teraz zadzwońmy bow()działają na słowach. Zapisaliśmy te funkcje w pliku o nazwie bagwords.py.
from bagwords import bow
bow(['we', 'are', 'using', 'tutorialspoint'])
Wynik
{'we': True, 'are': True, 'using': True, 'tutorialspoint': True}
Klasyfikatory szkolenia
W poprzednich sekcjach dowiedzieliśmy się, jak wyodrębnić cechy z tekstu. Więc teraz możemy wytrenować klasyfikator. Pierwszym i najłatwiejszym klasyfikatorem jestNaiveBayesClassifier klasa.
Naiwny klasyfikator Bayesa
Aby przewidzieć prawdopodobieństwo, że dany zestaw cech należy do określonej etykiety, wykorzystuje twierdzenie Bayesa. Wzór twierdzenia Bayesa jest następujący.
$$ P (A | B) = \ frac {P (B | A) P (A)} {P (B)} $$Tutaj,
P(A|B) - Nazywa się je również prawdopodobieństwem późniejszym, tj. Prawdopodobieństwem wystąpienia pierwszego zdarzenia, tj. A, przy założeniu, że wystąpiło drugie zdarzenie, tj. B.
P(B|A) - Jest to prawdopodobieństwo drugiego zdarzenia, tj. B, które wystąpi po pierwszym zdarzeniu, tj. A.
P(A), P(B) - Nazywa się to również prawdopodobieństwem wcześniejszym, tj. Prawdopodobieństwem wystąpienia pierwszego zdarzenia, tj. A lub drugiego zdarzenia, tj. B.
Aby wytrenować klasyfikator Naïve Bayes, będziemy używać movie_reviewskorpus z NLTK. Ten korpus ma dwie kategorie tekstu, a mianowicie:pos i neg. Te kategorie sprawiają, że uczony na nich klasyfikator jest klasyfikatorem binarnym. Każdy plik w korpusie składa się z dwóch, jeden to pozytywna recenzja filmu, a drugi to negatywna recenzja filmu. W naszym przykładzie użyjemy każdego pliku jako pojedynczej instancji zarówno do uczenia, jak i testowania klasyfikatora.
Przykład
Do klasyfikatora szkoleniowego potrzebujemy listy oznaczonych zestawów funkcji, która będzie miała postać [(featureset, label)]. Tutajfeatureset zmienna to dict a etykieta to znana etykieta klasy dla featureset. Stworzymy funkcję o nazwielabel_corpus() który weźmie korpus o nazwie movie_reviewsa także funkcję o nazwie feature_detector, która domyślnie bag of words. Zbuduje i zwróci mapowanie formularza, {etykieta: [zestaw cech]}. Następnie użyjemy tego mapowania do utworzenia listy oznaczonych instancji szkoleniowych i instancji testowych.
import collections
def label_corpus(corp, feature_detector=bow):
label_feats = collections.defaultdict(list)
for label in corp.categories():
for fileid in corp.fileids(categories=[label]):
feats = feature_detector(corp.words(fileids=[fileid]))
label_feats[label].append(feats)
return label_feats
Za pomocą powyższej funkcji uzyskamy mapowanie {label:fetaureset}. Teraz zamierzamy zdefiniować jeszcze jedną funkcję o nazwiesplit który przyjmie odwzorowanie zwrócone z label_corpus() funkcji i dzieli każdą listę zestawów funkcji na oznaczone szkolenia, a także instancje testowe.
def split(lfeats, split=0.75):
train_feats = []
test_feats = []
for label, feats in lfeats.items():
cutoff = int(len(feats) * split)
train_feats.extend([(feat, label) for feat in feats[:cutoff]])
test_feats.extend([(feat, label) for feat in feats[cutoff:]])
return train_feats, test_feats
Teraz użyjmy tych funkcji w naszym korpusie, tj. Movie_reviews -
from nltk.corpus import movie_reviews
from featx import label_feats_from_corpus, split_label_feats
movie_reviews.categories()
Wynik
['neg', 'pos']
Przykład
lfeats = label_feats_from_corpus(movie_reviews)
lfeats.keys()
Wynik
dict_keys(['neg', 'pos'])
Przykład
train_feats, test_feats = split_label_feats(lfeats, split = 0.75)
len(train_feats)
Wynik
1500
Przykład
len(test_feats)
Wynik
500
Widzieliśmy to w movie_reviewskorpusu, istnieje 1000 plików pos i 1000 plików neg. W rezultacie otrzymujemy również 1500 oznaczonych instancji szkoleniowych i 500 oznaczonych instancji testowych.
Teraz trenujmy NaïveBayesClassifier używając jego train() metoda klasowa -
from nltk.classify import NaiveBayesClassifier
NBC = NaiveBayesClassifier.train(train_feats)
NBC.labels()
Wynik
['neg', 'pos']
Klasyfikator drzewa decyzyjnego
Kolejnym ważnym klasyfikatorem jest klasyfikator drzewa decyzyjnego. Tutaj, aby go wyszkolićDecisionTreeClassifierclass utworzy strukturę drzewa. W tej strukturze drzewa każdy węzeł odpowiada nazwie funkcji, a gałęzie odpowiadają wartościom cech. A po gałęziach dotrzemy do liści drzewa, czyli etykiet klasyfikacyjnych.
Aby wytrenować klasyfikator drzewa decyzyjnego, użyjemy tych samych funkcji uczenia i testowania, tj train_feats i test_feats, zmienne, z których utworzyliśmy movie_reviews ciało.
Przykład
Aby wytrenować ten klasyfikator, zadzwonimy DecisionTreeClassifier.train() metoda klasy w następujący sposób -
from nltk.classify import DecisionTreeClassifier
decisiont_classifier = DecisionTreeClassifier.train(
train_feats, binary = True, entropy_cutoff = 0.8,
depth_cutoff = 5, support_cutoff = 30
)
accuracy(decisiont_classifier, test_feats)
Wynik
0.725
Maksymalny klasyfikator entropii
Innym ważnym klasyfikatorem jest MaxentClassifier który jest również znany jako conditional exponential classifier lub logistic regression classifier. Tutaj, aby to wyszkolićMaxentClassifier class przekonwertuje oznaczone zestawy funkcji na wektor przy użyciu kodowania.
Aby wytrenować klasyfikator drzewa decyzyjnego, użyjemy tych samych funkcji uczenia i testowania, tj train_featsi test_feats, zmienne, z których utworzyliśmy movie_reviews ciało.
Przykład
Aby wytrenować ten klasyfikator, zadzwonimy MaxentClassifier.train() metoda klasy w następujący sposób -
from nltk.classify import MaxentClassifier
maxent_classifier = MaxentClassifier
.train(train_feats,algorithm = 'gis', trace = 0, max_iter = 10, min_lldelta = 0.5)
accuracy(maxent_classifier, test_feats)
Wynik
0.786
Klasyfikator Scikit-Learn
Jedną z najlepszych bibliotek uczenia maszynowego (ML) jest Scikit-learn. W rzeczywistości zawiera różnego rodzaju algorytmy ML do różnych celów, ale wszystkie mają ten sam wzór dopasowania, jak poniżej -
- Dopasowanie modelu do danych
- I użyj tego modelu do prognozowania
Zamiast bezpośredniego dostępu do modeli scikit-learning, tutaj użyjemy NLTK SklearnClassifierklasa. Ta klasa jest klasą opakowującą wokół modelu scikit-learning, aby była zgodna z interfejsem klasyfikatora NLTK.
Wykonamy następujące kroki, aby wyszkolić SklearnClassifier klasa -
Step 1 - Najpierw utworzymy funkcje treningowe, tak jak to zrobiliśmy w poprzednich przepisach.
Step 2 - Teraz wybierz i zaimportuj algorytm uczenia się Scikit.
Step 3 - Następnie musimy skonstruować plik SklearnClassifier klasę z wybranym algorytmem.
Step 4 - Na koniec będziemy trenować SklearnClassifier z naszymi funkcjami szkoleniowymi.
Zaimplementujmy te kroki w poniższym przepisie Pythona -
from nltk.classify.scikitlearn import SklearnClassifier
from sklearn.naive_bayes import MultinomialNB
sklearn_classifier = SklearnClassifier(MultinomialNB())
sklearn_classifier.train(train_feats)
<SklearnClassifier(MultinomialNB(alpha = 1.0,class_prior = None,fit_prior = True))>
accuracy(sk_classifier, test_feats)
Wynik
0.885
Pomiar precyzji i przywołanie
Podczas szkolenia różnych klasyfikatorów mierzyliśmy również ich dokładność. Ale oprócz dokładności istnieje wiele innych metryk, które są używane do oceny klasyfikatorów. Dwa z tych wskaźników toprecision i recall.
Przykład
W tym przykładzie obliczymy precyzję i pamięć klasy NaiveBayesClassifier, którą trenowaliśmy wcześniej. Aby to osiągnąć, utworzymy funkcję o nazwie metrics_PR (), która będzie pobierać dwa argumenty, jeden to wyuczony klasyfikator, a drugi to oznaczone funkcje testowe. Oba argumenty są takie same, jakie przekazaliśmy podczas obliczania dokładności klasyfikatorów -
import collections
from nltk import metrics
def metrics_PR(classifier, testfeats):
refsets = collections.defaultdict(set)
testsets = collections.defaultdict(set)
for i, (feats, label) in enumerate(testfeats):
refsets[label].add(i)
observed = classifier.classify(feats)
testsets[observed].add(i)
precisions = {}
recalls = {}
for label in classifier.labels():
precisions[label] = metrics.precision(refsets[label],testsets[label])
recalls[label] = metrics.recall(refsets[label], testsets[label])
return precisions, recalls
Nazwijmy tę funkcję, aby znaleźć precyzję i przypomnieć sobie -
from metrics_classification import metrics_PR
nb_precisions, nb_recalls = metrics_PR(nb_classifier,test_feats)
nb_precisions['pos']
Wynik
0.6713532466435213
Przykład
nb_precisions['neg']
Wynik
0.9676271186440678
Przykład
nb_recalls['pos']
Wynik
0.96
Przykład
nb_recalls['neg']
Wynik
0.478
Połączenie klasyfikatora i głosowania
Łączenie klasyfikatorów to jeden z najlepszych sposobów na poprawę wydajności klasyfikacji. Głosowanie to jeden z najlepszych sposobów łączenia wielu klasyfikatorów. Do głosowania potrzebujemy nieparzystej liczby klasyfikatorów. W poniższym przepisie Pythona połączymy trzy klasyfikatory, a mianowicie klasę NaiveBayesClassifier, klasę DecisionTreeClassifier i klasę MaxentClassifier.
Aby to osiągnąć, zdefiniujemy funkcję o nazwie voting_classifiers () w następujący sposób.
import itertools
from nltk.classify import ClassifierI
from nltk.probability import FreqDist
class Voting_classifiers(ClassifierI):
def __init__(self, *classifiers):
self._classifiers = classifiers
self._labels = sorted(set(itertools.chain(*[c.labels() for c in classifiers])))
def labels(self):
return self._labels
def classify(self, feats):
counts = FreqDist()
for classifier in self._classifiers:
counts[classifier.classify(feats)] += 1
return counts.max()
Nazwijmy tę funkcję, aby połączyć trzy klasyfikatory i znaleźć dokładność -
from vote_classification import Voting_classifiers
combined_classifier = Voting_classifiers(NBC, decisiont_classifier, maxent_classifier)
combined_classifier.labels()
Wynik
['neg', 'pos']
Przykład
accuracy(combined_classifier, test_feats)
Wynik
0.948
Z powyższego wyniku widać, że połączone klasyfikatory uzyskały najwyższą dokładność niż indywidualne klasyfikatory.