古いMacで「mecab」のユーザー辞書を登録。改行コード変換でようやく動作

>**今回のmecabへのユーザー辞書登録手順概要**
>●Excelを使いutf-8のcsv（辞書ファイル）を用意
>●Macのターミナルを起動
>●「mecab-dict-index」を使いユーザー辞書としてコンパイル
>●nanoエディタを使ってユーザー辞書のパスを通す
>●「-D」オプションを使い適用辞書を確認
>●「-F」オプションを使い「左文脈 ID」 「右文脈 ID」「コスト」を確認
>●「--mime」オプションを使い文字コードを確認
>●改行コード「\r」（CR）を\n「」（LF）に変換
（Rは独学なので用語の使い方が適正でないかもしれません。ご容赦ください）

# 固有名詞を認識させたい

AAA活動休止前最後のドームツアー公演が先日札幌（2021/12/25）で幕を閉じました。
ツイートを取得し、形態素解析をかけてみようと思いましたが、途中で「ユーザー辞書」の登録に時間を割きました。
今回はその話について記載します。

これまでと同様の手順で、「R」と「RMeCab」をまず使ったのですが、処理途中に固有名詞が「姓」「名」（特に名）が、それぞれ分断されることが気になりました。
（使ったのはデフォルトの辞書）

~~~R
3573         と   助詞   格助詞  1087
3574       する   動詞     自立  1127
3575       この 連体詞        *  1128
3576         実   名詞 固有名詞  1142
3577         郎   名詞     一般  1147
3578       彩子   名詞 固有名詞  1151
3579       真司   名詞 固有名詞  1154
~~~

とか

~~~R
3584     ライブ   名詞     一般  1263
3585         末   名詞     接尾  1268
3586         與   名詞 固有名詞  1342
3587         年   名詞     接尾  1343
3588         日   名詞     接尾  1399
3589       西島   名詞 固有名詞  1494
3590         」   記号   括弧閉  1509
3591         太   名詞 固有名詞  1516
3592         「   記号   括弧開  1562
~~~

です。

そこで、「RMeCab」で使用している形態素解析エンジン「mecab」の「ユーザー辞書」に固有名詞を登録をすることにしました。
なお、ユーザー辞書登録今回初めてです。

# csvファイルをExcelで用意

まず、辞書として登録する用語をcsvファイルで作ります。
手順としては、

* Excelでcsvファイル作成
* csvを複製してテキストエディットで読み込む
* テキストエディットのメニューから複製
* 文字コードを「utf-8」を指定して保存

と、「utf-8形式のcsv」を作成します。
csv作成後は、辞書にコンパイルします。

* ターミナルを起動
* ユーザー辞書にコンパイル
* mecabcの設定ファイルにユーザ辞書のパスを指定
　（手順は後述）

今回準備したcsvファイルの内容です。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1143963/0e5e054a-0344-b5c5-0bfc-fd51f1a785b8.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1143963/b5f0ee51-fafe-1407-47bc-7537a4d157f6.png)

上述の通りテキストエディットで保存する際に「utf-8」を指定します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1143963/cc26f9cc-6130-588b-948c-fbea25e1080a.png)

# ターミナルで辞書をコンパイル

Macのターミナルを起動します。
今回は作成したcsvを以下ディテクトリに配置します。

~~~
mv useraaa2.csv /usr/local/lib/mecab/dic/ipadic/
~~~

「mecab-dict-index」を使い、ユーザー辞書としてコンパイルします。
作成したユーザー辞書名は「aaa．ｄｉｃ」です。

~~~
/usr/local/Cellar/mecab/0.996/libexec/mecab/mecab-dict-index \
-d /usr/local/lib/mecab/dic/ipadic \
-u aaa.dic \
-f utf-8 \
-t utf-8 useraaa2.csv

reading useraaa2.csv ... 11
emitting double-array: 100% |###########################################| 

done!
~~~

「done!」となれば無事コンパイルできたことになります。
オプションパラメータはこう読み解けます。

+ -d : 辞書が配置されているディレクトリを指定し、
+ -u : 生成したいユーザー辞書の名称も指定し、
+ -f : その文字コードを指定、
+ -t : そしてユーザー辞書の元となるcsv名称と文字コードを指定

ターミナルで動作するエディタ「nano」を使い、「mecab」の設定にユーザー辞書のパスを通します。

~~~
nano /usr/local/etc/mecabrc
~~~

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1143963/b40fb9ef-3e80-6e67-1fa3-066899eec82f.png)

# 辞書が機能しない原因を調べる

動作を確認するために、「-u」オプションでユーザー辞書の指定をします。
（指定すれば優先的にそのユーザー辞書を適用するようです）
しかし、変わらず名前が分割して認識されるなど、うまくいきません。

~~~
mecab -u /usr/local/lib/mecab/dic/ipadic/aaa.dic
與	名詞,固有名詞,人名,姓,*,*,與,アタエ,アタエ
真司	名詞,固有名詞,人名,名,*,*,真司,シンジ,シンジ
郎	名詞,一般,*,*,*,*,郎,ロウ,ロー
~~~

