Edited at

Wikificationをしてみよう ~Wikipediaを利用した情報抽出 & 曖昧性解消まで ~

More than 1 year has passed since last update.


この記事で紹介すること


そもそもWikifcationって何よ??

一言で簡単にまとめると、テキスト内の単語をWikipediaの記事と関連付ける作業です。

一例として、このような文があったとしましょう。

2016年現在出場しているのはヤマハ、ホンダ、スズキ、ドゥカティ、アプリリアの5メーカーと、ワークスマシンの貸与等を受けられるサテライトチームとなっている。

これはロードレース選手権からの1節です。

この時、テキスト内に存在している スズキスズキ (企業) に結びつける作業があります。

この作業のことをWikificationと呼びます。


Wikificationの利点は?

このウンコ記事を読むよりももっとスマートにメリットをまとめられている良記事がありますので、そちらもご覧ください。


重要キーワードの抽出

Wikipediaの記事は概ね、キーワードと言っても過言ではないでしょう。

先のテキストの例では2016、ヤマハ、ホンダ、スズキ、ドゥカティ、アプリリア、メーカー、ワークスマシン、貸与などがWikipediaと関連付けることができます。

2016貸与はキーワードなのか?と疑問に思われる方もいらっしゃるかもしれませんが、Wikipedia記事が存在している以上はキーワードとなります。

Wikipediaからゴミワードも含む単語拾って来た後に、うまく処理すれば、キーワード抽出としてはなかなか役に立つのではないでしょうか?


語義曖昧性解消

Wikificationの過程では語義曖昧性解消(以下、WSD)も実施されます。

なぜなら、1つの単語が複数の意味を持つことが、実世界では普通にあるからです。

例えば、きょうはTSUTAYAに行って、つぼみの新作DVDをかりた。というテキストがあったとしましょう。1

この時、単純なテキストマッチだと、つぼみに曖昧性が発生します。AV女優のつぼみ花のつぼみ、はたまたコブクロの曲なのか・・・という複数の可能性が発生します。

もちろん、私たち人間は、「TSUTAYAに行って、DVDをかりているんだから、つぼみ (AV女優)だろう!」と文脈から推測できます。

人間の優れた能力ですね。

このように文脈から正しい単語の意味を選択することをWSDと呼びます。

自然言語処理の1研究分野です。

Wikificationは「単語とwikipedia記事の関連付け」の作業の間に、一緒にWSDもやってしまいます。


機械学習のための特徴量

Wikipediaの利点の一つに、構造化されたデータという点があります。

具体的にはカテゴリ体系と記事テンプレートがその役割を果たしています。

カテゴリ体系と記事テンプレートを使えば、ネットワークグラフを構築することができます。

と、いうことは、文書分類や、クラスタリングのタスクに役に立つ情報をとして使えるわけです。

しかし、残念ながら、Wikipediaはこの目的にあまり向いているとは言えません。

その原因としては下記の点が指摘されています。2


  • 循環、複数パスが発生しているカテゴリ体系

  • 不統一のテンプレート利用

DBpediaWikiDataから発行されているデータの利用を推奨します。3

DBpediaとWikiDataではルールベースではありますが、データクリーニングを実施しています。


で、どうやって使うのよ?

Wikificationができるパッケージを作ったわけです。

パッケージ自体は pip install word2vec-wikification-py でインストールが走ります。(Python3.5.xでしかテストしていません。)

インストールのために、numpy, gensimあたりが必要なので、Anaconda3の利用をオススメします。

そのあと、 このスクリプトsh download_model.sh で実行します。

このモデルファイルがないと動きません。

ここからユースケースによって、やることが分岐します。


平文状態からWikificationしたい、形態素分割した状態からWikificationしたい

まずは以下の2つが必要になります。


  • 形態素分割できる環境

  • MysqlとWikipedia dumpデータ


形態素分割環境

もし、形態素分割できる環境が整っていない方は拙記事を参考程度にご覧ください。


MysqlとWikipedia dumpデータの準備

Mysqlのセットアップに関しては、環境によって大きく違うので、なんとも・・・がんばってください!(まるなげ)

Wikipedia dumpデータに関しては、READMEのこのセクションをご覧ください。


wikificaionを実施する

word2vec_wikification_py.interface.predict_japanese_wiki_names_with_wikidump()の関数を利用します。

戻り値は word2vec_wikification_py.word2vec_wikification_py.models.SequenceScore がリストに格納された状態です。

