designed by www.qrone.org
January
2009
Su Mo Tu We Th Fr Sa
        1 2 3
4 5 6 7 8 9 10
11 12 13 14 15 16 17
18 19 20 21 22 23 24
25 26 27 28 29 30 31
INFOMATION
- 自己紹介
- マイミク申請はお気軽に:-)
- いまいち使い方がわかりません
- 気になるURLをクリップ
- Awstats を使っています
RECENT ENTRIES
CATEGORIES
MONTHLY ARCHIVES
HATENA BOOKMARK
BLOG PET
LICENCE
CONTACT
shin at windy dot ac
文章要約プログラムを書いてみよう!
Category Archive.
2004年6月14日
文章要約プログラムを書いてみよう! その5 ~レポートをupload~ このエントリーを含むはてなブックマーク

その昔に書いたエントリ『文章要約プログラムを書いてみよう!』へのフォロー。ひさしぶりに「マイドキュメント」を整理していたらあの課題で書いたレポートが出てきたので、公開しておこうと思う。卒論締め切りまぎわのてんぱってた時期にやっつけ仕事で書いたもので、あまり良い出来ではありませんけど。

今年、古郡先生の『自然言語処理論』を取るひとは、よかったら参考にしてください(……そもそも、こんなページを見つけてくれるのかが疑問だけど)。もちろんそうでないひとも、ご自由にお持ちくださいませ:-)

 

http://www.seman.cs.uec.ac.jp/~shin/blog/
archives/SummaryMaker_report.doc

2003年12月25日
文章要約プログラムを書いてみよう!
 その4 ~実装、そしてより優れたシステムにするために~ 
このエントリーを含むはてなブックマーク

 TF-IDFとChasen、この2つがあればなにも問題はない。好きな環境と好きな言語を選んで、レッツ・トライ。最後に、あなたの作る文章要約プログラムをより優れたものにするためのアイディアを箇条書きにして紹介し、僕の書いたコードを恥ずかしながら公開して、この文章を終わりにする。
 
 
 ・より優れたコーパスを使う(難易度C)
  その2で書いたように、僕の作ったプログラムでは、『Yahoo! ニュース』に存在するHTMLをスパイダーでかき集め、コーパスとして使用した。正直、コーパスとしてのクオリティは高いとは言えない。
 まず、コーパスとしては文章の総量が小さい。HTMLで50MB、日本語の文章を抜き出すと10MBあるかないかというところ。それに加えて、単語の偏りも大きい。たった一つのサイトから引っ張ってきた文章であることが問題なのはもちろんだが、さらに、ある時点での写像になってしまっているのがまずい。たとえば、「フセイン」が全体の8%もの文章に登場している。明らかに多すぎる。
 もっと優れたコーパスを蒐集し、それをIDFの算出に使うことができれば、文章要約の精度を向上させることができる。というわけで、その気があるなら、がんばってHTMLをかき集めて、でかくて偏りのないコーパスを作ってみましょう。ちなみに、こんなレポートごときに使うことはあり得ないけど、お金を出してナイスなコーパスをゲットすることもできます。別にコードを書いたり頭を使ったりすることじゃないので、難易度はC。

 ・HTMLパーサを組み込む、または作る(難易度B)
  コードを見てもらえばわかるのだが、ぼくの作ったプログラムでは、単語の出現頻度表をつくるときに、HTMLファイルをそのままChasenに喰わせている。そのため、できあがった出現頻度表では、数字("0"~"9")やら、「カスタマイズ」「ヘルプ」やらがほぼすべての文章に登場している。また、明らかに広告のものと分かる単語の出現頻度も高い。
  HTMLをちゃんとパースし、日本語の文章部分のみを抜き出してやるのが望ましい。外部プログラムやライブラリを使っても良いし、自分で実装してもOK。また、非HTMLなコーパスを使うことによってもこの問題は回避できる。難易度はB。

 ・センテンス間の関連性を評価する(難易度S)
  単純に個々のセンテンスを独立したものとして扱ってしまうと、要約された文章に不自然な箇所が発生することがある。たとえば、次のような。
  a.代名詞が正しくつながっていない
  b.「」のような記号の対応が正しくとれていない
  c.接続詞の用法がおかしい
  要約された文章のクオリティを上げるためには、センテンス間の関連性を評価することがどうしても必要になってくる。「この代名詞は何を指しているのか?」。「この接続詞の意味は?」。……でも、これをやるのはとっても難しい。セマンティックな領域に踏み込んでいなかくちゃならないからね。興味のあるひとはチャレンジしてみようって感じ。難易度はもちろんS。ちなみに、僕の書いたプログラムではこの部分はまったく考慮されていない。

 ・粒度を小さくする(難易度S)
  僕の実装したプログラムでは、要約の単位をセンテンス(文)としている。これよりも粒度を小さくすると、つまり、センテンスのレベルで要約を行おうとすると、難易度は飛躍的にアップする。文法の領域に踏み込んで行かなくちゃならない。まあ、これもやってやろうと思う人は触ってみてもいいんじゃない、という感じ。これも難易度はS。
 
 
 
 んで、僕の書いたコードは以下。言語はc#、開発環境はVS.NET2003。
 開発環境を持っててC#が分かるひと、という時点で相当限定されてしまうが。

 http://windy.ac/dat/SummaryMaker.lzh

