形態素解析を行い名詞の出現回数を調べる

Yahoo デベロッパーネットワーク  を利用すると、形態素解析を行ってくれるWebサービスを利用することができる。

形態素解析が何かとか知りたいプログラマーさんは、

あたりの本がわかりやすいのではないでしょうか。

で、ちょっとアンケート結果みたいなものから単語を抽出したいなーと思い、まぁそんなに件数はないのですが、プログラマたるもの、めんどくさがりやで無ければならない と思い立ち、スクリプトを簡単に書きました。

ちょっと再利用できそうなので、メモもかねてブログに上げとこうかと。

あ、念のためですが、以下は Python のコードです。

# -*- coding: utf-8 -*-
import sys
import getopt
import codecs
import urllib
import urllib2
import xml.dom.minidom

APPID = r'yahoo デベロッパーネットワークでIDを取得してください'
REQUEST_URL = r'http://jlp.yahooapis.jp/MAService/V1/parse'

def main():
    try:
        opts, args = getopt.getopt(sys.argv[1:],"i:o:c:")
    except getopt.GetoptError:
        usage()
        sys.exit(2)
    content_file = None
    output_file = None
    code_set = None
    print opts
    for o, a in opts:
        if o == '-i':
            content_file = a
        if o == '-o':
            output_file = a
        if o == '-c':
            code_set = a
    if content_file == None:        
        usage()
        sys.exit(2)
    else:
        if output_file == None:
            output_file = content_file + ".out"
        if code_set == None:
            code_set = 'utf-8'
    analyze(content_file, output_file, code_set)
        
def usage():
    print 'usage: questionnaire -i {content_file} -o {output_file} -c {code_set}'
    
def analyze(content_file, output_file, code_set):
    sentence = make_sentence(content_file, code_set)
    param_map = {}
    param_map['sentence'] = sentence
    param_map['results'] = r'uniq' #r'uniq'
    param_map['filter'] = r'9'
    request = make_request(param_map)
    
    xml = urllib2.urlopen(request)
    ret = parse(xml)
    
    output_report(output_file, ret, code_set)
    
def output_report(output_file, ret, code_set):
    out_cols_ja = {'count':u'出現数','surface':u'語句'}
    ret.insert(0, out_cols_ja)
    
    out = codecs.open(output_file, 'w', code_set)
    
    for item in ret:
        line = '%s,%s' % (item['surface'],item['count'])
        print line
        out.write(line)

def parse(xml_response):
    result = []
    
    dom = xml.dom.minidom.parse(xml_response)
    root = dom.documentElement
    words = root.getElementsByTagName('word')

    for word in words:
        result_item = {'count':0,'surface':''}
        result.append(result_item)
        for child in word.childNodes:
            if child.nodeName == 'count': # 形態素の出現数
                result_item[child.nodeName] = get_node_text(child) 
            elif child.nodeName == 'surface': # 形態素の表記
                result_item[child.nodeName] = get_node_text(child)
    
    return result
    
def get_node_text(node):
    ret = ''
    for child in node.childNodes:
        if child.nodeType in (child.TEXT_NODE, child.CDATA_SECTION_NODE):
            ret = ret + child.data
    return ret
    
def make_request(param_map):
    param_map['appid'] = APPID
    return REQUEST_URL + '?' + urllib.urlencode(param_map) 
    
def make_sentence(content_file, code_set):
    f = codecs.open(content_file, 'r', code_set)
    return ''.join([l.replace('\r',' ').replace('\n',' ') for l in f])

if __name__ == '__main__':
    main()

こんな感じでパラメータを渡して上げると、テキスト中に含まれる名詞とその出現数を、CSV形式で出力します。

-i は テキストを含んだテキストファイル、-c はそのファイル&出力ファイルのエンコード、-o で出力ファイルを指定できます。

-i "c:\work\test.txt" -c "shift-jis"

Follow me!

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です