[PYTHON] Kaggle Competition Hands On: Echt oder nicht? NLP mit Katastrophen-Tweets ~ EDA / Preprocessing ~

Übersicht über den Artikel

Dieser Artikel besteht aus zwei Teilen.

・ Teil 1: EDA ・ Vorbehandlung ← Jetzt hier ・ Teil 2: Vektorisierung / Modellierung (LSTM, BERT) (Im Aufbau, in Kürze erhältlich!)

Da der zweite Teil die Daten verwendet, die im ersten Teil vorverarbeitet wurden, Am Ende des Artikels befindet sich ** Code, der die Vorverarbeitung in einem Stapel ausführen kann ** Wenn Sie den ersten Teil überspringen möchten, führen Sie ihn bitte aus und fahren Sie mit dem zweiten Teil fort. (* Bitte beziehen Sie sich auf diesen Artikel, um die Daten zu erhalten!)

Überblick über den Wettbewerb

Kaggle : Real or Not? NLP with Disaster Tweets Dies ist ein Einführungswettbewerb für die Verarbeitung natürlicher Sprache. Die Aufgabe besteht darin, Tweets in zwei Kategorien zu klassifizieren: "Katastrophen-Tweets" oder "Nicht-Katastrophen-Tweets".

In jüngster Zeit wurde Twitter für Rettungsanfragen im Katastrophenfall verwendet, und das Interesse an einer automatischen Tweet-Überwachung im Katastrophenfall bei Katastrophenhilfeorganisationen und Telekommunikationsunternehmen steigt. Es ist jedoch schwierig, mechanisch festzustellen, ob ein Tweet tatsächlich eine Katastrophe darstellt. Dies liegt beispielsweise daran, dass der Ausdruck "Brennen", der explizit eine Katastrophe ausdrückt, manchmal als metaphorischer Ausdruck verwendet wird, z. B. "Der Himmel brennt". In diesem Wettbewerb werden wir einen Datensatz von 10.000 Tweets verwenden, um ein Modell für maschinelles Lernen zu erstellen, das "Katastrophen-Tweets" oder "Nicht-Katastrophen-Tweets" vorhersagt.

Hands on!

Wir werden das Jupyter-Notizbuch zum Anfassen verwenden.

0. Daten abrufen

Kaggle : Real or Not? NLP with Disaster Tweets - Data Von der obigen Seite ・ Test.csv ・ Train.csv Laden Sie zwei davon herunter. Fügen Sie danach diese CSV-Datei in dieselbe Hierarchie wie das zu analysierende Notizbuch ein. スクリーンショット 2020-03-22 12.40.22.png

Der Inhalt jeder Spalte in der CSV-Datei lautet wie folgt.

Dateiname Erläuterung
id Eindeutige Kennung für jeden Tweet
text Tweet Textkörper
location Wohin der Tweet gesendet wurde(Es ist ein Leerzeichen)
keyword Bestimmte Schlüsselwörter in Tweets(Es ist ein Leerzeichen)
target Tweet-Label(Katastrophen-Tweet=1, andere Tweets als Katastrophe=0)

Spezifische Details und Informationen zu fehlenden Werten werden im nächsten Abschnitt erläutert. Der Wettbewerb sagt die Zielspalte von test.csv voraus.

1. Laden Sie die Bibliothek

Definieren Sie die Bibliothek vor, die in dieser praktischen Anwendung verwendet werden soll.

#Datenanalyse
import pandas as pd
import numpy as np

#Visualisierung
%matplotlib inline
import matplotlib.pyplot as plt
import seaborn as sns

#Verarbeitung natürlicher Sprache
import string #Symbol(punctuation)Holen Sie sich eine Liste von
import re
import contractions #Dokumentabkürzung
from wordcloud import STOPWORDS #Holen Sie sich eine Liste von Stoppwörtern
from collections import defaultdict # n-Wird beim Erstellen von Gramm verwendet

2. Überprüfen Sie den Inhalt der Daten

