Sentimentanalyse wordt in de praktijk gebruikt om bijvoorbeeld reviews van klanten te classificeren of om negatieve berichten op social media in verband met een product of een bedrijf automatisch te detecteren. Sentimentanalyse valt onder NLP (natural language processing) en kan uitgevoerd worden via complexe machine learning algoritmen.
In deze oefening zullen we een eigen eenvoudiger algoritme toepassen om het sentiment van teksten te bepalen. We maken daarvoor gebruik van twee lijsten: een lijst met woorden die duiden op een positieve opinie en een lijst met woorden die duiden op een negatieve opinie. De lijsten zijn bewaard in twee eenvoudige tekstbestanden: positive.txt en negative.txt. De woorden staan elk op een afzonderlijke lijn en staan in kleine letters.
Bron: Minqing Hu and Bing Liu, “Mining and summarizing customer reviews.”, Proceedings of the ACM SIGKDD International Conference on Knowledge Discovery & Data Mining (KDD-2004), Seattle, Washington, USA, Aug 22-25, 2004.
We zullen in deze oefening een sentimentanalyse toepassen op personages uit een aflevering van The Simpsons. Einddoel zal zijn om per scene te bepalen of een personage positief of negatief ingesteld is.
We beschikken over een transcript van elke scene (zie voorbeeld op de schermafdruk hieronder). Elke tekstregel begint met de persoon die aan het woord is, gevolgd door een dubbelpunt en spatie en vervolgens komt de tekstregel. Een tekstregel eindigt met een regeleinde (
Transcript
Het transcript is opgedeeld in verschillende scenes. Elke scene is een bestand moes_tavern_part_x.txt (waarin x het nummer van de scene is, genummerd van 1 tot 24).
De bestanden zijn geëncodeerd via utf-8 encoding. Je kan ze openen via volgende instructie:
f = open('moes_tavern_part_x.txt', 'r', encoding='utf-8')
De bestanden zijn beschikbaar in het working directory van Dodona. Als je de oefening echter lokaal wilt maken (in PyCharm of in een Jupyter Notebook), dan moet je de bestanden downloaden en bewaren in dezelfde map als je .py of .ipynb bestand.
Je kan de bestanden van de eerste 5 scenes hier downloaden (het bestand part 0 is geen afzonderlijke scene, maar een korter bestand om de voorbeeldjes overzichtelijk te houden):
Polarity words
Om de sentimentscore te berekenen, zullen we gebruik maken van twee bestanden met positieve en negatieve woorden.
Deze bestanden kan je hier downloaden:
polarity_words
Schrijf een functie polarity_words met één argument: een string ("positive" of "negative"). De de functie leest het bestand positive.txt of negative.txt in en retourneert een lijst met alle woorden uit het tekstbestand.>>> polarity_words('positive') ['a+', 'abound', 'abounds', 'abundance', 'abundant', ..., 'youthful', 'zeal', 'zenith', 'zest', 'zippy'] >>> polarity_words('negative') ['2-faced', '2-faces', 'abnormal', ..., 'zaps', 'zealot', 'zealous', 'zealously', 'zombie']
sentimentscore
Schrijf een functie sentimentscore met één argument: een tekst (string).
De functie splitst de zin op in woorden. Volg daarbij volgende stappen:
Vervolgens telt de functie hoeveel positieve en negatieve woorden voorkomen in deze tekst (maak gebruik van de functie polarity_words maar zorg ervoor dat het bestand niet telkens opnieuw moet ingelezen worden).
De functie retourneert een geheel getal dat een soort sentimentscore voorstelt en berekend wordt als volgt: de sentimentscore start bij 0 (neutraal) voor elk positief woord wordt één punt opgeteld, voor elk negatief woord wordt één punt afgetrokken. Als eenzelfde woord meer dan één keer voorkomt, dan telt het elke keer opnieuw.
>>> sentimentscore("I'd like to introduce Ned Flanders, my best friend.") 2 >>> sentimentscore("Not bad at all!") -1
sentiment
Schrijf een functie sentiment met twee argumenten: de naam van een personage (string) en het nummer van een scene (int).
De functie leest het transcript van deze scene in en extraheert de tekstregels die door dit personage uitgesproken worden.
Vervolgens wordt de sentimentscore van deze zinnen opgeteld en gedeeld door het aantal tekstregels. We krijgen dus een gemiddelde sentimentscore.
De functie retourneert een string:
>>> sentiment("Moe_Szyslak", 0) "heel negatief" >>> sentiment("Homer_Simpson", 0) "neutraal" >>> sentiment("Marge_Simpson", 0) "Marge_Simpson komt niet voor in scene 0"