Costruisci un programma di classificazione del testo: un tutorial NLP

Pubblicato: 2022-03-11

Il deep learning è una tecnologia che è diventata una parte essenziale dei flussi di lavoro di machine learning. Sfruttando i miglioramenti della potenza di elaborazione parallela e degli strumenti di supporto, le reti neurali complesse e profonde che un tempo erano poco pratiche stanno diventando praticabili.

L'emergere di librerie potenti e accessibili come Tensorflow, Torch e Deeplearning4j ha anche aperto lo sviluppo agli utenti al di là del mondo accademico e dei dipartimenti di ricerca di grandi aziende tecnologiche. A testimonianza della sua crescente ubiquità, aziende come Huawei e Apple stanno ora includendo processori dedicati e ottimizzati per il deep learning nei loro nuovi dispositivi per alimentare le applicazioni di deep learning.

Il deep learning ha dimostrato la sua potenza in molti domini. In particolare, AlphaGo di Google è stato in grado di sconfiggere giocatori umani in un gioco di Go, un gioco la cui sbalorditiva complessità un tempo era considerata una barriera quasi insormontabile per i computer nella sua competizione contro i giocatori umani. Il progetto Flow Machines di Sony ha sviluppato una rete neurale in grado di comporre musica nello stile di famosi musicisti del passato. FaceID, una funzionalità di sicurezza sviluppata da Apple, utilizza il deep learning per riconoscere il volto dell'utente e per tenere traccia delle modifiche al volto dell'utente nel tempo.

In questo articolo applicheremo il deep learning a due dei miei argomenti preferiti: elaborazione del linguaggio naturale e vino. Costruiremo un modello per comprendere le recensioni di vini in linguaggio naturale da parte di esperti e dedurre la varietà del vino che stanno recensendo.

Apprendimento profondo per la PNL

L'apprendimento profondo è stato ampiamente utilizzato nell'elaborazione del linguaggio naturale (PNL) perché è adatto per l'apprendimento della complessa struttura sottostante di una frase e della vicinanza semantica di varie parole. Ad esempio, l'attuale stato dell'arte per l'analisi dei sentimenti utilizza il deep learning per acquisire concetti linguistici difficili da modellare come negazioni e sentimenti contrastanti.

Il deep learning presenta diversi vantaggi rispetto ad altri algoritmi per la PNL:

  1. Modelli flessibili: i modelli di deep learning sono molto più flessibili rispetto ad altri modelli ML. Possiamo facilmente sperimentare diverse strutture, aggiungendo e rimuovendo strati secondo necessità. I modelli di deep learning consentono anche di creare modelli con output flessibili. La flessibilità è la chiave per lo sviluppo di modelli che ben si adattano alla comprensione di strutture linguistiche complesse. È anche essenziale per lo sviluppo di applicazioni NLP come traduzioni, chatbot e applicazioni di sintesi vocale.
  2. Meno conoscenza del dominio richiesta: sebbene sia necessaria una certa conoscenza del dominio e intuizione per sviluppare un buon modello di apprendimento profondo, la capacità degli algoritmi di apprendimento profondo di apprendere le gerarchie di funzionalità da soli significa che uno sviluppatore non ha bisogno di una conoscenza così approfondita del spazio problematico per sviluppare algoritmi di deep learning NLP. Per uno spazio problematico complesso come il linguaggio naturale, questo è un vantaggio molto gradito.
  3. Apprendimento continuo più semplice: gli algoritmi di deep learning sono facili da addestrare man mano che arrivano nuovi dati. Alcuni algoritmi di machine learning richiedono l'invio dell'intero set di dati attraverso il modello per l'aggiornamento, il che rappresenterebbe un problema per set di dati live e di grandi dimensioni.

Il problema oggi

Oggi costruiremo un algoritmo di deep learning per determinare la varietà del vino recensito in base al testo della recensione. Utilizzeremo il set di dati della rivista del vino su https://www.kaggle.com/zynicide/wine-reviews fornito dall'utente di Kaggle zackthoutt .

Concettualmente, la domanda è: possiamo fare una recensione del vino come...

Gli aromi includono frutta tropicale, ginestra, zolfo ed erbe essiccate. Al palato non è eccessivamente espressivo, offrendo mela acerba, agrumi e salvia essiccata insieme a una vivace acidità.

