Come fare la sentiment analysis in Python
Python mi permette di istruire un programma per l'analisi del sentimento di un testo tramite il machine learning (intelligenza artificiale). Per farlo utilizzo la libreria scikit-learn e un dataset di esempi di training.
Nota. La libreria scikit learn deve essere installata sul PC per essere utilizzata. Nello script uso anche la libreria pandas e la liberia numpy.
Per semplicità scarico dal sito kaggle un dataset di training didattico contenente alcune recensioni di film positive e negative. Ha il vantaggio d'essere un csv. Le recensioni positive hanno l'etichetta "pos" nella colonna "tag" (F). Quelle negative hanno l'etichetta "neg" nella stessa colonna.
Salvo il file csv (movie_review.csv) nella stessa cartella dove si trova lo script python che sto programmando per la sentiment analysis.
Nota. Il dataset è in lingua inglese. Per usare un dataset in italiano, basta crearlo e sostituirlo al precedente. Non solo film. Qualsiasi altro argomento va bene. Il programma resta lo stesso.
Apro python e importo alcune librerie, funzioni e metodi che mi serviranno.
Per prima cosa importo la libreria pandas.
import pandas as pd
In questo modo posso leggere il file csv con la funzione read_csv e assegnarla alla variabile df (dataframe).
df = pd.read_csv('movie_review.csv')
Salvo le colonne text e tag del csv in due variabili distinte X e y.
X = df['text']
y = df['tag']
Poi importo le funzioni random e array dalla libreria numpy.
from numpy import random,array
Uso subito la funzione random per fissarla a un generatore di numeri casuali.
random.seed(0)
In questo modo la casualità non influirà sulle varie prove di configurazione del training.
Ora importo la classe CountVectorizer da scikit-learn
from sklearn.feature_extraction.text import CountVectorizer
La classe CountVectorizer mi permette di vettorizzare i dati del dataset di training X
vect=CountVectorizer(ngram_range=(1,2))
X=vect.fit_transform(X)
In questo caso imposto l'opzione ngram_range a (1,2) per considerare anche le parole composte da due termini contigui.
Per considerarne una sola basta mettere (1,1). L'apprendimento è più veloce.
Importo il metodo train_test_split da scikit-learn
from sklearn.model_selection import train_test_split
e lo uso per separare il dataset in training e test.
X_train, X_test, y_train, y_test = train_test_split(X,y,test_size=0.3)
Il test set è composto dal 30% degli esempi. Mi servirà per provare l'affidabilità del modello.
A questo punto scelgo un algoritmo di apprendimento tra i classificatori disponibili.
Opto per l'algoritmo di naive bayes BernoulliNB.
from sklearn.naive_bayes import BernoulliNB
Imposto il modello con l'algoritmo
model = BernoulliNB()
e lo addestro sui dati di training con il metodo fit()
model.fit(X_train, y_train)
Al termine dell'addestramento uso il metodo predict() per ottenere i risultati sui di test
p_test = model.predict(X_test)
Importo da scikit learn un metodo per valutare l'accuratezza.
Uno dei più semplici è accuracy_score().
from sklearn.metrics import accuracy_score
Poi lo utilizzo per confrontare le etichette corrette dei dati di test (y) con le risposte elaborate dal programma (p_test).
errori = accuracy_score(y_test, p_test)
Infine, stampo il confronto
print(errori)
Il modello ha classificato i dati di test con un'accuratezza del 70%.
Vuol dire che ha classificato correttamente 7 esempi su 10.
0.7052430984754842
Usando altri algoritmi classificatori il risultato può essere migliore o peggiore.
Ad esempio, usando l'algoritmo perceptron l'accuratezza è del 64%. Molto però dipende dalla qualità del dataset.
Come analizzare una singola query
Una volta costruito il modello posso anche interrogarlo con query libere.
Ad esempio, creo una query e la vettorizzo. E' importante che la vettorizzazione sia la stessa già usata per il modello.
q=array(['good wonderful film'])
q=vect.transform(q)
Poi uso il metodo predict() per classificare la query
print(model.predict(q))
Il modello classifica la stringa come "pos" (positiva).
['pos']
In effetti è una stringa positiva.
E così via.