自然言語解析 in MONMO(中編)
一連の自然言語処理をMONMOちゃん上で実現する試みの第2弾
前回は形態素解析まで行った。
今回は、形態素解析結果から、そのドキュメントの特徴を表す『ベクトル』を算出する、ベクタライズを行う。
monmo-NLProcessing
TF-IDF
自然言語処理における代表的なベクタライズ手法。
考え方
- ドキュメント中、何回も出現する単語はそのドキュメントを表す重要な単語である。
- 多くのドキュメント中に出現する単語は普遍的な単語なので重要ではない。
シンプルだ。
TF-IDFの要素
- N
- 総ドキュメント数
- TF[a]
- ある単語(a)がその1ドキュメント中に現れた回数
- DF[a]
- ある単語が現れたドキュメント数
- IDF[a]
- log( N / DF[a] )
- TF-IDF[a]
- TF[a] x IDF[a]
TF-IDFの例
私はそれを読みたい。
私はそれを書きたい。
"私はそれを読みたい。"={ "私" : 0, "は" : 0, "それ" : 0, "を" : 0, "読み" : 0.3, "たい" : 0 } "私はそれを書きたい。"={ "私" : 0, "は" : 0, "それ" : 0, "を" : 0, "書き" : 0.3, "たい" : 0 }
- N=2
- 『私』『は』『それ』『を』『たい』のIDFはlog(2/2) = log(1) = 0; よってTF-IDFも0となる。
- 『読み』『書き』のIDFはlog(2/1) = log(2) = 約0.3;
- 『読み』『書き』のTFは、それぞれ1
これはあくまで例。
実際はDF=1 の単語は他のドキュメントと結び付けようが無く、無視して良い。
(処理量を減らすために積極的に削るべき)
そんな訳で
今回も、これをMONMOちゃんのMAPジョブを使って大量(?)のドキュメントと品詞を並列に処理する。
monmo-NLProcessing/vectorize
処理順
- tokenize結果からTFを算出
- TFからDFを算出
- DFからIDFを算出
- TF & IDF からTIF-IDFを算出
MongoDBの特性を考慮すると、この順が一番効率が良いだろう。
ベクタライズ(簡易版)
./vectorize.sh -s test.token.sampledoc
- 文書検索
- TF結果を使うと高度な検索が出来る。
./fulltext_search.sh -s test.vector.tf.token.sampledoc -w 'はさみや糊など' -V = META = { "dic" : "analysis.dictionary", "doc" : "test.sampledoc", "doc_field" : "body", "docs" : 73, "normalize" : true, "tf" : "test.vector.tf.token.sampledoc", "token" : "test.token.sampledoc", "type" : "TF" } = DIC = 5212ed32b399b667b8567608 => はさみ 5212ed33b399b667b85685b3 => や 5212ed55b399b667b858df1f => 糊 5212ed32b399b667b85671f3 => など = QUERY = { "value.w" : { "$all" : [ "5212ed32b399b667b8567608", "5212ed33b399b667b85685b3", "5212ed55b399b667b858df1f", "5212ed32b399b667b85671f3" ] } } = DOCS = [ ObjectId("51e64d60c507ed1f43d21400") ] = VERBOSE = * 51e64d60c507ed1f43d21400 : 折り紙出典:フリー百科事典『ウィキペディア(Wikipedia)』移動:案内、検索この項目では、紙を折る遊びについて記述しています。"折紙"、"折り紙"の他の用
ベクタライズ(正規手順)
1.TF
./tf.sh -s test.token.sampledoc -o test.vector.tf.token.sampledoc
2.DF
./df.sh -s test.vector.tf.token.sampledoc -o test.vector.df.token.sampledoc
3.IDF ※要チューニング
./idf.sh -s test.vector.df.token.sampledoc -o test.vector.idf.token.sampledoc
4.TF-IDF
./tfidf.sh -s test.vector.idf.token.sampledoc -o test.vector.tfidf.token.sampledoc
IDFチューニング
このフェーズで色々なチューニングをする。
1.DFとIDFを確認する。
./view_df.sh -s test.vector.df.token.sampledoc ./view_df.sh -s test.vector.idf.token.sampledoc
2.上を確認しながら、limit,threshold,verb-onlyの値を調整する。
- limit
- (DF / 総ドキュメント数)の最大値
- threshold
- DFの最小値
- verb-only
- 名詞だけ抽出
- 切り捨て過ぎの場合はlimit値を下げる
./idf.sh --limit 0.3 -s test.vector.df.token.sampledoc -o test.vector.idf.token.sampledoc
- もっと切り捨てたい場合はlimit値を上げる
./idf.sh --limit 0.5 -s test.vector.df.token.sampledoc -o test.vector.idf.token.sampledoc
- 名詞だけを評価する(大抵の場合、条件を緩くした方が良い)
./idf.sh --limit 0.3 --verb-only -s test.vector.df.token.sampledoc -o test.vector.idf.token.sampledoc
3.結果が良くなるまで繰り返す
4.TF-IDFを再産出
./tfidf.sh -s test.vector.idf.token.sampledoc -o test.vector.tfidf.token.sampledoc
まとめ
これで、ドキュメントをベクトル化する所まで出来たMONMOちゃん。
ベクトルはドキュメントの特徴を数学的にパラメータ化したもので、後は数学的手法によって色々な使い方が出来る。
次回はベクトルのクラスタリングを行う予定。
ドキュメントの関連度や、グループ化などが出来る!!
修正
TF=1 => DF=1 の単語は・・・
ご指摘ありがとうございます!!