…e riconosci che si tratta di una miscela bianca? Alcuni appassionati di vino potrebbero riconoscere segni rivelatori di vini bianchi come mela, agrumi e un'acidità pronunciata, ma possiamo addestrare la nostra rete neurale a riconoscere questi segnali? Inoltre, possiamo addestrare la nostra rete neurale a riconoscere le sottili differenze tra una recensione di una miscela bianca e una recensione di pinot grigio?

Algoritmi simili

Il problema con cui stiamo lavorando oggi è essenzialmente un problema di classificazione della PNL. Esistono diversi algoritmi di classificazione della PNL che sono stati applicati a vari problemi nella PNL. Ad esempio, Bayes ingenuo sono stati utilizzati in vari algoritmi di rilevamento dello spam e le macchine vettoriali di supporto (SVM) sono state utilizzate per classificare testi come note di avanzamento presso le istituzioni sanitarie. Sarebbe interessante implementare una versione semplice di questi algoritmi che funga da base per il nostro modello di deep learning.

Ingenuo Bayes

Un'implementazione popolare di Bayes ingenuo per NLP prevede la preelaborazione del testo utilizzando TF-IDF e quindi l'esecuzione di Bayes ingenuo multinomiale sugli output preelaborati. Ciò consente all'algoritmo di essere eseguito sulle parole più importanti all'interno di un documento. Possiamo implementare l'ingenuo Bayes come segue:

 import numpy as np from sklearn.naive_bayes import MultinomialNB from sklearn.feature_extraction.text import CountVectorizer import pandas as pd from collections import Counter from sklearn.model_selection import train_test_split from sklearn.feature_extraction.text import TfidfTransformer df = pd.read_csv('data/wine_data.csv') counter = Counter(df['variety'].tolist()) top_10_varieties = {i[0]: idx for idx, i in enumerate(counter.most_common(10))} df = df[df['variety'].map(lambda x: x in top_10_varieties)] description_list = df['description'].tolist() varietal_list = [top_10_varieties[i] for i in df['variety'].tolist()] varietal_list = np.array(varietal_list) count_vect = CountVectorizer() x_train_counts = count_vect.fit_transform(description_list) tfidf_transformer = TfidfTransformer() x_train_tfidf = tfidf_transformer.fit_transform(x_train_counts) train_x, test_x, train_y, test_y = train_test_split(x_train_tfidf, varietal_list, test_size=0.3) clf = MultinomialNB().fit(train_x, train_y) y_score = clf.predict(test_x) n_right = 0 for i in range(len(y_score)): if y_score[i] == test_y[i]: n_right += 1 print("Accuracy: %.2f%%" % ((n_right/float(len(test_y)) * 100)))

Esegui il codice sopra e dovresti vedere qualcosa di simile al seguente: 73,56%

Considerando che stiamo esaminando 10 classi, questo è un buon risultato.

Possiamo anche usare la macchina vettoriale di supporto e vedere come funzionerebbe. Per vedere come si comporta, sostituisci semplicemente la definizione del classificatore con

 clf = SVC(kernel='linear').fit(train_x, train_y)

Esegui questo e dovresti vedere il seguente output:

Precisione: 80,66%

Neanche troppo malandato.

Vediamo se possiamo costruire un modello di deep learning in grado di superare o almeno eguagliare questi risultati. Se riuscissimo a farlo, sarebbe un'ottima indicazione del fatto che il nostro modello di deep learning è efficace almeno nel replicare i risultati dei popolari modelli di machine learning basati sulle competenze di dominio.

Costruire il modello

Oggi useremo Keras con Tensorflow per costruire il nostro modello. Keras è una libreria Python che semplifica la creazione di modelli di deep learning rispetto all'interfaccia di livello relativamente basso dell'API Tensorflow. Oltre agli strati densi, utilizzeremo anche strati di incorporamento e convoluzionali per apprendere le informazioni semantiche sottostanti delle parole e i potenziali modelli strutturali all'interno dei dati.

Pulizia dei dati

Innanzitutto, dovremo ristrutturare i dati in modo che possano essere facilmente elaborati e compresi dalla nostra rete neurale. Possiamo farlo sostituendo le parole con numeri identificativi univoci. Combinato con un vettore di incorporamento, siamo in grado di rappresentare le parole in un modo flessibile e semanticamente sensibile.

In pratica, vorremo essere un po' più intelligenti riguardo a questa preelaborazione. Avrebbe senso concentrarsi sulle parole comunemente usate e filtrare anche le parole più comunemente usate (ad esempio, the, this, a).