2003年12月20日
文章要約プログラムを書いてみよう!
 その3 ~Chasen~ 
このエントリーを含むはてなブックマーク

 その2では、単語の重要度を教えてくれる「TF-IDF」というとっても素敵なアルゴリズムを紹介した。「なるほど、これを使えば文章を要約するプログラムなんて簡単に書けるぜ!」って、思った? だけど、TF-IDFを使うには、日本語の文章を単語に分割する必要がある。日本語は英語のように分かち書きされてないので、単語に分割するだけの処理をするのも容易じゃない。文法的な知識と辞書を用意して、膨大な規則をコーディングして行かなくてはならない……というわけで、この部分を自力で実装するのは現実的でない。与えられた文を構成要素に分割する処理のことを、「形態素解析」という。すばらしいことに、これをやってくれるいかしたツールがいくつか公開されている。今回書いたプログラムでは、『Chasen(茶筌)』という形態素解析ツールを使っている。

 試しにやってみよう。次のような文をChasenに喰わせる。

 NTT基礎研究所を経て, 2000年より電気通信大学電気通信学部情報工学科教授(大学院情報工学専攻 教授兼任).

 すると、たとえば次のようなアウトプットを得られる。

 
N	記号-アルファベット
T	記号-アルファベット
T	記号-アルファベット
基礎	名詞-一般
研究所	名詞-一般
を	助詞-格助詞-一般
経	動詞-自立
て	助詞-接続助詞
,	未知語
2	名詞-数
0	名詞-数
0	名詞-数
0	名詞-数
年	名詞-接尾-助数詞
より	助詞-格助詞-一般
電気通信大学	名詞-固有名詞-組織
電気	名詞-一般
通信	名詞-サ変接続
学部	名詞-一般
情報	名詞-一般
工学科	名詞-一般
教授	名詞-一般
(	未知語
大学院	名詞-一般
情報	名詞-一般
工学	名詞-一般
専攻	名詞-サ変接続
 	記号-空白
教授	名詞-一般
兼任	名詞-サ変接続
)	未知語
.	未知語
EOS

 便利至極。この例だと、単語(形態素)とその分類とが、タブで区切って出力される。"EOS"ってのはEnd Of Sentenceの略で、文の終わりをあらわす。所望するならもっと詳細な情報を得ることもできる。
 
 
 
 では、どうやってChasenをプログラムに組み込んだらよいのか。いくつかの方法がある。

  ・Chasenの実行ファイルを呼びだす
   Chasenの実行ファイルをプログラム内から直接叩く。パイプを使うか、ファイルを経由するかして、input&outputを行う。僕が作ったプログラムではこの方法を使っている。
   実装はもっとも容易だが、処理速度は劣るし、Windowsで書くとコマンドプロンプトのウィンドウがぽんぽん出てきて非常に鬱陶しい。実装としては、ライブラリをリンクするほうが望ましい。vectorにある古いバージョンのChasenのアーカイブには、旧VB(Visual Basic6)で作成されたサンプルコードが添付されている。旧VBのコードが読めるなら、これを参考にすると手っ取り早く使い方を習得できるとおもう。

  ・ライブラリ(Windowsなら.dll、Linuxなら.so & .a)をリンクする
   手間を惜しまないならおすすめ。ライブラリの使い方はマニュアルに記載されている。

  ・Chasen.pmを使う。ただしperlのみ
   マニュアルに記載がある。perlで書こうという人は使えるかも。

 Chasenのマニュアルはインストールされたディレクトリの./docにある。一通りのことは書いてあるので、困ったらマニュアルを見よう。

