
- Caso d'uso della data science nelle vendite: analisi del sentiment dei clienti
- Preparazione del dataset
- Applicare il metodo BOW
- Usare un modello di machine learning supervisionato per prevedere il sentiment
- Conclusione
I casi d'uso della data science possono riguardare praticamente qualsiasi settore in cui si accumulano (o si possono accumulare) grandi quantità di dati. Negozi e siti e-commerce sono i luoghi in cui si realizza la vera esperienza dei clienti attratti dalle campagne di marketing e dove vengono raccolti i dati di acquisto di valore per un determinato brand o azienda. Qui le persone prendono la decisione finale se acquistare davvero un certo prodotto, se sono interessate ad acquistare qualcos'altro che prima non avevano pianificato, quanto sono disposte a pagare, se torneranno in quel negozio e quale recensione lascerebbero sulla loro esperienza d'acquisto.
Le recensioni dei clienti costituiscono infatti una solida fonte di dati per analizzare e capire cosa può essere cambiato o rafforzato nell'intero processo di vendita. Analizzare i dati in questo modo può permettere di ridurre i costi, aumentare l'efficienza operativa, migliorare l'esperienza cliente, scoprire nuove opportunità, far crescere il business e, in definitiva, incrementare i ricavi. Vediamo più da vicino come queste informazioni preziose possono essere analizzate e modellate con algoritmi di data science per ottenere insight nascosti e cogliere il messaggio complessivo di ogni singolo cliente.
Caso d'uso della data science nelle vendite: analisi del sentiment dei clienti
L'analisi del sentiment dei clienti è un processo automatizzato per identificare le emozioni dei clienti quando utilizzano i servizi o i prodotti di una determinata azienda. Si tratta di dati testuali non strutturati raccolti da sondaggi online, social media, ticket di supporto, moduli di feedback, recensioni di prodotto, forum, telefonate, email e chatbot. Nel machine learning, l'analisi del sentiment viene effettuata tramite il natural language processing (NLP), che applica metodi statistici e linguistici per estrarre i sentiment positivi, negativi e neutri direttamente dai testi. In sostanza, restituisce due parametri:
- Polarità: indica se un sentiment è positivo o negativo.
- Magnitudo: indica l'intensità di quel sentiment.
L'analisi del sentiment dei clienti è uno strumento chiave per qualsiasi business moderno, perché aiuta a ottenere insight azionabili, individuare e correggere problemi ricorrenti critici che rendono i clienti insoddisfatti, rafforzare le caratteristiche del prodotto o del servizio che generano emozioni positive e prendere decisioni più efficienti basate sui dati. A un livello più granulare, l'analisi del sentiment consente di:
- migliorare l'assistenza clienti e quindi le esperienze dei clienti,
- aumentare la fidelizzazione,
- ridurre il tasso di abbandono,
- aggiornare tempestivamente prodotti e servizi,
- ottimizzare le campagne di marketing,
- anticipare nuove tendenze e mercati,
- mantenere alta la reputazione della nostra azienda,
- aumentare i profitti.
Come per qualsiasi attività di analisi del testo, nell'analisi del sentiment dei clienti si possono incontrare alcune insidie. Ad esempio, l'algoritmo di NLP non coglie il sarcasmo in alcune recensioni e le classifica in modo errato. A volte può anche non riuscire a decifrare abbreviazioni molto specifiche o parole gergali poco usate.
Preparazione del dataset
Vediamo come funziona in pratica l'analisi del sentiment dei clienti usando un dataset di recensioni di film su IMDB:
import pandas as pd
movies = pd.read_csv('movies.csv', index_col=0).reset_index(drop=True)
print(f'Number of reviews: {movies.shape[0]:,}\n')
print(movies.head())
Number of reviews: 7,501
review label
0 This short spoof can be found on Elite's Mille... 0
1 A singularly unfunny musical comedy that artif... 0
2 An excellent series, masterfully acted and dir... 1
3 The master of movie spectacle Cecil B. De Mill... 1
4 I was gifted with this movie as it had such a ... 0
Abbiamo due colonne: una con il testo di ogni recensione e un'altra con la valutazione del sentiment complessivo: positivo (1) o negativo (0).
Calcoliamo la percentuale di recensioni positive e negative:
round(movies['label'].value_counts()*100/len(movies['label'])).convert_dtypes()
0 50
1 50
Name: label, dtype: Int64
Abbiamo quindi proporzioni quasi uguali di recensioni positive e negative.
Applicare il metodo BOW
Il passo successivo è trasformare i dati testuali in forma numerica, perché un modello di machine learning può lavorare solo con caratteristiche numeriche. In particolare, andremo a creare delle feature che contano quante volte ciascuna parola compare nella rispettiva recensione. L'approccio più semplice e diretto per questo scopo è chiamato bag-of-words (BOW): costruisce un vocabolario di tutte le parole che appaiono nel documento e conta la frequenza di ogni parola in ciascuna recensione. Di conseguenza, otterremo nuove feature, una per ogni parola, con le frequenze corrispondenti.
Applichiamo il metodo BOW al nostro dataset:
from sklearn.feature_extraction.text import CountVectorizer
# Creating new features
vect = CountVectorizer(max_features=200)
vect.fit(movies.review)
X_review = vect.transform(movies.review)
X_df = pd.DataFrame(X_review.toarray(), columns=vect.get_feature_names())
# Combining the new features with the label
movies_bow = pd.concat([movies['label'], X_df], axis=1)
print(movies_bow.head())
label 10 about acting action actors actually after again all ... \
0 0 0 0 0 0 0 0 0 0 0 ...
1 0 1 0 1 0 1 0 0 0 3 ...
2 1 0 0 0 0 0 0 1 0 0 ...
3 1 0 0 0 1 0 0 0 0 0 ...
4 0 1 0 0 1 0 0 0 0 3 ...
will with without work world would years you young your
0 0 1 0 0 0 1 0 0 0 0
1 2 7 1 0 0 2 0 3 0 2
2 0 2 0 0 0 0 0 0 1 0
3 0 0 0 0 0 0 0 1 1 0
4 0 2 0 1 0 0 0 0 0 0
[5 rows x 201 columns]
Sopra abbiamo applicato un parametro opzionale, max_features, per considerare solo le 200 parole più frequenti ed evitare un potenziale overfitting del modello.
Usare un modello di machine learning supervisionato per prevedere il sentiment
Ora useremo un modello di machine learning supervisionato per prevedere il sentiment. Poiché vogliamo stimare se il sentiment di una nuova recensione appartenga alla categoria positiva o negativa sulla base di recensioni già etichettate, dobbiamo affrontare nuovamente un problema di classificazione. Anche qui, usiamo un algoritmo di regressione logistica e misuriamo l'accuratezza del modello:
Accuracy score: 0.754
Confusion matrix:
[[37.62772101 13.23856064]
[11.32829853 37.80541981]]
Vediamo che il modello ha etichettato come negative l'11% di tutte le recensioni che erano positive e come positive il 13% di quelle che erano negative. Per migliorare l'accuratezza del modello, potremmo considerare di escludere le stopword (cioè parole poco informative che compaiono molto spesso, come "about", "will", "you", ecc.) e aumentare la dimensione del vocabolario.
Quando applichiamo il metodo BOW, potremmo ritrovarci con centinaia o addirittura migliaia di nuove feature nel nostro dataframe. Questo può portare a creare un modello eccessivamente complesso: sovradattato, con troppe feature e parametri inutili. Un modo per risolvere è usare la regolarizzazione, che limita la funzione del modello. Il parametro da regolare qui è C, che rappresenta l'intensità della regolarizzazione. Proviamo 2 valori di questo parametro: 100 e 0,1, e vediamo quale offre le migliori prestazioni del modello sui dati di test:
lr_1 = LogisticRegression(C=100)
lr_1.fit(X_train, y_train)
predictions_1 = lr_1.predict(X_test)
lr_2 = LogisticRegression(C=0.1)
lr_2.fit(X_train, y_train)
predictions_2 = lr_2.predict(X_test)
print(f'Accuracy score, lr_1 model: {round(accuracy_score(y_test, predictions_1), 3)}\n'
f'Accuracy score, lr_2 model: {round(accuracy_score(y_test, predictions_2), 3)}\n\n'
f'Confusion matrix for lr_1 model, %:\n{confusion_matrix(y_test, predictions_1)/len(y_test)*100}\n\n'
f'Confusion matrix for lr_2 model, %:\n{confusion_matrix(y_test, predictions_2)/len(y_test)*100}')
Accuracy score, lr_1 model: 0.753
Accuracy score, lr_2 model: 0.756
Confusion matrix for lr_1 model, %:
[[37.53887161 13.32741004]
[11.32829853 37.80541981]]
Confusion matrix for lr_2 model, %:
[[37.67214571 13.19413594]
[11.19502443 37.93869391]]
La differenza nell'accuratezza del modello usando i valori selezionati del parametro C è trascurabile. Probabilmente potremmo trovare un parametro che migliori di più le prestazioni sperimentando con altri valori. Tuttavia, qui abbiamo solo 200 nuove feature, quindi il modello non è così complesso e la regolarizzazione non è davvero necessaria nel nostro caso.
Invece di prevedere le etichette 0 o 1 con la funzione predict, è possibile prevedere una probabilità di sentiment usando predict_proba. Qui bisogna tenere presente che non possiamo applicare direttamente l'accuracy score o la confusion matrix alle probabilità previste, poiché queste metriche funzionano solo con le classi. Di conseguenza, dobbiamo poi ricodificarle in classi. Per impostazione predefinita, una probabilità maggiore o uguale a 0,5 viene tradotta nella classe 1, altrimenti nella classe 0.
lr = LogisticRegression()
lr.fit(X_train, y_train)
# Predicting the probability of the 0 class
predictions_prob_0 = lr.predict_proba(X_test)[:, 0]
# Predicting the probability of the 1 class
predictions_prob_1 = lr.predict_proba(X_test)[:, 1]
print(f'First 10 predicted probabilities of class 0: {predictions_prob_0[:10].round(3)}\n'
f'First 10 predicted probabilities of class 1: {predictions_prob_1[:10].round(3)}')
First 10 predicted probabilities of class 0: [0.246 0.143 0.123 0.708 0.001 0.828 0.204 0.531 0.121 0.515]
First 10 predicted probabilities of class 1: [0.754 0.857 0.877 0.292 0.999 0.172 0.796 0.469 0.879 0.485]
Conclusione
Ci sono molti altri approcci utili che possiamo applicare al nostro dataset per condurre un'analisi del sentiment più granulare:
- usare n-grammi (combinazioni di parole) invece delle sole parole singole per preservare il contesto,
- escludere le stopword,
- limitare la dimensione del vocabolario in base a valori di frequenza superiori o inferiori,
- creare ulteriori feature numeriche che descrivano la lunghezza di ogni recensione o il numero di segni di punteggiatura (quest'ultimo a volte può correlare con l'intensità del sentiment),
- escludere numeri, alcuni caratteri, parole di una certa lunghezza o considerare pattern di parole più complessi,
- applicare stemming e lemmatizzazione, cioè ricondurre le parole alle loro radici,
- usare approcci più sofisticati del BOW per creare un vocabolario, ad esempio TfIdf (term frequency-inverse document frequency), che tiene conto della frequenza con cui una parola compare in una recensione rispetto al resto delle recensioni.
- usare librerie specializzate progettate per l'analisi del sentiment, come TextBlob, SentiWordNet, VADER (Valence Aware Dictionary and Sentiment Reasoner).
Se ti interessa esplorare queste e altre tecniche utili per condurre un'analisi del sentiment efficace, dai un'occhiata al corso Sentiment Analysis in Python.