Ich möchte den Inhalt der Daten sofort überprüfen. Lesen Sie zuerst die Daten als Datenrahmen. Zeigen Sie die Anzahl der Zeilen und Spalten des Datenrahmens an und versuchen Sie, 10 Zeilen nach dem Zufallsprinzip zu extrahieren.

#Trainingsdaten und Testdaten lesen
df_train = pd.read_csv('train.csv', dtype={'id': np.int16, 'target': np.int8})
df_test = pd.read_csv('test.csv', dtype={'id': np.int16})

#Zeigen Sie die Anzahl der Zeilen und Spalten der Trainingsdaten und Testdaten an
print('Training Set Shape = {}'.format(df_train.shape))
print('Test Set Shape = {}'.format(df_test.shape))

#Extrahiere zufällig 10 Zeilen aus den Trainingsdaten
df_train.sample(n=10, random_state=28)

Teil des Ausführungsergebnisses


Training Set Shape = (7613, 5)
Test Set Shape = (3263, 4)

Unten die Fortsetzung des Ausführungsergebnisses (Inhalt zufällig extrahierter Zeilen) スクリーンショット 2020-03-22 20.38.25.png

Möglicherweise fehlt in den Spalten keyword und location der Wert NaN.

Ich möchte die fehlenden Werte im Detail untersuchen.

#Berechnen Sie die fehlende Wertrate für jede Spalte mit Trainingsdaten und Testdaten
print("missing-value ratio of training data(%)")
print(df_train.isnull().sum()/df_train.shape[0]*100)
print("\nmissing-value ratio of test data(%)")
print(df_test.isnull().sum()/df_test.shape[0]*100)

Ausführungsergebnis


missing-value ratio of training data(%)
id           0.000000
keyword      0.801261
location    33.272035
text         0.000000
target       0.000000
dtype: float64

missing-value ratio of test data(%)
id           0.000000
keyword      0.796813
location    33.864542
text         0.000000
dtype: float64

Es ist ersichtlich, dass die fehlenden Werte sowohl in Trainingsdaten als auch in Testdaten 0,8% für "Schlüsselwort" und 33 bis 34% für "Ort" betragen.

Als nächstes schauen wir uns die Verteilung von "Ziel" in den Trainingsdaten an.

#Zeichnen Sie die Zielelemente und ihre Anzahl
target_vals = df_train.target.value_counts()
sns.barplot(target_vals.index, target_vals)
plt.gca().set_ylabel('samples')

value_counts.png

Sie können sehen, dass der Datensatz mehr "Nicht-Katastrophen-Tweets = 0" als "Katastrophen-Tweets = 1" enthält.

Als nächstes möchte ich die Anzahl der eindeutigen Elemente in jeder Spalte von "Text", "Schlüsselwort" und "Ort" herausfinden.

#Zeigt die Anzahl der eindeutigen Elemente in Text, Schlüsselwort und Position an
print(f'Number of unique values in text = {df_train["text"].nunique()} (Training) - {df_test["text"].nunique()} (Test)')
print(f'Number of unique values in keyword = {df_train["keyword"].nunique()} (Training) - {df_test["keyword"].nunique()} (Test)')
print(f'Number of unique values in location = {df_train["location"].nunique()} (Training) - {df_test["location"].nunique()} (Test)')

Ausführungsergebnis


Number of unique values in text = 7503 (Training) - 3243 (Test)
Number of unique values in keyword = 221 (Training) - 221 (Test)
Number of unique values in location = 3342 (Training) - 1603 (Test)

Sie können sehen, dass Text und Ort freie Eingabe sind. Auf der anderen Seite können Sie sehen, dass keyword automatisch 221 vordefinierte Schlüsselwörter aus text extrahiert.

3. Erklärende Datenanalyse (EDA)

