Natural Language Toolkit - Classificazione del testo
Cos'è la classificazione del testo?
La classificazione del testo, come suggerisce il nome, è il modo per classificare parti di testo o documenti. Ma qui sorge la domanda: perché dobbiamo usare classificatori di testo? Dopo aver esaminato l'uso delle parole in un documento o in una parte di testo, i classificatori saranno in grado di decidere quale etichetta di classe assegnargli.
Classificatore binario
Come suggerisce il nome, il classificatore binario deciderà tra due etichette. Ad esempio, positivo o negativo. In questo il pezzo di testo o documento può essere un'etichetta o un'altra, ma non entrambe.
Classificatore multi-etichetta
Opposto al classificatore binario, il classificatore multietichetta può assegnare una o più etichette a una parte di testo o documento.
Insieme di funzioni con etichetta e senza etichetta
Una mappatura del valore-chiave dei nomi delle caratteristiche ai valori delle caratteristiche è chiamata insieme di caratteristiche. I set di funzionalità etichettati oi dati di addestramento sono molto importanti per l'addestramento alla classificazione in modo che possa successivamente classificare i set di funzionalità senza etichetta.
Insieme di funzioni etichettato | Set di funzionalità senza etichetta |
---|---|
È una tupla che assomiglia a (feat, label). | È un'impresa in sé. |
È un'istanza con un'etichetta di classe nota. | Senza etichetta associata, possiamo chiamarla istanza. |
Utilizzato per addestrare un algoritmo di classificazione. | Una volta addestrato, l'algoritmo di classificazione può classificare un insieme di funzionalità senza etichetta. |
Estrazione di feature di testo
L'estrazione delle caratteristiche del testo, come suggerisce il nome, è il processo di trasformazione di un elenco di parole in un insieme di caratteristiche utilizzabili da un classificatore. Dobbiamo trasformare il nostro testo in‘dict’ set di funzionalità di stile perché Natural Language Tool Kit (NLTK) si aspetta ‘dict’ set di funzionalità di stile.
Modello Bag of Words (BoW)
BoW, uno dei modelli più semplici in PNL, viene utilizzato per estrarre le caratteristiche da una parte di testo o documento in modo che possa essere utilizzato nella modellazione come negli algoritmi ML. Fondamentalmente costruisce un set di funzionalità di presenza di parole da tutte le parole di un'istanza. Il concetto alla base di questo metodo è che non si preoccupa di quante volte una parola ricorre o dell'ordine delle parole, si preoccupa solo del fatto che la parola sia presente o meno in un elenco di parole.
Esempio
Per questo esempio, definiremo una funzione chiamata bow () -
def bow(words):
return dict([(word, True) for word in words])
Ora chiamiamo bow()funzione sulle parole. Abbiamo salvato queste funzioni in un file chiamato bagwords.py.
from bagwords import bow
bow(['we', 'are', 'using', 'tutorialspoint'])
Produzione
{'we': True, 'are': True, 'using': True, 'tutorialspoint': True}
Classificatori di formazione
Nelle sezioni precedenti, abbiamo imparato come estrarre le caratteristiche dal testo. Quindi ora possiamo addestrare un classificatore. Il primo e più semplice classificatore èNaiveBayesClassifier classe.
Classificatore Naïve Bayes
Per prevedere la probabilità che un dato insieme di caratteristiche appartenga a una particolare etichetta, utilizza il teorema di Bayes. La formula del teorema di Bayes è la seguente.
$$ P (A | B) = \ frac {P (B | A) P (A)} {P (B)} $$Qui,
P(A|B) - È anche chiamata probabilità a posteriori, cioè probabilità che il primo evento, cioè A, si verifichi dato che il secondo evento, cioè B, si è verificato.
P(B|A) - È la probabilità che il secondo evento, cioè B, si verifichi dopo il primo evento, cioè che si sia verificato A.
P(A), P(B) - È anche chiamata probabilità a priori, ovvero probabilità che si verifichi il primo evento, ovvero A o il secondo evento, ovvero B.
Per addestrare il classificatore Naïve Bayes, useremo il movie_reviewscorpus da NLTK. Questo corpus ha due categorie di testo, vale a dire:pos e neg. Queste categorie rendono un classificatore addestrato su di esse un classificatore binario. Ogni file nel corpus è composto da due, uno è una recensione positiva del film e l'altro è una recensione negativa del film. Nel nostro esempio, utilizzeremo ogni file come una singola istanza sia per l'addestramento che per il test del classificatore.
Esempio
Per il classificatore di addestramento, abbiamo bisogno di un elenco di set di funzionalità etichettati, che sarà nel formato [(featureset, label)]. Qui il filefeatureset variabile è una dict e label è l'etichetta di classe nota per featureset. Creeremo una funzione denominatalabel_corpus() che prenderà un corpus denominato movie_reviewse anche una funzione chiamata feature_detector, che per impostazione predefinita è bag of words. Costruirà e restituirà una mappatura del modulo, {label: [featureset]}. Dopodiché utilizzeremo questa mappatura per creare un elenco di istanze di addestramento e istanze di test etichettate.
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
Con l'aiuto della funzione precedente otterremo una mappatura {label:fetaureset}. Ora definiremo un'altra funzione denominatasplit che richiederà una mappatura restituita da label_corpus() funzione e suddivide ogni elenco di set di funzionalità in training etichettati e istanze di test.
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
Ora, usiamo queste funzioni nel nostro corpus, ad esempio movie” -
from nltk.corpus import movie_reviews
from featx import label_feats_from_corpus, split_label_feats
movie_reviews.categories()
Produzione
['neg', 'pos']
Esempio
lfeats = label_feats_from_corpus(movie_reviews)
lfeats.keys()
Produzione
dict_keys(['neg', 'pos'])
Esempio
train_feats, test_feats = split_label_feats(lfeats, split = 0.75)
len(train_feats)
Produzione
1500
Esempio
len(test_feats)
Produzione
500
Lo abbiamo visto in movie_reviewscorpus, ci sono 1000 file pos e 1000 file neg. Finiamo anche con 1500 istanze di formazione etichettate e 500 istanze di test etichettate.
Adesso alleniamoci NaïveBayesClassifier usando il suo train() metodo di classe -
from nltk.classify import NaiveBayesClassifier
NBC = NaiveBayesClassifier.train(train_feats)
NBC.labels()
Produzione
['neg', 'pos']
Classificatore dell'albero decisionale
Un altro classificatore importante è il classificatore dell'albero decisionale. Qui per addestrarloDecisionTreeClassifierclass creerà una struttura ad albero. In questa struttura ad albero ogni nodo corrisponde a un nome di caratteristica ei rami corrispondono ai valori della caratteristica. E giù per i rami arriveremo alle foglie dell'albero, cioè alle etichette di classificazione.
Per addestrare il classificatore dell'albero decisionale, utilizzeremo le stesse funzionalità di formazione e test, ad es train_feats e test_feats, variabili da cui abbiamo creato movie_reviews corpus.
Esempio
Per addestrare questo classificatore, chiameremo DecisionTreeClassifier.train() metodo di classe come segue -
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)
Produzione
0.725
Classificatore di entropia massima
Un altro importante classificatore è MaxentClassifier che è anche conosciuto come a conditional exponential classifier o logistic regression classifier. Qui per addestrarlo, ilMaxentClassifier class convertirà i set di feature etichettati in vettoriali usando la codifica.
Per addestrare il classificatore dell'albero decisionale, utilizzeremo le stesse funzionalità di formazione e test, ad es train_featse test_feats, variabili da cui abbiamo creato movie_reviews corpus.
Esempio
Per addestrare questo classificatore, chiameremo MaxentClassifier.train() metodo di classe come segue -
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)
Produzione
0.786
Classificatore di scikit-learn
Una delle migliori librerie di machine learning (ML) è Scikit-learn. In realtà contiene tutti i tipi di algoritmi ML per vari scopi, ma hanno tutti lo stesso modello di progettazione di adattamento come segue:
- Adattamento del modello ai dati
- E usa quel modello per fare previsioni
Piuttosto che accedere direttamente ai modelli di scikit-learn, qui useremo NLTK SklearnClassifierclasse. Questa classe è una classe wrapper attorno a un modello scikit-learn per renderlo conforme all'interfaccia Classifier di NLTK.
Seguiremo i seguenti passaggi per addestrare un SklearnClassifier classe -
Step 1 - Per prima cosa creeremo funzioni di allenamento come abbiamo fatto nelle ricette precedenti.
Step 2 - Ora scegli e importa un algoritmo di apprendimento Scikit.
Step 3 - Successivamente, dobbiamo costruire un file SklearnClassifier classe con l'algoritmo scelto.
Step 4 - Infine, ci alleneremo SklearnClassifier classe con le nostre funzionalità di formazione.
Cerchiamo di implementare questi passaggi nella ricetta Python sottostante:
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)
Produzione
0.885
Precisione di misurazione e richiamo
Durante la formazione di vari classificatori, abbiamo misurato anche la loro accuratezza. Ma a parte l'accuratezza, ci sono un certo numero di altre metriche che vengono utilizzate per valutare i classificatori. Due di queste metriche sonoprecision e recall.
Esempio
In questo esempio, calcoleremo la precisione e il richiamo della classe NaiveBayesClassifier che abbiamo addestrato in precedenza. Per ottenere ciò creeremo una funzione denominata metrics_PR () che richiederà due argomenti, uno è il classificatore addestrato e l'altro è la funzionalità di test etichettata. Entrambi gli argomenti sono gli stessi che abbiamo passato durante il calcolo dell'accuratezza dei classificatori -
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
Chiamiamo questa funzione per trovare la precisione e richiamare -
from metrics_classification import metrics_PR
nb_precisions, nb_recalls = metrics_PR(nb_classifier,test_feats)
nb_precisions['pos']
Produzione
0.6713532466435213
Esempio
nb_precisions['neg']
Produzione
0.9676271186440678
Esempio
nb_recalls['pos']
Produzione
0.96
Esempio
nb_recalls['neg']
Produzione
0.478
Combinazione di classificatore e votazione
La combinazione di classificatori è uno dei modi migliori per migliorare le prestazioni di classificazione. E votare è uno dei modi migliori per combinare più classificatori. Per votare dobbiamo avere un numero dispari di classificatori. Nella seguente ricetta Python combineremo tre classificatori: la classe NaiveBayesClassifier, la classe DecisionTreeClassifier e la classe MaxentClassifier.
Per ottenere ciò definiremo una funzione denominata voting_classifiers () come segue.
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()
Chiamiamo questa funzione per combinare tre classificatori e trovare l'accuratezza:
from vote_classification import Voting_classifiers
combined_classifier = Voting_classifiers(NBC, decisiont_classifier, maxent_classifier)
combined_classifier.labels()
Produzione
['neg', 'pos']
Esempio
accuracy(combined_classifier, test_feats)
Produzione
0.948
Dall'output di cui sopra, possiamo vedere che i classificatori combinati hanno ottenuto la massima precisione rispetto ai classificatori individuali.