はじめに
書籍「Rによるテキストマイニング tidytextを活用したデータ分析と可視化の基礎」のサイトにある「付録1 RMeCabを用いた日本語テキストマイニング」を参考に、新美南吉作「ごん狐」のワードクラウドづくりに取り組んだが、書かれている通り「ごん」「兵十」が現れない。
そこで、「ごん」「兵十」が現れるワードクラウドが作りたくて、MeCabの作者のサイトを参考に、Google Colaboratory で、MeCabのユーザー辞書の作成に取り組んでみた。
「コストの自動推定機能」によるユーザー辞書作成
準備
ます、ColabでMeCabが使えるようにする。「Google ColabにMeCabとipadic-NEologdをインストールする」を参考にした。
! apt-get install -y mecab libmecab-dev mecab-ipadic-utf8 > /dev/null 2>&1
! pip install mecab-python3 > /dev/null 2>&1
! ln -s /etc/mecabrc /usr/local/etc/mecabrc
次に、MeCabの作者のサイトにある「単語の追加方法」に従い、次の順で、準備を行った。
1.modelファイルのダウンロード
import urllib.request
url = 'https://drive.google.com/uc?export=download&id=0B4y35FiV1wh7bnc5aFZSTE9qNnM'
file_name = 'mecab-ipadic-2.7.0-20070801.model'
save_name = file_name + '.bz2'
urllib.request.urlretrieve(url, save_name)
2.modelファイルの解凍
import bz2, shutil
file_name = 'mecab-ipadic-2.7.0-20070801.model'
save_name = file_name + '.bz2'
with bz2.BZ2File(save_name, "rb") as fr:
with open(file_name,"wb") as fw:
shutil.copyfileobj(fr,fw)
3.modelファイルの文字コードをutf-8へ変換
import codecs
file_name = 'mecab-ipadic-2.7.0-20070801.model'
with codecs.open(file_name, 'r', encoding='euc_jp') as f_in:
with codecs.open(file_name + '.utf8', 'w', encoding='utf_8') as f_out:
f_out.write(f_in.read())
4.utf-8へ変換したmodelファイルの6行目を「charset: utf-8」に書き換え
! sed -i -e "s!charset: euc-jp!charset: utf-8!g" mecab-ipadic-2.7.0-20070801.model.utf8
5.システム辞書のcsv、defファイルの文字コードをutf-8へ変換、コピー
import os, codecs
dicDir_in = '/usr/share/mecab/dic/ipadic'
dicDir_out = '/var/lib/mecab/dic/debian'
for file in os.listdir(dicDir_in):
if file.endswith('.csv') or file.endswith('.def'):
with codecs.open(dicDir_in + '/' + file, 'r', encoding='euc_jp') as f_in:
with codecs.open(dicDir_out + '/'+ file, 'w', encoding='utf_8') as f_out:
f_out.write(f_in.read())
5.は、/etc/mecabrc
で、システム辞書のフォルダが/var/lib/mecab/dic/debian
になっていたので、ここをユーザー辞書作成のシステム辞書フォルダにしていたが、csv、defファイルがなかったので、文字コードをutf-8に変換するついでにコピーした。
ユーザー辞書作成には、csv、defファイルが必要なことになかなか気づくことができず苦労した。
最初は、文字コードはeuc-jpのままで実行していたが、エラーでユーザー辞書ができなかった。必ず文字コードはutf-8に変更してください。これにもなかなか気づくことができず苦労した。
modelファイルによるユーザー辞書の作成
今回は、品詞は、すべて「名詞、固有名詞、一般、*」に統一した。また、「原形、読み、発音」はすべて「*」にしている。
import csv
# ユーザ辞書へ追加したい名詞のList
target_txt = ['ごん', '兵十', '加助', '弥助', 'おはぐろ', '新兵衛']
# user_dic.csv の作成
with open('user_dic.csv', "w") as f:
writer = csv.writer(f)
for i in range(len(target_txt)):
dic = [target_txt[i]] + [''] * 3 + ['名詞','固有名詞','一般'] + ['*'] * 6
writer.writerow(dic)
# modelファイルを利用しコスト値を自動推定したユーザー辞書の作成
! /usr/lib/mecab/mecab-dict-index \
-m mecab-ipadic-2.7.0-20070801.model.utf8 \
-d /var/lib/mecab/dic/debian -t utf-8 \
-u user.dic \
user_dic.csv -f utf-8
できあがったユーザー辞書を確認してみる。
import MeCab
tagger = MeCab.Tagger('-O wakati -u user.dic')
print(tagger.parse('その中山から、少しはなれた山の中に、「ごん狐」という狐がいました。'))
print(tagger.parse('「兵十だな」と、ごんは思いました。'))
結果は次のようになった。1行目の「ごん」は成功しているが、2行目の「兵十」と「ごん」は失敗している。
その 中山 から 、 少し は なれ た 山 の 中 に 、 「 ごん 狐 」 という 狐 が い まし た 。
「 兵 十 だ な 」 と 、 ご ん は 思い まし た 。
最適なコストを求める
modelファイルを使うやり方では、うまくいかなかったので、「あらびき日記 MeCab の形態素解析誤りを修正する生起コストの求め方」とMeCabの作者のサイトにある「スクリプト言語のバインディング」を参考に、最適なコストを求めユーザー辞書を作成するコードを書いてみた。
import MeCab
import csv
def make_dic(text):
dic = [text, 1288, 1288, 20000, '名詞', '固有名詞', '一般'] + ['*'] * 6
for h in range(len(h_txt)):
for i in range(len(t_txt)):
txt = [''] * 2
txt[0] = h_txt[h] + text + t_txt[i]
if h_txt[h] == '':
txt[1] = text
else:
txt[1] = h_txt[h] + '\t*\n' + text
if t_txt[i] == '':
txt[1] = txt[1] + '\t名詞,固有名詞,一般,*\nEOS\n'
else:
txt[1] = txt[1] + '\t名詞,固有名詞,一般,*\n' + t_txt[i] + '\t*\nEOS\n'
cst = [0] * 2
for j in range(2):
node = tagger[j].parseToNode(txt[j])
while node.stat != 3:
if node.surface == text:
wcst = node.wcost
node = node.next
cst[j] = node.cost
wcst = wcst - ( cst[1] -cst[0] ) - 1
if dic[3] > wcst:
dic[3] = wcst
return dic
# ユーザ辞書へ追加したい名詞のリスト
target_txt = ['ごん', '兵十', '加助', '弥助', 'おはぐろ', '新兵衛']
# コスト計算のため、単語の前後につける語のリスト
h_txt = ['そして', '日']
t_txt = ['です', '、']
tagger = [''] * 2
tagger[0] = MeCab.Tagger()
tagger[1] = MeCab.Tagger('-p')
# user_dic.csv の作成
with open('user_dic.csv', "w") as f:
writer = csv.writer(f)
for k in range(len(target_txt)):
dicLine = make_dic(target_txt[k])
writer.writerow(dicLine)
# ユーザ辞書のコンパイル
! /usr/lib/mecab/mecab-dict-index \
-d /var/lib/mecab/dic/debian -t utf-8 \
-u user.dic \
user_dic.csv-f utf-8
ユーザー辞書を確認してみるとうまくいった。
その 中山 から 、 少し は なれ た 山 の 中 に 、 「 ごん 狐 」 という 狐 が い まし た 。
「 兵十 だ な 」 と 、 ごん は 思い まし た 。
しかし、まだ「こないだうなぎをぬすみやがったあのごん狐めが、またいたずらをしに来たな。」を分かち書きすると、次のようになる。
こないだ う な ぎをぬすみやがったあのごん 狐 め が 、 また いたずら を し に 来 た な 。
これには、「ぎをぬすみやがったあのごん」のコストを21130にして、ユーザー辞書に追加するとうまくいった。
pythonは初心者です。ググりながらコードを作成しました。間違い等をご指摘いただけたらありがたいです。
参考サイト
-
[Rによるテキストマイニング tidytextを活用したデータ分析と可視化の基礎
付録1 RMeCabを用いた日本語テキストマイニング]
(https://www.oreilly.co.jp/pub/9784873118307/appa.html) -
[MeCab: Yet Another Part-of-Speech and Morphological Analyzer]
(https://taku910.github.io/mecab/) -
[Google ColabにMeCabとipadic-NEologdをインストールする]
(https://qiita.com/jun40vn/items/78e33e29dce3d50c2df1) -
[英語の勉強サイト
Pythonプログラミング:bz2解凍進行状況をtqdmで視覚化]
(https://eigo.rumisunheart.com/2018/04/10/how-to-decompress-bz2-file-in-python-2/) -
[TechAcademyマガジン
PythonでCSVファイルの文字コードを変換する方法【初心者向け】]
(https://techacademy.jp/magazine/21128) -
[桃缶食べたい。
MeCab の IPA 辞書を UTF8 化する]
(https://blog.chocolapod.net/momokan/entry/54) -
[あらびき日記
MeCab の形態素解析誤りを修正する生起コストの求め方]
(https://abicky.net/2016/11/28/204542/)