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
参考にした情報はこのあたり.
- Sublime Text 2ってエディタがすごくイイ。Dreamweaverから乗り換えた時の初期設定とか使い方とかをメモ | Mnemoniqs Web Designer Blog
- Sublime Text 2の基礎 (全13回) - ドットインストール
- Sublime Text 2によるストレスフリーな開発環境 | ntcncp.net
PythonやRubyをエディタ上で実行できたり,複数箇所の同時編集をする機能は便利だなぁと思いました.また,インターフェイスは英語ですが,日本語の情報も多く,Mac/Windows/LinuxとOS環境を選ばないのもいいですね.これからコードを書く頻度によっては購入してもいいかなと感じています.円高なうちに….