2003年12月19日
文章要約プログラムを書いてみよう!
 その2 ~TF/IDFといっしょ!~ 
このエントリーを含むはてなブックマーク

 さてさて、それでは前回の続きを。

 僕が書いた文章要約プログラム(前回しめしたこいつのことね)、この中核を担っているのが『TF/IDF』というアルゴリズムだ。今回はこれについて解説して行こう。こやつは名前こそ偉そうでなんだか小難しそうだと思ってしまうが、実際には簡潔で扱いやすくそのうえ直感的という、とっても素敵なアルゴリズムだ。数式を書くのが面倒なので、そこんところはURLをこぴぺしてお茶を濁させていただく。このあたりをちぇき。新しいウィンドウで開くとかして適宜参照してください。

 TF/IDFは、文章から重要単語を選択する手法として、情報検索の分野でよく知られているアルゴリズム。まず、その意義を理解しておこう。TF/IDFを使うと、「ある単語の、その文章における相対的な重要性」を算出することができる。……イメージしづらいかしら。TF/IDFにある文章を喰わせて、その文章のなかに登場する単語の一つを指定し、「この単語の重要度はどれくらい?」って訪ねると、「その単語の重要度はこれくらいだよ」ってことを教えてくれるわけ。文章を要約するっていうのは、その文章の中でどこが重要な箇所であるかを判断するということだ。だから、文章要約という目的にTF/IDFはもってこいだといえる。

 このTF/IDF、簡略して式を書くとこんなふうになる。 
  TF/IDF = TF × IDF

 TF。その文章のなかでのその単語の出現率。その文章のなかで、その単語がいっぱい出てくれば出てくるほど大きな値になる。たくさん出てくる単語がその文章を特徴付ける(=重要な)単語である、という考え方に基づいている。
 IDF。その単語がどれだけレアかを表す指標。その単語がたくさんの文書に登場すれば小さな値になり、逆に特定の文章に限定して現れれば大きな値となる。事象の確率が低いほど大きい情報とする、情報量の考え方に基づいている。
 この2つの積を取ったものがTF/IDFとなる。上に貼ったリンクを見てもらえれば分かるとおり、簡潔な式になっているので、実装は容易だとおもう。
 
 
 
 とりあえず、TF/IDFそれ自体についてはこれでお仕舞い。しかし、ここで扱うべき事柄がもう一つある。IDFを算出するには、「すべての文章のなかで、その単語が登場する文章の数」が明らかになっている必要がある。じゃあ、すべての文章っていうのはいったい何なんだろう、という疑問が当然でてくる。それをどうやって定義するのか。それに、定義したとして、実際にそれを蒐集することができなくちゃ意味がない。さて、いったいどうしたら良いんでしょう。
 この、「すべての文章」に、当たるモノをコーパスと言います。今回のプログラムでいうなら、世界に存在するすべての日本語の文章を蒐集し、それを解析、データを作るっていうのがベスト・ソリューション。でも、そんなことは当然できないわけで、一定量の、それも電子化されたデータを蒐集し、それを使うというのが現実的な線になる。このデータがコーパス。適当なコーパスを古郡先生が提供してくれたって良いと思うんだけど、残念ながらそうしてはくれなかったので、自力で蒐集しなくちゃいけません。面倒くさいけど。

 で。その使途にも依るけど、コーパスには求められる条件がある。一般に、おおむね次の2点。
  ・十分な量
  ・ドメインに(できるだけ)非依存であること
 まず、統計的なデータを引っ張り出したいわけなので、統計的なゆらぎが無視できるほど小さくなるだけの総量が必要になる。加えて、ただ量が大きいだけではなく、ドメインに依存しないことが望ましい(たとえばだけど、2chから引っ張ってきた文章をコーパスとして使うことを考えてみましょう。最高に偏ったデータが得られることは想像に難くないでしょう)。

 幸いにして、僕らにはWebがあり、Webからデータをゲットするための便利なツール(スパイダーなどと呼ばれる、自動的にリンクを辿ってデータをダウンロードしてくれるいかしたソフト)がある。適当なスパイダーを入手して、適当なサイトからHTMLをぶっこ抜いてコーパスとするのが手間の掛からないやり方だろう。僕の場合、「Yahoo! ニュース」をコーパスとして使った。また、スパイダーとしては、「インターネットNinja2001 for Windows」の体験版を使った。
 
 
 
 最後に、僕が使ったコーパスと、それを解析して作った単語の出現頻度表を置いておく。自分でコーパスを集めたり、解析したりするのが面倒なひとはこれを使えば楽ができる。

 ・コーパス
 http://www.seman.cs.uec.ac.jp/~shin/blog/corpus.lzh (14.5MB)
 2003/12/06午前5時ごろの「Yahoo! ニュース」のデータ。
 http://headlines.yahoo.co.jp/hl以下に存在するHTMLをすべてダウンロードしたもの。
 
 ・単語の出現頻度表
 http://www.seman.cs.uec.ac.jp/~shin/blog/corpus.txt (228KB)
 上のコーパスを解析したもの。
 1行目に文章数。2行目以下は出現数、タブ、単語。 
 
 
 
 #なんだか、いまいちこなれてない説明になってしまった。なるべく数式や記号を使わないようにしてみたんだけど、そのせいで「ある文章」「その単語」みたいな言葉を多用することになり、逆に分かりにくくなっているという。使うべきところでは記号を使って説明したほうがわかりやすくなるんだなー、ということを学習しましたです。次からはそうします。