「-D」オプションを使い、辞書が適用されているか調べてみます。

~~~
mecab -D
filename:	/usr/local/lib/mecab/dic/ipadic/sys.dic
version:	102
charset:	utf8
type:	0
size:	392126
left size:	1316
right size:	1316

filename:	/usr/local/lib/mecab/dic/ipadic/aaa.dic
version:	102
charset:	utf-8
type:	1
size:	11
left size:	1316
right size:	1316
~~~

「aaa.dic」は適用されています。

「-F」オプションを使い「左文脈 ID」 と「右文脈 ID」、「コスト」を調べます。
この数値を参考に、ユーザー辞書のチューニングを行います。
今回はそこまでノウハウが蓄積されてないので、他のサイトを参考に「空」「空」「1000」としてました。
「真司郎,,,1000・・・」という感じです。

~~~
echo "與真司郎" | mecab -F"%m,%phl,%phr,%c\n"
與,1290,1290,7623
真司,1291,1291,8040
郎,1285,1285,6722
~~~

コストは小さいほど, 出現しやすくなります。
ユーザー辞書に登録した値は「1000」なので、上記の値「7623」「8040」などより小いので、意図通り適用されるかと考えましたが、そうなりません。
「-N3」オプションで解析パターンを3つ出すことも試しましたが、いずれも名前が分割された状態でした。

~~~
echo "真司郎" | mecab -F"%m,%c,%pc\n" -N3
真,7716,7432
司郎,8557,13570
EOS
真,8583,8299
司郎,8557,13570
EOS
真司,8040,7844
郎,6722,14751
EOS
~~~

# catコマンドで改行コードをLFに変換

ユーザー辞書の元データcsvの文字コードは「utf-8」になっています。

~~~
file --mime uuseraaa2.csv
user.csv: text/plain; charset=utf-8
~~~

となると、疑わしいのは、「改行コード」です。
調べたところ、古いMac（今回使用したのは１０年以上前のMacBook Pro）の改行コードは「CR」。
一方、辞書に使うCSVの改行コードは予め「LF」または「CR+LF」にしておく必要があるそうです。
改行コードを確認します。
「\r」は「CR」です。

~~~
od -c useraaa2.csv
シ  **  **  ジ  **  **  マ  **  **  \r  宇  **  **  野
~~~

改行コード「\r」（CR）を\n「」（LF）に変換します。

~~~
cat useraaa2.csv | tr '\r' '\n' > useraaa2LF.csv
~~~

「useraaa2LF.csv」という名称にして複製していますが、下記実行の後で「useraaa2.csv」に戻しています。
catコマンドで以下のように表示されれば、改行コードが正しく変換されています。

~~~
cat useraaa2.csv
西島,,,1000, 名詞, 固有名詞, 人名, 姓,*,*,にしじま,ニシジマ,ニシジマ
宇野,,,1000, 名詞, 固有名詞, 人名, 姓,*,*,うの,ウノ,ウノ
日高,,,1000, 名詞, 固有名詞, 人名, 姓,*,*,ひだか,ヒダカ,ヒダカ
與,,,1000, 名詞, 固有名詞, 人名, 姓,*,*,あたえ,アタエ,アタエ
末吉,,,1000, 名詞, 固有名詞, 人名, 姓,*,*,すえよし,スエヨシ,スエヨシ
隆弘,,,1000, 名詞, 固有名詞, 人名, 名,*,*,たかひろ,タカヒロ,タカヒロ
実彩子,,,1000, 名詞, 固有名詞, 人名, 名,*,*,みさこ,ミサコ,ミサコ
光啓,,,1000, 名詞, 固有名詞, 人名, 名,*,*,みつひろ,ミツヒロ,ミツヒロ
真司郎,,,1000, 名詞, 固有名詞, 人名, 名,*,*,しんじろう,シンジロウ,シンジロウ
秀太,,,1000, 名詞, 固有名詞, 人名, 名,*,*,しゅうた,シュウタ,シュウタ
~~~

# ようやく意図通り動作

再度コンパイルします。

~~~
/usr/local/Cellar/mecab/0.996/libexec/mecab/mecab-dict-index \
-d /usr/local/lib/mecab/dic/ipadic \
-u aaa.dic \
-f utf-8 \
-t utf-8 useraaa2.csv

reading useraaa2.csv ... 11
emitting double-array: 100% |###########################################| 

done!
~~~

ユーザー辞書が正しく動作する再度試します。
「-u」オプションを使いユーザー辞書を指定しなくても、コストを小さくしているからか、適用されています。

~~~
mecab
與真司郎
與	名詞, 固有名詞, 人名, 姓,*,*,あたえ,アタエ,アタエ
真司郎	名詞, 固有名詞, 人名, 名,*,*,しんじろう,シンジロウ,シンジロウ

echo "真司郎" | mecab -F"%m,%c,%pc\n" -N3
真司郎,1000,804
EOS
真,7716,7432
司郎,8557,13570
EOS
真,8583,8299
司郎,8557,13570
EOS
~~~

これでユーザー辞書が機能するようになりました。

**了**