SlideShare a Scribd company logo
Web本文抽出 using CRF

      2010/7/4
  中谷 秀洋@サイボウズ・ラボ
本文抽出 for Project Gutenberg
• Project Gutenberg (http://gutenberg.org/)
  – 著作権フリーテキストのデータベース
    • 英語が主だが、最近は他の言語もぼちぼち
  – コーパスの宝庫
    • DVDのisoイメージがtorrentで配布されている
• テキストの前後にヘッダ・フッタが
  – 分量多め&規則性無し。カオス!
  – サボると頻出語の上位に“Gutenberg”
パターン1



            それっぽいセパレータ




   ここから本文
パターン2

            それっぽいセパレータ




   ここから本文
パターン3
       それっぽいセパレータ




ここから本文かと思いきや




               本当はここから本文
正規表現による切り出し




http://d.hatena.ne.jp/n_shuyo/20081118/gutenberg
本文抽出 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/)
    • みんなのアクセスログで作るランキングサービス
  – カテゴライズはナイーブベイズで
  – 分類アルゴリズムより
    本文抽出の方が精度への影響が大きい
本文抽出の方が
精度への影響が大きい
ノイズの少ない
コーパス重要
ExtractContentのアルゴリズム概略
• html をブロックに分割
• ブロックごとにスコアを計算
 – 句読点が多い
 – 非リンクテキストが長い
 – 本文っぽくないフレーズが含まれている
• 連続するブロックを「大ブロック」にまとめる
 – スコアの高いものをつなげていく
 – スコアが低いとつながる確率は減衰していく
• スコアが最大となる「大ブロック」が本文

• 「ヒューリスティック」と言えば聞こえがいいが
 – 思いつきのアイデア+感覚による調整
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
                               :
ExtractContentの課題
• 本文おまけ問題
 – 本文とその他の要素(関連記事リンク、コメント)が
   <br> 区切りで続く場合に、それらを分離できない
   • 現行の方式で <br> でも区切ると、1つのブロック長が短く&
     本文ブロック数が増えすぎてスコアの評価がうまくいかない
• 本文がない問題
 – 「本文がない/極端に短い」ページで、出来るだけ長
   いテキスト(≠本文)を抽出してしまう
 – サイドバーに長文のレビューや自己紹介が書かれてい
   て、そっちを抜いてしまうケースも。
• アプリごとに違うよ問題
 – 「本文」として求める範囲がアプリによって違う
   • 分類ではコメント不要。全文検索では必要。
本文がない/短い
ExtractContentのアルゴリズム概略(再)
• html をブロックに分割
• ブロックごとにスコアを計算
 – 句読点が多い
 – 非リンクテキストが長い        ←素性
 – 本文っぽくないフレーズが含まれている
• 連続するブロックを「大ブロック」にまとめる
 – スコアの高いものをつなげていく
 – スコアが低いとつながる確率は減衰   ←転移確率
• スコアが最大となる「大ブロック」が【本文】
                    ←ラベル
  どうみても「系列ラベリング」の問題
系列ラベリング
• 系列に対してラベルを付与する
 – 観測変数と隠れ変数が1対1に対応
• 様々な問題を解くための定式化の一つ
 – 形態素解析
  • 品詞推定           隠れ変数
  • 分かち書き
            代名詞   動詞   不定冠詞   名詞
 – 係り受け
 – 音声認識      I    am      a   pen
 – DNA解析           観測変数
隠れマルコフモデル
     – HMM(Hidden Markov Model)
     – Pettern Recognition and Machine Learning 13章
• 代表的な系列タギング手法の一つ
• 隠れ変数は(1次の)マルコフ連鎖をなす
 – 観測変数は対応する隠れ変数にのみ依存
 – 観測変数間の条件付独立を仮定しない
• 高速な計算方法がある
 – Baum-Welch/Viterbi
• 教師無し
                         ������1            ������2           ������3               ������������
• 生成モデル
                         ������1            ������2           ������3               ������������

                      ������ ������������+1 ������������ と������ ������������ ������������ から ������(������, ������)と������(������|������)を求める