スコアが高い順に「もっともらしいwikipedia記事名の系列」です。

とりあえず、単語の系列が欲しい方はword2vec_wikification_py.word2vec_wikification_py.models.SequenceScore.get_tokens()で、単語系列を得ることができます。

詳しくはexampleをご覧ください。


Wikipedia記事名の候補一覧はわかっている。WSDをやりたい。

もしかすると、すでになにかしろの手段でwikipediaの記事候補列挙が終わっている方もいらっしゃるかもしれません。

そのような場合は、次の手順でWSDをします。



  1. word2vec_wikification_py.word2vec_wikification_py.models. WikipediaArticleObject を生成する

  2. モデルファイルの読み込みをする


  3. word2vec_wikification_py.interface. compute_wiki_node_probability()を呼び出す


候補情報の作成

まずは候補の一覧情報を作成します。

下のコードのように ヤマハ の場合は ヤマハ 、それとも ヤマハ発動機 と候補のwikipedia記事名を入力します。

この時、記事名を[]で囲うことを忘れないでください。

[]で囲っていないと、著しく精度が低下します。


seq_wikipedia_article_object = [
WikipediaArticleObject(page_title='ヤマハ', candidate_article_name=['[ヤマハ]', '[ヤマハ発動機]']),
WikipediaArticleObject(page_title='スズキ', candidate_article_name=['[スズキ_(企業)]', '[スズキ_(魚)]']),
WikipediaArticleObject(page_title='ドゥカティ', candidate_article_name=['[ドゥカティ]'])
]


モデルファイルの読み込み

一行で完了です。

モデルファイルは entity_vector.model.bin を選択してください。


model_object = load_entity_model.load_entity_model(path_entity_model=path_model_file, is_use_cache=True)


インターフェースの呼び出し

word2vec_wikification_py.interface. compute_wiki_node_probability() を呼び出して、候補情報とモデルファイルを与えます。


sequence_score_objects = interface.compute_wiki_node_probability(
seq_wiki_article_name=seq_wikipedia_article_object,
entity_vector_model=model_object,
is_use_cache=True
)

戻り値は word2vec_wikification_py.word2vec_wikification_py.models.SequenceScore がリストに格納された状態です。

スコアが高い順に「もっともらしいwikipedia記事名の系列」です。

とりあえず、単語の系列が欲しい方はword2vec_wikification_py.word2vec_wikification_py.models.SequenceScore.get_tokens()で、単語系列を得ることができます。


どうやって動作しているの?

まず大前提として、このパッケージは日本語Wikipedia エンティティベクトルの上に成り立っています。

これは東北大乾研究室の鈴木さんの研究成果です。このような素晴らしい研究成果を公表している鈴木さんには頭が下がります。

簡潔に日本語Wikipedia エンティティベクトルの役割を説明すると、「wikipedia記事間のword2vecモデル」です。

ですので、wikipediaの記事間の類似距離が算出できるようになっているという状態です。

では、「お前は何をやったんや?」という話です。

このパッケージでやっていることは下記の通りです。

1. 入力単語からwikipedia記事候補を作成する

2. 記事候補の組み合わせを使ってグラフを作成する

3. グラフから最適なパスを選び出す(最適なパスの計算に日本語Wikipedia エンティティベクトルを使っています。)

2の工程はMeCabの動作過程をご存知の方ならばイメージできるのではないかと思います。

ちょうどCookpadの技術ブログにMeCabの動作過程を紹介した良記事があるので、載せておきますね。

この記事で、「ラティス」と呼ばれている構造が、ここで作っているグラフです。

ちなみに、wikipedia記事情報は日本語wikipediaエンティティベクトルモデルの単語情報に依存します。

ですので、2016年後半以降に出現した新しい記事はwikificationの対象外です。

日本語wikipediaエンティティベクトルも更新がされると嬉しいなぁ(|ω・`)チラ |ω・`)チラ |ω・`)チラ


まとめ



  • Wikificationができるパッケージを作ったよ

  • Wikificationができると、キーワード獲得できたり、語義曖昧性解消できたりするお

  • 東北大乾研ってやっぱすげーとこだな!

  • Wikificationの技術のためにも、Wikipediaへの寄付と記事作成をお願いします。

  • バグ、その他はGithubのIssueにお願いします。






  1. つぼみかわいいですよね(´ω`



  2. このように書くと「独自研究のおそれがあります。出典を明記してください」とWikipediaの世界では指摘されます。  



  3. WikiDataに関しては、いずれ活用法の記事を書きます。