Ich möchte etwas verarbeiten, um die Eigenschaften der Daten zu verstehen. Zunächst möchte ich die Funktionen in "Text" grob erfassen und vergleichen. Merkmale sind "Wortanzahl", "eindeutige Wortzahl", "Stoppwortanzahl", "URL-Anzahl", "durchschnittliche Anzahl von Wortzeichen", "Zeichenanzahl" , Anzahl der Satzzeichen (*), Anzahl der Hash-Tags, Anzahl der Erwähnungen. Ein Punkt, der hinzugefügt werden muss: Interpunktion (*) bedeutet hier keine Interpunktion, sondern bezieht sich auf andere ASCII-Zeichen als alphanumerische Zeichen. Grob gesagt ist es in Ordnung, wenn Sie ein Bild wie das in string.punctuation definierte "Symbol" haben. Darüber hinaus werden diese Features als Meta-Features in den Datenrahmen integriert. Darüber hinaus ist in den Trainingsdaten Disaster Tweet = 1 `Tweet anders als Disaster = 0` `, Trainingsdaten ⇄ Testdaten Vergleichen Sie die Verteilung von 9 Funktionen. Da Tweets im Zusammenhang mit Katastrophen, Tweets, die nicht mit Katastrophen zusammenhängen, Trainingsdaten und Testdaten unterschiedliche Datenwerte aufweisen. Bei der Visualisierung der Verteilung können mit der Kernel-Dichteschätzung die Skalen ausgerichtet und die Verteilungen intuitiv verglichen werden. Das Standardargument von distplotder Visualisierungsbibliothek seabornist kde = True, aber dieses Mal werden wir kde = True`` explizit beschreiben.

#Anzahl der Wörter
df_train['word_count'] = df_train['text'].apply(lambda x: len(str(x).split()))
df_test['word_count'] = df_test['text'].apply(lambda x: len(str(x).split()))

#Einzigartige Anzahl von Wörtern
df_train['unique_word_count'] = df_train['text'].apply(lambda x: len(set(str(x).split())))
df_test['unique_word_count'] = df_test['text'].apply(lambda x: len(set(str(x).split())))

#Anzahl der Stoppwörter
df_train['stop_word_count'] = df_train['text'].apply(lambda x: len([w for w in str(x).lower().split() if w in STOPWORDS]))
df_test['stop_word_count'] = df_test['text'].apply(lambda x: len([w for w in str(x).lower().split() if w in STOPWORDS]))

#Anzahl der URLs
df_train['url_count'] = df_train['text'].apply(lambda x: len([w for w in str(x).lower().split() if 'http' in w or 'https' in w]))
df_test['url_count'] = df_test['text'].apply(lambda x: len([w for w in str(x).lower().split() if 'http' in w or 'https' in w]))

#Durchschnittliche Anzahl von Wortzeichen
df_train['mean_word_length'] = df_train['text'].apply(lambda x: np.mean([len(w) for w in str(x).split()]))
df_test['mean_word_length'] = df_test['text'].apply(lambda x: np.mean([len(w) for w in str(x).split()]))

#Wortzahl
df_train['char_count'] = df_train['text'].apply(lambda x: len(str(x)))
df_test['char_count'] = df_test['text'].apply(lambda x: len(str(x)))

#Anzahl der Satzzeichen
df_train['punctuation_count'] = df_train['text'].apply(lambda x: len([c for c in str(x) if c in string.punctuation]))
df_test['punctuation_count'] = df_test['text'].apply(lambda x: len([c for c in str(x) if c in string.punctuation]))

#Anzahl der Hash-Tags
df_train['hashtag_count'] = df_train['text'].apply(lambda x: len([c for c in str(x) if c == '#']))
df_test['hashtag_count'] = df_test['text'].apply(lambda x: len([c for c in str(x) if c == '#']))

#Anzahl der Erwähnungen
df_train['mention_count'] = df_train['text'].apply(lambda x: len([c for c in str(x) if c == '@']))
df_test['mention_count'] = df_test['text'].apply(lambda x: len([c for c in str(x) if c == '@']))
#Katastrophen-Tweet über die Verteilung von 9 Funktionen=1 ⇄ Andere Tweets als Katastrophen=0, Trainingsdaten ⇄ Mit Testdaten vergleichen
METAFEATURES = ['word_count', 'unique_word_count', 'stop_word_count', 'url_count', 'mean_word_length',
                'char_count', 'punctuation_count', 'hashtag_count', 'mention_count']
DISASTER_TWEETS = df_train['target'] == 1

fig, axes = plt.subplots(ncols=2, nrows=len(METAFEATURES), figsize=(20, 50), dpi=100)

for i, feature in enumerate(METAFEATURES):
    #Katastrophen-Tweet=1 ⇄ Andere Tweets als Katastrophen=Vergleichen Sie die Verteilung von 0(Führen Sie eine Kernel-Dichteschätzung durch)
    sns.distplot(df_train.loc[~DISASTER_TWEETS][feature], label='Not Disaster', ax=axes[i][0], color='green', kde=True)
    sns.distplot(df_train.loc[DISASTER_TWEETS][feature], label='Disaster', ax=axes[i][0], color='red', kde=True)
    
    #Trainingsdaten ⇄ Vergleichen Sie die Verteilung der Testdaten(Führen Sie eine Kernel-Dichteschätzung durch)
    sns.distplot(df_train[feature], label='Training', ax=axes[i][1], kde=True)
    sns.distplot(df_test[feature], label='Test', ax=axes[i][1], kde=True)

    for j in range(2):
        axes[i][j].set_xlabel('')
        axes[i][j].tick_params(axis='x', labelsize=12)
        axes[i][j].tick_params(axis='y', labelsize=12)
        axes[i][j].legend()

    axes[i][0].set_title(f'{feature} Target Distribution in Training Set', fontsize=13)
    axes[i][1].set_title(f'{feature} Training & Test Set Distribution', fontsize=13)

plt.show()

meta_feature.png

Sie können sehen, dass es keinen großen Unterschied in der Verteilung zwischen "Katastrophen-Tweets" und "anderen Tweets als Katastrophen", Trainingsdaten und Testdaten gibt. Sie können sehen, dass Tweets mit URLs, Hashtags und Erwähnungen so gut oder besser sind als Tweets ohne diese. Notationen wie URLs, Hash-Tags und Erwähnungen sind wahrscheinlich keine notwendigen Informationen, um Katastrophen-Tweets und andere Tweets als Katastrophen zu bestimmen. Daher ist es möglicherweise besser, sie bei der Vorverarbeitung zu bereinigen.

Als nächstes finden Sie heraus, welches der Schlüsselwörter in Katastrophen-Tweets am häufigsten und welches in Nicht-Katastrophen-Tweets am häufigsten vorkommt. Da Ziel von Katastrophen-Tweets eine Ganzzahl 1 ist und andere Tweets als Katastrophen Ganzzahlen 0 sind, Nehmen Sie den Durchschnittswert von "Ziel" für jedes Wort von "Schlüsselwort", und wenn es nahe bei 1 liegt, Wörter, die dazu neigen, in Katastrophen-Tweets zu erscheinen. Wenn es nahe bei 0 liegt, können Sie sehen, dass es sich um ein Wort handelt, das in anderen Tweets als Katastrophen vorkommt. Verwenden Sie die pandas-Methode "groupby", um den Durchschnittswert von "target" für jedes Wort von "keyword" zu ermitteln und diesen Wert zu den gesamten Trainingsdaten hinzuzufügen. Danach wird die Anzahl der Auftritte in der Reihenfolge des Wortes aufgezeichnet, das im Katastrophen-Tweet erscheint.

#Suchen Sie den Durchschnittswert des Ziels für jedes Schlüsselwort und fügen Sie diesen Wert zu den gesamten Trainingsdaten hinzu
df_train['target_mean'] = df_train.groupby('keyword')['target'].transform('mean')

fig = plt.figure(figsize=(8, 72), dpi=100)

#Überprüfen Sie die im Schlüsselwort enthaltene Etikettenverteilung
sns.countplot(y=df_train.sort_values(by='target_mean', ascending=False)['keyword'],
             hue=df_train.sort_values(by='target_mean', ascending=False)['target'])

plt.tick_params(axis='x', labelsize=15)
plt.tick_params(axis='y', labelsize=12)
plt.legend(loc=1)
plt.title('Target Distribution in Keywords')

plt.show()

#Löschen Sie die Spalte mit dem Durchschnittswert des Zielwerts, da dieser nicht mehr verwendet wird.
df_train.drop(columns=['target_mean'], inplace=True)

Das Ausgabeergebnis ist wie folgt. Wenn Sie in diesem Artikel die gesamte Beschriftungsverteilung von 221 Wörtern anzeigen, ist diese vertikal lang. Wörter, die in Katastrophen-Tweets vorkommen, und Wörter, die in Nicht-Katastrophen-Tweets vorkommen, Es wird jeweils nur die Oberseite angezeigt (tatsächlich können Sie ein Diagramm der vertikalen Etikettenverteilung erhalten). target_dist_head_foot.png

Die Nomenklatur für bestimmte katastrophenbedingte Zustände wie Entgleisung, Trümmer und Trümmer erscheint in der Regel in Katastrophen-Tweets. Auf der anderen Seite sind Nachbeben (= Nachbeben, Nachwirkungen), Leichensäcke (= Leichensäcke), Ruine (= Ruine (Substantiv), Ruine (Verb)) scheinbar katastrophenbezogene Wörter. Es erscheint normalerweise nicht in Katastrophen-Tweets. Dies liegt wahrscheinlich daran, dass es sich um ein Wort handelt, das auch als metaphorischer Ausdruck verwendet wird.

Überprüfen Sie als Nächstes die häufig verwendeten Wörter in n-Gramm. Dieses Mal verwendeten Unigramm (n = 1), Bigram (n = 2), Trigramm (n = 3) häufig verwendete Wörter, "Katastrophen-Tweet = 1", "Nicht-Katastrophen-Tweet = 0". bestätigen. Definieren Sie zunächst eine Funktion, die eine n-Gramm-Liste generiert. Weitere Informationen finden Sie im Detaillierten Erklärungsartikel der Funktion, die die Liste der n-Gramm generiert.

def generate_ngrams(text, n_gram=1):
    #Tokenisieren Sie nur Wörter, die nicht in der Liste der Stoppwörter enthalten sind
    token = [token for token in text.lower().split(' ') if token != '' if token not in STOPWORDS]
    # n_Erstellen von Gramm-Taples, Reißverschluss(*)Extrahiert Elemente mit demselben Index vom Anfang der Liste.
    ngrams = zip(*[token[i:] for i in range(n_gram)])
    return [' '.join(ngram) for ngram in ngrams]

Verwenden Sie dann die Funktion, um das Unigramm (n = 1), das Bigram (n = 2), das Trigramm (n = 3) und deren Häufigkeit zu berechnen.

#Unigramm
disaster_unigrams = defaultdict(int)
nondisaster_unigrams = defaultdict(int)

# df_Erstellen Sie ein Unigramm von Katastrophen-Tweets im Zug
for tweet in df_train[DISASTER_TWEETS]['text']:
    for word in generate_ngrams(tweet):
        disaster_unigrams[word] += 1

# df_Erstellen Sie im Zug ein Unigramm von Nicht-Katastrophen-Tweets.
for tweet in df_train[~DISASTER_TWEETS]['text']:
    for word in generate_ngrams(tweet):
        nondisaster_unigrams[word] += 1

#Nach Häufigkeit des Auftretens sortieren
df_disaster_unigrams = pd.DataFrame(sorted(disaster_unigrams.items(), key=lambda x: x[1])[::-1])
df_nondisaster_unigrams = pd.DataFrame(sorted(nondisaster_unigrams.items(), key=lambda x: x[1])[::-1])

#Biggram
disaster_bigrams = defaultdict(int)
nondisaster_bigrams = defaultdict(int)

for tweet in df_train[DISASTER_TWEETS]['text']:
    for word in generate_ngrams(tweet, n_gram=2):
        disaster_bigrams[word] += 1
        
for tweet in df_train[~DISASTER_TWEETS]['text']:
    for word in generate_ngrams(tweet, n_gram=2):
        nondisaster_bigrams[word] += 1
        
df_disaster_bigrams = pd.DataFrame(sorted(disaster_bigrams.items(), key=lambda x: x[1])[::-1])
df_nondisaster_bigrams = pd.DataFrame(sorted(nondisaster_bigrams.items(), key=lambda x: x[1])[::-1])

#Trigramm
disaster_trigrams = defaultdict(int)
nondisaster_trigrams = defaultdict(int)

for tweet in df_train[DISASTER_TWEETS]['text']:
    for word in generate_ngrams(tweet, n_gram=3):
        disaster_trigrams[word] += 1
        
for tweet in df_train[~DISASTER_TWEETS]['text']:
    for word in generate_ngrams(tweet, n_gram=3):
        nondisaster_trigrams[word] += 1
        
df_disaster_trigrams = pd.DataFrame(sorted(disaster_trigrams.items(), key=lambda x: x[1])[::-1])
df_nondisaster_trigrams = pd.DataFrame(sorted(nondisaster_trigrams.items(), key=lambda x: x[1])[::-1])

Schauen wir uns zunächst die 30 am häufigsten vorkommenden Unigramme an.

N = 30 #Nur die Top 30 Unigramme anzeigen

fig, axes = plt.subplots(ncols=2, figsize=(15, 15), dpi=100)
plt.tight_layout()

sns.barplot(y=df_disaster_unigrams[0].values[:N], x=df_disaster_unigrams[1].values[:N], ax=axes[0], color='red')
sns.barplot(y=df_nondisaster_unigrams[0].values[:N], x=df_nondisaster_unigrams[1].values[:N], ax=axes[1], color='green')

for i in range(2):
    axes[i].spines['right'].set_visible(False)
    axes[i].set_xlabel('')
    axes[i].set_ylabel('')
    axes[i].tick_params(axis='x', labelsize=13)
    axes[i].tick_params(axis='y', labelsize=13)

axes[0].set_title(f'Top {N} most common unigrams in Disaster Tweets', fontsize=15)
axes[1].set_title(f'Top {N} most common unigrams in Non-disaster Tweets', fontsize=15)

plt.show()

unigrams.png

Sie können sehen, dass viele der häufigsten Unigramme Symbole, Stoppwörter, die nicht entfernt werden konnten, und Zahlen sind, selbst für Katastrophen-Tweets und Nicht-Katastrophen-Tweets. Diese Unigramme sind kein Kriterium für "Ziel" und sollten vor der Modellierung entfernt werden.

Sie können auch sehen, dass Unigram, das häufig in Katastrophen-Tweets angezeigt wird, spezifische Informationen über die Katastrophe enthält. Auf der anderen Seite können Sie sehen, dass die Unigramme viele Verben enthalten, die häufig in anderen Tweets als Katastrophen vorkommen. Dies liegt wahrscheinlich daran, dass Benutzer in Nicht-Katastrophen-Tweets dazu neigen, über sich selbst oder etwas anderes zu twittern.

Schauen wir uns auch Bigramme und Trigramme an.

#Biggram
fig, axes = plt.subplots(ncols=2, figsize=(20, 15), dpi=100)
plt.subplots_adjust(wspace=0.4, hspace=0.6)

sns.barplot(y=df_disaster_bigrams[0].values[:N], x=df_disaster_bigrams[1].values[:N], ax=axes[0], color='red')
sns.barplot(y=df_nondisaster_bigrams[0].values[:N], x=df_nondisaster_bigrams[1].values[:N], ax=axes[1], color='green')

for i in range(2):
    axes[i].spines['right'].set_visible(False)
    axes[i].set_xlabel('')
    axes[i].set_ylabel('')
    axes[i].tick_params(axis='x', labelsize=20)
    axes[i].tick_params(axis='y', labelsize=20)

axes[0].set_title(f'Top {N} most common bigrams in Disaster Tweets', fontsize=20)
axes[1].set_title(f'Top {N} most common bigrams in Non-disaster Tweets', fontsize=20)

plt.show()

#Trigramm
fig, axes = plt.subplots(ncols=2, figsize=(20, 15), dpi=100)
plt.subplots_adjust(wspace=0.7, hspace=0.6)

sns.barplot(y=df_disaster_trigrams[0].values[:N], x=df_disaster_trigrams[1].values[:N], ax=axes[0], color='red')
sns.barplot(y=df_nondisaster_trigrams[0].values[:N], x=df_nondisaster_trigrams[1].values[:N], ax=axes[1], color='green')

for i in range(2):
    axes[i].spines['right'].set_visible(False)
    axes[i].set_xlabel('')
    axes[i].set_ylabel('')
    axes[i].tick_params(axis='x', labelsize=20)
    axes[i].tick_params(axis='y', labelsize=20)

axes[0].set_title(f'Top {N} most common trigrams in Disaster Tweets', fontsize=20)
axes[1].set_title(f'Top {N} most common trigrams in Non-disaster Tweets', fontsize=20)

plt.show()

bigrams.png

trigrams.png

Es ist ersichtlich, dass Katastrophen-Tweets viele spezifische Katastropheninhalte enthalten, die sowohl mit Bigram als auch mit Trigramm gemeinsam sind. Sie können auch sehen, dass Katastrophen-Tweets selten Symbole, Stoppwörter und Zahlen enthalten, die in Unigram gefunden wurden. Auf der anderen Seite erscheinen in anderen Tweets als Katastrophen Trennzeichen und Stoppwörter, und viele Wörter wie reddit und youtube erscheinen ebenfalls.

4. Datenvorverarbeitung

Die explorative Datenanalyse hat gezeigt, dass Tweets von Informationen befreit werden müssen, die zum Erstellen des Modells nicht benötigt werden. Vor dem Erstellen des Modells wird eine Vorverarbeitung der Trainingsdaten und Testdaten durchgeführt.

Konvertieren Sie zunächst abgekürzte Wörter wie "Ich bin" und "Wir haben" zurück in "Ich bin" und "Wir haben". Python bietet ein Modul namens "Kontraktionen" mit "Kontraktionen.fix (Text)" Sie können die ursprüngliche Form der Abkürzung wiederherstellen.

def fix_contractions(text):
    return contractions.fix(text)

#Tweet Beispiel vor Funktionsanpassung
print("tweet before contractions fix : ", df_train.iloc[1055]["text"])

#Funktion anwenden
df_train['text']=df_train['text'].apply(lambda x : fix_contractions(x))
df_test['text']=df_test['text'].apply(lambda x : fix_contractions(x))

#Tweet Beispiel nach dem Anwenden der Funktion
print("tweet after contractions fix : ", df_train.iloc[1055]["text"])

Ausführungsergebnis


tweet before contractions fix :  @asymbina @tithenai I'm hampered by only liking cross-body bags. I really like Ella Vickers bags: machine washable. http://t.co/YsFYEahpVg
tweet after contractions fix :  @asymbina @tithenai I am hampered by only liking cross-body bags. I really like Ella Vickers bags: machine washable. http://t.co/YsFYEahpVg

Löschen Sie anschließend mit regulären Ausdrücken nur die URL aus den Tweets, die die URL enthalten.

def remove_URL(text):
    url = re.compile(r'https?://\S+|www\.\S+')
    return url.sub(r'',text)

#Tweet Beispiel vor Funktionsanpassung
print("tweet before URL removal : ", df_train.iloc[1055]["text"])

#Funktion anwenden
df_train['text']=df_train['text'].apply(lambda x : remove_URL(x))
df_test['text']=df_test['text'].apply(lambda x : remove_URL(x))

#Tweet Beispiel nach dem Anwenden der Funktion
print("tweet after URL removal : ", df_train.iloc[1055]["text"])

Ausführungsergebnis


tweet before URL removal :  @asymbina @tithenai I am hampered by only liking cross-body bags. I really like Ella Vickers bags: machine washable. http://t.co/YsFYEahpVg
tweet after URL removal :  @asymbina @tithenai I am hampered by only liking cross-body bags. I really like Ella Vickers bags: machine washable. 

Als nächstes möchte ich das Symbol entfernen. Dies beinhaltet # @! "$% & \ '() * +, -. / :; <=>? [\\] ^ _` {|} ~` `einschließlich Hash-Tags und Erwähnungssymbolen. Das Symbol wird entfernt. Eine Liste der zu löschenden Symbole erhalten Sie mit string.punctuation``.

