Website-Suche

Wie man eine Sentiment-Analyse in Python 3 mit dem Natural Language Toolkit (NLTK) durchführt


Der Autor hat den Open Internet/Free Speech Fonds ausgewählt, um eine Spende im Rahmen des Write for Donations-Programms zu erhalten.

Einführung

Eine große Menge an Daten, die heute generiert wird, ist unstrukturiert, was eine Verarbeitung erfordert, um Erkenntnisse zu gewinnen. Einige Beispiele für unstrukturierte Daten sind Nachrichtenartikel, Posts in sozialen Medien und Suchverlauf. Der Prozess der Analyse natürlicher Sprache und des Verstehens davon fällt in den Bereich der natürlichen Sprachverarbeitung (NLP). Sentiment-Analyse ist eine gängige NLP-Aufgabe, die darin besteht, Texte oder Textteile in eine vordefinierte Stimmung zu klassifizieren. Sie werden das Natural Language Toolkit (NLTK), eine häufig verwendete NLP-Bibliothek in Python, verwenden, um Textdaten zu analysieren.

In diesem Tutorial werden Sie einen Datensatz von Beispiel-Tweets aus dem NLTK-Paket für NLP mit verschiedenen Datenreinigungsmethoden vorbereiten. Sobald der Datensatz bereit zur Verarbeitung ist, werden Sie ein Modell mit vorab klassifizierten Tweets trainieren und das Modell verwenden, um die Beispiel-Tweets in negative und positive Stimmungen zu klassifizieren.

Dieser Artikel geht davon aus, dass Sie mit den Grundlagen von Python vertraut sind (siehe unsere Reihe "Wie man in Python 3 programmiert"), insbesondere mit der Verwendung von Datenstrukturen, Klassen und Methoden. Das Tutorial geht davon aus, dass Sie keine Kenntnisse in NLP und nltk haben, obwohl einige Kenntnisse darüber von Vorteil sind.

Voraussetzungen

  • Dieses Tutorial basiert auf der Python-Version 3.6.5. Wenn Sie Python 3 nicht installiert haben, finden Sie hier eine Anleitung zur Installation und Einrichtung einer lokalen Programmierumgebung für Python 3.
  • Es wird empfohlen, mit Sprachdaten vertraut zu sein. Wenn Sie neu im Umgang mit NLTK sind, sehen Sie sich den Leitfaden "So arbeiten Sie mit Sprachdaten in Python 3 unter Verwendung des Natural Language Toolkit (NLTK)" an.

Schritt 1 — NLTK installieren und die Daten herunterladen

Sie werden das NLTK-Paket in Python für alle NLP-Aufgaben in diesem Tutorial verwenden. In diesem Schritt installieren Sie NLTK und laden die Beispieltweets herunter, die Sie zum Trainieren und Testen Ihres Modells verwenden werden.

Zuerst installieren Sie das NLTK-Paket mit dem pip Paketmanager:

  1. pip install nltk==3.3

Dieses Tutorial verwendet Beispiel-Tweets, die Teil des NLTK-Pakets sind. Zuerst starten Sie eine interaktive Python-Sitzung, indem Sie den folgenden Befehl ausführen:

  1. python3

Importieren Sie dann das nltk Modul im Python-Interpreter.

  1. import nltk

Laden Sie die Beispiel-Tweets aus dem NLTK-Paket herunter:

  1. nltk.download('twitter_samples')

Das Ausführen dieses Befehls im Python-Interpreter lädt die Tweets herunter und speichert sie lokal. Sobald die Beispiele heruntergeladen sind, stehen sie Ihnen zur Verfügung.

Sie werden die negativen und positiven Tweets später im Tutorial verwenden, um Ihr Modell zur Sentimentanalyse zu trainieren. Die Tweets ohne Sentimente werden verwendet, um Ihr Modell zu testen.

Wenn Sie Ihr eigenes Datensatz verwenden möchten, können Sie Tweets aus einem bestimmten Zeitraum, Benutzer oder Hashtag sammeln, indem Sie die Twitter API verwenden.

Jetzt, da Sie NLTK importiert und die Beispieltweets heruntergeladen haben, beenden Sie die interaktive Sitzung, indem Sie exit() eingeben. Sie sind bereit, die Tweets zu importieren und mit der Datenverarbeitung zu beginnen.

Schritt 2 — Tokenisierung der Daten

Die Sprache in ihrer ursprünglichen Form kann von einer Maschine nicht genau verarbeitet werden, daher müssen Sie die Sprache verarbeiten, um es der Maschine zu ermöglichen, sie besser zu verstehen. Der erste Teil, um die Daten zu verstehen, ist ein Prozess namens Tokenisierung, also das Aufteilen von Zeichenfolgen in kleinere Teile, die als Tokens bezeichnet werden.

Ein Token ist eine Folge von Zeichen in einem Text, die als Einheit dient. Je nachdem, wie Sie die Tokens erstellen, können sie aus Wörtern, Emoticons, Hashtags, Links oder sogar einzelnen Zeichen bestehen. Eine grundlegende Methode, um Sprache in Tokens zu zerlegen, besteht darin, den Text anhand von Leerzeichen und Satzzeichen zu trennen.

Um zu beginnen, erstellen Sie eine neue .py-Datei, um Ihr Skript zu speichern. Dieses Tutorial verwendet nlp_test.py:

  1. nano nlp_test.py

