読者です 読者をやめる 読者になる 読者になる

Pythonでtf-idf その一

Pythonで形態素解析 - よしなしごとの続きです.
日本語出力ではまってしまった*1ので,今回はtfの算出までです.idfは週末に終わらせる予定….

tf-idfとは

索引語の重みづけの一種です.

tfは"Term Frequency",idfは"Inverse Document Frequency"の省略で.それぞれ単語出現頻度、逆文書頻度となります.

tfは単語出現頻度そのままです.文書の中に特定の単語がどの程度出現するかというものです.頻度が高いほど,その単語について詳しい情報が書かれていると判断できます.

idfはある単語が全文書のうちどのくらい割合の文書で利用されているのかを表すものです.使用されている割合が小さい単語の方が多くの文書で利用されている単語よりも,その文書の特長を詳しく表していると考えられるます.単純化した計算式としては全文書数を特定の単語が出現する文書数で割ったものになります.*2この値が高いほど特定の文書を検索する能力の高い単語ということになります.*3

tf-idfはtfとidfの積になります.tfで繰り返し出てくる単語に重みを付け.idfで一般的な語の重みを下げるという処理をしていることになります.

tfの算出

以下の処理を行うプログラムを書きます.

  1. 文書を形態素解析
  2. 文書ごとに名詞のリストを抽出
  3. 頻度をカウント
#与えられたテキストをMeCabで形態素解析.名詞のみを抽出してリストで返す.
def extractNouns(text):
    tagger = MeCab.Tagger('-Ochasen')
    encoded_text = text.encode('utf-8')
    node = tagger.parseToNode(encoded_text)
    nouns= []
    while node:
        if node.posid >=38 and node.posid <=60:
            nouns.append(node.surface)
        node = node.next
    return nouns

#リストから辞書を生成.単語をキーに,出現回数をアイテムに保存.TF
def listToDict(list): 
    result={}
    for i in list:
        if result.has_key(i):
            result[i]+=1
        else:
            result[i]=1
    return result

とりあえず先日のエントリPythonで形態素解析 - よしなしごとを解析すると

形態素 7
Python 5
インストール 5
MeCab 5
MacPorts 3

といった結果になります.

名詞の品詞判定を行っているのは

        if node.posid >=38 and node.posid <=60:

です.

MeCabでは品詞ごとに番号がふられており,38から60*4というのが名詞に割り当てられている番号になります.

というわけで次でidfとtf-idfの算出を終わらせます.

*1:ターミナルの出力がうまく日本語で行われず…,ファイルに出力した場合は特に問題ないのでとりあえずそれで進めています.

*2:実際には対数を使ったりするのですが,ここでは省略します.

*3:極端な例でいうと、10個の文書のうち全てに「図書館」という単語が含まれていれば,「図書館」のidfは1(10/10)になります.「ラーニングコモンズ」という単語が2つの文書に含まれていればidfは5(10/2)となり,当然「ラーニングコモンズ」の方が索引語としての重みが高いと言えます.

*4:正確には36から67です.ただ,ノイズになる記号なども解析されていたので,今回は一部対象外にとしました.ただ,私が設定した範囲には何の根拠もありません.どの品詞にどのような番号が割り当てられているかは/opt/local/lib/mecab/dic/ipadic-utf8/pos-id.defを参照すれば分かります.