def remove_punct(text):
    table=str.maketrans('','',string.punctuation)
    return text.translate(table)

#Tweet Beispiel vor Funktionsanpassung
print("tweet before punctuation removal : ", df_train.iloc[1055]["text"])

#Funktion anwenden
df_train['text']=df_train['text'].apply(lambda x : remove_punct(x))
df_test['text']=df_test['text'].apply(lambda x : remove_punct(x))

#Tweet Beispiel nach dem Anwenden der Funktion
print("tweet after punctuation removal : ", df_train.iloc[1055]["text"])

Ausführungsergebnis


tweet before punctuation removal :  @asymbina @tithenai I am hampered by only liking cross-body bags. I really like Ella Vickers bags: machine washable. 
tweet after punctuation removal :  asymbina tithenai I am hampered by only liking crossbody bags I really like Ella Vickers bags machine washable 

Der Tweet-Körper wurde durch die oben genannten drei Prozesse bereinigt. In Zukunft möchte ich mit dem bereinigten Text vektorisieren und modellieren!

Ein Artikel über Vektorisierung und Modellierung wird gerade geschrieben! Warten Sie mal!

Referenziertes Notizbuch

Wettbewerbsheft, auf das in diesem Artikel Bezug genommen wird (oder das verwendet wird)

・ Https://www.kaggle.com/gunesevitan/nlp-with-disaster-tweets-eda-cleaning-and-bert (EDA, Datenvorverarbeitung, Vektorisierung, BERT)