Possiamo implementare questa funzionalità utilizzando Defaultdict e NLTK. Scrivi il codice seguente in un modulo Python separato. L'ho inserito in lib/get_top_x_words.py .

 from nltk import word_tokenize from collections import defaultdict def count_top_x_words(corpus, top_x, skip_top_n): count = defaultdict(lambda: 0) for c in corpus: for w in word_tokenize(c): count[w] += 1 count_tuples = sorted([(w, c) for w, c in count.items()], key=lambda x: x[1], reverse=True) return [i[0] for i in count_tuples[skip_top_n: skip_top_n + top_x]] def replace_top_x_words_with_vectors(corpus, top_x): topx_dict = {top_x[i]: i for i in range(len(top_x))} return [ [topx_dict[w] for w in word_tokenize(s) if w in topx_dict] for s in corpus ], topx_dict def filter_to_top_x(corpus, n_top, skip_n_top=0): top_x = count_top_x_words(corpus, n_top, skip_n_top) return replace_top_x_words_with_vectors(corpus, top_x)

Ora siamo pronti per costruire il modello. Vogliamo un livello di incorporamento, uno convoluzionale e uno denso per sfruttare tutte le funzionalità di deep learning che possono essere utili per la nostra applicazione. Con Keras possiamo costruire il modello in modo molto semplice:

 from keras.models import Sequential from keras.layers import Dense, Conv1D, Flatten from keras.layers.embeddings import Embedding from keras.preprocessing import sequence from keras.utils import to_categorical import pandas as pd from collections import Counter from sklearn.model_selection import train_test_split from lib.get_top_xwords import filter_to_top_x df = pd.read_csv('data/wine_data.csv') counter = Counter(df['variety'].tolist()) top_10_varieties = {i[0]: idx for idx, i in enumerate(counter.most_common(10))} df = df[df['variety'].map(lambda x: x in top_10_varieties)] description_list = df['description'].tolist() mapped_list, word_list = filter_to_top_x(description_list, 2500, 10) varietal_list_o = [top_10_varieties[i] for i in df['variety'].tolist()] varietal_list = to_categorical(varietal_list_o) max_review_length = 150 mapped_list = sequence.pad_sequences(mapped_list, maxlen=max_review_length) train_x, test_x, train_y, test_y = train_test_split(mapped_list, varietal_list, test_size=0.3) max_review_length = 150 embedding_vector_length = 64 model = Sequential() model.add(Embedding(2500, embedding_vector_length, input_length=max_review_length)) model.add(Conv1D(50, 5)) model.add(Flatten()) model.add(Dense(100, activation='relu')) model.add(Dense(max(varietal_list_o) + 1, activation='softmax')) model.compile(loss='categorical_crossentropy', optimizer='adam', metrics=['accuracy']) model.fit(train_x, train_y, epochs=3, batch_size=64) y_score = model.predict(test_x) y_score = [[1 if i == max(sc) else 0 for i in sc] for sc in y_score] n_right = 0 for i in range(len(y_score)): if all(y_score[i][j] == test_y[i][j] for j in range(len(y_score[i]))): n_right += 1 print("Accuracy: %.2f%%" % ((n_right/float(len(test_y)) * 100)))

Esegui il codice e dovresti vedere il seguente output.

Precisione: 77,20%

Ricordiamo che l'accuratezza per Bayes ingenuo e SVC era rispettivamente del 73,56% e dell'80,66%. Quindi la nostra rete neurale sta tenendo testa ad alcuni dei metodi di classificazione del testo più comuni là fuori.

Conclusione

Oggi abbiamo trattato la costruzione di un modello di deep learning di classificazione per analizzare le recensioni dei vini.

Abbiamo scoperto che siamo stati in grado di costruire un modello in grado di competere e superare in prestazioni alcuni degli altri algoritmi di apprendimento automatico. Ci auguriamo che tu sia ispirato a utilizzare queste informazioni per creare applicazioni che analizzino set di dati più complessi e generino output più complessi!

Nota: puoi trovare il codice che ho usato per questo articolo su GitHub.


Ulteriori letture sul blog di Toptal Engineering:

  • Un significato più profondo: modellazione di argomenti in Python
  • Come creare un bot di analisi del sentimento dell'e-mail: un tutorial NLP