概要
今回はテキストコーパスから用語を自動抽出する技術である、AutoPhraseを紹介したいと思います。
この技術の特徴は対象コーパスに対して人手アノテーションが不要であるという点です。
論文リンク: [1702.04457] Automated Phrase Mining from Massive Text Corpora
Githubレポジトリ:GitHub - shangjingbo1226/AutoPhrase: AutoPhrase: Automated Phrase Mining from Massive Text Corpora
日本語での利用法
技術の詳細に移る前に、日本語でAutoPhraseを試すための方法について紹介したいと思います。
幸い著者らによる実装が公開されていますが、新しい言語でAutoPhraseを利用するにはストップワードのリストや知識ベースから抽出した用語リストなどの必要なファイルを準備する必要があります。
これらをWikipediaやGinzaを利用して作成済みの実装をGithubにアップロードしましたので、ここではこちらの実装を利用して実験を行います。
準備
まず前提となる環境を整えます。
sudo apt install g++ openjdk-8-jdk curl
続いてコンパイルなどを行います。
bash compile.sh chmod 755 tools/treetagger/bin/tree-tagger
入力コーパス
入力コーパスは各行に1つの文章が記述されたテキストファイルの形にしておきます。
今回は実験用としてAPIを通して取得した2018年の国会議事録コーパスを利用しました。
実行
以下のコマンドによりAutoPhraseによる用語抽出を行います。
MODEL=model/kokkai RAW_TRAIN=corpus.txt THREAD=$(nproc) ./auto_phrase.sh
設定する環境変数の意味はそれぞれ以下の通りです。
非常に大きなコーパスに対して処理する場合:
12GBほどのコーパスに対して上記処理を行おうとしたところ、以下のエラーが表示されてしまいました。
terminate called after throwing an instance of 'std::bad_array_new_length' what(): std::bad_array_new_length ./auto_phrase.sh: 129 行: 152487 中止 (コアダンプ) ./bin/segphrase_train --pos_tag --thread $THREAD --pos_prune ${DATA_DIR}/BAD_POS_TAGS.txt --label_method $LABEL_METHOD --label $LABEL_FILE --max_positives $MAX_POSITIVES --min_sup $MIN_SUP
issueでやり取りされているように、この場合はsrc/utils/parameters.h
の#define LARGE
の箇所をコメントアウトする必要があるようです。
出力
実行後MODEL
に指定したディレクトリが作成され、内部に様々な出力ファイルが保存されています。主に利用することになるのは以下の2つかと思います。
Autophrase_multi-words.txt
- 複数単語により構成される用語リスト。スコアが大きい順に並んでいる。
Autophrase_single-word.txt
- 単一の単語により構成される用語リスト。同じくスコアが大きい順に並んでいる。
実際に国会議事録コーパスで得られた用語について確認すると、スコア上位と下位はそれぞれ以下のようになっています。実際に用語らしい単語列が用語として選ばれていることがわかります。トークナイザーによって複数単語に分かち書きされてしまっても、コーパス中で用語としてまとめて使われる傾向のある単語列をこのように抽出できる点がAutoPhraseの利点です。
0.9672302699 退 所 0.9670377906 小売 店 0.9667992563 非違 行為 0.9667326281 留置 権 0.9666839416 皆 伐 0.9666048674 臨床 研修 0.9665188348 行方 不明 0.9664195190 名誉 校長 0.9663571678 言葉 遣い 0.9663410581 国庫 補助 0.9661804795 関税 撤廃
0.0112053909 を 講ずる こと が 0.0112053909 で いる から 0.0112053909 し た と 言っ て 0.0112053909 を 評価 を し 0.0112053909 を 知っ た の 0.0112053909 の は 事実 で 0.0112053909 で 変わっ て 0.0111783639 が 認識 さ れ 0.0110249359 で あっ 0.0100696418 なし で
コーパスのアノテーション
学習されたモデルによって、コーパスに対して用語箇所のアノテーションを行うこともできます。コマンド例は以下の通りです。
MODEL=model/kokkai TEXT_TO_SEG=corpus.txt HIGHLIGHT_MULTI=0.5 HIGHLIGHT_SINGLE=0.7 ./phrasal_segmentation.sh
指定する環境変数の意味は:
MODEL
TEXT_TO_SEG
- 分割対象のコーパスのファイルパス
HIGHLIGHT_MULTI
,HIGHLIGHT_SINGLE
アノテーション結果
MODEL
で指定したディレクトリ以下に、segmentation.txt
というファイル名でアノテーション結果が出力されます。
- この形式のファイルから用語が1単語になるよう分かち書きを行う方法について記事を書きました。よろしければこちらもご覧ください。
具体例は以下の通りです。<phrase></phrase>
のタグにより用語部分がアノテーションされています。(オリジナルの文章は『国会会議録検索システム』により収集した文章であり、2018/6/1の『参議院沖縄及び北方問題に関する特別委員会』の議事録より抜粋したもの。)
○<phrase>国務大臣</phrase>(<phrase>福井照君</phrase>) OISTにつきましては、<phrase>世界最高水準</phrase>を目指して<phrase>科学技術に関する</phrase><phrase>教育研究</phrase>を推進しております。その中で、<phrase>沖縄</phrase>の特性や<phrase>資源</phrase>を生かした<phrase>研究</phrase>を行っております。例えば、<phrase>サンゴ</phrase>の保全につながる<phrase>研究</phrase>、<phrase>サンゴ</phrase>を食い荒らす<phrase>オニヒトデ</phrase>の<phrase>全</phrase><phrase>ゲノム</phrase>解読に成功いたしまして、<phrase>サンゴ</phrase>の保全につながる<phrase>研究</phrase>を実際に実施しているところと伺っております。また、OIST<phrase>発のベンチャー</phrase><phrase>企業</phrase>、たんぱく質<phrase>分子構造</phrase>の<phrase>解析</phrase><phrase>サービス</phrase>を提供する<phrase>企業</phrase>でありますけれども、が<phrase>誕生</phrase>しているほか、県内の小中学生や高校生を<phrase>対象</phrase>に<phrase>科学</phrase><phrase>教室</phrase>を行うなど、<phrase>沖縄</phrase>の<phrase>人材</phrase>育成に資する<phrase>取組</phrase>も行っており、<phrase>沖縄</phrase>の振興に貢献していると<phrase>認識</phrase>をしてございます。 OISTはまだ<phrase>開学</phrase>から<phrase>日</phrase>が浅い<phrase>大学院大学</phrase>でございます。引き続き、<phrase>教育研究活動</phrase>を深化させることにより、<phrase>沖縄</phrase>の振興に<phrase>一層</phrase>貢献いただくことを<phrase>期待</phrase>しております。
結果を見るとおおむね良さそうですが、「OIST」が用語として認識されていなかったり「発のベンチャー」のようなおかしなフレーズが用語として認識されてしまっているところなどが気になります。この手法は複数単語の用語の方が強みがあるようなので、トークナイザ部分の改良などで改善する余地があるのかもしれません。
技術紹介
ここからは興味のある方へ向けてAutoPhraseの手法の詳細について書いていきたいと思います。基本的に原論文に書かれている内容となります。
そもそも用語とは?
AutoPhraseでは抽出対象である用語 (quality phrase)を以下の4条件を満たす単語列であると定義しています。
- 頻出する (popularity)
- コーパス中に十分な頻度で出現している。
- 偶然の産物でない (concordance)
- 用語中の単語がたまたまその順序で出現しているわけではない
- 情報的に価値がある (informativeness)
- 特定のトピックや概念を表現している
- 意味的に完全である (completeness)
- 文中において意味的に解釈できる完全な要素となっている
- たとえば、より長い用語(New York)の一部分 (York)は、それ単体で意味が通らなければ用語でない
AutoPhraseの処理の流れ
以上で定義された用語を抽出するためのAutoPhraseの処理の流れを追っていきます。
AutoPhraseの処理はおおまかに以下のようになっています:
- 用語候補の抽出 (candidate selection)
- 頻度がある閾値(例えば30)より大きく、単語列としての長さが一定以下(例えば6以下)の単語列を候補として抽出します
- 単語列が用語であるかの評価モデル、phrase quality estimator、を学習する
- コーパス中の各文を適切な分割(segmentation)に区切る (phrasal segmentation)
- 適切な分割とは、 私 | は | 大手食品メーカー | に | いま | す のように、用語がそれ単体で1つのユニットになっているような分割です
- phrasal segmentation後の単語列頻度(その単語列がそのままsegmentとなった頻度)を用いて特徴量を再計算し、phrase quality estimatorを再学習する
このうちcandidate selectionは頻度情報を用いることでpopularityの条件を担保し、phrase quality estimatorは統計的な特徴量を用いることでconcordance, informativenessの条件に合致する用語をフィルタリングします。そしてphrasal segmentationは用語ごとに区切ってから頻度情報を計算し直すことでcompleteness条件を満たす用語をフィルタリングすることにつながります。
Phrase Quality Estimatorの学習について
Phrase Quality Estimatorは与えられた単語列が用語として抽出されるべき単語列かどうかを分類するモデルです。このモデルは機械学習によってデータから学習されます。
訓練データのデータインスタンスにはcandidate selectionにより得られたn-gram集合とその特徴量を利用することができますが、学習のためにはさらに用語として抽出すべき単語列(正例)か、もしくは抽出すべきでない単語列(負例)なのかのラベルをこれらの単語列に付与する必要があります。このラベル付与にかかる人手作業を不要とするため、AutoPhraseは以下のようなアイデアを利用しています。
- 公開されている大規模知識ベースから抽出した用語リストに含まれている場合に正例ラベルを付ける
- 利用した知識ベース中に含まれる単語列は用語として妥当であることと、ある程度大規模な知識ベースを利用すれば手元のコーパスにマッチする単語列がそれなりに存在するであろう、という2つの仮定を置いています
- 例えばWikipediaのタイトル一覧のリストに含まれる単語列(「東京都」、「東京ディズニーランド」)に正例を付与します
- 最初のステップで取り出した用語候補のうち正例とならなかったものを(ノイズを含みうる)負例として扱ってしまう
以上のように自動的にアノテーションされた単語列の集合を訓練データとしてランダムフォレストを学習しますが、それぞれの木の学習にはランダムにそれぞれK個サンプルされた正例と負例を用います。
このようにランダムにサンプルされた訓練データを用いて学習された木をアンサンブルすることで、負例中のノイズ(本来正例として扱うべき単語列)の影響を効果的に軽減することができます。
Phrase Quality Estimatorの特徴量について
特徴量については論文中では詳細は割愛されており、実装を確認する必要がありました。
- 統計的な特徴量
- 単語列ABを分割後の部分単語列の出現確率の積 が最大となるようにA,Bと分割
- point-wise mutual information (PMI)
- point-wise KL divergence (と著者が呼んでいるもの?)
- point-wise mutual information (PMI)
- 単語列 中の単語 について、inverse document frequency (IDF) とのコーパス中の周辺文脈(前後1文)における出現頻度 , 周辺文脈数 を用いる
- 単語列ABを分割後の部分単語列の出現確率の積 が最大となるようにA,Bと分割
- 文字列的な特徴量
- 出現文脈で前後に括弧、引用符がそれぞれあるか、後ろにダッシュがあるか、全ての単語の最初が大文字(capitalizedされている)か
- ストップワードに関する特徴量
- 意味的な完全さを評価する特徴量
- 単語列 W の最初または最後の単語を除いた部分文字列 sub の頻度を用いる
- 単語列 W について、Wの前後どちらかにもう1つ単語が加わった単語列 superをコーパス中から探し頻度を比較 (superは複数ありえる)
- 単語列 W の最初または最後の単語を除いた部分文字列 sub の頻度を用いる
単語列がunigramの場合には部分単語列を用いる特徴量は利用しません。また統計的な特徴量も対数頻度 とindependent ratioのみとなります。(independent ratioは公開実装で定義されている特徴量。頻度の比のようだが、何を表しているのかは読み解けませんでした。)
論文中ではunigramのphrase qualityは常に1にすると記載されていますが、どうも実装を見る限りモデルを用いて予測しているように見えます。このあたりは謎です。
Phrasal Segmentationについて
POSタグを用いた分割手法であるPOS-guided phrasal segmentationについて説明します。
POS-guided phrasal segmentationは、POSタグが付与された単語列 (ただしは単語とPOSタグのペア)と分割時の境界位置集合 に対する生成モデルを仮定します。具体的な生成プロセスは以下の通りです:
- に従い次の境界位置をサンプルする
- ここでPOS quality は境界位置との間に境界が存在しない確率で、境界位置の間のPOSタグによって決まります。
- は2つのPOSタグの間に境界が存在する確率がPOSタグの種類ごとにパラメータとして定義されており、この確率からPOS qualityが計算されます。
- 境界位置の間の単語列が、長さの単語列集合のカテゴリ分布からサンプルされる
- 論文中では多項分布とされていましたが、カテゴリ分布の誤りか?
- 境界位置の間の単語列が用語であるかのindicator関数が、quality phrase estimatorの出力確率によってサンプルされる
以上の生成モデルのパラメータをViterbiアルゴリズムによるsegment分けなどのMAP推定を用いたHard EMによって学習し、そのモデルによって得られた分割を出力します。