termextractを使って保持データから専門用語を抽出しmecabのユーザ辞書を作成する


```環境
macOS High Sierra 10.13
Python 3.6.5
mecab of 0.996
```

#背景
形態素解析を行うにあたっては、その業界ならではの単語などをまとめた専門用語辞書を作っておくと分かち書きされる際に良い形となりやすいと言うことで、termextractを使ってmecabのユーザ辞書を作ることにした。

#手順
[1.元データを準備する](#1元データを準備する)
[2.mecab形式のインプットデータを作成する](#2mecab形式のインプットデータを作成する)
[3.termextractで複合語を抜き出しユーザ辞書を作成する](#3termextractで複合語を抜き出しユーザ辞書を作成する)
[4.ユーザ辞書のコストを算出する](#4ユーザ辞書のコストを算出する)
[5.ユーザ辞書のバイナリ化](#5ユーザ辞書のバイナリ化)


<a name="#a1"></a>
#1.元データを準備する
単語抽出を行いたいテキストファイルを用意します。
注意点はutf-8で用意するぐらいと思います。

<a id="#a２"></a>
#2.mecab形式のインプットデータを作成する
termextractはインプットするデータ形式としてプレーンテキスト型とmecab型の2つを選択できますが、今回はmecab形式で行うことにしました。
mecab形式ではインプットするデータをmecabのアウトプットの形に生成しておく必要がありますので、まずは元データをmecabを使って、mecab形式に変換します。

````ターミナル
mecab input.txt -o input_mecab.txt -E ""
````

こんなファイルができていればOKです。

````input_mecab.txt
流れ	名詞,一般,*,*,*,*,流れ,ナガレ,ナガレ
が	助詞,格助詞,一般,*,*,*,が,ガ,ガ
悪い	形容詞,自立,*,*,形容詞・アウオ段,基本形,悪い,ワルイ,ワルイ
````

<a id="a3"></a>
#3.termextractで複合語を抜き出しユーザ辞書を作成する
先ほど作ったファイルをインプットファイルとしてtermextractに突っ込んでmecabのユーザ辞書を作成します。コストは後で計算するためここでは入れていません。面倒臭ければ1285,1285,5000など適当な数値にしておいてもいいかもしれません。
また、正しいかどうか分かりませんが、既に複合語としてmecabのシステム辞書に登録されている可能性も考慮して既にある複合語は省く処理も入れています。
（termextractの中身をよく理解していないので、もしかしたら必要のない処理かもしれません。。）

````termexstract.py
#termextractを使ってmecabのユーザ辞書の作成を行う
import MeCab
import termextract.mecab
import termextract.core
import collections

tagger = MeCab.Tagger("-d /usr/local/lib/mecab/dic/mecab-ipadic-neologd")

# インプットするファイルを指定(２．で作成したテキストファイル)
input_text = open("input_mecab.txt", "r", encoding="utf-8").read()

#アウトプットするファイルを指定
f = open("mecab_dic.csv", mode='w')

#bag-of-wordsする
frequency = termextract.mecab.cmp_noun_dict(input_text)
#LR(単名詞の左右の連接情報)を生成
LR = termextract.core.score_lr(frequency,
         ignore_words=termextract.mecab.IGNORE_WORDS,
         lr_mode=1, average_rate=1)
# 重要度が高い順に並べ替えて出力
term_imp = termextract.core.term_importance(frequency, LR)
data_collection = collections.Counter(term_imp)

#termextractで抽出した複合語をmecab-ipadic-neologdの辞書とぶつけ、重複する複合語は取り除く
for cmp_noun, value in data_collection.most_common():
    word = termextract.core.modify_agglutinative_lang(cmp_noun)
    word_list = tagger.parse(word).splitlines()[:-1] #最後のEOSの記述を無視するため-1している
    if len(word_list) != 1: #分かち書きの結果が１行（分かち書きされない）のものは複合語として既に既存の辞書に登録があるとみなし削除
        line = u"%s,,,,名詞,一般,*,*,*,*,%s,*,*" % (word,word) #コストは後から算出する
        #line = u"%s,1285,1285,5000,名詞,一般,*,*,*,*,%s,*,*" % (word,word) #コストを入れておくときはこちら
        f.write(line + "\n")
f.close()
````
<a id="a4"></a>
#4.ユーザ辞書のコストを算出する
ユーザ辞書のコストを算出します。コストの算出はmecab-dict-indexのを機能を使うことで簡単にできます。
mecab関連のファイルをどこに置いたか忘れた場合は`find / -name "*mecab-dict-index*"`で探してください。

また、コスト計算するためにはmodelファイルが必要になりますので、モデルファイル(mecab-ipadic-2.7.0-20070801.tar.gz)をダウンロードします。
https://drive.google.com/uc?export=download&id=0B4y35FiV1wh7MWVlSDBCSXZMTXM

モデルファイルはeuc-jpで作成されていますのでutf-8に変換しておく必要があります。

````ターミナル
tree -L 1 #実行環境
.
├── mecab_dic.csv
├── mecab_dic2.csv #←最終的にこれができる
├── mecab-ipadic-2.7.0-20070801
├── mecab-ipadic-2.7.0-20070801.model


vi ./mecab-ipadic-2.7.0-20070801.model #charset: euc-jp ←6行目のここをutf-8に修正
nkf -w --overwrite ./mecab-ipadic-2.7.0-20070801.model #文字コードをutf-8へ変換

#コストを算出
/usr/local/libexec/mecab/mecab-dict-index \
-m ./mecab-ipadic-2.7.0-20070801.model \
-d ./mecab-ipadic-2.7.0-20070801 \
-u ./mecab_dic2.csv \
-f utf-8 -t utf-8 \
-a ./mecab_dic.csv  #-aはコスト自動計算の引数
````

###参考サイト
[mecabの辞書を自動コストで作成][1]
[1]:https://qiita.com/wakisuke/items/d15b5defc1aad61cc910

<a id="a5"></a>
#5.ユーザ辞書のバイナリ化
最後に作成したユーザ辞書をバイナリ化して設定を行えば完了です。

````ターミナル
#ユーザ辞書のバイナリ化
 /usr/local/libexec/mecab/mecab-dict-index \
 -d /usr/local/lib/mecab/dic/ipadic/ \
 -u ./mecab.dic \
 -f utf-8 -t utf-8 ./mecab_dic2.csv
 
 vi /usr/local/etc/mecabrc
#userdicに作成したユーザ辞書を紐付け
dicdir =  /usr/local/lib/mecab/dic/ipadic
userdic = /usr/local/lib/mecab/dic/userdic/mecab.dic
````

#終わりに
ユーザ辞書を作成した目的は、その後bowやTFIDFをして作る分類モデルの精度を上げるためでしたが結果はありませんでした。むしろ数値が下がりました。。
今回はtermextractで取得した複合語をそのまま全部使ったので必要のない単語も多く含まれてしまったことが原因と思われます。ユーザ辞書の登録前にきちんと見てそれぞれの単語の取捨選択が必要と感じました。

◾️F1値比較
mecab(ユーザ辞書無し):0.87
mecab(ユーザ辞書有り):0.82

###参考サイト
[専門用語（キーワード）自動抽出Pythonモジュールtermextract][2]
[2]:http://gensen.dl.itc.u-tokyo.ac.jp/pytermextract/