fasttext は本当に好きなツールで, 中身は word2vec (SGNS) の高速化+subword に他ならない. 中身への信用度もあるけど, テキスト分類ツールとして必要な操作が全てコマンドで提供されいているのもいい. だからとりあえずテキスト分類したいものが手元にあって, 労力を掛けずにどの程度分類出来るのかを試すのによく使う.
ただしそれが日本語の場合はままならない. subword があるにしても, 基本的にはトークナイズがなされていることが前提にある. 従って MeCab なりなんなりで, ある程度はトークナイズをしてから fasttext に投げるのが理想的だ. しかしそんな労力すら惜しい.
1 は簡単だからその内やるとして, 今は fasttext の文字CNN 版を作っている.
中身は Keras だし, 別に fast ではない. いい加減 Python を脱却したいので, いい自動微分ライブラリがあれば Rust なりで書き直したい. GPU を要求するのもいい加減ダサいし.
データフォーマットは fasttext と全く同様. 具体的には次のようなもの.
URL=https://storage.googleapis.com/dataset-uploader/bbc/bbc-text.csv
curl $URL | tail -n +2 | sed 's/^\([^,]*\),/__label__\1\t/' > data.all
cat data.all | awk 'NR % 4 != 0' > data.train
cat data.all | awk 'NR % 4 == 0' > data.valid
ちなみにこのデータセットはニュース記事に5種類のラベルが貼られている.
走らせる. 実際には Keras のいろんなログや警告メッセージが大量に流れるけど省略.
fastcnn supervised data.train --verbose --validate data.valid --stat --maxlen 100 --kernel-size 5 --dim 300 --epochs 300 --stop-window 90 --lr 0.2 --clip-norm 2.0
___________________________________________
/ \
| Task: classify_single, #labels=5, #chars=57 |
| - Training with 1669 samples |
| - Validation with 556 samples |
\ /
===========================================
\
\
^__^
(oo)\_______
(__)\ )\/\
||----w |
|| ||
______________________________
/ \
| Training data stat: |
| Labels: |
| - __label__tech : 300 |
| - __label__business : 373 |
| - __label__sport : 390 |
| - __label__entertainment : 292 |
| - __label__politics : 314 |
| Sentence Length: |
| - max : 25483 |
| - min : 727 |
| - avg : 2271.0107849011383 |
\ /
==============================
\
\
^__^
(oo)\_______
(__)\ )\/\
||----w |
|| ||
_____________________________
/ \
| Validation data stat: |
| Labels: |
| - __label__sport : 121 |
| - __label__business : 137 |
| - __label__tech : 101 |
| - __label__politics : 103 |
| - __label__entertainment : 94 |
| Sentence Length: |
| - max : 19136 |
| - min : 501 |
| - avg : 2238.6978417266187 |
\ /
=============================
\
\
^__^
(oo)\_______
(__)\ )\/\
||----w |
|| ||
Model: "classify_single"
_________________________________________________________________
Layer (type) Output Shape Param #
=================================================================
embedding_1 (Embedding) (None, 100, 300) 18300
_________________________________________________________________
conv1d_1 (Conv1D) (None, 96, 600) 900600
_________________________________________________________________
max_pooling1d_1 (MaxPooling1 (None, 48, 600) 0
_________________________________________________________________
conv1d_2 (Conv1D) (None, 47, 600) 720600
_________________________________________________________________
max_pooling1d_2 (MaxPooling1 (None, 1, 600) 0
_________________________________________________________________
flatten_1 (Flatten) (None, 600) 0
_________________________________________________________________
gaussian_noise_1 (GaussianNo (None, 600) 0
_________________________________________________________________
dropout_1 (Dropout) (None, 600) 0
_________________________________________________________________
dense_1 (Dense) (None, 300) 180300
_________________________________________________________________
dense_2 (Dense) (None, 5) 1505
=================================================================
Total params: 1,821,305
Trainable params: 1,821,305
Non-trainable params: 0
_________________________________________________________________
Epoch 1/300
- 4s - loss: 1.6090 - acc: 0.2205 - val_loss: 1.6088 - val_acc: 0.2176
Epoch 2/300
- 2s - loss: 1.5968 - acc: 0.2536 - val_loss: 1.5963 - val_acc: 0.2464
Epoch 3/300
- 2s - loss: 1.5914 - acc: 0.2634 - val_loss: 1.5900 - val_acc: 0.3040
:
Epoch 41/300
- 2s - loss: 0.0249 - acc: 0.9982 - val_loss: 0.5630 - val_acc: 0.8183
Epoch 42/300
- 2s - loss: 0.0212 - acc: 0.9994 - val_loss: 0.5485 - val_acc: 0.8129
Epoch 43/300
- 2s - loss: 0.0153 - acc: 1.0000 - val_loss: 0.5409 - val_acc: 0.8255
ちなみにこのデータセットはそんなに難しくないらしくて, この人は学習済み GloVe 300 次元を使って 90% を簡単に達成してる. https://github.com/cemsaz/bbc-news-classifier
しかし, 単語ベクトルの学習がそうであるように教師なし学習は偉い. 教師ありで 300 次元なんてやっても, 簡単に訓練データに過学習するだけだ. 教師なしは過学習とかが無いから偉い.