RSS2.0

MeCab の IPA 辞書を UTF8 化する

配布されている MeCab の IPA 辞書は、文字コードが EUC JP になっています。
辞書のビルド時に文字コードを指定できるので、ちょっと試してみる分にはいいのですが、単語を登録しようとしたり、再学習をさせようとすると、文字コードが統一されていないことは障壁になります。

そこで MeCab 推奨の IPA 辞書を UTF8 に変換するツールを書いてみました。
テキストファイルの文字コードを変更するだけなのでシェルスクリプトでもできますが、個人的にのちのち再利用できそうなので python を使っています。


ソースコードはこちら。

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

#################################################################
#
#  MeCab 用の辞書の文字コードを、任意の文字コードに変換する
#
#################################################################

import sys 
import shutil
import os

# http://docs.python.jp/2/library/argparse.html
import argparse

class MecabDictionaryEncoder:
	SUPPORTED_CHARSET = [
 'shift_jis', 'utf-8', 'euc_jp', 'cp932', 'euc_jis_2004','euc_jisx0213',
 'iso2022_jp','iso2022_jp_1', 'iso2022_jp_2','iso2022_jp_2004','iso2022_jp_3',
 'iso2022_jp_ext', 'shift_jis_2004','shift_jisx0213','utf_16','utf_16_be',
 'utf_16_le','utf_7','utf_8_sig'
 ]   
	BACKUP_DIR = 'backup'

	def encodeDictFilesIn(self, dictDir, srcCharset, dstCharset):
		# オリジナルのファイルのバックアップ用ディレクトリを作る
		backupDir = os.path.join(dictDir, self.BACKUP_DIR)
		if not os.path.exists(backupDir):
			os.makedirs(backupDir)
		print 'backup original files to %s' % backupDir

		for file in os.listdir(dictDir):
			if file.endswith('.csv') or file.endswith('.def'):
				srcFile = os.path.join(dictDir, file)
				backupFile = os.path.join(backupDir, file)

				# 変換するファイルをバックアップする
				shutil.move(srcFile, backupFile)

				try:
					# 指定の文字コードから変換する
					self.encodeDictFile(backupFile, srcFile, srcCharset, dstCharset)
				except:
					# 失敗した場合、文字コードを自動判定して変換する
					for charset in self.SUPPORTED_CHARSET:
						try:
							self.encodeDictFile(backupFile, srcFile, charset, dstCharset)
							break
						except:
							#raise
							continue
					else:
						# 失敗したファイルは元にもどしておく
						print 'failed to encode %s' % srcFile
						shutil.move(backupFile, srcFile)

	def encodeDictFile(self, srcFile, dstFile, srcCharset, dstCharset):
		print 'encode %s from %s...' % (dstFile, srcCharset)

		try:
			src = open(srcFile, 'r')
			dst = open(dstFile, 'w')

			for line in src.readlines():
				line = line.decode(srcCharset)
				line = line.encode(dstCharset)
				dst.write(line)
		finally:
			if src:
				src.close()
			if dst:
				dst.close()


if __name__ == '__main__':
	parser = argparse.ArgumentParser(description='MeCab の辞書の文字コードを任意の文字コードに変換する。変換対象のファイルは形態素を記載した .csv と、品詞の定義などを記載した .def になる。')
	parser.add_argument('-d', '--dictDir', metavar='dir', type=str, default='.', help='文字コードを変換する辞書が格納されているディレクトリ\nデフォルトではカレントディレクトリ')
	parser.add_argument('-s', '--srcCharset', metavar='charset', type=str, default='euc_jp', help='変換する辞書の現在の文字コード。この文字コードで辞書の読み取りに失敗した場合には自動検出が行われる。\nデフォルトでは EUC JP')
	parser.add_argument('-t', '--dstCharset', metavar='charset', type=str, default='utf-8', help='辞書の変換先文字コード\nデフォルトでは UTF8')
	args = parser.parse_args(sys.argv[1:])

	encoder = MecabDictionaryEncoder()
	encoder.encodeDictFilesIn(args.dictDir, args.srcCharset, args.dstCharset)

encodeDictCharset.py の機能

-h オプションをつけて実行すればツールのヘルプが見れますが、簡単に機能について書いておきたいと思います。

辞書の変換対象のファイル

文字コードを変更する必要があるのは、配布されている辞書のうち、形態素を記載した .csv ファイルと品詞や接続方法の定義を記載した .def ファイルになります。このツールでも、対象の辞書ディレクトリ直下にある .csv ファイルと .def ファイルのみを変換対象としています。

変換する際には、対象の辞書ディレクトリ内に backup ディレクトリを作り、その中にオリジナルのファイルを置くようにしてますので、変換前後のファイルを見比べたい場合にはご利用ください。

