ナード戦隊データマン

データサイエンスを用いて悪と戦うぞ

ツイートをCNNで感情分析 (成功)

前回、文字ベースCNNによるツイート分類が失敗しました。結局、失敗要因は「特徴量設計がおかしい」だけでした。具体的には、データの行列化でasciiコードのOne-hotを作ってConv2Dに渡すのがそもそも無理がありました。今回は、もっと単純なCNNモデルで高い精度が得られることを示します。

Jupyter notebookで実行

githubにアップロードしたので、以下のノートブックを参照してください。 https://github.com/sugiyamath/credibility_analysis/blob/master/notebook/sentiment_analysis/cnn_sentiment140.ipynb

重要な部分だけ

まず、入力テキストは以下の関数でエンコーディングします。

def encoding(texts, max_len=None):
    tx2chs = [list(text) for text in texts]
    if max_len is None:
        max_len = max([len(chs) for chs in tx2chs])
    vectors = [list(map(ord, chs))+[0 for _ in range(max_len-len(chs))] for chs in tx2chs]
    max_features = max([max(x) for x in vectors])
    return np.array(vectors), max_len, max_features

以前の失敗コードでは各文を行列化しましたが、今回は各文を単一のベクトルで表します。本当は、Kerasの用意しているTokenizerを使ったほうが良いのですが、実行過程がわかるようにあえて関数として書いています。

エンコーディングされたベクトルは、Embeddingレイヤーに渡され、Conv1Dへ渡されます。以下は、Kerasの文字ベースCNNモデルです。

model = Sequential()
model.add(Embedding(max_features+1, 150, input_length=max_len))
model.add(SpatialDropout1D(0.2))
model.add(Conv1D(32, kernel_size=3, padding='same', activation='relu'))
model.add(MaxPooling1D(pool_size=2))
model.add(Conv1D(64, kernel_size=3, padding='same', activation='relu'))
model.add(MaxPooling1D(pool_size=2))
model.add(Flatten())
model.add(Dense(2, activation='softmax'))
model.compile(loss='binary_crossentropy', optimizer='rmsprop', metrics=['accuracy'])

epochs = 30
batch_size = 1000
model.fit(X_train, y_train, validation_data=(X_val, y_val), epochs=epochs, batch_size=batch_size)

注意: GPUを使ってください。

何度か訓練してみて, 以下の精度が出ました:

AUC, ACC = 0.796649954004895, 0.7966525

これは、nnlm + tfidf + logregのモデルよりも精度が高いことを意味しています。

考察

文字レベルCNNで感情分析ができましたが、ツイートは文字数制限がある上にフォーマルな文章ではないので、直感的には、単語レベルのCNNで精度を出すような気がしません。

ただ、文字レベルのCNNでもこの程度しか精度がでないのは、sentiment140コーパスがノイズを多く含んでいるからだと思います。

このモデルが日本語ツイートでも同様に適用できるのかはやってみないとわかりませんが、どちらにせよ、distant supervisionではノイズが含まれてしまうので、テストデータに関しては、別途データを用意したほうがいいかもしれません。

訓練速度はGPUを使えば2時間以内に訓練が終えることができました。

参考

[0] https://www.kaggle.com/kazanova/sentiment140 [1] https://www.kaggle.com/antmarakis/cnn-baseline-model

追記

2018/08/27 17:06

会社からKaggleへアクセスしてKernelをコミットしたけど、実行がずっと終わらない。 https://www.kaggle.com/shunsugiyama/fix-character-based-cnn-for-tweet-classification