
- Studiu de caz Data Science în vânzări: Analiza sentimentelor clienților
- Pregătirea setului de date
- Aplicarea metodei BOW
- Folosirea unui model de învățare supervizată pentru a prezice sentimentul
- Concluzie
Cazurile de utilizare a data science pot fi legate practic de orice industrie în care se acumulează sau se poate acumula o cantitate mare de date. Magazinele și site-urile de e-commerce sunt locurile unde are loc experiența reală a clienților atrași de campaniile de marketing și unde se colectează datele valoroase despre achiziții pentru un anumit brand sau o anumită companie. Aici oamenii iau decizia finală dacă chiar vor să cumpere un anumit produs, dacă sunt interesați să cumpere altceva la care nu se gândeau înainte, cât sunt dispuși să plătească, dacă s-ar întoarce în acest magazin și ce recenzie ar lăsa despre experiența lor de client.
Într-adevăr, recenziile clienților reprezintă o sursă solidă de date pentru a analiza și înțelege ce poate fi schimbat sau întărit în întregul proces de vânzare. Analizând datele în acest mod, poți reduce costurile, crește eficiența operațională, îmbunătăți experiența clienților, descoperi noi oportunități, dezvolta afacerea și, în cele din urmă, crește veniturile. Hai să vedem mai îndeaproape cum poate fi analizată și modelată această informație prețioasă folosind algoritmi de data science, pentru a obține insighturi ascunse și a surprinde mesajul de ansamblu de la fiecare client în parte.
Studiu de caz Data Science în vânzări: Analiza sentimentelor clienților
Analiza sentimentelor clienților este un proces automat de identificare a emoțiilor clienților când folosesc serviciile sau produsele unei anumite companii. De obicei, este vorba despre date textuale nestructurate colectate din sondaje online, rețele sociale, tichete de suport, formulare de feedback, recenzii de produse, forumuri, apeluri telefonice, emailuri și chatboți. În învățarea automată, analiza sentimentelor clienților este realizată prin procesarea limbajului natural (NLP), care aplică metode statistice și lingvistice pentru a extrage sentimente pozitive, negative și neutre direct din datele text. În esență, returnează doi parametri:
- Polaritate: indică dacă un sentiment este pozitiv sau negativ.
- Magnitudine: indică intensitatea acelui sentiment.
Analiza sentimentelor clienților este un instrument esențial pentru orice afacere modernă, deoarece ajută la obținerea de insighturi acționabile, la identificarea și remedierea problemelor recurente critice care îi fac pe clienți nefericiți, la întărirea caracteristicilor produsului sau serviciului care generează emoții pozitive și, per total, la luarea unor decizii mai eficiente bazate pe date. La un nivel mai granular, analiza sentimentelor clienților ne permite să:
- îmbunătățim serviciul pentru clienți și, implicit, experiențele clienților,
- creștem loialitatea clienților,
- reducem rata de churn,
- actualizăm la timp produsele și serviciile,
- optimizăm campaniile de marketing,
- anticipăm noi tendințe și piețe,
- menținem reputația ridicată a companiei,
- creștem profiturile.
Ca în orice sarcină de analiză de text, pot apărea anumite capcane în timpul analizei sentimentelor. De exemplu, algoritmul NLP nu surprinde sarcasmul din unele recenzii și le clasifică greșit. De asemenea, uneori poate eșua în a descifra abrevieri foarte specifice sau cuvinte de argou rar folosite.
Pregătirea setului de date
Hai să explorăm cum funcționează în practică analiza sentimentelor clienților, folosind un set de date cu recenzii de filme de pe 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
Avem două coloane: una cu textul fiecărei recenzii și alta cu estimarea sentimentului general: pozitiv (1) sau negativ (0).
Hai să calculăm procentul recenziilor pozitive și negative:
round(movies['label'].value_counts()*100/len(movies['label'])).convert_dtypes()
0 50
1 50
Name: label, dtype: Int64
Prin urmare, avem proporții aproape egale de recenzii pozitive și negative.
Aplicarea metodei BOW
Următorul pas va fi să transformăm datele text în formă numerică, deoarece un model de învățare automată poate lucra doar cu caracteristici numerice. În special, vom crea caracteristici care numără de câte ori apare fiecare cuvânt în recenzia respectivă. Abordarea cea mai de bază și directă pentru acest scop se numește bag-of-words (BOW), care construiește un vocabular al tuturor cuvintelor care apar în document și numără frecvența fiecărui cuvânt în fiecare recenzie. Ca rezultat, vom obține caracteristici noi, câte una pentru fiecare cuvânt, cu frecvențele corespunzătoare.
Hai să aplicăm metoda BOW la setul nostru de date:
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]
Mai sus, am aplicat un parametru opțional, max_features, pentru a lua în considerare doar cele mai frecvente 200 de cuvinte și a evita posibila supraînvățare a modelului.
Folosirea unui model de învățare supervizată pentru a prezice sentimentul
Acum vom folosi un model de învățare supervizată pentru a prezice sentimentul. Deoarece vrem să estimăm dacă sentimentul dintr-o recenzie nouă aparține categoriei pozitive sau negative pe baza recenziilor deja etichetate, avem din nou de-a face cu o problemă de clasificare. Să folosim din nou un algoritm de regresie logistică și să măsurăm acuratețea modelului:
Accuracy score: 0.754
Confusion matrix:
[[37.62772101 13.23856064]
[11.32829853 37.80541981]]
Vedem că modelul a etichetat 11% din toate recenziile care erau pozitive drept negative și 13% drept pozitive, deși erau negative. Ca posibile direcții de îmbunătățire a acurateții modelului, putem lua în considerare excluderea cuvintelor de legătură (adică a cuvintelor puțin informative care apar foarte frecvent, precum „about”, „will”, „you” etc.) și mărirea dimensiunii vocabularului.
Când aplicăm metoda BOW, s-ar putea să ajungem la sute sau chiar mii de caracteristici noi în dataframe. Acest lucru poate duce la crearea unui model excesiv de complex: supraînvățat, cu prea multe caracteristici și parametri inutili. O modalitate de a remedia este folosirea regularizării, care restricționează funcția modelului. Parametrul de reglat aici este C, care reprezintă forța regularizării. Hai să testăm 2 valori ale acestui parametru: 100 și 0.1 și să vedem care oferă cea mai bună performanță pe datele de 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]]
Diferența în acuratețea modelului când folosim valorile selectate ale parametrului C este nesemnificativă. Probabil am putea găsi un parametru care să îmbunătățească mai mult performanța modelului, experimentând în continuare cu mai multe valori ale acestuia. Totuși, aici avem doar 200 de caracteristici noi, deci modelul nostru nu este atât de complex, iar pasul de regularizare nu este chiar necesar în cazul nostru.
În loc să prezicem etichetele 0 sau 1 folosind funcția predict, este posibil să prezicem o probabilitate a sentimentului folosind predict_proba. Aici trebuie să ținem cont că nu putem aplica direct scorul de acuratețe sau matricea de confuzie pe probabilitățile prezise, deoarece aceste metrici funcționează doar cu clase. Prin urmare, trebuie să le codificăm ulterior ca și clase. Implicit, probabilitatea mai mare sau egală cu 0.5 este tradusă în clasa 1, altfel în clasa 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]
Concluzie
Există multe alte abordări utile pe care le putem aplica setului nostru de date pentru a realiza o analiză a sentimentelor mai granulară:
- folosirea n-gramelor (combinații de cuvinte) în loc de cuvinte singulare pentru a păstra contextul,
- excluderea cuvintelor de legătură,
- limitarea dimensiunii vocabularului pe baza valorilor de frecvență superioare sau inferioare,
- crearea de caracteristici numerice suplimentare care descriu lungimea fiecărei recenzii sau numărul de semne de punctuație (acestea din urmă pot corela uneori cu magnitudinea sentimentului),
- excluderea numerelor, a anumitor caractere, a cuvintelor de o anumită lungime sau luarea în considerare a unor tipare de cuvinte mai complexe,
- aplicarea stemmingului și lematizării, adică reducerea cuvintelor la rădăcinile lor,
- folosirea unor abordări mai sofisticate decât BOW pentru crearea unui vocabular, de exemplu TfIdf (term frequency–inverse document frequency), care ține cont de cât de des apare un cuvânt într-o recenzie în raport cu restul recenziilor.
- folosirea unor biblioteci specializate pentru analiza sentimentelor, precum TextBlob, SentiWordNet, VADER (Valence Aware Dictionary and Sentiment Reasoner).
Dacă ești interesat să explorezi aceste tehnici și alte metode utile pentru a realiza o analiză a sentimentelor relevantă, aruncă o privire la cursul Sentiment Analysis in Python.