In dieser Datei importieren Sie zuerst die twitter_samples, damit Sie mit diesen Daten arbeiten können:

from nltk.corpus import twitter_samples

Dies wird drei Datensätze aus NLTK importieren, die verschiedene Tweets enthalten, um das Modell zu trainieren und zu testen:

  • negative_tweets.json: 5000 Tweets mit negativen Sentiments
  • 5000 Tweets mit positiven Sentimenten
  • tweets.20150430-223406.json: 20000 Tweets ohne Sentiments

Als nächstes erstellen Sie Variablen für positive_tweets, negative_tweets und text:

from nltk.corpus import twitter_samples

positive_tweets = twitter_samples.strings('positive_tweets.json')
negative_tweets = twitter_samples.strings('negative_tweets.json')
text = twitter_samples.strings('tweets.20150430-223406.json')

Die strings()-Methode von twitter_samples gibt alle Tweets innerhalb eines Datensatzes als Strings aus. Wenn die verschiedenen Tweet-Sammlungen als Variablen festgelegt werden, wird die Verarbeitung und das Testen einfacher.

Bevor Sie einen Tokenizer in NLTK verwenden, müssen Sie eine zusätzliche Ressource herunterladen, punkt. Das punkt-Modul ist ein vortrainiertes Modell, das Ihnen hilft, Wörter und Sätze zu tokenisieren. Zum Beispiel weiß dieses Modell, dass ein Name einen Punkt enthalten kann (wie „S. Daityari“), und das Vorhandensein dieses Punktes in einem Satz bedeutet nicht unbedingt, dass der Satz endet. Zuerst starten Sie eine interaktive Python-Sitzung:

  1. python3

Führen Sie die folgenden Befehle in der Sitzung aus, um die punkt Ressource herunterzuladen:

  1. import nltk
  2. nltk.download('punkt')

Sobald der Download abgeschlossen ist, können Sie die Tokenizer von NLTK verwenden. NLTK bietet einen Standard-Tokenizer für Tweets mit der .tokenized()-Methode. Fügen Sie eine Zeile hinzu, um ein Objekt zu erstellen, das das positive_tweets.json-Dataset tokenisiert:

from nltk.corpus import twitter_samples

positive_tweets = twitter_samples.strings('positive_tweets.json')
negative_tweets = twitter_samples.strings('negative_tweets.json')
text = twitter_samples.strings('tweets.20150430-223406.json')
tweet_tokens = twitter_samples.tokenized('positive_tweets.json')

Wenn Sie das Skript testen möchten, um die .tokenized Methode in Aktion zu sehen, fügen Sie den hervorgehobenen Inhalt zu Ihrem nlp_test.py Skript hinzu. Dies tokenisiert einen einzelnen Tweet aus dem positive_tweets.json Dataset:

from nltk.corpus import twitter_samples

positive_tweets = twitter_samples.strings('positive_tweets.json')
negative_tweets = twitter_samples.strings('negative_tweets.json')
text = twitter_samples.strings('tweets.20150430-223406.json')
tweet_tokens = twitter_samples.tokenized('positive_tweets.json')[0]

print(tweet_tokens[0])

Speichern Sie die Datei und schließen Sie sie, und führen Sie das Skript aus:

  1. python3 nlp_test.py

Der Prozess der Tokenisierung benötigt einige Zeit, da es sich nicht um eine einfache Trennung bei Leerzeichen handelt. Nach ein paar Momenten der Verarbeitung sehen Sie Folgendes:

['#FollowFriday',
 '@France_Inte',
 '@PKuchly57',
 '@Milipol_Paris',
 'for',
 'being',
 'top',
 'engaged',
 'members',
 'in',
 'my',
 'community',
 'this',
 'week',
 ':)']

Hier gibt die Methode .tokenized() Sonderzeichen wie @ und _ zurück. Diese Zeichen werden später in diesem Tutorial durch reguläre Ausdrücke entfernt.

Jetzt, wo Sie gesehen haben, wie die .tokenized() Methode funktioniert, stellen Sie sicher, die letzte Zeile zum Drucken des tokenisierten Tweets im Skript auszukommentieren oder zu entfernen, indem Sie ein # an den Anfang der Zeile hinzufügen:

from nltk.corpus import twitter_samples

positive_tweets = twitter_samples.strings('positive_tweets.json')
negative_tweets = twitter_samples.strings('negative_tweets.json')
text = twitter_samples.strings('tweets.20150430-223406.json')
tweet_tokens = twitter_samples.tokenized('positive_tweets.json')[0]

#print(tweet_tokens[0])

Ihr Skript ist jetzt so konfiguriert, dass es Daten tokenisiert. Im nächsten Schritt werden Sie das Skript aktualisieren, um die Daten zu normalisieren.

Schritt 3 — Normalisierung der Daten

Wörter haben unterschiedliche Formen - zum Beispiel sind „ran“, „runs“ und „running“ verschiedene Formen des gleichen Verbs „run“. Je nach den Anforderungen Ihrer Analyse müssen all diese Versionen möglicherweise in die gleiche Form „run“ umgewandelt werden. Normalisierung in der NLP ist der Prozess, ein Wort in seine kanonische Form zu verwandeln.

Normalisierung hilft, Wörter mit der gleichen Bedeutung, aber in unterschiedlichen Formen zusammenzufassen. Ohne Normalisierung würden "ran", "runs" und "running" als verschiedene Wörter behandelt, obwohl man sie als dasselbe Wort betrachten möchte. In diesem Abschnitt erkunden Sie Stemming und Lemmatisierung, zwei beliebte Techniken der Normalisierung.

