TPTブログ

テックポート株式会社のブログです。 技術情報や製品・サービス情報、 また未経験社員がデータサイエンティストを 目指す奮闘記など、更新していきます。

▲Kaggleやってみよう【Movie Reviews:映画レビューの感情分析】後篇

f:id:TBT_matsu:20200421115711p:plain
こんにちは!
テービーテックの村松です。

本日は、こちら2つ↓↓の続き。
▲Kaggleやってみよう【Movie Reviews:映画レビューの感情分析】前篇 - テービーテックのデータサイエンス
▲Kaggleやってみよう【Movie Reviews:映画レビューの感情分析】中篇 - テービーテックのデータサイエンス

どうにかこうにか精度を上げられないか色々試した最終報告になります。

結局どうなった?

前回から色々試しましたが前処理は結局変わらずモデルを一部変更しました。
結果がこちらです。

model=Sequential()
model.add(Embedding(Embedding(len(list(unique_words)),100,input_length=max_lenght))
model.add(LSTM(128,dropout=0.3, recurrent_dropout=0.3,return_sequences=True))
model.add(LSTM(64,dropout=0.3, recurrent_dropout=0.3,return_sequences=False))
model.add(Dense(5,activation='softmax'))
model.compile(loss='sparse_categorical_crossentropy',optimizer='adam',metrics=['accuracy'])
model.summary()

ドロップアウトの比率や損失関数を変えて、少し層を変更しました。

history=model.fit(x_train, y_train, batch_size=128, epochs=10, verbose=1)

エポック数もちょっと増やしました。

##結果
Epoch 1/15
1220/1220 [==============================] - 517s 424ms/step - loss: 0.9638 - accuracy: 0.6111
Epoch 2/15
1220/1220 [==============================] - 516s 423ms/step - loss: 0.7896 - accuracy: 0.6749
Epoch 3/15
1220/1220 [==============================] - 520s 426ms/step - loss: 0.7322 - accuracy: 0.6960
Epoch 4/15
1220/1220 [==============================] - 521s 427ms/step - loss: 0.6915 - accuracy: 0.7105
Epoch 5/15
1220/1220 [==============================] - 517s 424ms/step - loss: 0.6612 - accuracy: 0.7234
Epoch 6/15
1220/1220 [==============================] - 517s 424ms/step - loss: 0.6359 - accuracy: 0.7312
Epoch 7/15
1220/1220 [==============================] - 522s 428ms/step - loss: 0.6142 - accuracy: 0.7401
Epoch 8/15
1220/1220 [==============================] - 526s 431ms/step - loss: 0.5939 - accuracy: 0.7475
Epoch 9/15
1220/1220 [==============================] - 525s 430ms/step - loss: 0.5773 - accuracy: 0.7529
Epoch 10/15
1220/1220 [==============================] - 530s 434ms/step - loss: 0.5603 - accuracy: 0.7591

それではこのモデルで最終の予測を出してKaggleに提出してみます。
提出したスコアがこちら。
f:id:TBT_matsu:20200427163939p:plain
順位でいうと140位付近。
まあまあ、ですかね?

おまけ

他の手法でも試していたのでおまけでご紹介いたします。
①ナイーブベイズ分類器
②サポートベクターマシーン
③ランダムフォレスト

共通前処理

#必要なモジュールのインポート
import numpy as np
import pandas as pd
import re
import nltk
from nltk.tokenize import word_tokenize
nltk.download('punkt')
from sklearn.feature_extraction.text import CountVectorizer
vect = CountVectorizer()

#データの読み込み
df_train = pd.read_csv('train.tsvのパス', sep='\t')
df_test = pd.read_csv('test.tsvのパス', sep='\t')

#前処理開始
#全て小文字に
df_train['Phrase'] = df_train['Phrase'].str.lower()
#アルファベット以外の文字を削除
df_train['Phrase'] = df_train['Phrase'].apply(lambda x: re.sub("[^a-zA-Z]"," ", x))

#ストップワードの削除  ←←←new
from nltk.corpus import stopwords
nltk.download('stopwords')
stop_word = set(stopwords.words('english')) 
df_train['Phrase_no_stopwords'] = df_train['Phrase'].apply(lambda x: [word for word in x.split() if word not in (stop_word)])

#単語の変形を直す    ←←←new(色んなやり方があるみたいです)
from nltk.stem.snowball import SnowballStemmer
stemmer = SnowballStemmer('english')
df_train['Phrase_no_stopwords'] = df_train['Phrase_no_stopwords'].apply(lambda x: [stemmer.stem(y) for y in x])
df_train['Phrase_no_stopwords'] = df_train['Phrase_no_stopwords'].apply(lambda x: ' '.join(x))

#訓練データとテストデータに分割
from sklearn.model_selection import train_test_split
x=df_train.Phrase_no_stopwords
y=df_train.Sentiment
x_train, x_test, y_train, y_test = train_test_split(x, y, test_size=0.2,  random_state=1)

#ベクトル化
x_train_df = vect.fit_transform(x_train)
x_test_df = vect.transform(x_test)

print('Vocabulary size: {}'.format(len(vect.vocabulary_)))
print('Vocabulary content: {}'.format(vect.vocabulary_))
##結果
Vocabulary size: 10209
Vocabulary content: {'assembl': 474, 'somber': 8286, 'film': 3238, 'live': 5222, 'rock': 7487,・・・中略・・・'zigzag': 10193, 'petter': 6569}

①ナイーブベイズ

from sklearn.naive_bayes import MultinomialNB
nb = MultinomialNB()
nb.fit(x_train_df, y_train)
y_pred_class = nb.predict(x_test_df)
print(metrics.accuracy_score(y_test, y_pred_class))
##結果
0.6101179033704985

②サポートベクターマシーン

from sklearn.linear_model import SGDClassifier
SVM = SGDClassifier()
SVM.fit(x_train_df, y_train)
y_pred_class = SVM.predict(x_test_df)
print(metrics.accuracy_score(y_test, y_pred_class))
##結果
0.6018198128924772

③ランダムフォレスト

from sklearn.ensemble import RandomForestClassifier
rfc = RandomForestClassifier()
rfc.fit(x_train_df, y_train)
y_pred_class = rfc.predict(x_test_df)
print(metrics.accuracy_score(y_test, y_pred_class))
##結果
0.6378956811482763

自然言語分析にも色々な手法が使われています。
今回ご紹介した手法も色々な工夫で結果が変わってくると思います。
調べれば調べるほど沢山あるので今後も色々試しながら試行錯誤していこうと思います。


初めての自然言語処理だったので目新しいことが多く楽しかったのが素直な感想ですね。
今後もやったこのないテーマを含め沢山挑戦していきます!
そして今回の課題に取り組んだ一番の感想は、
Kaggleは時間泥棒・・・。
色々試しているうちにあっという間に時間が、あ、予定よりも大幅オーバー・・・なんてことが何回か続きました。
私が知らないことが多いので逐一調べる時間が長いのも問題なんですが・・・。
皆さんも没頭し過ぎないように気を付けましょう。