Contenu connexe Similaire à Web本文抽出 using crf Similaire à Web本文抽出 using crf (20) Plus de Shuyo Nakatani (20) Web本文抽出 using crf2. 本文抽出 for Project Gutenberg
• Project Gutenberg (http://gutenberg.org/)
– 著作権フリーテキストのデータベース
• 英語が主だが、最近は他の言語もぼちぼち
– コーパスの宝庫
• DVDのisoイメージがtorrentで配布されている
• テキストの前後にヘッダ・フッタが
– 分量多め&規則性無し。カオス!
– サボると頻出語の上位に“Gutenberg”
3. パターン1
それっぽいセパレータ
ここから本文
4. パターン2
それっぽいセパレータ
ここから本文
5. パターン3
それっぽいセパレータ
ここから本文かと思いきや
本当はここから本文
7. 本文抽出 for Web
• ExtractContent for Ruby
– Webページの本文抽出を行うRubyモジュール
• http://rubyforge.org/projects/extractcontent/
• http://labs.cybozu.co.jp/blog/nakatani/2007/09/web_1.html
– HTML::ExtractContent
• Perl への移植&改良 by はてな
• Webページカテゴライズのために開発
– Pathtraq (http://pathtraq.com/)
• みんなのアクセスログで作るランキングサービス
– カテゴライズはナイーブベイズで
– 分類アルゴリズムより
本文抽出の方が精度への影響が大きい
10. ExtractContentのアルゴリズム概略
• html をブロックに分割
• ブロックごとにスコアを計算
– 句読点が多い
– 非リンクテキストが長い
– 本文っぽくないフレーズが含まれている
• 連続するブロックを「大ブロック」にまとめる
– スコアの高いものをつなげていく
– スコアが低いとつながる確率は減衰していく
• スコアが最大となる「大ブロック」が本文
• 「ヒューリスティック」と言えば聞こえがいいが
– 思いつきのアイデア+感覚による調整
11. ExtractContentのコード(抜粋)
module ExtractContent
# Default option parameters.
@default = {
:threshold => 100,
:min_length => 80,
:decay_factor => 0.73,
:continuous_factor => 1.62,
:punctuation_weight => 10,
:
# スコア算出
c = (notlinked.length + notlinked.scan(punctu..
factor *= decay_factor
not_body_rate = block.scan(waste_expressions)..
c *= (0.72 ** not_body_rate) if not_body_rate>0
c1 = c * continuous
:
12. ExtractContentの課題
• 本文おまけ問題
– 本文とその他の要素(関連記事リンク、コメント)が
<br> 区切りで続く場合に、それらを分離できない
• 現行の方式で <br> でも区切ると、1つのブロック長が短く&
本文ブロック数が増えすぎてスコアの評価がうまくいかない
• 本文がない問題
– 「本文がない/極端に短い」ページで、出来るだけ長
いテキスト(≠本文)を抽出してしまう
– サイドバーに長文のレビューや自己紹介が書かれてい
て、そっちを抜いてしまうケースも。
• アプリごとに違うよ問題
– 「本文」として求める範囲がアプリによって違う
• 分類ではコメント不要。全文検索では必要。
14. ExtractContentのアルゴリズム概略(再)
• html をブロックに分割
• ブロックごとにスコアを計算
– 句読点が多い
– 非リンクテキストが長い ←素性
– 本文っぽくないフレーズが含まれている
• 連続するブロックを「大ブロック」にまとめる
– スコアの高いものをつなげていく
– スコアが低いとつながる確率は減衰 ←転移確率
• スコアが最大となる「大ブロック」が【本文】
←ラベル
どうみても「系列ラベリング」の問題
15. 系列ラベリング
• 系列に対してラベルを付与する
– 観測変数と隠れ変数が1対1に対応
• 様々な問題を解くための定式化の一つ
– 形態素解析
• 品詞推定 隠れ変数
• 分かち書き
代名詞 動詞 不定冠詞 名詞
– 係り受け
– 音声認識 I am a pen
– DNA解析 観測変数
16. 隠れマルコフモデル
– HMM(Hidden Markov Model)
– Pettern Recognition and Machine Learning 13章
• 代表的な系列タギング手法の一つ
• 隠れ変数は(1次の)マルコフ連鎖をなす
– 観測変数は対応する隠れ変数にのみ依存
– 観測変数間の条件付独立を仮定しない
• 高速な計算方法がある
– Baum-Welch/Viterbi
• 教師無し
������1 ������2 ������3 ������������
• 生成モデル
������1 ������2 ������3 ������������
������ ������������+1 ������������ と������ ������������ ������������ から ������(������, ������)と������(������|������)を求める
17. HMM の問題点
• 未知の観測値を扱うことが出来ない
– p(X|Y) が値を持たないと計算できない
• 非独立/同時に起きうる素性を扱うことが出来ない
– 「テキストが長い」と「句読点が多い」は同時に起きやすい
– 「<table>タグを含む」と「<ul>タグを含む」は非独立
• 大域的な最適性を得られない可能性がある
– 分岐の少ない経路が選ばれやすい
• Label bias と Length bias
– 同じラベルを持つ系列の続く確率が指数的に減衰するため
、「長い本文」が選ばれにくい
• 局所的な条件付き確率の積によって尤度を求めるため
[Kudo+ 2004] より
18. CRF(条件付き乱数場)
» CRF (Conditional Random Fields)[Lafferty+ 2001]
• 系列ラベリングのための識別モデル
– 無向グラフ/マルコフ確率場 [PRML 8章]
– クリークに対しバイナリ素性 ������������ (������������−1 , ������������ , ������)を定義
• 例:「������������ が大文字で始まる」かつ「������������ が名詞」なら1
– ������ ������ ������ ∝ exp ������ ������������ ������
������ ������������−1 , ������������ , ������ より������の推定を行う
• 高速に計算するアルゴリズムがある(Forward/Backward)
• HMMより最適な系列を得やすい
• Mecabで利用 Linear-chain CRF
������0 ������1 ������2 ������3 ������������ ������������+1
������
素性からエネルギー関数を定義、������(������|������)を直接計算する
19. HMM と CRF の相違点
Hidden Markov Model Conditional Random Fields
状態空間モデル マルコフ確率場
(有向グラフィカルモデル) (無向グラフィカルモデル)
生成モデル 識別モデル
教師無し 教師有り
������(������������ |������������ )で記述できる素性 バイナリ素性を自由に設計
������(������, ������)から������(������|������)を計算 ������(������|������)を直接計算
計算量はどちらも O(素性数×状態数^2×系列長) だが、
CRFは素性数が爆発する傾向あり(bigramの素性=状態数^2)
• Vapnikの原理:ある問題を解くとき,その問題よりも難しい問題
を途中段階で解いてはならない
• "When solving a problem of interest, do not solve a more general problem as an
intermediate step. Try to get the answer that you really need but not a more general one."
• http://en.wikipedia.org/wiki/Transduction_(machine_learning)
20. CRFのPython実装
» http://github.com/shuyo/iir/blob/master/sequence/crf.py
• Linear-chain CRF の学習&ラベリング実装
– 1つの素性に1つの観測値
• 簡略化というより
実装開始時の誤解から……
• [Lafferty+ 2001]のグラフが右図だった……
– scipy の BFGS を使ってパラメータを推論
• [Lafferty+ 2001] Forward/Backward
• [Sutton+ 2006] gradient
• L2正則化
– numpy/scipyにできる限り処理させる
• ラベル数=11、素性数=700、学習データの系列長=2500でパ
ラメータ推論に4分
• 系列長=300のラベリングに4秒
• スクリプト言語のわりには?
• 実用より、「読める実装」としての値打ち??
– CRF処理部は 200行弱
23. Project Gutenberg本文抽出 using CRF
• 系列ラベリングの問題に定式化
– テキストの空行でパラグラフに分割
– パラグラフの系列に対し、 3種類のラベル H(ヘッダ)、
B(本文)、F(フッタ)を付与する
• 素性設計(素性数: 188)
– 特徴的なキーワードが含まれているか
• Project, Gutenberg, David Reed, など
– 使われている文字種
• 大文字、数値、記号
– 先頭、末尾
• “*” が続いている、インデントされている
– 行数
• 3行以上ある、2行以上の空行で区切られている
• 学習データ=7(系列長=3300)
• http://github.com/shuyo/iir/blob/master/sequence/pg.py
24. 実行例(パターン3)
• 正しく抽出(先頭が付与されたラベル)
H Project Gutenberg's Etext of Shakespeare's First Folio/35 Plays
H Copyright laws are changing all over the world, be sure to check
H Please take a look at the important information in this header.
不規則な本文開始位置を
: ( 66 paragraphs) 正しく判定
H If you find any scanning errors, out and out typos, punctuation
H David Reed
H Project Gutenberg's Etext of Shakespeare's First Folio/35 Plays
B To the Reader.
B This Figure, that thou here feest put, It was for gentle Shakesp
B B.I. 長い系列でも
: ( 27143 paragraphs) 正しくラベリング
B Cym. Laud we the Gods, And let our crooked Smoakes climbe to
B Exeunt.
B FINIS. THE TRAGEDIE OF CYMBELINE.
F End of Project Gutenberg's Etext of Shakespeare's First Folio/35
26. Web本文抽出 using CRF
• 系列ラベリングの問題に定式化
– htmlを閉じタグおよび<br>で分割、ブロックの系列を得る
– ブロックの系列に9種類のラベル付けを行う
• head, header, menu, title, body, comment, linklist, cm, footer
• 素性設計(647個)
– タグ(a/p/div/...)
– キーワード(Copyright/会社概要/利用規約/など)
– 句読点、日付、アフィリエイトリンク
– テキスト長、リンクされているテキスト長
• 学習データ=15(系列長=2500)
• 素性設計以外にヒューリスティックな工夫はしない
– script/style タグの除去のみ例外として行っている
– Google AdSense Section Targetは無視
• 本文抽出における魔法のアイテム
• http://github.com/shuyo/iir/blob/master/extractcontent/webextract.py
27. 実行例(本文おまけ~Yahoo! Sports)
[head] <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "
[header] <body class="yj950-2"> <div id="wrapper"> <!--- header --->
[header] <div class="yjmth"> <div class="yjmthproplogoarea"><a href=htt
[header] <div class="yjmthloginarea"><strong><a href="https://login.yaho
: ( 29 blocks)
[header] <li title="ニュース" class="active_click"><a href="/news">
[header] <li title="コラム" class="end"><a href="/column/">コラム</
[header] <!---/globalnavi---> <div id="contents-header"> <div id="cat-pa
[title] <!--- body ---> <div id="contents-body"> <span class="yj-guid"
[title] <em>サンケイスポーツ - 2009/7/9 7:52</em> </div>
[body] <!----- article -----> <div class="Article clearfix"> <table
[body] <p> (セ・リーグ、巨人3x-2横浜、11
[body] 一塁ベースを回っても、坂本は下を向いたま
: ( 5 blocks) 関連記事へのリンクを
[body] 「チームにとっても彼にとっても大きな本塁 linklist として正しく分類
[body] 現役時代に何度もスランプを味わった原監督
[body] 【関連記事】<br />
[linklist] ・<a href="http://www.sanspo.com/baseball/news/090709/bsa09070
[linklist] ・<a href="http://www.sanspo.com/baseball/news/090709/bsa09070
[linklist] ・<a href="http://www.sanspo.com/baseball/news/090709/bsa09070
: ( 3 blocks)
[linklist] <!-- anemos --> <!-- /anemos --> <div class="Kejiban"> <im
28. 実行例(はてなダイアリー)
[head] <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
[header] <body> <div id="simple-header"> <a href="http://www.hatena.
: ( 9 paragraphs)
[header] <p class="sectionheader"><span class="sectioncategory"><a hre
コメントを分離
[body] <p><a class="keyword" href="http://d.hatena.ne.jp/keyword/Py
アプリごとに必要なラベルを
[body] <p>でも以下のように書くと、<a class="keyword" hr
[body] <pre class="syntax-highlight"> <span class="synComment"># A, B,
: ( 2 paragraphs)
[body] <pre class="syntax-highlight"> labels = ["<span class="syn
[body] <p>そのせいで以下のようなハマりパターンも
[body] <pre class="syntax-highlight"> <span class="synStatement">def</
[comment] <p class="sectionfooter"><a href="/n_shuyo/20100629/python">
[comment] <!-- google_ad_section_end --> </div>
[comment] <form id="comment-form" method="post" action="/n_shuyo/comment
: ( 14 paragraphs)
[comment] <div class="refererlist"> <div class="caption">
[comment] <div class="refererlist"> <div class="caption"><a
[linklist] <ul> <li><a href="http://d.ha
[linklist] <div class="refererlist"> <div class="caption
: ( 121 paragraphs)
29. 実行例(Yahoo! Japan トップ)
[head] <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "
[menu] <body> <div id="wrapper"> <div id="header"> <div id="masthead"
[menu] <ul id="mhicon"> <li id="mhi1st"><a title="Yahoo! BB" href="r/m
記事見出しや抜粋を
[menu] <li id="mhi2nd"><a title="オークション" href="r/mauc">オ
: ( 30 paragraphs)
linklist として正しく分類
[menu] <li id="clr5"><a href="r/header/color/5/*-http://www.yahoo.co.
[menu] <li id="clr6"><a href="r/header/color/6/*-http://www.yahoo.co.
[menu] <p class="help"><a href="r/mht">ヘルプ</a></p></div> </div> <
[linklist] <hr class="separate"> <div id="contents"> <div id="toptxt"> <u
[linklist] <li id="toptxt2"><a href=s/69879>全国約1000件の花火大莨
[linklist] <li id="toptxt3"><a href=s/69950>新機能は?「ポケモン
: ( 150 paragraphs)
[linklist] <li><a title="Yahoo!ノートパッド" class="second" href="r/p
[linklist] <li><a title="Yahoo!ブリーフケース" class="third" href="r
[linklist] <div id="pbindexbg"><div id="pbindex"> <div id="pbcalendar"><di
[footer] </tr> <tr> <td><a href="f/pbox/clndr/06/27/*-http://calendar.ya
[footer] <td><a href="f/pbox/clndr/06/28/*-http://calendar.yahoo.co.jp/?
[footer] <td><a href="f/pbox/clndr/06/29/*-http://calendar.yahoo.co.jp/?
: ( 101 paragraphs)
[footer] <li><a href="r/fdi">免責事項</a></li></ul>
[footer] <address>Copyright (C) 2010 Yahoo Japan Corporation. All Rights
[footer] </body> <!--http://ard.yahoo.co.jp/SIG=15blcke9p/M=300330001.
30. 実行例(しょこたんブログ)
[head] <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "
[menu] <body id="mainIndex"> <!--bodyTop--> <ul id="amebaBar"> <li id
[menu] <li><a href="http://pigg.ameba.jp/" title="ピグ">ピグ</a></
[menu] <li class="last"><a href="http://blog.ameba.jp/ucs/entry/srvent
: ( 167 paragraphs)
[menu] <p><a href="http://blog.ameba.jp/reader.do?bnm=nakagawa-shoko">
[menu] <!--//.readerMainLink--> <div class="page articlePaging"> <a ti
手強すなよ……
[menu] <!--TopPagingBottom--> <div class="entry new"> <div class="ent
[cm] <!--//.entry_head--> <h3 class="title"><!-- google_ad_s
[cm] <span class="theme">テーマ:<!-- google_ad_section_s
[cm] <DIV>ぽこ(<●><●>)メポぽん</DIV><DIV>
: ( 33 paragraphs)
[cm] <!--//#footer_ad--></div>
[cm] <!--//#sub_main--> </div><!--//#main--> </div>
[cm] <!--//#subFirstContentsArea--> </div>
[linklist] <!--//#firstContentsArea--> <div id="sub_b"> <!--subBTop--> <!--
[linklist] “中川翔子物語~空色デイズ~”連載中<br
[linklist] 原明日美 (著)<br>
: ( 53 paragraphs)
[linklist] <li><a href="http://ameblo.jp/nakagawa-shoko/theme-10014191488.
32. CRFについて雑感
• CRFはおもしろい!
– 非独立な素性を好きに設計できる
• 効果を見込めそうな素性を適当に放り込める
– 不必要な素性を選んでしまっても性能悪化しにくい
• 職人技がなくても、それなりのものが作れる
– 期待していたより精度が高い
• おもしろいものがいろいろ作れそう!!!
• CRFはまだちょっと難しい
– こなれた解説がまだない
• エンジニアにはハードルが高い
– ライブラリはあるが研究用?
• アプリからはまだ使いにくい
今回試した範囲での「感想」ですので、あしからず。
33. CLEANEVAL: 本文抽出コンテスト
» http://cleaneval.sigwac.org.uk/
• 2007年に行われたWebページcleaning
(本文抽出)のコンテスト
– 英語と中国語の開発用データセット(約60件ずつ)
は現在もサイトで配布されている
• テスト用データセットは約650件ずつあるらしいが、
配布されていない?
• あまり変な(=普通な)データはなさそう。
– 開発データセット120件中、「本文なし」は1件だけ
– ファイルサイズの最大は150KB
– 結果:
• 中国語は参加1組。精度は18%……
• 英語は9組。精度の最高値は84%
34. 先行研究
• [Marek+ 2007] Web Page Cleaning with
Conditional Random Fields
– CLEANEVALで精度が一番高かったチーム
– 今回紹介したのとだいたい同じ内容?
• 4日前に存在に気づいた。あえてまだ読んでない
– 評価はCLEANEVALのデータセット(英語)に対
してのみ
• 他の言語でもうまくいくの?
• 現実には1MB超えるhtmlとかざらにあるんだけど
• 研究者にそこらへんのモチベーションはない
– できることはわかってるけどやってない
• 「2chまとめ系ブログの本文抽出」で論文書けないし
– エンジニアが がんばる!
35. 機械学習をはじめたいエンジニアへ
• 「機械学習 はじめよう」
– gihyo.jpにて大絶賛(?)連載中!
• http://gihyo.jp/dev/serial/01/machine-learning
– 機械学習を知らない人、勉強してみたい人向け
• チュートリアルではなく結構硬派に
• 数式ばんばん
– 実際に勉強し始めたらつまずきそうなところ
• 独立とか、近似とか
• 事前分布とか、事後分布とか
– 次回第2回は 7/10 ごろ掲載予定
• 機械学習を初めてまだ1年のにわかですが、
応援・ご教授いただけると嬉しいです
36. References
• [Lafferty+ 2001] Conditional Random Fields: Probabilistic
Models for Segmenting and Labeling Sequence Data
• [Sutton+ 2006] An Introduction to Conditional Random
Fields for Relational Learning
• [Kudo+ 2004] Conditional Random Fieldsを用いた日本語
形態素解析
• [Marek+ 2007] Web Page Cleaning with Conditional
Random Fields
• 岡野原さんの「機械学習による自然言語処理チュート
リアル~PerceptronからCRFまで~」
– http://hillbig.cocolog-nifty.com/do/2008/08/post_040f.html