Stemming ist ein Prozess, bei dem Affixe von einem Wort entfernt werden. Stemming, das nur mit einfachen Verbformen arbeitet, ist ein heuristischer Prozess, der die Enden von Wörtern entfernt.

In diesem Tutorial werden Sie den Prozess der Lemmatisierung verwenden, der ein Wort im Kontext des Wortschatzes und der morphologischen Analyse von Wörtern im Text normalisiert. Der Lemmatisierungsalgorithmus analysiert die Struktur des Wortes und seinen Kontext, um es in eine normalisierte Form zu konvertieren. Daher kommt es mit einem Geschwindigkeitsnachteil. Ein Vergleich von Stemming und Lemmatisierung reduziert sich letztendlich auf einen Kompromiss zwischen Geschwindigkeit und Genauigkeit.

Bevor Sie mit der Lemmatisierung fortfahren, laden Sie die notwendigen Ressourcen herunter, indem Sie Folgendes in eine interaktive Python-Sitzung eingeben:

  1. python3

Führen Sie die folgenden Befehle in der Sitzung aus, um die Ressourcen herunterzuladen:

  1. import nltk
  2. nltk.download('wordnet')
  3. nltk.download('averaged_perceptron_tagger')

wordnet ist eine lexikalische Datenbank für die englische Sprache, die dem Skript hilft, das Grundwort zu bestimmen. Sie benötigen die Ressource averaged_perceptron_tagger, um den Kontext eines Wortes in einem Satz zu bestimmen.

Sobald heruntergeladen, sind Sie fast bereit, den Lemmatisierer zu verwenden. Bevor Sie einen Lemmatisierer ausführen, müssen Sie den Kontext für jedes Wort in Ihrem Text bestimmen. Dies wird durch einen Tagging-Algorithmus erreicht, der die relative Position eines Wortes in einem Satz bewertet. In einer Python-Sitzung importieren Sie die pos_tag-Funktion und geben Sie eine Liste von Tokens als Argument an, um die Tags zu erhalten. Lassen Sie uns dies in Python ausprobieren:

  1. from nltk.tag import pos_tag
  2. from nltk.corpus import twitter_samples
  3. tweet_tokens = twitter_samples.tokenized('positive_tweets.json')
  4. print(pos_tag(tweet_tokens[0]))

Hier ist die Ausgabe der pos_tag Funktion.

[('#FollowFriday', 'JJ'),
 ('@France_Inte', 'NNP'),
 ('@PKuchly57', 'NNP'),
 ('@Milipol_Paris', 'NNP'),
 ('for', 'IN'),
 ('being', 'VBG'),
 ('top', 'JJ'),
 ('engaged', 'VBN'),
 ('members', 'NNS'),
 ('in', 'IN'),
 ('my', 'PRP$'),
 ('community', 'NN'),
 ('this', 'DT'),
 ('week', 'NN'),
 (':)', 'NN')]

Aus der Liste der Tags hier die Liste der häufigsten Elemente und deren Bedeutung:

  • NNP: Nomen, eigen, Singular
  • NN: Nomen, gewöhnlich, Singular oder Masse
  • IN: Präposition oder Konjunktion, unterordnend
  • VBG: Verb, Gerundium oder Partizip Präsens
  • VBN: Verb, Partizip Perfekt

Hier ist eine vollständige Liste des Datensatzes.

Im Allgemeinen, wenn ein Tag mit NN beginnt, ist das Wort ein Substantiv, und wenn es mit VB beginnt, ist das Wort ein Verb. Nach der Überprüfung der Tags beenden Sie die Python-Sitzung, indem Sie exit() eingeben.

Um dies in eine Funktion zu integrieren, die einen Satz normalisiert, sollten Sie zunächst die Tags für jedes Token im Text generieren und dann jedes Wort mit dem Tag lemmatisieren.

Aktualisieren Sie die nlp_test.py Datei mit der folgenden Funktion, die einen Satz lemmatisiert:

...

from nltk.tag import pos_tag
from nltk.stem.wordnet import WordNetLemmatizer

def lemmatize_sentence(tokens):
    lemmatizer = WordNetLemmatizer()
    lemmatized_sentence = []
    for word, tag in pos_tag(tokens):
        if tag.startswith('NN'):
            pos = 'n'
        elif tag.startswith('VB'):
            pos = 'v'
        else:
            pos = 'a'
        lemmatized_sentence.append(lemmatizer.lemmatize(word, pos))
    return lemmatized_sentence

print(lemmatize_sentence(tweet_tokens[0]))

Dieser Code importiert die Klasse WordNetLemmatizer und initialisiert sie mit einer Variablen, lemmatizer.

Die Funktion lemmatize_sentence ermittelt zunächst das Positions-Tag jedes Tokens eines Tweets. Innerhalb der if-Anweisung, wenn das Tag mit NN beginnt, wird das Token als Substantiv zugewiesen. Ähnlich wird, wenn das Tag mit VB beginnt, das Token als Verb zugewiesen.

Speichern Sie die Datei und schließen Sie sie, und führen Sie das Skript aus:

  1. python3 nlp_test.py

Hier ist die Ausgabe:

['#FollowFriday',
 '@France_Inte',
 '@PKuchly57',
 '@Milipol_Paris',
 'for',
 'be',
 'top',
 'engage',
 'member',
 'in',
 'my',
 'community',
 'this',
 'week',
 ':)']

