大規模日本語ビジネスニュースコーパスを学習したELMo（MeCab利用）モデルの利用方法と精度比較検証


こんにちは、ストックマークの kaerururu (@kaeru_nantoka) です。

今回は、

1 ) 弊社の森長がビジネスドメインのニュース記事で学習し、先日ご紹介した 事前学習済みELMo を Google Colaboratory 上で動かす方法のご紹介

2 ) 単語単位埋め込みモデルと文字単位・単語単位埋め込みモデル、両モデルの精度比較検証

について書いていきます。

精度比較検証のソースコードは私の [GitHub リポジトリ](https://github.com/osuossu8/Utils/blob/master/Introduce_ELMo_Char_and_Word.ipynb) に置いておりますので、よろしければご覧ください。

___

### 目次

1. ELMo とは

2. ELMo を Google Colaboratory で使う

3. 単語単位埋め込みモデルと文字単位・単語単位埋め込みモデル、両モデルの精度比較検証

4. まとめ
___

## 1. ELMo とは

森長の [こちらの記事](https://qiita.com/mkt3/items/9577b63900109ff91665) をご参照ください。

___

## 2. ELMo を Google Colaboratory で使う

```python

# まず GoogleCoraboratory の実行環境上で Google Drive にアップロードしているファイル等を使用できるように同期します。 (マウント)
# 以下のコードを実行すると /content/drive/My\Drive のパスで 'マイドライブ' にアクセスできるようになります。
from google.colab import drive
drive.mount('/content/drive')


# 必要なライブラリをインストールします。
!pip install overrides
!git clone https://github.com/HIT-SCIR/ELMoForManyLangs.git
!sudo python 'ELMoForManyLangs/setup.py' install


# 必要なライブラリをインポートします。
import numpy as np
import pandas as pd

from ELMoForManyLangs.elmoformanylangs import Embedder
from overrides import overrides

```
```
# https://drive.google.com/drive/u/1/folders/1sau1I10rFeAn8BDk8eZDL5qaEjTlNghp
# こちらからダウンロードし、マイドライブにアップロードします。

# ディレクトリ構成図は以下のようにしました。

マイドライブ/
    | 
    ┗ ELMo(MeCab+NEologd,大規模日本語ビジネスニュースコーパス)
            |
            ┝ 単語単位埋め込みモデル
            |
            ┗ 文字単位・単語単位埋め込みモデル
```
```python

word_model_path = "drive/My Drive/ELMo(MeCab+NEologd,大規模日本語ビジネスニュースコーパス)/単語単位埋め込みモデル"
char_model_path = "drive/My Drive/ELMo(MeCab+NEologd,大規模日本語ビジネスニュースコーパス)/文字単位・単語単位埋め込みモデル"


# 検証を簡単にするために以下の分かち書き済みの文章をベクトル化してみます。
sentence = [["私", "は", "かえるるる", "です", "。"]]

# 二文以上を入力とする場合は以下のような形式にします。
#sentence = [["私", "は", "かえるるる", "です", "。"], ["今日", "は", "良い", "日", "です", "。"]]

# 文字ベースモデルを読み込みます。
char_e = Embedder(char_model_path)

# ベクトル化します。
char_e.sents2elmo(sentence)

'''
[array([[-0.4960455 ,  0.23145533, -0.68693703, ..., -1.8998976 ,
          0.12295818,  0.84103614],
        [-0.5553099 ,  0.38843736,  1.1085998 , ..., -1.2523936 ,
          0.3710082 ,  0.47726187],
        [ 0.66378814,  0.7664747 , -0.7795389 , ...,  0.15099259,
          0.5987463 ,  0.25316635],
        [ 1.6014119 , -0.8411358 ,  0.14325786, ..., -1.3320394 ,
         -0.28175083, -0.13953142],
        [ 0.06204838, -0.19042088,  0.03529637, ...,  0.43587098,
         -0.3109077 ,  0.8177585 ]], dtype=float32)]
'''

# 上記のケースだと次元数は以下のようになります。
# (文章数, 文章の単語数, 各単語ベクトルの次元数)
# (1, 5, 1024)


# 単語ベースモデルを読み込みます。
word_e = Embedder(word_model_path)

# ベクトル化します。
word_e.sents2elmo(sentence)

'''
[array([[-0.9826827 ,  1.348456  , -0.10182356, ...,  0.08225163,
          0.2174012 ,  0.19200923],
        [-1.1222464 ,  1.0925405 ,  0.21446343, ...,  0.2424735 ,
         -0.10293475, -1.7148284 ],
        [-0.84306383,  1.1494427 ,  0.45648345, ..., -0.00976461,
          0.15618794,  0.3466216 ],
        [-0.6785489 ,  1.3507837 , -0.01715413, ...,  0.27897805,
         -0.16935939, -1.5792443 ],
        [-0.3811637 ,  1.2148697 ,  1.1317929 , ...,  0.31342533,
         -0.4075661 , -0.68974656]], dtype=float32)]
'''

# 上記のケースだと次元数は以下のようになります。
# (文章数, 文章の単語数, 各単語ベクトルの次元数)
# (1, 5, 1024)


```

以上、簡単に ELMo を Google Colaboratory で使用することができました。

___


## 3. 単語単位埋め込みモデルと文字単位・単語単位埋め込みモデル、両モデルの精度比較検証

入力の文章を単語単位で入力としているモデルが単語単位埋め込みモデルで、入力の文章を文字単位及び単語単位で入力としているモデルが文字単位・単語単位埋め込みモデルです。

単語単位と文字単位のモデルの違いについての説明は、[こちらの記事](https://hironsan.hatenablog.com/entry/how-to-develop-character-based-neural-language-model) が分かりやすいです。


文字単位の入力も受け付けている分、文字単位・単語単位埋め込みモデルの方が、表現力が高そうです。そこで、簡単な検証で精度比較をしてみました。


### 検証設定

+ 検証コード : [GitHub リポジトリ](https://github.com/osuossu8/Utils/blob/master/Introduce_ELMo_Char_and_Word.ipynb)

+ データセット : Livedoor ニュースコーパス
+ タスク : 記事のトピック9値分類
+ 使用フレームワーク : PyTorch 
+ 使用ニューラルネットワークモデル : 双方向 LSTM
+ 形態素解析器 ( janome 利用) (学習には Mecab + Neologd を使用しておりますが、本検証では GoogleColaboratry で簡単に pip install できる janome を利用しております。)
+ 評価指標 : accuracy, f1-score
+ 比較モデル

    ( 1 ) [日本語 wiki 事前学習済み word2vec](http://www.cl.ecei.tohoku.ac.jp/~m-suzuki/jawiki_vector/) (以下 : 日本語 w2v) (単語ベクトルの次元数 : 200次元)

    　　東北大学の乾・岡崎研究室が公開してくださっている「日本語 Wikipedia エンティティベクトル」を使用させていただきました。

    ( 2 ) 日本語 w2v + [日本語 ELMo 単語単位埋め込みモデル](https://drive.google.com/drive/u/1/folders/1bwVauzAykFdkmxPTZ3j071SdqCVOMZwu) (単語ベクトルの次元数 : 200次元(w2v)と 1024次元(ELMo)を連結した 1224次元)

    ( 3 ) 日本語 w2v + [日本語 ELMo  文字単位・単語単位埋め込みモデル](https://drive.google.com/drive/u/1/folders/1qZmVGefIywvgL13lpgG7wJNWJgCUbX9Y) (単語ベクトルの次元数 : 200次元(w2v)と 1024次元(ELMo)を連結した 1224次元)


### 検証結果

|比較モデル|accuracy|f1-score|
|:---:|:---:|:---:|
|(1)|0.811397557666214|0.816528911339967|
|(2)|0.825644504748982|0.827270317269987|
|(3)|0.835820895522388|0.832877040710358|


簡単な検証でも、w2v モデルで獲得したベクトルに ELMo で獲得したベクトルを結合させた方が w2v 単体で獲得したベクトル使用時よりも accuracy と f1-score 両方の指標で 1~2% 程度精度が向上しました。

また、文字単位でも学習している ELMo モデルは未知語でも文字構成からベクトルを生成できるので、未知語が多いタスクでも有用です。本検証で使用した Livedoor ニュースコーパスはビジネスニュース以外のドメインのニュース記事も含まれておりましたので、今回の ELMo モデルにとって未知語が多くあったことから、文字単位で学習させた ELMo を利用したモデルが一番良い精度が出たと思われます。


___

### 4. まとめ

今回は、弊社の森長が先日紹介しましたビジネスニュースで学習した ELMo を GoogleColaboratory 上で使用する方法と、単語単位、文字単位・単語単位の両モデルについて 日本語 w2v モデルに結合した時の効果と精度検証の結果をご紹介しました。

この記事をきっかけに弊社の ELMo モデルを使用して楽しく NLP できる方が増えれば大変嬉しいです。