2008-05-04

日本語テキストのトピック分割

先日からcodereposに置いている自動要約モジュールに、日本語テキストのトピック分割のソースをコミットしました。
(->そのソース)

このスクリプトでは、与えられた日本語のテキストを、トピックごとに分割する機能を提供しています。

基本的には論文"Advances in domain independent linear text segmentation"を参考にしています。
この論文では
1. 文ごとにTFベクトルを計算し、
2. そのベクトル間でcos正規化された内積を計算して文間の類似度を算出、
3. 近接する文同士の類似度の変化具合を見て、トピックの変わり目を決定。
という方式をとっています。
ですが、今回の実装では、上記を日本語にも適用するためにさらに以下の改良を加えています。

動詞も使うことにした。


日本語のテキスト、特にブログの記事などは、名詞だけでなく、「節約する」とか「怒る」とかの動詞も考慮にいれたほうがよかろうと思い、動詞も使っています。ただし、動詞は活用しますので、mecabでの処理結果の品詞情報の行から動詞の原型を取得して使うことにしました。
(->対応するソースの部分

表記揺れ対策


原論文では英語のporter stemmingをしていましたが、日本語では独自の表記揺れ対策をしなければいけません。
表記揺れ対策には以下の方針をとりました。

1. カタカナ語は地道に辞書を作る。
カタカナ語の表記揺れ辞書データは本職で半自動生成したことがありますので、近いうちに作ろうと思います。大量の生テキストデータが必要ですので、どこかからテキストを取得せねばなりません。wikipediaデータでもいいかもしれませんが、できればあんなきれいな文章ではないほうがいいので考えます。
(->対応するソースHyokiyureData.py)

2. 漢字の単語はunigramも生成する
名詞&未知語の場合のみ、漢字の単語の表記揺れは、その語のunigramもTFカウントすることで対応します。
例えば、通常「人」と「人々」は異なる語と認識されてしまいますが、「人々」の方を文字単位で分割し、「人」と「々」それぞれについてもカウントすることにより、「人」と「人々」が互いに多少は類似していると判定できるようになります。
(->対応するソース)

語の重みのバリエーション


語の重みを以下のように変えて計算しています。
* 名詞、未知語: 1語 = 重み1
* 名詞、未知語unigram: 1語(1文字) = 重み0.3
* 動詞: 1語 = 重み0.5
これは、一文でTFベクトルを作っても、たいていはTF=1の語ばかりで、あまりその文の特徴を表しているとも思えませんでしたので、unigramや動詞も考慮に入れた上で、それらの重みの間に差を付けることで、文の間により特色の違いをだせないかという試みです。検証してませんが、まあ、見たかんじ結果がよくなったように思うので、ひとまずこれで行きます。
(->対応するソース)

TFベクトルではなく、TFIDF的ベクトルを使用


ブログ記事のような中程度の長さの文を扱うことを想定していますので、より文の間の特徴を鋭く認識したほうがいいかと思いました。
そこで、文全体でまんべんなく頻出している単語の効果を間引くために語が現れた文の数の逆数をかけることで、ベクトルの重みを調整しています。
(->対応するソース


まだまだ先は長いですが、こつこつ作って行きます。