Sie werden feststellen, dass das Verb being in seine Grundform be wechselt und das Substantiv members zu member wird. Bevor Sie fortfahren, kommentieren Sie die letzte Zeile aus, die den Beispiel-Tweet aus dem Skript ausgibt.

Jetzt, da Sie erfolgreich eine Funktion zur Normalisierung von Wörtern erstellt haben, sind Sie bereit, das Rauschen zu entfernen.

Schritt 4 — Rauschen aus den Daten entfernen

In diesem Schritt werden Sie Rauschen aus dem Datensatz entfernen. Rauschen ist jeder Teil des Textes, der keine Bedeutung oder Information zu den Daten hinzufügt.

Lärm ist spezifisch für jedes Projekt, daher kann das, was in einem Projekt Lärm darstellt, in einem anderen Projekt nicht als solcher gelten. Zum Beispiel werden die häufigsten Wörter in einer Sprache als Stoppwörter bezeichnet. Einige Beispiele für Stoppwörter sind „ist“, „der“ und „ein“. Sie sind im Allgemeinen irrelevant, wenn es darum geht, Sprache zu verarbeiten, es sei denn, ein spezifischer Anwendungsfall rechtfertigt ihre Einbeziehung.

In diesem Tutorial werden Sie reguläre Ausdrücke in Python verwenden, um diese Elemente zu suchen und zu entfernen:

  • Hyperlinks - Alle Hyperlinks auf Twitter werden in den URL-Shortener t.co umgewandelt. Daher würde es keinen Mehrwert für die Analyse bringen, sie in der Textverarbeitung zu belassen.
  • Twitter-Benutzernamen in Antworten - Diese Twitter-Benutzernamen werden von einem @-Symbol gefolgt, das keine Bedeutung vermittelt.
  • Interpunktion und Sonderzeichen - Während diese oft Kontext zu textlichen Daten liefern, ist dieser Kontext oft schwierig zu verarbeiten. Zur Vereinfachung werden Sie alle Interpunktionszeichen und Sonderzeichen aus den Tweets entfernen.

Um Hyperlinks zu entfernen, müssen Sie zuerst nach einer Teilzeichenfolge suchen, die mit einer URL übereinstimmt, die mit http:// oder https:// beginnt, gefolgt von Buchstaben, Zahlen oder Sonderzeichen. Sobald ein Muster übereinstimmt, ersetzt die Methode .sub() es durch einen leeren String.

Da wir die Wortformen innerhalb der remove_noise()-Funktion normalisieren werden, können Sie die lemmatize_sentence()-Funktion im Skript auskommentieren.

Fügen Sie den folgenden Code zu Ihrer nlp_test.py Datei hinzu, um Rauschen aus dem Datensatz zu entfernen:

...

import re, string

def remove_noise(tweet_tokens, stop_words = ()):

    cleaned_tokens = []

    for token, tag in pos_tag(tweet_tokens):
        token = re.sub('http[s]?://(?:[a-zA-Z]|[0-9]|[$-_@.&+#]|[!*\(\),]|'\
                       '(?:%[0-9a-fA-F][0-9a-fA-F]))+','', token)
        token = re.sub("(@[A-Za-z0-9_]+)","", token)

        if tag.startswith("NN"):
            pos = 'n'
        elif tag.startswith('VB'):
            pos = 'v'
        else:
            pos = 'a'

        lemmatizer = WordNetLemmatizer()
        token = lemmatizer.lemmatize(token, pos)

        if len(token) > 0 and token not in string.punctuation and token.lower() not in stop_words:
            cleaned_tokens.append(token.lower())
    return cleaned_tokens

Dieser Code erstellt eine remove_noise() Funktion, die Rauschen entfernt und die in der vorherigen Sektion erwähnte Normalisierung und Lemmatisierung integriert. Der Code nimmt zwei Argumente: die Tweet-Token und das Tuple der Stoppwörter.

Der Code verwendet dann eine Schleife, um das Rauschen aus dem Datensatz zu entfernen. Um Hyperlinks zu entfernen, sucht der Code zunächst nach einer Teilzeichenfolge, die mit einer URL übereinstimmt, die mit http:// oder https:// beginnt, gefolgt von Buchstaben, Zahlen oder Sonderzeichen. Sobald ein Muster gefunden wurde, ersetzt die .sub() Methode es durch einen leeren String oder ''.

Ähnlich entfernt der Code @-Erwähnungen, indem er den entsprechenden Teil des Textes mit regulären Ausdrücken ersetzt. Der Code verwendet die re-Bibliothek, um nach @-Symbolen zu suchen, gefolgt von Zahlen, Buchstaben oder _, und ersetzt sie durch einen leeren String.

Schließlich können Sie Zeichensetzung mit der Bibliothek string entfernen.

Darüber hinaus werden Sie auch Stoppwörter entfernen, indem Sie ein integriertes Set von Stoppwörtern in NLTK verwenden, das separat heruntergeladen werden muss.

Führen Sie den folgenden Befehl in einer interaktiven Python-Sitzung aus, um diese Ressource herunterzuladen:

  1. nltk.download('stopwords')

Sobald die Ressource heruntergeladen ist, beenden Sie die interaktive Sitzung.