この変換対象の辞書ディレクトリは、-d オプションで指定します。オプションを指定しない場合はカレントディレクトリになります。

変換もと、変換先の文字コード

デフォルトでは、辞書の文字コードは EUC JP から UTF8 に変換するように動作します。
ただし、変換もとの文字コードは -s、変換先の文字コードは -t オプションでそれぞれ指定できます。

変換もとの文字コードは、指定した文字コードでの変換に失敗した場合、自動判定されて変換されます。これは MecabDictionaryEncoder クラスのインスタンス変数 SUPPORTED_CHARSET に書かれている文字コードで変換できるかを順次試していき、失敗せずに変換しきれるかで判定しています。

IPA 辞書の文字コードを UTF8 に変換する

前提条件として、--enable-utf8-only オプションをつけて MeCab をビルドし、インストールしておいてください。
素の後、以下の手順で IPA 辞書の文字コードを UTF8 に変換します。

IPA 辞書を展開する
$ tar xvfz mecab-ipadic-2.7.0-20070801.tar.gz

文字コードを EUC JP から UTF8 に変換する
$ python encodeDictCharset.py -d mecab-ipadic-2.7.0-20070801

UTF8 にした IPA 辞書をビルドする
$ mkdir newDict
$ /usr/local/libexec/mecab/mecab-dict-index -d mecab-ipadic-2.7.0-20070801 -o newDict
$ cp mecab-ipadic-2.7.0-20070801/dicrc newDict/
辞書ディレクトリの中には dicrc が必要なので、ビルドした新しい辞書のディレクトリ内にコピーしておきます。

mecab-dict-index は MeCab 付属のツールで、インストールすれば使えるようになります。
mecab-dict-index は -f オプションで辞書の文字コードを指定できますが、既に encodeDictCharset.py で変換してあるので特に指定はしません。

UTF8 化した IPA 辞書を使ってみる

mecab コマンドの -d オプションで、使用する辞書を指定することができます。
これに UTF8 化した新しい IPA 辞書を指定して実行すると、以下のように UTF8 による標準出力が得られます。
$ echo "昨日カスピアン王子のつのぶえを読み終えた" | mecab -d newDict
昨日	名詞,副詞可能,*,*,*,*,昨日,キノウ,キノー
カスピアン	名詞,一般,*,*,*,*,*
王子	名詞,固有名詞,地域,一般,*,*,王子,オウジ,オージ
の	助詞,連体化,*,*,*,*,の,ノ,ノ
つ	助動詞,*,*,*,下二・タ行,基本形,つ,ツ,ツ
のぶえ	名詞,固有名詞,人名,名,*,*,のぶえ,ノブエ,ノブエ
を	助詞,格助詞,一般,*,*,*,を,ヲ,ヲ
読み	動詞,自立,*,*,五段・マ行,連用形,読む,ヨミ,ヨミ
終え	動詞,非自立,*,*,一段,連用形,終える,オエ,オエ
た	助動詞,*,*,*,特殊・タ,基本形,た,タ,タ
EOS

ちなみに、辞書ディレクトリ内の .csv ファイルを除いてみると、UTF8 に変換されているのがわかると思います。
一方で backup ディレクトリ内の本来の .csv ファイルは EUC JP になっています。
$ head mecab-ipadic-2.7.0-20070801/Noun.csv 
仕舞い,1285,1285,5543,名詞,一般,*,*,*,*,仕舞い,シマイ,シマイ
綺,1285,1285,5622,名詞,一般,*,*,*,*,綺,アヤギヌ,アヤギヌ
洋裁,1285,1285,5618,名詞,一般,*,*,*,*,洋裁,ヨウサイ,ヨーサイ
組打ち,1285,1285,5622,名詞,一般,*,*,*,*,組打ち,クミウチ,クミウチ
畿内,1285,1285,5770,名詞,一般,*,*,*,*,畿内,キナイ,キナイ
明き家,1285,1285,5402,名詞,一般,*,*,*,*,明き家,アキヤ,アキヤ
酔,1285,1285,4879,名詞,一般,*,*,*,*,酔,ヨイ,ヨイ
乱臣,1285,1285,5622,名詞,一般,*,*,*,*,乱臣,ランシン,ランシン
シルバー,1285,1285,2925,名詞,一般,*,*,*,*,シルバー,シルバー,シルバー
放課後,1285,1285,5494,名詞,一般,*,*,*,*,放課後,ホウカゴ,ホーカゴ

  MeCabpython  コメント (0) 2013/04/19 22:46:59


公開範囲:
プロフィール HN: ももかん
ゲーム作ったり雑談書いたり・・・していた時期が私にもありました。
カレンダー
<<2024, 11>>
272829303112
3456789
10111213141516
17181920212223
24252627282930