MeCabにユーザ辞書を追加する。

MeCabを使うと名詞をキーワードとして抜き出すことができますが、デフォルトでは長いキーワードは名詞ごとに分割されてしまいます。

% mecab
攻殻機動隊
攻	名詞,固有名詞,人名,名,*,*,攻,オサム,オサム,,
殻	名詞,接尾,一般,*,*,*,殻,ガラ,ガラ,,
機動	名詞,一般,*,*,*,*,機動,キドウ,キドー,,
隊	名詞,接尾,一般,*,*,*,隊,タイ,タイ,,
EOS

MeCabの辞書に単語を追加することによって、長いキーワードも1つの名詞として抜き出すことができます。

ということで、今回ははてなキーワードWikipediaにある単語を辞書に追加してみました。


0. 辞書にキーワードを追加する方法

MeCabへの単語の追加方法には、システム辞書に追加する方法とユーザ辞書に追加する方法の2種類があります。

システム辞書に追加する場合、解析速度は落ちませんが、システム辞書の再コンパイルが必要になります。

ユーザ辞書に追加する場合、解析速度は落ちますが、システム辞書の再コンパイルは必要ありません。

今回はより簡単なユーザ辞書に追加する方法を試してみました。


1. 手順

・追加したい単語をフォーマットに従って記述したcsvファイルを用意する
csvファイルをユーザ辞書にするためにコンパイルする
・mecabrcにユーザ辞書のパスを追加する


2. 素になるデータのダウンロード

はてなダイアリーキーワードふりがなリストを公開しました
Wikipedia:データベースダウンロード


上記より、ファイルをダウンロードします。

はてなキーワードからはkeywordlist_furigana.csvWikipediaからはjawiki-latest-all-titles-in-ns0.gzをダウンロードしました。

それぞれ前処理として、文字コード変換と解凍を行います。

# 文字コード変換(euc -> utf-8)
% nkf -Ew keywordlist_furigana.csv > hatena_keywordlist.csv

# 解凍
% gunzip jawiki-latest-all-titles-in-ns0.gz  


3. csvファイルの作成

csvファイル作成のために、素データを整形するPythonプログラムを作成しました。

コメントアウトの箇所を入れ替えると、はてなキーワードWikipedia両方のデータを整形できます。

csvファイルに記述する単語のフォーマットとコストは下記を参照しました。

単語の追加方法
MeCab の辞書構造と汎用テキスト変換ツールとしての利用

% vi create_dictionary.py

# -*- encoding: utf-8 -*-
import sys
import re
import codecs
import unicodedata

year = re.compile("[0-9]{4}")
alias = re.compile(ur"_\(.*?\)")
alldigit = re.compile(ur"^[0-9]+$")
ng = [chr(i) for i in range(0,32)] 

def isValid(word):
	if len(word) == 1:
		return False
	if re.search(year, word):
		return False
        if alias.search(word):
                return False
        if alldigit.search(word):
                return False
	for ng_ch in ng:
                if ng_ch in word:
                        return False
	if len(word) == 2 and unicodedata.name(word[0])[0:8] == "HIRAGANA" and unicodedata.name(word[1])[0:8] == "HIRAGANA":
		return False
	for c in word:
        	if not (unicodedata.name(c)[0:8] == "HIRAGANA" or
                	unicodedata.name(c)[0:8] == "KATAKANA" or
                	unicodedata.name(c)[0:3] == "CJK" or
                	unicodedata.name(c)[0:5] == "DIGIT" or
                	unicodedata.name(c)[0:5] == "LATIN"):
			return False
	return True

if __name__ == "__main__":
	argvs = sys.argv
	argc = len(argvs)
	if (argc != 3):
		print 'Usage: # python %s Input_FileName Output_FileName' % argvs[0]
		quit()

	fin_name = argvs[1]
	fout_name = argvs[2]

	fin = codecs.open(fin_name, "r", "utf-8")
	fout = codecs.open(fout_name, "w", "utf-8")
	for line in fin:
		word = line[:-1].split('\t')[1]
		# word = line.rstrip() 
		if isValid(word):
			word = word.lower()
			cost = int(max(-36000, -400*len(word)**1.5))
			fout.write("%s,-1,-1,%d,名詞,一般,*,*,*,*,*,*,*,%s\n" % (word, cost, "はてなキーワード"))
			# fout.write("%s,-1,-1,%d,名詞,一般,*,*,*,*,*,*,*,%s\n" % (word, cost, "Wikipedia"))
	fin.close()
	fout.close()

# csvファイルを作成
% python create_dictionary.py hatena_keywordlist.csv hatena_userdic.csv
% python create_dictionary.py jawiki-latest-all-titles-in-ns0 wikipedia_userdic.csv


3. ユーザ辞書のコンパイル

MeCabのユーティリティを使ってユーザ辞書をコンパイルします。

# コンパイル
% /usr/local/libexec/mecab/mecab-dict-index -d /usr/local/lib/mecab/dic/naist-jdic -u hatena-keyword.dic -f utf-8 -t utf-8 hatena_userdic.csv
% /usr/local/libexec/mecab/mecab-dict-index -d /usr/local/lib/mecab/dic/naist-jdic -u wikipedia-keyword.dic -f utf-8 -t utf-8 wikipedia_userdic.cs

# 移動
% mv hatena-keyword.dic /usr/local/lib/mecab/dic/naist-jdic/
% mv wikipedia-keyword.dic /usr/local/lib/mecab/dic/naist-jdic/


4. mecabrcにユーザ辞書のパスを追加

ユーザ辞書はカンマで区切って指定することで複数認識させることができます。

% sudo vi /usr/local/etc/mecabrc 

# 追加
userdic = /usr/local/lib/mecab/dic/naist-jdic/hatena-keyword.dic, /usr/local/lib/mecab/dic/naist-jdic/wikipedia-keyword.dic


5. テスト

% mecab
攻殻機動隊	名詞,一般,*,*,*,*,*,*,*,はてなキーワード
EOS

無事、キーワードを抜き出すことができました。

新しいキーワードでもお手軽に加えることができるのでオススメです。



[参考]
MeCabの辞書にはてなキーワードを追加しよう
テキストからWikipedia見出し語を抽出