Sie können die .words() Methode verwenden, um eine Liste von Stopwörtern in Englisch zu erhalten. Um die Funktion zu testen, lassen Sie uns sie auf unserem Beispiel-Tweet ausführen. Fügen Sie die folgenden Zeilen am Ende der Datei nlp_test.py hinzu:

...
from nltk.corpus import stopwords
stop_words = stopwords.words('english')

print(remove_noise(tweet_tokens[0], stop_words))

Nachdem Sie die Datei gespeichert und geschlossen haben, führen Sie das Skript erneut aus, um eine Ausgabe ähnlich der folgenden zu erhalten:

['#followfriday', 'top', 'engage', 'member', 'community', 'week', ':)']

Beachten Sie, dass die Funktion alle @ Erwähnungen, Stoppwörter entfernt und die Wörter in Kleinbuchstaben umwandelt.

Bevor Sie im nächsten Schritt mit der Modellierungsübung fortfahren, verwenden Sie die Funktion remove_noise(), um die positiven und negativen Tweets zu bereinigen. Kommentieren Sie die Zeile aus, um die Ausgabe von remove_noise() für den Beispiel-Tweet anzuzeigen, und fügen Sie Folgendes zum Skript nlp_test.py hinzu:

...
from nltk.corpus import stopwords
stop_words = stopwords.words('english')

#print(remove_noise(tweet_tokens[0], stop_words))

positive_tweet_tokens = twitter_samples.tokenized('positive_tweets.json')
negative_tweet_tokens = twitter_samples.tokenized('negative_tweets.json')

positive_cleaned_tokens_list = []
negative_cleaned_tokens_list = []

for tokens in positive_tweet_tokens:
    positive_cleaned_tokens_list.append(remove_noise(tokens, stop_words))

for tokens in negative_tweet_tokens:
    negative_cleaned_tokens_list.append(remove_noise(tokens, stop_words))

Jetzt, da Sie den Code zum Reinigen der Beispiel-Tweets hinzugefügt haben, möchten Sie möglicherweise die ursprünglichen Tokens mit den bereinigten Tokens eines Beispiel-Tweets vergleichen. Wenn Sie dies testen möchten, fügen Sie den folgenden Code in die Datei ein, um beide Versionen des 500. Tweets in der Liste zu vergleichen:

...
print(positive_tweet_tokens[500])
print(positive_cleaned_tokens_list[500])

Speichern Sie die Datei und schließen Sie sie, und führen Sie das Skript aus. Aus der Ausgabe werden Sie sehen, dass die Interpunktion und Links entfernt wurden und die Wörter in Kleinbuchstaben umgewandelt wurden.

['Dang', 'that', 'is', 'some', 'rad', '@AbzuGame', '#fanart', '!', ':D', 'https://t.co/bI8k8tb9ht']
['dang', 'rad', '#fanart', ':d']

Es gibt bestimmte Probleme, die während der Vorverarbeitung von Text auftreten können. Zum Beispiel werden Wörter ohne Leerzeichen („iLoveYou“) als eines behandelt, und es kann schwierig sein, solche Wörter zu trennen. Darüber hinaus werden „Hi“, „Hii“ und „Hiiiii“ vom Skript unterschiedlich behandelt, es sei denn, Sie schreiben etwas Spezielles, um das Problem zu lösen. Es ist üblich, den Prozess der Geräuschbeseitigung für Ihre spezifischen Daten fein abzustimmen.

Jetzt, da Sie die Funktion remove_noise() in Aktion gesehen haben, stellen Sie sicher, dass Sie die letzten beiden Zeilen des Skripts auskommentieren oder entfernen, damit Sie mehr hinzufügen können:

...
#print(positive_tweet_tokens[500])
#print(positive_cleaned_tokens_list[500])

In diesem Schritt haben Sie Rauschen aus den Daten entfernt, um die Analyse effektiver zu gestalten. Im nächsten Schritt werden Sie die Daten analysieren, um die häufigsten Wörter in Ihrem Beispieldatensatz zu finden.

Schritt 5 — Bestimmung der Wortdichte

Die grundlegendste Form der Analyse von Textdaten besteht darin, die Wortfrequenz zu ermitteln. Ein einzelner Tweet ist zu klein, um die Verteilung der Wörter herauszufinden; daher wird die Analyse der Wortfrequenz auf allen positiven Tweets durchgeführt.

Der folgende Snippet definiert eine Generatorfunktion mit dem Namen get_all_words, die eine Liste von Tweets als Argument entgegennimmt, um eine Liste von Wörtern aus allen Tweet-Token bereitzustellen. Fügen Sie den folgenden Code zu Ihrer nlp_test.py-Datei hinzu:

...

def get_all_words(cleaned_tokens_list):
    for tokens in cleaned_tokens_list:
        for token in tokens:
            yield token

all_pos_words = get_all_words(positive_cleaned_tokens_list)

Jetzt, da Sie alle Wörter in der Stichprobe der Tweets gesammelt haben, können Sie mit der FreqDist-Klasse von NLTK herausfinden, welche die häufigsten Wörter sind. Fügen Sie den folgenden Code in die nlp_test.py-Datei ein:

from nltk import FreqDist

freq_dist_pos = FreqDist(all_pos_words)
print(freq_dist_pos.most_common(10))

Die .most_common()-Methode listet die Wörter auf, die am häufigsten in den Daten vorkommen. Speichern Sie die Datei und schließen Sie sie nach diesen Änderungen.

Wenn Sie die Datei jetzt ausführen, finden Sie die häufigsten Begriffe in den Daten:

[(':)', 3691),
 (':-)', 701),
 (':d', 658),
 ('thanks', 388),
 ('follow', 357),
 ('love', 333),
 ('...', 290),
 ('good', 283),
 ('get', 263),
 ('thank', 253)]

Anhand dieser Daten können Sie sehen, dass Emoticon-Entitäten einige der häufigsten Bestandteile positiver Tweets bilden. Bevor Sie mit dem nächsten Schritt fortfahren, stellen Sie sicher, dass Sie die letzte Zeile des Skripts, die die zehn häufigsten Tokens ausgibt, auskommentieren.

Zusammenfassend hast du die Tweets aus nltk extrahiert, tokenisiert, normalisiert und bereinigt, um sie im Modell zu verwenden. Schließlich hast du auch die Häufigkeiten der Tokens in den Daten betrachtet und die Häufigkeiten der zehn häufigsten Tokens überprüft.

Im nächsten Schritt werden Sie die Daten für die Sentiment-Analyse vorbereiten.

Schritt 6 — Daten für das Modell vorbereiten

Die Sentiment-Analyse ist ein Prozess zur Identifizierung der Haltung des Autors zu einem Thema, über das geschrieben wird. Sie werden einen Trainingsdatensatz erstellen, um ein Modell zu trainieren. Es ist ein überwachter Lernprozess im maschinellen Lernen, bei dem Sie jeden Datensatz mit einem "Sentiment" für das Training verknüpfen müssen. In diesem Tutorial wird Ihr Modell die "positiven" und "negativen" Sentiments verwenden.

Sentiment-Analyse kann verwendet werden, um Texte in eine Vielzahl von Stimmungen zu kategorisieren. Zur Vereinfachung und Verfügbarkeit des Trainingsdatensatzes hilft Ihnen dieses Tutorial, Ihr Modell nur in zwei Kategorien zu trainieren: positiv und negativ.

Ein Modell ist eine Beschreibung eines Systems mit Hilfe von Regeln und Gleichungen. Es kann so einfach sein wie eine Gleichung, die das Gewicht einer Person basierend auf ihrer Größe vorhersagt. Ein Sentiment-Analyse-Modell, das Sie erstellen werden, würde Tweets mit einem positiven oder negativen Sentiment verknüpfen. Sie müssen Ihr Dataset in zwei Teile aufteilen. Der Zweck des ersten Teils besteht darin, das Modell zu erstellen, während der nächste Teil die Leistung des Modells testet.

Im Schritt der Datenvorbereitung werden Sie die Daten für die Sentiment-Analyse vorbereiten, indem Sie die Tokens in die Grundform umwandeln und dann die Daten für Trainings- und Testzwecke aufteilen.

Tokens in ein Wörterbuch umwandeln

Zuerst werden Sie die Daten vorbereiten, die in das Modell eingespeist werden sollen. Sie werden den Naive Bayes-Klassifikator in NLTK verwenden, um die Modellierungsübung durchzuführen. Beachten Sie, dass das Modell nicht nur eine Liste von Wörtern in einem Tweet benötigt, sondern ein Python-Wörterbuch mit Wörtern als Schlüsseln und True als Werten. Die folgende Funktion erstellt eine Generatormethode, um das Format der bereinigten Daten zu ändern.

Fügen Sie den folgenden Code hinzu, um die Tweets von einer Liste bereinigter Token in Wörterbücher zu konvertieren, wobei die Schlüssel die Token und True die Werte sind. Die entsprechenden Wörterbücher werden in positive_tokens_for_model und negative_tokens_for_model gespeichert.

...
def get_tweets_for_model(cleaned_tokens_list):
    for tweet_tokens in cleaned_tokens_list:
        yield dict([token, True] for token in tweet_tokens)

positive_tokens_for_model = get_tweets_for_model(positive_cleaned_tokens_list)
negative_tokens_for_model = get_tweets_for_model(negative_cleaned_tokens_list)

Aufteilen des Datensatzes für das Training und Testen des Modells

Als nächstes müssen Sie die Daten zur Vorbereitung des NaiveBayesClassifier-Klasse vorbereiten. Fügen Sie den folgenden Code in die Datei ein, um die Daten vorzubereiten:

...
import random

positive_dataset = [(tweet_dict, "Positive")
                     for tweet_dict in positive_tokens_for_model]

negative_dataset = [(tweet_dict, "Negative")
                     for tweet_dict in negative_tokens_for_model]

dataset = positive_dataset + negative_dataset

random.shuffle(dataset)

train_data = dataset[:7000]
test_data = dataset[7000:]

Dieser Code fügt jedem Tweet ein Positiv oder Negativ Label hinzu. Dann erstellt er ein Datensatz, indem er die positiven und negativen Tweets zusammenfügt.

Standardmäßig enthält die Daten alle positiven Tweets, gefolgt von allen negativen Tweets in Sequenz. Beim Trainieren des Modells sollten Sie eine Probe Ihrer Daten bereitstellen, die keine Voreingenommenheit enthält. Um Voreingenommenheit zu vermeiden, haben Sie Code hinzugefügt, um die Daten zufällig mithilfe der .shuffle()-Methode von random anzuordnen.

Schließlich wird der gemischte Datensatz im Verhältnis 70:30 für das Training und das Testing aufgeteilt. Da die Anzahl der Tweets 10000 beträgt, können Sie die ersten 7000 Tweets aus dem mischten Datensatz für das Training des Modells und die letzten 3000 für das Testen des Modells verwenden.