HMM の問題点
• 未知の観測値を扱うことが出来ない
 – p(X|Y) が値を持たないと計算できない
• 非独立/同時に起きうる素性を扱うことが出来ない
 – 「テキストが長い」と「句読点が多い」は同時に起きやすい
 – 「<table>タグを含む」と「<ul>タグを含む」は非独立
• 大域的な最適性を得られない可能性がある
 – 分岐の少ない経路が選ばれやすい
   • Label bias と Length bias
 – 同じラベルを持つ系列の続く確率が指数的に減衰するため
   、「長い本文」が選ばれにくい
   • 局所的な条件付き確率の積によって尤度を求めるため




                                [Kudo+ 2004] より
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


                                         ������
               素性からエネルギー関数を定義、������(������|������)を直接計算する
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)
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行弱
アプリケーション
まずは
Project Gutenbergで
    試してみよう
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
実行例(パターン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
CRFで
Webページ本文抽出
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
実行例(本文おまけ~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
実行例(はてなダイアリー)
[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 = [&quot;<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)
実行例(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.
実行例(しょこたんブログ)
[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.
参考
CRFについて雑感
• CRFはおもしろい!
 – 非独立な素性を好きに設計できる
   • 効果を見込めそうな素性を適当に放り込める
 – 不必要な素性を選んでしまっても性能悪化しにくい
   • 職人技がなくても、それなりのものが作れる
 – 期待していたより精度が高い
   • おもしろいものがいろいろ作れそう!!!

• CRFはまだちょっと難しい
 – こなれた解説がまだない
   • エンジニアにはハードルが高い
 – ライブラリはあるが研究用?
   • アプリからはまだ使いにくい


今回試した範囲での「感想」ですので、あしからず。
CLEANEVAL: 本文抽出コンテスト
         » http://cleaneval.sigwac.org.uk/

• 2007年に行われたWebページcleaning
  (本文抽出)のコンテスト
 – 英語と中国語の開発用データセット(約60件ずつ)
   は現在もサイトで配布されている
   • テスト用データセットは約650件ずつあるらしいが、
     配布されていない?
   • あまり変な(=普通な)データはなさそう。
    – 開発データセット120件中、「本文なし」は1件だけ
    – ファイルサイズの最大は150KB
 – 結果:
   • 中国語は参加1組。精度は18%……
   • 英語は9組。精度の最高値は84%
先行研究
• [Marek+ 2007] Web Page Cleaning with
  Conditional Random Fields
  – CLEANEVALで精度が一番高かったチーム
  – 今回紹介したのとだいたい同じ内容?
     • 4日前に存在に気づいた。あえてまだ読んでない
  – 評価はCLEANEVALのデータセット(英語)に対
    してのみ
     • 他の言語でもうまくいくの?
     • 現実には1MB超えるhtmlとかざらにあるんだけど
• 研究者にそこらへんのモチベーションはない
  – できることはわかってるけどやってない
     • 「2chまとめ系ブログの本文抽出」で論文書けないし
  – エンジニアが がんばる!
機械学習をはじめたいエンジニアへ
• 「機械学習 はじめよう」
 – gihyo.jpにて大絶賛(?)連載中!
   • http://gihyo.jp/dev/serial/01/machine-learning
 – 機械学習を知らない人、勉強してみたい人向け
   • チュートリアルではなく結構硬派に
   • 数式ばんばん
 – 実際に勉強し始めたらつまずきそうなところ
   • 独立とか、近似とか
   • 事前分布とか、事後分布とか
 – 次回第2回は 7/10 ごろ掲載予定
• 機械学習を初めてまだ1年のにわかですが、
  応援・ご教授いただけると嬉しいです
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

More Related Content

Web本文抽出 using crf

  • 1. Web本文抽出 using CRF 2010/7/4 中谷 秀洋@サイボウズ・ラボ
  • 2. 本文抽出 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行弱
  • 22. まずは Project Gutenbergで 試してみよう
  • 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 = [&quot;<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>ぽこ(&lt;●&gt;&lt;●&gt;)メポぽん</DIV><DIV>&nbsp; : ( 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