
- Data-science-usecase in sales: klantensentiment analyseren
- De dataset voorbereiden
- De BOW-methode toepassen
- Een gesuperviseerd machinelearningmodel gebruiken om sentiment te voorspellen
- Conclusie
Data-science-usecases kunnen raakvlakken hebben met vrijwel elke sector waarin veel data wordt verzameld of kan worden verzameld. Winkels en e-commercewebsites zijn de plekken waar de échte klantervaring van mensen die door marketingcampagnes zijn aangetrokken plaatsvindt, en waar de waardevolle aankoopdata van een bepaald merk of bedrijf worden verzameld. Hier nemen mensen een definitieve beslissing of ze een bepaald product echt willen kopen, of ze interesse hebben in iets anders dat ze eerder niet van plan waren te kopen, hoeveel ze bereid zijn te betalen, of ze terugkeren naar deze winkel en welke beoordeling ze zouden achterlaten over hun klantervaring.
Klantbeoordelingen vormen inderdaad een solide databron om te analyseren en te begrijpen wat er in het hele salesproces veranderd of juist versterkt kan worden. Op deze manier data analyseren kan kosten verlagen, de operationele efficiëntie verbeteren, de klantervaring optimaliseren, nieuwe kansen blootleggen, het bedrijf laten groeien en uiteindelijk de omzet verhogen. Laten we eens nader bekijken hoe deze waardevolle informatie kan worden geanalyseerd en gemodelleerd met data-science-algoritmen om verborgen inzichten te verkrijgen en de algemene boodschap van elke individuele klant te vangen.
Data-science-usecase in sales: klantensentiment analyseren
Klantensentimentanalyse is een geautomatiseerd proces om de emoties van klanten te identificeren wanneer ze de diensten of producten van een bepaald bedrijf gebruiken. Dit betreft meestal ongestructureerde tekstuele data verzameld via online enquêtes, sociale media, supporttickets, feedbackformulieren, productreviews, forums, telefoongesprekken, e-mails en chatbots. In machine learning wordt klantensentimentanalyse uitgevoerd via natural language processing (NLP), dat statistische en taalkundige methoden toepast om positieve, negatieve en neutrale sentimenten rechtstreeks uit tekstdata te extraheren. In essentie levert het twee parameters op:
- Polariteit: geeft aan of een sentiment positief of negatief is.
- Sterkte: geeft de intensiteit van dat sentiment aan.
Klantensentimentanalyse is een essentieel hulpmiddel voor elk modern bedrijf, omdat het helpt om bruikbare inzichten te verkrijgen, kritieke terugkerende issues die klanten ontevreden maken te signaleren en op te lossen, de product- of servicekenmerken te versterken die tot positieve emoties leiden en over de hele linie efficiëntere datagedreven beslissingen te nemen. Op een gedetailleerder niveau stelt klantensentimentanalyse ons in staat om:
- de klantenservice en daarmee de klantervaring te verbeteren,
- klantloyaliteit te vergroten,
- churn te verlagen,
- producten en services tijdig te updaten,
- marketingcampagnes te optimaliseren,
- nieuwe trends en markten te voorspellen,
- de goede reputatie van ons bedrijf te behouden,
- de winst te verhogen.
Zoals bij elke tekstanalysetaak kunnen er valkuilen optreden bij het uitvoeren van klantensentimentanalyse. Zo kan het NLP-algoritme sarcasme in sommige reviews niet oppikken en deze onjuist categoriseren. Ook kan het soms moeite hebben met zeer specifieke afkortingen of zelden gebruikte slangwoorden.
De dataset voorbereiden
Laten we onderzoeken hoe klantensentimentanalyse in de praktijk werkt met een dataset van IMDB-filmbesprekingen:
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
We hebben twee kolommen: één met de tekst van elke review en één met de inschatting van het algehele sentiment: positief (1) of negatief (0).
Laten we het percentage positieve en negatieve reviews berekenen:
round(movies['label'].value_counts()*100/len(movies['label'])).convert_dtypes()
0 50
1 50
Name: label, dtype: Int64
We hebben dus bijna gelijke verhoudingen van positieve en negatieve reviews.
De BOW-methode toepassen
Onze volgende stap is om de tekstdata om te zetten naar numerieke vorm, omdat een machinelearningmodel alleen met numerieke features kan werken. We gaan in het bijzonder features maken die tellen hoe vaak elk woord in de betreffende review voorkomt. De meest basale en rechttoe-rechtaan aanpak hiervoor heet bag-of-words (BOW). Deze bouwt een vocabulaire van alle woorden die in het document voorkomen en telt de frequentie van elk woord in elke review. Als resultaat krijgen we nieuwe features, één voor elk woord, met de bijbehorende frequenties.
Laten we de BOW-methode toepassen op onze 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]
Hierboven hebben we de optionele parameter max_features toegepast om alleen de 200 meest gebruikte woorden mee te nemen en mogelijke overfitting van het model te voorkomen.
Een gesuperviseerd machinelearningmodel gebruiken om sentiment te voorspellen
Nu gebruiken we een gesuperviseerd machinelearningmodel om het sentiment te voorspellen. Omdat we willen inschatten of het sentiment van een nieuwe review tot een positieve of negatieve categorie behoort op basis van reeds gelabelde reviews, hebben we opnieuw te maken met een classificatieprobleem. Laten we weer een logistieke-regressie-algoritme gebruiken en de nauwkeurigheid van het model meten:
Accuracy score: 0.754
Confusion matrix:
[[37.62772101 13.23856064]
[11.32829853 37.80541981]]
We zien dat het model 11% van alle reviews die positief waren als negatief heeft gelabeld, en 13% als positief terwijl ze negatief waren. Mogelijke vervolgstappen om de nauwkeurigheid te verbeteren zijn het uitsluiten van stopwoorden (dus weinig informatieve woorden die te vaak voorkomen, zoals "about", "will", "you", enz.) en het vergroten van de omvang van het vocabulaire.
Wanneer we de BOW-methode toepassen, kunnen we honderden of zelfs duizenden nieuwe features in onze dataframe krijgen. Dit kan resulteren in een onnodig complex model: overfitted, met te veel overbodige features en parameters. Een manier om dit op te lossen is regularisatie, waarmee de functie van het model wordt beperkt. De parameter die je hier afstelt is C, die de sterkte van de regularisatie vertegenwoordigt. Laten we 2 waarden van deze parameter testen: 100 en 0,1, en kijken welke de beste modelprestatie op de testdata oplevert:
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]]
Het verschil in modelnauwkeurigheid bij de gekozen waarden van parameter C is verwaarloosbaar. Waarschijnlijk zouden we een parameter kunnen vinden die de modelprestatie sterker verbetert door verder te experimenteren met meer waarden. We hebben hier echter slechts 200 nieuwe features, dus ons model is niet zo complex en de regularisatiestap is in dit geval niet echt nodig.
In plaats van labels 0 of 1 te voorspellen met de predict-functie, kun je ook een kans op sentiment voorspellen met predict_proba. We moeten er wel rekening mee houden dat we de accuracy score of confusion matrix niet direct kunnen toepassen op de voorspelde kansen, omdat deze statistieken alleen met klassen werken. Daarom moeten we ze vervolgens als klassen encoderen. Standaard wordt een kans groter dan of gelijk aan 0,5 vertaald naar klasse 1, anders naar klasse 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]
Conclusie
Er zijn veel andere nuttige aanpakken die we op onze dataset kunnen toepassen om een meer gedetailleerde sentimentanalyse uit te voeren:
- n-grams (woordcombinaties) gebruiken in plaats van alleen losse woorden om de context te behouden,
- stopwoorden uitsluiten,
- de omvang van het vocabulaire beperken op basis van boven- of ondergrenzen voor frequentie,
- numerieke extra features maken die de lengte van elke review of het aantal leestekens beschrijven (dat laatste kan soms correleren met de sterkte van het sentiment),
- getallen, bepaalde tekens of woorden van een bepaalde lengte uitsluiten, of complexere woordpatronen overwegen,
- stemming en lemmatizatie toepassen, oftewel woorden terugbrengen tot hun woordstam,
- geavanceerdere methoden dan BOW gebruiken om een vocabulaire te maken, zoals TfIdf (term frequency–inverse document frequency), dat rekening houdt met hoe vaak een woord in een review voorkomt ten opzichte van de rest van de reviews.
- gespecialiseerde libraries gebruiken die zijn ontworpen voor sentimentanalyse, zoals TextBlob, SentiWordNet, VADER (Valence Aware Dictionary and Sentiment Reasoner).
Wil je deze en andere nuttige technieken ontdekken voor het uitvoeren van een inzichtelijke sentimentanalyse? Bekijk dan de cursus Sentiment Analysis in Python.