In diesem Schritt hast du die bereinigten Tokens in ein Wörterbuchformat umgewandelt, den Datensatz zufällig gemischt und in Trainings- und Testdaten aufgeteilt.

Schritt 7 — Das Modell erstellen und testen

Schließlich können Sie die Klasse NaiveBayesClassifier verwenden, um das Modell zu erstellen. Verwenden Sie die Methode .train(), um das Modell zu trainieren, und die Methode .accuracy(), um das Modell mit den Testdaten zu überprüfen.

...
from nltk import classify
from nltk import NaiveBayesClassifier
classifier = NaiveBayesClassifier.train(train_data)

print("Accuracy is:", classify.accuracy(classifier, test_data))

print(classifier.show_most_informative_features(10))

Speichern Sie die Datei, schließen Sie sie und führen Sie sie aus, nachdem Sie den Code hinzugefügt haben. Die Ausgabe des Codes wird wie folgt aussehen:

Accuracy is: 0.9956666666666667

Most Informative Features
                      :( = True           Negati : Positi =   2085.6 : 1.0
                      :) = True           Positi : Negati =    986.0 : 1.0
                 welcome = True           Positi : Negati =     37.2 : 1.0
                  arrive = True           Positi : Negati =     31.3 : 1.0
                     sad = True           Negati : Positi =     25.9 : 1.0
                follower = True           Positi : Negati =     21.1 : 1.0
                     bam = True           Positi : Negati =     20.7 : 1.0
                    glad = True           Positi : Negati =     18.1 : 1.0
                     x15 = True           Negati : Positi =     15.9 : 1.0
               community = True           Positi : Negati =     14.1 : 1.0

Die Genauigkeit wird definiert als der Prozentsatz der Tweets im Testdatensatz, für die das Modell in der Lage war, die Stimmung korrekt vorherzusagen. Eine Genauigkeit von 99,5 % im Testdatensatz ist ziemlich gut.

