Python
自然言語処理
機械学習
ディープラーニング
Keras

文字ベース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


2018/08/27 17:27

このencoding関数は、「前処理」なのか「特徴量設計」なのかちょっとわからんのですが、「特徴量設計」という言葉をディープラーニングの文脈で使うのをおかしいと考えた人がいるかもしれません。

特徴量設計は、ディープラーニングでも使う利点はあり、収束が早くなります。事前になんらかの特徴量設計がすばやく行える場合は、「生データ」にこだわる必要がありません。