fastTextを使って文章ベクトル作成（視覚化もあるよ）

[「fastTextの学習済みモデルを公開しました」](https://qiita.com/Hironsan/items/513b9f93752ecee9e670)を参照して、このモデルを使った日本語の文章ベクトル作成をしてみました。BERTやfastTextなどモデルを作るのは大変なのでこういったものを公開していただいている方には頭が下がります。なので、こういうものを使って何ができるかの様なノウハウはできるだけ共有していきたいと思います。

前回の記事[「BERT（Keras BERT）を使用した文章ベクトル作成」](https://qiita.com/jjking/items/a9fe907f992ccaefbd2a)に続き、[Google Colaboratory](https://colab.research.google.com/)を使って、自分のマシンに色々入れずに手軽にやる方法でやってみたいと思います。

# fastTextで文章ベクトルをどう作るか
方法はともかく文章ベクトル作りを試したい方はここは読み飛ばして次の節に行ってください。
fastTextは単語のベクトルを表現を得るロジックです。単語間の相関関係がベクトルの関係に現れるので近い用法の単語については類似したベクトルが得られます。この単語ベクトルを使って文章のベクトルを得るための方法はいろいろ考案されているようですが、今回は単純に、**文章に含まれるすべての単語のベクトルを求めてその平均を分取ベクトルとする**方法をとりました。この方法だと語順の情報は消えてしまうので係り受けや前後関係が文の意味に影響を与えるような複雑な文章には適さないですが、語順が乱れる会話文や短い質問文のようなものでは十分利用でき、計算も高速であると思われます。

# fastTextのモデルを準備する
まずはfastTextの学習済みモデルを準備します。冒頭で紹介したこちらから入手します。

- [fastTextの学習済みモデルを公開しました](https://qiita.com/Hironsan/items/513b9f93752ecee9e670)

こちらのページに**Download Word Vectors**のリンクがあるのでそちらからファイルをダウンロードしてください。こちらからは普通のMecabの辞書で元文章を単語分割して作成されたモデルがダウンロードできます。NEologdを使って単語分割したモデルも公開されていますが、今回のサンプルでは普通のほうを使います。

ダウンロードしたvector.zipを展開して**model.vec**を取り出します。自分のGoogle Driveの**マイドライブ**の下に**bert**フォルダを作成、その中に**fasttext**フォルダ、**vector**フォルダを作成し、その中に**model.vec**をアップロードします。以下のようになっていれば大丈夫です。今回bertは関係ないのですがサンプルの都合上のフォルダ名なので、、、もし気持ち悪ければリネームしてください。
![googledrive.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/54031/30545106-343b-11a7-9609-69d2ab52af56.png)
# 文章ベクトルを作るプログラムを動かす
[こちらから](https://drive.google.com/drive/folders/1tGiWcYJ6Q3xnZK8nMtTQVDaPNm5pYfq9?usp=sharing)プログラム本体である以下のipynbファイルをダウンロードしてGoogle Driveの任意の場所にアップロードします。

- fasttext_sentencevector.ipynb

あと、今回のサンプルは、最後で文章のリストのそれぞれの文をベクトル化して視覚化する部分もおまけで付けましたので、そこまで試したい方は以下のリストをダウンロードして、Google Driveの**bert**フォルダ直下に格納してください。

- sample_corpus1.csv

[Google Colaboratory](https://colab.research.google.com/)が使えるようにGoogle Driveに設定をして、**fasttext_sentencevector.ipynb**をGoogle Colaboratoryで開きます。開いたらRun all ([Ctrl]+[F9])で実行します。

コードが順に走り、途中一か所「Google Driveをパス/content/driveにマウントする」という部分で以下のように表示されます。Google Driveのファイルを参照するために認証を通す必要がるため、表示されたリンクをクリックし、画面の指示に従ってアクセス許可を与え、最後に表示されたコードを、"Enter your authorization code:" のところに入れてやると先に進みます。

```
Go to this URL in a browser: https://accounts.google.com/o/oauth2/auth?client_id=...

Enter your authorization code:
```

以下コードセルの、`sentence_vector`関数に設定された文章が文章ベクトルを作る対象の文章です。

```
print(sentence_vector('レストランの予約がしたいのですが'))
```

作られた文章ベクトルは300次元になり、こんな感じです。

```
[[ 0.1202     -0.01985181 -0.03682778  0.09241433  0.06526966 -0.03810288
   0.002114    0.031315   -0.07302511  0.05999633  0.12339155  0.036735
  -0.01310033  0.00162244 -0.1747051   0.0203813  -0.07293266 -0.16425289
        ...
  -0.113902    0.07032856  0.00790416 -0.05663266 -0.00517633  0.0051248
  -0.04521288 -0.13712189 -0.17047666 -0.01394678  0.03347553  0.09704111
  -0.04956407 -0.10511766 -0.06996578 -0.016097   -0.07823177 -0.06531233]]
```

うまくうごきましたでしょうか？
引数を書き換えて、このコードセルを再度実行すると文章ベクトルが再計算され出力されます。

# 質問文リストの文章ベクトルを視覚化
おまけとして、質問文のリストの各文章のベクトルを求めて、グラフ上にプロットし視覚化してみましょう。この質問文リストは質問の種別ごとに分類されており`category`に質問種別の番号が設定されています。

```cs
category,input
1,お弁当の配達はお願いできますか？
1,弁当を配達してもらえる？
1,お弁当はやってますか
1,会社にお弁当を届けてほしい
1,弁当はありますか
1,ランチの宅配はある？
1,宅配してもらえますか
1,食事を配達してもらえる？
1,宅配サービスやってますか
2,ペットを連れて利用できますか？
2,ペット同伴してもいいですか
2,ペットは一緒に入れる
2,犬を連れて入れますか
2,犬を入れてもいいですか
2,犬と一緒に利用できるか
..
```

各質問文のベクトルを求めた後に`category`で色分けしてプロットしてみます。質問文のベクトルは300次元あるのでt-SNEを使って2次元に圧縮してプロットしてみるとこんな感じです。質問リストは30カテゴリほどありますが全てに色付けすると見にくくなるので、そのうち10カテゴリだけ色を付けて残りは黒にしてみました。同じ質問種別は比較的固まっていることが分かります。すなわち近い意味の質問文は近しい文章ベクトルになると言えるかと思います。
![plot.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/54031/1817428d-3062-ba92-f7fc-c2c8930fa4d2.png)

# はまったところ
ある日を境に急にmecabをロードするところでエラーが出てくるようになってしまいました。理由が全く分からなかったのですが、参考文献のおかげで原因が分かり、mecab側のアップグレードによるものと分かりました。そのためサンプルでは特定のバージョンのmecabを使うようにしています。

```
error message: [ifs] no such file or directory: /usr/local/etc/mecabrc
```

# 参考文献
こちらのドキュメントを参考にさせていただきました。

- [fastTextの学習済みモデルを公開しました](https://qiita.com/Hironsan/items/513b9f93752ecee9e670)
- [mecab ipadic-NEologd を Google Colaboratory で使う](https://qiita.com/Fulltea/items/90f6ebe6dcceaf64eaef)
- [mecabrc が見つからないというエラー](https://medium.com/@jiraffestaff/mecabrc-%E3%81%8C%E8%A6%8B%E3%81%A4%E3%81%8B%E3%82%89%E3%81%AA%E3%81%84%E3%81%A8%E3%81%84%E3%81%86%E3%82%A8%E3%83%A9%E3%83%BC-b3e278e9ed07)

コード説明を追加した改訂記事、ベクトルの視覚化の記事を公開していますので、こちらもぜひご覧ください。

- [fastTextを使用した文章ベクトル作成（コード説明あり）](https://www.enoki.ifocus-network.com/tech-8/)

# おわりに
できるだけ簡単に最短手順で文章ベクトルを作る方法をご紹介しましたが、うまくいかなかったなどあればコメントください。文章がベクトルにできると使い道がいろいろ広がりそうです。BERTもいいですがfastTextはモデルのサイズも小さく軽いのがとてもいいですね。

普段はこちらで自然言語やAI関連の製品開発をしています。
fastText以外の技術も使っていますのでAIや機械学習のご相談あればぜひご連絡ください。
→  [アイフォーカス・ネットワーク株式会社](https://wwww.ifocus-network.com/)