In der Tabelle, die die informativsten Merkmale zeigt, zeigt jede Zeile im Output das Verhältnis des Auftretens eines Tokens in positiv und negativ gekennzeichneten Tweets im Trainingsdatensatz. Die erste Zeile in den Daten weist darauf hin, dass in allen Tweets, die das Token :( enthalten, das Verhältnis von negativen zu positiven Tweets 2085.6 zu 1 betrug. Interessanterweise scheint es ein Token mit :( in den positiven Datensätzen gegeben zu haben. Man kann sehen, dass die beiden wichtigsten diskriminierenden Elemente im Text die Emoticons sind. Außerdem führen Wörter wie sad zu negativen Empfindungen, während welcome und glad mit positiven Empfindungen assoziiert werden.

Als Nächstes können Sie überprüfen, wie das Modell bei zufälligen Tweets von Twitter abschneidet. Fügen Sie diesen Code in die Datei ein:

...
from nltk.tokenize import word_tokenize

custom_tweet = "I ordered just once from TerribleCo, they screwed up, never used the app again."

custom_tokens = remove_noise(word_tokenize(custom_tweet))

print(classifier.classify(dict([token, True] for token in custom_tokens)))

Dieser Code ermöglicht es Ihnen, benutzerdefinierte Tweets zu testen, indem Sie die mit der Variable custom_tweet verknüpfte Zeichenfolge aktualisieren. Speichern Sie die Datei und schließen Sie sie, nachdem Sie diese Änderungen vorgenommen haben.

Führen Sie das Skript aus, um den benutzerdefinierten Text zu analysieren. Hier ist die Ausgabe für den benutzerdefinierten Text im Beispiel:

'Negative'

Sie können auch überprüfen, ob es positive Tweets korrekt kennzeichnet:

...
custom_tweet = 'Congrats #SportStar on your 7th best goal from last season winning goal of the year :) #Baller #Topbin #oneofmanyworldies'

Hier ist die Ausgabe:

'Positive'

Jetzt, da du sowohl positive als auch negative Stimmungen getestet hast, aktualisiere die Variable, um eine komplexere Stimmung wie Sarkasmus zu testen.

...
custom_tweet = 'Thank you for sending my baggage to CityX and flying me to CityY at the same time. Brilliant service. #thanksGenericAirline'

Hier ist die Ausgabe:

'Positive'

Das Modell klassifizierte dieses Beispiel als positiv. Dies liegt daran, dass die Trainingsdaten nicht umfassend genug waren, um sarkastische Tweets als negativ zu klassifizieren. Falls Sie möchten, dass Ihr Modell Sarkasmus vorhersagt, müssten Sie eine ausreichende Menge an Trainingsdaten bereitstellen, um es entsprechend zu trainieren.

In diesem Schritt haben Sie das Modell erstellt und getestet. Sie haben auch einige seiner Einschränkungen erkundet, wie zum Beispiel das Nichte erkennen von Sarkasmus in bestimmten Beispielen. Ihr fertiggestellter Code weist weiterhin Überreste vom Befolgen des Tutorials auf, daher wird der nächste Schritt Sie durch die Anpassung des Codes an die besten Praktiken von Python führen.

Schritt 8 — Den Code Aufräumen (Optional)

Obwohl Sie das Tutorial abgeschlossen haben, wird empfohlen, den Code in der nlp_test.py Datei umzuorganisieren, um den besten Programmierpraktiken zu folgen. Nach den Best Practices sollte Ihr Code die folgenden Kriterien erfüllen:

  • Alle Importe sollten am Anfang der Datei stehen. Importe aus derselben Bibliothek sollten in einer einzigen Anweisung zusammengefasst werden.
  • Alle Funktionen sollten nach den Importen definiert werden.
  • Alle Anweisungen in der Datei sollten unter einer if __name__ == "__main__": Bedingung stehen. Dies stellt sicher, dass die Anweisungen nicht ausgeführt werden, wenn Sie die Funktionen der Datei in einer anderen Datei importieren.

Wir werden auch den Code entfernen, der gemäß dem Tutorial auskommentiert wurde, zusammen mit der lemmatize_sentence-Funktion, da die Lemmatisierung durch die neue remove_noise-Funktion abgeschlossen wird.

Hier ist die bereinigte Version von nlp_test.py:

from nltk.stem.wordnet import WordNetLemmatizer
from nltk.corpus import twitter_samples, stopwords
from nltk.tag import pos_tag
from nltk.tokenize import word_tokenize
from nltk import FreqDist, classify, NaiveBayesClassifier

import re, string, random

def remove_noise(tweet_tokens, stop_words = ()):

    cleaned_tokens = []

    for token, tag in pos_tag(tweet_tokens):
        token = re.sub('http[s]?://(?:[a-zA-Z]|[0-9]|[$-_@.&+#]|[!*\(\),]|'\
                       '(?:%[0-9a-fA-F][0-9a-fA-F]))+','', token)
        token = re.sub("(@[A-Za-z0-9_]+)","", token)

        if tag.startswith("NN"):
            pos = 'n'
        elif tag.startswith('VB'):
            pos = 'v'
        else:
            pos = 'a'

        lemmatizer = WordNetLemmatizer()
        token = lemmatizer.lemmatize(token, pos)

        if len(token) > 0 and token not in string.punctuation and token.lower() not in stop_words:
            cleaned_tokens.append(token.lower())
    return cleaned_tokens

def get_all_words(cleaned_tokens_list):
    for tokens in cleaned_tokens_list:
        for token in tokens:
            yield token

def get_tweets_for_model(cleaned_tokens_list):
    for tweet_tokens in cleaned_tokens_list:
        yield dict([token, True] for token in tweet_tokens)

if __name__ == "__main__":

    positive_tweets = twitter_samples.strings('positive_tweets.json')
    negative_tweets = twitter_samples.strings('negative_tweets.json')
    text = twitter_samples.strings('tweets.20150430-223406.json')
    tweet_tokens = twitter_samples.tokenized('positive_tweets.json')[0]

    stop_words = stopwords.words('english')

    positive_tweet_tokens = twitter_samples.tokenized('positive_tweets.json')
    negative_tweet_tokens = twitter_samples.tokenized('negative_tweets.json')

    positive_cleaned_tokens_list = []
    negative_cleaned_tokens_list = []

    for tokens in positive_tweet_tokens:
        positive_cleaned_tokens_list.append(remove_noise(tokens, stop_words))

    for tokens in negative_tweet_tokens:
        negative_cleaned_tokens_list.append(remove_noise(tokens, stop_words))

    all_pos_words = get_all_words(positive_cleaned_tokens_list)

    freq_dist_pos = FreqDist(all_pos_words)
    print(freq_dist_pos.most_common(10))

    positive_tokens_for_model = get_tweets_for_model(positive_cleaned_tokens_list)
    negative_tokens_for_model = get_tweets_for_model(negative_cleaned_tokens_list)

    positive_dataset = [(tweet_dict, "Positive")
                         for tweet_dict in positive_tokens_for_model]

    negative_dataset = [(tweet_dict, "Negative")
                         for tweet_dict in negative_tokens_for_model]

    dataset = positive_dataset + negative_dataset

    random.shuffle(dataset)

    train_data = dataset[:7000]
    test_data = dataset[7000:]

    classifier = NaiveBayesClassifier.train(train_data)

    print("Accuracy is:", classify.accuracy(classifier, test_data))

    print(classifier.show_most_informative_features(10))

    custom_tweet = "I ordered just once from TerribleCo, they screwed up, never used the app again."

    custom_tokens = remove_noise(word_tokenize(custom_tweet))

    print(custom_tweet, classifier.classify(dict([token, True] for token in custom_tokens)))

Schlussfolgerung

Dieses Tutorial hat Sie in ein grundlegendes Sentiment-Analyse-Modell mit der nltk-Bibliothek in Python 3 eingeführt. Zuerst haben Sie eine Vorverarbeitung von Tweets durchgeführt, indem Sie einen Tweet tokenisiert, die Wörter normalisiert und Rauschen entfernt haben. Als Nächstes haben Sie häufig vorkommende Elemente in den Daten visualisiert. Schließlich haben Sie ein Modell erstellt, um Tweets einem bestimmten Sentiment zuzuordnen.

Ein überwacht lernendes Modell ist nur so gut wie seine Trainingsdaten. Um das Modell weiter zu stärken, könnten Sie in Betracht ziehen, weitere Kategorien wie Aufregung und Wut hinzuzufügen. In diesem Tutorial haben Sie nur an der Oberfläche gekratzt, indem Sie ein rudimentäres Modell aufgebaut haben. Hier ist ein detaillierter Leitfaden zu verschiedenen Überlegungen, die man beim Durchführen einer Sentimentanalyse beachten muss.