Pythonでtf-idf その二

の続きです.といってもあとはコードを書くだけだったので,書きました.ひたすらfor文でループを回しているので,とても遅そうですが….まあ今回は動けばいいやということで.
実行速度が気になるとコメント貰ったので,関数の実行時間をはかるスクリプトも書いてみました.
自分のブログエントリ10個,合計文字数8000字程度で,0.04秒で解析できました.そのうち,もっと大きなデータを使って計測してみようと思います.
しかし,もっと適切な課題を見つけてコード書かないとなぁと痛感しました.


以下,最終的なコードです.

import MeCab
import time
import math 

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

def listToDict(wordlist):#配列を辞書に変換.配列の要素をキーに,要素の個数を値として返す
    result={}
    for i in wordlist:
        if result.has_key(i):   
            result[i]+=1
        else:
            result[i]=1
    return result

def timing(f):#関数の実行時間計測のためのデコレータ
    import time
    def new_f(*args,**kwds):
        t=time.time()
        result=f(*args,**kwds)
        print('%s: %ss'%(f.func_name, time.time()-t))
        return result
    return new_f

@timing
def tfIdf(worddict):#文書名をキーに,文書を値とした辞書を引数として渡すと,tfidfを返す関数
    docNumber=len(worddict)
    allNounsList=[]
    tfIdfList={}
    idfList={}
    for key,value in worddict.items():
        nouns=extractNouns(value)
        allNounsList+=nouns
        tfIdfList[key]=listToDict(nouns)#文書ごとのtfの算出
    allNounsList=set(allNounsList)
    for n in allNounsList:
        count=0.0
        for value in tfIdfList.values():
            if n in value:
                count+=1
        idfList[n]=math.log(docNumber/count)#idfの算出
    for doc,tf in tfIdfList.items():
        for nouns in tf:
            tfIdfList[doc][nouns]=tfIdfList[doc][nouns]*idfList[nouns]#tfの値をtfとidfの積に置き換え
    return(tfIdfList)

 今回久しぶりにコードを書くので,プログラミングの話題を扱うブログなどでよく取り上げられて気になっていたSublime Text: The text editor you'll fall in love withを使用してみました.*1
参考にした情報はこのあたり.

PythonRubyをエディタ上で実行できたり,複数箇所の同時編集をする機能は便利だなぁと思いました.また,インターフェイスは英語ですが,日本語の情報も多く,Mac/Windows/LinuxとOS環境を選ばないのもいいですね.これからコードを書く頻度によっては購入してもいいかなと感じています.円高なうちに….

*1:シェアウェア$59,試用期間あり