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)
解説は気が向いたら。。。