wikipediaの各記事における重要な語を抜き出す

wikipediaのある記事に対して、その記事を特徴付けるような語を抽出したい。
まずは、単純にTF(term-frequency:単語の出現頻度)を用いた方法。
まず、事前準備として解析対象となる記事を取得する。

(記事を指定する場合)
http://en.wikipedia.org/wiki/Special:Export
から、タイトル記事を入れてExportを押す。
指定した記事がxml形式でダウンロードされる。

(全記事を取ってくる場合)
英語:http://dumps.wikimedia.org/enwiki/latest/
にアクセス。
(日本語:http://dumps.wikimedia.org/jawiki/latest/

enwiki-latest-pages-articles.xml.bz2をとってくる(容量が一番でかいやつ)。

これをWP2TXTにかけてtxtファイルに整形してもらう。
http://wp2txt.rubyforge.org/
WP2TXTは.txtか.bz2にしか対応していないので、xmlの場合は強引にtxtに直して読み込ませた。
全記事を解析する場合は時間がかかるので、ご注意を。

準備が整ったのでtfを計算するプログラムを書く。
(全記事を取ってきた場合です)

#!/usr/bin/env python
# -*- coding: utf-8 -*-

#wpcount_n.py

import re
import nltk
from eparser import Parser 
from collections import defaultdict
import glob

p = Parser()

files = glob.glob('./wikipedia/wp2txt_out/*')

i = 0
for f in files:
    ff = open(f)
    articles = []       
    title = content = "" #title and content for each  article
    for line in ff: # for each line
        if line[:2] == "[[" and line[-3:] == "]]\n":
            articles.append((title[2:-3],content)) #save latest content 
            title = line #initialize content
            content = ""
        else:
            content += line
    articles.append((title[2:-3],content))#save rest title and article 

    for title,text in articles:

        text = re.sub('\n',' ',text)
        text = re.sub('"',' ',text)
        text = re.sub('\.','',text)
        text = re.sub(',',' ',text)
        text = p.clean(text)
        print text

        splts = nltk.word_tokenize(text) # tokenize by nltk
        splts = nltk.pos_tag(splts) # tagging by nltk
        splts = [ (w,t) for w,t in splts if w not in p.stopwords ]
        splts = [(p.stemmer.stem(w,0,len(w)-1),t) for w,t in splts]

        d = defaultdict(int)
        for splt in splts:
            splt0 = splt[0]
            if splt[1][0] == 'N':
              d[splt0] += 1
        x = sorted(d.items(), key=lambda a:a[1], reverse=True)
        output = open('./wikipedia/tmp/'+str(i)+'.txt','w')
        for k,v in x:
            output.write('%s\t%s\t%s\n' % (str(k),v,title))
        output.close()
        i +=1

(処理の概要)

import re
import nltk
from eparser import Parser 
from collections import defaultdict
import glob

re=regular expression 正規表現
NLTK=natural language toolkit 後述
eparser 後述


(補足1)eparser.pyについて

#! /usr/bin/python
# -*- encoding: utf-8 -*-

from porterStemmer import PorterStemmer
import glob
import re
import os

class Parser:

    #A processor for removing the commoner morphological and inflexional endings from words in English
    stemmer=None
    stopwords=[]

    def __init__(self,):
        self.stemmer = PorterStemmer()
        self.p = re.compile(r"&.{1,5}?;|[!-@[-`{-~]")
        for file in glob.glob(os.path.dirname(__file__)+'/stopwords/*/*.txt'):
            self.stopwords += [ line.strip() for line in open(file).readlines() ]
        self.stopwords.append('the')

    def clean(self, string):
        """ remove any nasty grammar tokens from string """
        string = self.p.sub(' ',string)
        string = string.lower()
        return string

    def removeStopwords(self,list):
        """ Remove common words which have no search value """
        return [word for word in list if word not in self.stopwords ]

    def tokenise(self, string, stem=False):
        """ break string up into tokens and stem words """
        string = self.clean(string)
        words = string.split()
        
        if stem:
            return [self.stemmer.stem(word,0,len(word)-1) for word in words]
        else:
            return words
    
    def tokenize(self, string, stem=False):
        tokenise(self, string, stem=stem)


解説は気が向いたら。。。