2003年12月17日
文章要約プログラムを書いてみよう!
 その1 ~はじまり、はじまり~ 
このエントリーを含むはてなブックマーク

makesummary.PNG

 

 今期受講している「自然言語処理論」で、文章を要約するプログラムを書け、という課題が出た。出たのは良いのだが、まず課題自体の難易度がわりあい高いことと、講義では文章要約とはほとんど関連のないことを扱っており、前提となる知識が与えられていないこと、加えてなにより古郡先生が講義のなかでまったくこの課題について指針を示していないことから、これを容易にこなせるひとはあまりいないと思われる。幸いにして僕は尾内研のゼミで文章要約の基礎的な話題を扱っていたため、とりあえず最低限のものをすんなり書くことができた。そこで、何をどうして良いかまったく目星がつかないというひとのために、簡単な解説を書いておこうと思ったわけ。訳の分からない課題を与えられて途方に暮れているひとの目にこれが止まればいいなーと思いつつ、それでは始めましょう。

 まず、今回、僕が実際に書いたプログラムをお見せするのが良いとおもう。元々のプログラムはC#で書かれているのだが、それをASP.NETに移したものがこれ。ブラウザ上で動かすことができるので、試してみてもらいたい。
 テキストボックスが2つある。上に要約したい文章を貼り付けて、"Make Summary"ボタンを押すと、下に要約された文章が出力される。デフォルトでスポーツ新聞社のWebサイトから拾ってきた記事が貼ってあるので、そのままボタンを押せば動作を見られるようになっている。要約の精度はともかくとして、とりあえずそれっぽい動作ができているということがわかるとおもう。

 このプログラムが文章の要約にどんなアルゴリズムを使っているのか。これを書くのにどんな作業が必要なのか。流れをおおざっぱに書き出すと、以下のようになる。

 1. コーパスを集める
 2. コーパスを形態素解析して、名詞の出現頻度データを作る
 3. 要約したい文章を形態素解析し、名詞のリストとその登場回数を得る
 4. TF/IDFっていうアルゴリズムに通して、名詞ごとの重要度を得る
 5. 4の結果からセンテンスごとに重要度を設定し、上位n%を抜き出して要約とする

 こうやって書かれてみても、予備知識がないと、「なにを言ってるのか意味不明」って感じでしょうか。次節から、個々の事柄について、詳しく説明をしていきます。一通り読み終えれば、とりあえずレポートになるだけのプログラムは書けるようになっているはず……たぶん。乞うご期待。

今日の井原. Since 2003.11.12 by Ihara
614 Entries - 0 Comments