TermExtractで手軽にキーワード抽出 for Python

TermExtractはテキストデータから専門用語を取り出すためのモジュールらしいです。

[専門用語（キーワード）自動抽出システム](http://gensen.dl.itc.u-tokyo.ac.jp/)

これまではPerlのモジュールとしてしか提供されてませんでしたが、去年末にPython向けにβ版が出たようです。テキスト解析する際の未知語対策として利用できないかと思い、試しに使ってみました。

# インストール

[公式](http://gensen.dl.itc.u-tokyo.ac.jp/pytermextract/)からzipファイルをダウンロードし、適当な場所に解凍して以下を実行するだけです。

```
python setup.py install
```

pipとかcondaからのインストールは残念ながらなさそうです。

# 形態素解析器の出力結果を使ったキーワード抽出

公式には、

> 和文の形態素解析ソフトである和布蕪の形態素解析結果を受け取り、複合語（空白区切りの単名詞）のリストか、ディクショナリ（複合語をキー、複合語の出現回数を値）を返す。

とあります。

渡す形態素解析結果というのは、以下のような形式で渡すみたいです(以下公式のサンプルテキスト)。

```txt:sample.txt
自然言語処理  名詞,一般,*,*,*,*,ダミー,ダミー,ダミー
（ 記号,括弧開,*,*,*,*,（,（,（
り 助動詞,*,*,*,文語・リ,基本形,り,リ,リ
、 記号,読点,*,*,*,*,、,、,、
英 名詞,一般,*,*,*,*,ダミー,ダミー,ダミー
語 名詞,一般,*,*,*,*,ダミー,ダミー,ダミー
: 名詞,サ変接続,*,*,*,*,*
natural 名詞,一般,*,*,*,*,*
language  名詞,一般,*,*,*,*,*
processing  名詞,一般,*,*,*,*,*
・
・
・
```

Mecabでの形態素解析結果が、一行ごとに分かれている形ですね。これを以下のPythonスクリプトで読み込みます。

```py
import termextract.mecab
import termextract.core
import collections

# ファイルを読み込む
tagged_text = open("sample.txt", "r", encoding="utf-8").read()

# 複合語を抽出し、重要度を算出
frequency = termextract.mecab.cmp_noun_dict(tagged_text)
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)
for cmp_noun, value in data_collection.most_common():
    print(termextract.core.modify_agglutinative_lang(cmp_noun), value, sep="\t")
```

出力は以下のような感じになります。

```txt
自然言語処理  31.843366656181313
they  11.618950038622252
意味  10.392304845413264
英語  10.059467437463484
基礎技術  9.361389277282864
統計的自然言語処理 9.085602964160698
解析  8.485281374238571
・
・
・
```

結果はまずまずな感じで、それなりに複合語が抽出できてます(明らかにおかしいケースも多々ありますが・・・)。

ただ、**入力がMecabの形態素解析結果**というのが微妙に使いにくいですね。プレーンなテキスト、もしくは分かち書きしたテキストが渡せれば、もっと使いやすいと感じました。

# 和文ストップワード方式のキーワード抽出

別方式での抽出も提供されているみたいです。その一つである**和文ストップワード方式の専門用語抽出**は、公式で以下のように説明されています。

> 和文のプレインテキストを受けとり、複合語（空白区切りの単名詞）のリストか、ディクショナリ（複合語をキー、複合語の出現回数を値）を返す。複合語の切り出しは「ひらがな」「記号」による文の分割。

ひらがな・記号を区切りとしてトークナイズするってことだと思われます(すみません、ちゃんと読んでません・・・)

こちらは、プレーンなテキストを読み込ませるだけです。

```py
import collections
import termextract.japanese_plaintext
import termextract.core

# ファイルを読み込む
text = open("sample.txt", "r", encoding="utf-8").read()

# 複合語を抽出し、重要度を算出
frequency = termextract.japanese_plaintext.cmp_noun_dict(text)
LR = termextract.core.score_lr(frequency,
         ignore_words=termextract.japanese_plaintext.IGNORE_WORDS,
         lr_mode=1, average_rate=1
     )
term_imp = termextract.core.term_importance(frequency, LR)

# 重要度が高い順に並べ替えて出力
data_collection = collections.Counter(term_imp)
for cmp_noun, value in data_collection.most_common():
    print(termextract.core.modify_agglutinative_lang(cmp_noun), value, sep="\t")
```

出力は以下のような感じになります。

```txt
人工知能  1226.4288753047445
人間  277.1173032591193
知能  185.75930965317852
開発  88.6373649378885
意識  60.00624902367479
人工的 57.917332434843445
可能  55.20783921098894
・
・
・
```

こちらは手軽に使えるのがいいですね。

# 両方式の比較

上記で、形態素解析結果方式とストップワード方式の二つを紹介しましたが、各方式での上位スコア20件を見てみます。

## 形態素解析方式

```
知能  12.649110640673518
計算知能  5.029733718731742
戦闘機 4.7381372205375865
戦闘  4.58257569495584
戦闘機操縦用  4.4406237146062955
計算機 4.426727678801286
人工知能  4.355877174692862
研究  4.0
計算  4.0
自動操縦  3.9359793425308607
学習  3.872983346207417
自動戦闘システム  3.802742902833608
人工知能技術  3.7719455481170785
論理計算  3.7224194364083982
機械学習  3.6628415014847064
記号的AI 3.6342411856642793
自動操縦可能  3.5254687665352296
論理  3.4641016151377544
機械  3.4641016151377544
機械式計算機  3.413473673690155
```

## ストップワード方式

```
人工知能  1226.4288753047445
人間  277.1173032591193
知能  185.75930965317852
開発  88.6373649378885
意識  60.00624902367479
人工的 57.917332434843445
可能  55.20783921098894
研究  51.27978102078589
学習  49.31317739277511
人工知能学会  48.855373993311964
実現  48.748063633179314
理論  40.51490946041508
発表  39.39438441683934
計算知能  35.98098913381863
可能性 34.82443169313786
手法  34.6517883306879
利用  32.82677759681713
知的  31.52620185751426
動作  30.582796407248203
行動  30.582796407248203
登場  29.146786564179294
```

パッと見た感じだと、やはり形態素解析方式のほうが重要なキーワードをハイスコアで抽出できてそうですね。

# 感想
Mecab + Neologdでは検出できない未知語対応の手軽な対応手段として、検討してもいいかも？ただ、形態素解析方式の場合はモジュールとして使いにくので、薄いラッパー的なものを自分で作る必要がありそう。あと、ちゃんと検証も必要。