・ Https://www.kaggle.com/shahules/basic-eda-cleaning-and-glove (EDA, Datenvorverarbeitung, GloVe)

Die Vorverarbeitung muss durchgeführt werden, bevor mit dem nächsten Kapitel fortgefahren wird

Fahren Sie mit dem nächsten ausgeführten Code mit dem nächsten Kapitel fort

#Datenanalyse
import pandas as pd
import numpy as np

#Visualisierung
%matplotlib inline
import matplotlib.pyplot as plt
import seaborn as sns

#Verarbeitung natürlicher Sprache
import string #Symbol(punctuation)Holen Sie sich eine Liste von
import re
import contractions #Dokumentabkürzung
from wordcloud import STOPWORDS #Holen Sie sich eine Liste von Stoppwörtern
from collections import defaultdict # n-Wird beim Erstellen von Gramm verwendet

#Abgekürzte Restaurierung
def fix_contractions(text):
    return contractions.fix(text)

#URL löschen
def remove_URL(text):
    url = re.compile(r'https?://\S+|www\.\S+')
    return url.sub(r'',text)

#Symbol entfernen
def remove_punct(text):
    table=str.maketrans('','',string.punctuation)
    return text.translate(table)

#Funktion anwenden
df_train['text']=df_train['text'].apply(lambda x : fix_contractions(x))
df_test['text']=df_test['text'].apply(lambda x : fix_contractions(x))

df_train['text']=df_train['text'].apply(lambda x : remove_URL(x))
df_test['text']=df_test['text'].apply(lambda x : remove_URL(x))

df_train['text']=df_train['text'].apply(lambda x : remove_punct(x))
df_test['text']=df_test['text'].apply(lambda x : remove_punct(x))


Recommended Posts

Kaggle Competition Hands On: Echt oder nicht? NLP mit Katastrophen-Tweets ~ EDA / Preprocessing ~
Kaggle Memorandum ~ NLP mit Katastrophen-Tweets Teil 1 ~