文章特徴抽出ライブラリWordBatchを試してみる

GWを使って、文章から特徴を抽出するライブラリwordbatchを試しました。wordbatchって何なの？って人も見たことあるって人もこれから使ってみようという人にも役に立てればと思います。

## WordBatchとは
[こちら](https://github.com/anttttti/Wordbatch)で公開されております。
一言で言うと
「機械学習用の並列処理テキスト抽出ライブラリ(予測器付き)」です。
ミニバッチで文章からの特徴抽出を行うため、少ないメモリかつ並列処理で文章からの特徴抽出が可能です。カスタマイズ性も高く、他のライブラリをそのまま置き換えることができます。
また、wordbatchというライブラリは文章特徴抽出器の他に、単一ラベル用のオンラインで並列処理できる予測器も備えています。こちらも実際にメモリに乗りづらい大きいデータの予測などに活用できると思われます。

ユースケースとしては、以下の要望に応えられるものかと思います。

* なるべく時間かけずに文章の特徴抽出したい
* メモリの使用量を減らしたい
* オンライン学習を行いたい
* kaggleなどのコンペで良さげな特徴見つけたい

## 何が凄いのか
元々topのkagglerの人が作ったライブラリで、いくつかkaggleのKernelをみていると、このライブラリを使ってかなりの精度を叩いているものがいくつかあります(そんなにうまく行っていないものもありますが....)。個人的に面白いのが、文章分類でないコンペで特徴量を文章みたいに繋げて、wordbatchをかけることで性能が上がるみたいなのがあって非常に興味深かったです。文章系のタスクに加え、ラベル分類や回帰で使ってみるなど、思ったより幅広い使い方ができそうです。

## ライブラリの簡単な説明
内容盛り沢山なので、簡単な概要にとどめます。もし興味がある人は上記のリンクを自分で読むのが一番早いかと思います。

特徴抽出器

* WordHash:　sklearnのHashingVectorizerの並列処理対応版
* WordBag:　Wordhashの亜種。 ハッシュ化された特徴量にIDFやN-Gramの重み付けをする場合など、より柔軟な特徴抽出が可能
* WordSeq:　LSTMベースでシーケンスで単語を特徴量化する
* WordVec:　word -> wordvectorに変換（word2vecみたいなもの？）

オンライン予測器（ただし単一ラベル用）

* FTRL:　kaggleで最も有名なオンラインでの線形学習モデルLinear model Proximal-FTRL。cython化されていて速度も速い、らしい
* FM_FTRL:　Factorization Machinesを入れた推定器。linear effectをFTRLで拾い、factor effectをadaptive SGDで最適化
* NN_Relu_H1:　隠れ層1層、活性化関数ReLUのNeural Network(optimizerはadaptive SGD)
* NN_Relu_H2:　隠れ層2層、活性化関数ReLUのNeural Network(optimizerはadaptive SGD)

## インストール
pipでもインストール可能なのですが、最新版を落とすことができずkaggleのKernelで紹介されていたコードが動きませんでした。基本的に直接インストールすることをオススメします

https://github.com/anttttti/Wordbatch
から本体をダウンロードして、直下のフォルダで下記コマンドを実行します

```
$ CC=gcc-7 CXX=g++-7 python setup.py install
```
おそらく、gccやopenMPなどをインストールする必要があるので注意してください(自分は色々入れていたのでここは分かりませんでした)。あと個人的にドハマりした点として、numpyとcythonを最新版にアップグレードしておく必要があります。基本的ですが依存ライブラリを勝手にupgradeしてくれるわけではないので気をつけましょう。

## 使い方
流石に全部はあれなので一部の部分だけ紹介します(WordHash, WordBag, FTRL, FM-FTRL)。
他のものも同様に利用できるかと思います。

### WordHash
下記のようにして呼び出します

```python
import wordbatch
from wordbatch.extractors import WordBag, WordHash

wb = wordbatch.WordBatch(None, extractor=(WordHash, {"ngram_range": (1, 1), "analyzer": "word",
                                                               "lowercase": False, "n_features": D,
                                                               "norm": None, "binary": True})
                         , minibatch_size=batchsize // 200, procs=8, freeze=True, timeout=1800, verbose=0)
```

データを変換するときは

```python
word_comment = wb.fit_transform(str_array)
X = word_comment.tocsr() # csrにするとき
```

### WordBag

WordHashと同じように利用できます。引数が若干異なるので注意

```python
from nltk.corpus import stopwords
import re

# stopword dict for wordbatch
stopwords_dict = {x: 1 for x in stopwords.words("english")}
non_alphanums = re.compile(u"[^A-Za-z0-9]+")
def normalize_text(text):
    return u" ".join([x for x in [y for y in non_alphanums.sub(' ', text).lower().strip().split(" ")] 
                      if len(x) > 1 and x not in stopwords_dict])


wb = wordbatch.WordBatch(normalize_text, 
                         extractor=(WordBag, {"hash_ngrams": 1, "hash_ngrams_weights": [1.0, 1.0],
                                              "hash_size": 2**28, "norm": "l2", "tf": 1.0,
                                              "idf": None}), procs=8)
```

今回はnormalize_textで前処理する関数を指定しましたが、不要な場合はここをNoneとすれば良いです。

### FTRL
こちらはオンライン予測になります。普通のsklearnと同じように利用できます。

```python

clf = FTRL(alpha=0.01, beta=0.01, L1=0.0, L2=0.0, D=2**28, iters=3, 
            inv_link="sigmoid", e_clip=1.0, threads=4, verbose=0) 

clf.fit(train_X, train_y)
preds = clf.predict(X=valid_X)
```

### FM-FTRL
FTRLのFM版。fmとついているものがこちらで新たに指定できる引数になります。

```python
clf = FM_FTRL(alpha=0.01, beta=0.01, L1=0.00001, L2=0.1, D=1000, alpha_fm=0.01, L2_fm=0.0, init_fm=0.01,
                    D_fm=200, e_noise=0.0001, iters=15, inv_link="identity", threads=4)
```

## まとめ

文章特徴抽出ライブラリWordBatchを紹介しました。まだまだ若いライブラリですが、単純な文章分類にも収まらず色々な使い方ができそうなので是非試してみてください。ちなみにちょっと触った感じだとこのライブラリ、パラメータで相当挙動が変わるので、その辺のチューニングのコツとかも大事になってくるかもしれません。
まだまだ理解が足りないので、その辺のベストプラクティスなど分かったら是非教えてください。

今回のコード群(一部変えてありますが)は[こちら](https://github.com/sh-tatsuno/WordBatch_Example/blob/master/WordBatch_Example.ipynb)にまとめてあります。上記では説明しきれなかったストリーム処理を行っております。チューニングなどが相当甘いので精度上は微妙だったりしますが、参考になれば幸いです。

## 参考文献

主にKaggleのKernalのリンクをまとめます。

WordBatchの公式リンク
https://github.com/anttttti/Wordbatch

Toxic Comment Classification ChallengeでのWordBatchの例 (1)
https://www.kaggle.com/anttip/wordbatch-1-3-3-fm-ftrl-lb-0-9812

Toxic Comment Classification ChallengeでのWordBatchの例 (2)
https://www.kaggle.com/konohayui/attempt-with-wordbatch

メルカリコンペの例
https://www.kaggle.com/anttip/wordbatch-ftrl-fm-lgb-lbl-0-42555

TalkingData AdTracking Fraud Detection Challengeの例(文章系ではない例)
https://www.kaggle.com/anttip/talkingdata-wordbatch-fm-ftrl-lb-0-9769/code