「Web本文抽出 using CRF」の学習用データの作り方

第2回自然言語処理勉強会@東京が 9/25 に行われます。
前回よりキャパの大きい会場&週末に参加募集が始まったばかりですが、早くもほぼ定員。
自然言語処理に興味のある人はぜひ。でも、計画的なドタキャンは運営の方にご迷惑がかかるのでやめてね。


今度の第2回でも出しゃばって発表させてもらう予定だが、第1回も「Web本文抽出 using CRF」という話をさせてもらった。
CRF(Conditional Randam Fields) を Web ページからの本文抽出に用いるという手法の提案という内容で、実際に動作する Python スクリプトもあわせて公開している。

が、肝心のモデルファイルや学習用データを公開していなかった(公開できるものを作っていなかった)し、学習用データの作り方をドキュメント化していなかったところ、「試したいんですけど」とお問い合わせをいただいてしまって、大あわて。


というわけで返答メールの内容の流用で、非常に簡単な内容だが、せっかくなので公開しておく。
かなり今頃ただよう感じだがご容赦。
TODO: github にもドキュメントをコミット。

      • -

「Web本文抽出 using CRF」概要

  • Webページからの本文抽出を系列ラベリングの問題に定式化
    • htmlを閉じタグおよび<br>で分割、ブロックの系列を得る
    • ブロックの系列にラベル付け(メニュー、本文、コメント、リンクリスト等)
  • 系列ラベリング問題を Conditional Random Fields で解く
    • CRF についての学習と検証が目的。MEMM で十分かもしれない(未検証)
    • ヒューリスティックな工夫は最小限。実用上最も有用な Google AdSense Section Target はあえて無視

「Web本文抽出 using CRF」の学習用データ作成方法

学習データは、一般の Web ページの html を保存したものに対して、状態の変化点の正解を html のコメント形式で埋め込む、という方法で作成します。

例えば本文の開始位置に、以下のコメントを挿入します。

<!-- extractcontent_body -->

extractcontent_??? の部分は系列のラベルとなり、任意の英字列を記述して、ラベルを定義することが出来ます。
中谷の検証では、以下の9個のラベルを使用しました。

head html の <head> 部(テストデータは自動的に head で始まるので、明示は不要)
header ページの表示されているヘッダ部
menu メニューやナビゲーション部
title ページ(記事)のタイトル
body ページ(記事)の本文
comment コメントやトラックバック
linklist リンクリスト部(関連ページや最新記事などの一覧)
cm 広告
footer ページのフッタ部

作成した学習用データは extractcontent/webextract.py で学習を行います。

cd extractcontent
python ./webextract.py -d [学習データを置いたディレクトリ]

これにより学習用データを元に model ファイルが生成されますので、同じく webextract.py でテスト(判別)を行います。

python ./webextract.py -f [テストデータ(単一)のファイルパス]

or

python ./webextract.py -t [テストデータ(複数)を置いたディレクトリ]

テスト結果の出力形式は、正解ありデータ(学習用データと同じフォーマット)の場合と正解なしデータの場合で異なります。


正解ありデータの場合は正解率(正しくラベル付けを行えた率)を出力します。
正解なしデータの場合はブロック(抜粋)の先頭にラベルが負荷されたシーケンスとして出力されます。

      • -

そういえば CRF の Python 実装についての説明も [あとで書く] と言ったっきり書いてないなあ……。