LoginSignup
0
0

MeCab 辞書を未知語の英数字が分割されないようにカスタマイズする

Last updated at Posted at 2023-12-06

はじめに

突然ですが、次の文章を MeCab で形態素解析してみましょう。

eneloop proの単3形(4本入)の型番はBK-3HCD/4Hです。
$ echo "eneloop proの単3形(4本入)の型番はBK-3HCD/4Hです。" | mecab                      
eneloop 名詞,固有名詞,組織,*,*,*,*
pro     名詞,一般,*,*,*,*,*
の      助詞,連体化,*,*,*,*,の,ノ,ノ
単      接頭詞,名詞接続,*,*,*,*,単,タン,タン
3       名詞,数,*,*,*,*,*
形      名詞,一般,*,*,*,*,形,カタチ,カタチ
(       名詞,サ変接続,*,*,*,*,*
4       名詞,数,*,*,*,*,*
本      名詞,接尾,助数詞,*,*,*,本,ホン,ホン
入      接頭詞,名詞接続,*,*,*,*,入,ニュウ,ニュー
)       名詞,サ変接続,*,*,*,*,*
の      助詞,連体化,*,*,*,*,の,ノ,ノ
型番    名詞,一般,*,*,*,*,型番,カタバン,カタバン
は      助詞,係助詞,*,*,*,*,は,ハ,ワ
BK      名詞,固有名詞,組織,*,*,*,*
-       名詞,サ変接続,*,*,*,*,*
3       名詞,数,*,*,*,*,*
HCD     名詞,一般,*,*,*,*,*
/       名詞,サ変接続,*,*,*,*,*
4       名詞,数,*,*,*,*,*
H       名詞,一般,*,*,*,*,*
です    助動詞,*,*,*,特殊・デス,基本形,です,デス,デス
。      記号,句点,*,*,*,*,。,。,。
EOS

型番部分である BK-3HCD/4H はもちろん辞書に登録されていない未知語なので、以下のような細切れなトークンに分割されてしまいました。

BK      名詞,固有名詞,組織,*,*,*,*
-       名詞,サ変接続,*,*,*,*,*
3       名詞,数,*,*,*,*,*
HCD     名詞,一般,*,*,*,*,*
/       名詞,サ変接続,*,*,*,*,*
4       名詞,数,*,*,*,*,*
H       名詞,一般,*,*,*,*,*

オークファンのシステムで処理しなければいけない文字列には型番が含まれていることがあるので、この形態素解析結果はかなり問題です。

そこでこの記事では、未知語の英数字 (と一部の記号) が分割されてしまわないように MeCab の辞書をカスタマイズする方法をご紹介しようと思います。

作業は macOS または Ubuntu (Windows の WSL 上の Ubuntu でも OK) で実施する想定とします。

辞書の準備

IPA 辞書の取得

MeCab のデフォルトの辞書は IPA 辞書なので、MeCab のページのダウンロード から mecab-ipadic-2.7.0-20070801.tar.gz を取得しておきます。

ここでは seed ディレクトリを作成し、そこに辞書データを展開します。

$ mkdir ./seed
$ mv ~/Downloads/mecab-ipadic-2.7.0-20070801.tar.gz ./seed/
$ tar -zxvf ./seed/mecab-ipadic-2.7.0-20070801.tar.gz -C ./seed/

展開されたデータから配布用のバイナリ辞書を作成するのに必要なファイルのみ seed/mecab-ipadic ディレクトリにコピーします。具体的には Seed 辞書 (*.csv)、定義ファイル (*.def)、設定ファイル (dicrc) をコピーします。

$ mkdir ./seed/mecab-ipadic
$ cp ./seed/mecab-ipadic-2.7.0-20070801/*.{csv,def} ./seed/mecab-ipadic/
$ cp ./seed/mecab-ipadic-2.7.0-20070801/dicrc ./seed/mecab-ipadic/

文字コードの変換

ここで、ダウンロードした IPA 辞書の Seed 辞書と定義ファイルの文字コードが EUC-JP なので、今後のカスタマイズをしやすくするために UTF-8 に一括変換しておきます。

nkf コマンドを使用するのでインストールしておきます。

macOS の場合

$ brew install nkf

Ubuntu の場合

$ sudo apt install nkf

文字コードを UTF-8 に一括変換します。(改行コードも LF に統一しています。)

$ find ./seed/mecab-ipadic -type f -name "*.*" -exec nkf -w -Lu --overwrite {} \;

設定ファイル dicrc を以下のように変更しておきます。

;
; Configuration file of IPADIC
;
; $Id: dicrc,v 1.4 2006/04/08 06:41:36 taku-ku Exp $;
;
cost-factor = 800
bos-feature = BOS/EOS,*,*,*,*,*,*,*,*
eval-size = 8
unk-eval-size = 4
; 以下を EUC-JP から UTF-8 に変更
config-charset = UTF-8

; (後略)

IPA 辞書のコンパイル

まず、何もカスタマイズしていない IPA 辞書をコンパイルして配布用バイナリ辞書を dic/mecab-ipadic に作成してみます。

出力用のディレクトリを作成しておきます。

$ mkdir -p ./dic/mecab-ipadic

MeCab をインストールして辞書をコンパイルします。

macOS の場合

$ brew install mecab
$ /opt/homebrew/Cellar/mecab/0.996/libexec/mecab/mecab-dict-index -f utf-8 -t utf-8 -d ./seed/mecab-ipadic -o ./dic/mecab-ipadic

Ubuntu の場合

$ sudo apt install mecab libmecab-dev
$ /usr/lib/mecab/mecab-dict-index -f utf-8 -t utf-8 -d ./seed/mecab-ipadic -o ./dic/mecab-ipadic

配布用バイナリ辞書にも設定ファイルの dicrc が必要なのでコピーしておきます。

$ cp ./seed/mecab-ipadic/dicrc ./dic/mecab-ipadic/

作成された配布用バイナリ辞書を確認しておきます。

$ mecab -D -d ./dic/mecab-ipadic                      
filename:       ./dic/mecab-ipadic/sys.dic
version:        102
charset:        utf-8
type:   0
size:   392126
left size:      1316
right size:     1316

カスタマイズ前の形態素解析結果も確認しておきます。

$ echo "eneloop proの単3形(4本入)の型番はBK-3HCD/4Hです。" | mecab -d ./dic/mecab-ipadic
eneloop 名詞,固有名詞,組織,*,*,*,*
pro     名詞,一般,*,*,*,*,*
の      助詞,連体化,*,*,*,*,の,ノ,ノ
単      接頭詞,名詞接続,*,*,*,*,単,タン,タン
3       名詞,数,*,*,*,*,*
形      名詞,一般,*,*,*,*,形,カタチ,カタチ
(       名詞,サ変接続,*,*,*,*,*
4       名詞,数,*,*,*,*,*
本      名詞,接尾,助数詞,*,*,*,本,ホン,ホン
入      接頭詞,名詞接続,*,*,*,*,入,ニュウ,ニュー
)       名詞,サ変接続,*,*,*,*,*
の      助詞,連体化,*,*,*,*,の,ノ,ノ
型番    名詞,一般,*,*,*,*,型番,カタバン,カタバン
は      助詞,係助詞,*,*,*,*,は,ハ,ワ
BK      名詞,固有名詞,組織,*,*,*,*
-       名詞,サ変接続,*,*,*,*,*
3       名詞,数,*,*,*,*,*
HCD     名詞,一般,*,*,*,*,*
/       名詞,サ変接続,*,*,*,*,*
4       名詞,数,*,*,*,*,*
H       名詞,一般,*,*,*,*,*
です    助動詞,*,*,*,特殊・デス,基本形,です,デス,デス
。      記号,句点,*,*,*,*,。,。,。
EOS

辞書のカスタマイズ

辞書の準備ができたのでカスタマイズしていきます。ここでは以下の文字が連続する部分がひとかたまりのトークンとなるようにカスタマイズしてみます。

  • 大文字の英字
  • 小文字の英字
  • 数字
  • -
  • /

英数字対応の Seed 辞書を格納する seed/mecab-ipadic-alphanumeric ディレクトリを作成し、元データをコピーします。

$ cp -r ./seed/mecab-ipadic ./seed/mecab-ipadic-alphanumeric

未知語処理の定義ファイル char.def と未知語用の辞書 unk.def をカスタマイズしていきます。

未知語処理定義のカスタマイズ

seed/mecab-ipadic-alphanumeric/char.def はもともと以下のように定義されています。

# (前略)

DEFAULT	       0 1 0  # DEFAULT is a mandatory category!
SPACE	       0 1 0
KANJI	       0 0 2
SYMBOL	       1 1 0
NUMERIC	       1 1 0
ALPHA	       1 1 0
HIRAGANA       0 1 2
KATAKANA       1 1 2
KANJINUMERIC   1 1 0
GREEK	       1 1 0
CYRILLIC       1 1 0

# (中略)

# ASCII
# ! から /
0x0021..0x002F SYMBOL
# 0 から 9
0x0030..0x0039 NUMERIC
# : から @
0x003A..0x0040 SYMBOL
# A から Z
0x0041..0x005A ALPHA
# [ から `
0x005B..0x0060 SYMBOL
# a から z
0x0061..0x007A ALPHA
# { から ~
0x007B..0x007E SYMBOL

# (後略)

16 進数と ASCII 文字の対応は以下の表のようになっています。

16 進数 文字 16 進数 文字 16 進数 文字 16 進数 文字
0x0000 NUL 0x0010 DLE 0x0020 SP 0x0030 0
0x0001 SOH 0x0011 DC1 0x0021 ! 0x0031 1
0x0002 STX 0x0012 DC2 0x0022 " 0x0032 2
0x0003 ETX 0x0013 DC3 0x0023 # 0x0033 3
0x0004 EOT 0x0014 DC4 0x0024 $ 0x0034 4
0x0005 ENQ 0x0015 NAK 0x0025 % 0x0035 5
0x0006 ACK 0x0016 SYN 0x0026 & 0x0036 6
0x0007 BEL 0x0017 ETB 0x0027 ' 0x0037 7
0x0008 BS 0x0018 CAN 0x0028 ( 0x0038 8
0x0009 HT 0x0019 EM 0x0029 ) 0x0039 9
0x000A LF 0x001A SUB 0x002A * 0x003A :
0x000B VT 0x001B ESC 0x002B + 0x003B ;
0x000C FF 0x001C FS 0x002C , 0x003C <
0x000D CR 0x001D GS 0x002D - 0x003D =
0x000E SO 0x001E RS 0x002E . 0x003E >
0x000F SI 0x001F US 0x002F / 0x003F ?
16 進数 文字 16 進数 文字 16 進数 文字 16 進数 文字
0x0040 @ 0x0050 P 0x0060 ` 0x0070 p
0x0041 A 0x0051 Q 0x0061 a 0x0071 q
0x0042 B 0x0052 R 0x0062 b 0x0072 r
0x0043 C 0x0053 S 0x0063 c 0x0073 s
0x0044 D 0x0054 T 0x0064 d 0x0074 t
0x0045 E 0x0055 U 0x0065 e 0x0075 u
0x0046 F 0x0056 V 0x0066 f 0x0076 v
0x0047 G 0x0057 W 0x0067 g 0x0077 w
0x0048 H 0x0058 X 0x0068 h 0x0078 x
0x0049 I 0x0059 Y 0x0069 i 0x0079 y
0x004A J 0x005A Z 0x006A j 0x007A z
0x004B K 0x005B [ 0x006B k 0x007B {
0x004C L 0x005C ¥ 0x006C l 0x007C |
0x004D M 0x005D ] 0x006D m 0x007D }
0x004E N 0x005E ^ 0x006E n 0x007E ~
0x004F O 0x005F _ 0x006F o 0x007F DEL

上記の ASCII コード表を確認しながら seed/mecab-ipadic-alphanumeric/char.def を以下のように変更します。

# (前略)

DEFAULT	       0 1 0  # DEFAULT is a mandatory category!
SPACE	       0 1 0
KANJI	       0 0 2
SYMBOL	       1 1 0
NUMERIC	       1 1 0
ALPHA	       1 1 0
# 英数字の字種を追加
ALPHANUMERIC   1 1 0
HIRAGANA       0 1 2
KATAKANA       1 1 2
KANJINUMERIC   1 1 0
GREEK	       1 1 0
CYRILLIC       1 1 0

# (中略)

# ASCII
# ! から ,
0x0021..0x002C SYMBOL
# -
0x002D         SYMBOL ALPHANUMERIC
# .
0x002E         SYMBOL
# /
0x002F         SYMBOL ALPHANUMERIC
# 0 から 9
0x0030..0x0039 NUMERIC ALPHANUMERIC
# : から @
0x003A..0x0040 SYMBOL
# A から Z
0x0041..0x005A ALPHANUMERIC
# [ から `
0x005B..0x0060 SYMBOL
# a から z
0x0061..0x007A ALPHANUMERIC
# { から ~
0x007B..0x007E SYMBOL

# (後略)

未知語用辞書のカスタマイズ

次に seed/mecab-ipadic-alphanumeric/unk.def に英数字の字種の定義を以下のように追記します。また、ここでは記号の字種 SYMBOL の品詞の 名詞,サ変接続 から 記号,一般 への変更も実施しています。(unk.def はコメントの記述に対応していないようなので、下記の # の行は削除してください。)

DEFAULT,5,5,4769,記号,一般,*,*,*,*,*
SPACE,9,9,8903,記号,空白,*,*,*,*,*
KANJI,1285,1285,11426,名詞,一般,*,*,*,*,*
KANJI,1283,1283,17290,名詞,サ変接続,*,*,*,*,*
KANJI,1293,1293,17611,名詞,固有名詞,地域,一般,*,*,*
KANJI,1292,1292,12649,名詞,固有名詞,組織,*,*,*,*
KANJI,1289,1289,17340,名詞,固有名詞,人名,一般,*,*,*
KANJI,1288,1288,15295,名詞,固有名詞,一般,*,*,*,*
# 英数字の字種の定義を追加
ALPHANUMERIC,1204,1204,0,名詞,英数字,*,*,*,*,*
# 記号の字種の品詞を `名詞,サ変接続` から `記号,一般` に変更
SYMBOL,1283,1283,17585,記号,一般,*,*,*,*,*
NUMERIC,1295,1295,27386,名詞,数,*,*,*,*,*
ALPHA,1285,1285,13398,名詞,一般,*,*,*,*,*
ALPHA,1293,1293,18706,名詞,固有名詞,地域,一般,*,*,*
ALPHA,1292,1292,13835,名詞,固有名詞,組織,*,*,*,*
ALPHA,1289,1289,18188,名詞,固有名詞,人名,一般,*,*,*
ALPHA,1288,1288,15673,名詞,固有名詞,一般,*,*,*,*
ALPHA,3,3,15235,感動詞,*,*,*,*,*,*
HIRAGANA,1285,1285,13069,名詞,一般,*,*,*,*,*
HIRAGANA,1283,1283,20223,名詞,サ変接続,*,*,*,*,*
# (後略)

英数字対応辞書のコンパイル

英数字対応の配布用バイナリ辞書を出力するディレクトリを作成しておきます。

$ mkdir ./dic/mecab-ipadic-alphanumeric

カスタマイズした辞書をコンパイルします。

macOS の場合

$ /opt/homebrew/Cellar/mecab/0.996/libexec/mecab/mecab-dict-index -f utf-8 -t utf-8 -d ./seed/mecab-ipadic-alphanumeric -o ./dic/mecab-ipadic-alphanumeric

Ubuntu の場合

$ /usr/lib/mecab/mecab-dict-index -f utf-8 -t utf-8 -d ./seed/mecab-ipadic-alphanumeric -o ./dic/mecab-ipadic-alphanumeric

設定ファイル dicrc をコピーします。

$ cp ./seed/mecab-ipadic-alphanumeric/dicrc ./dic/mecab-ipadic-alphanumeric/

作成された配布用バイナリ辞書を確認しておきます。

$ mecab -D -d ./dic/mecab-ipadic-alphanumeric                                   
filename:       ./dic/mecab-ipadic-alphanumeric/sys.dic
version:        102
charset:        utf-8
type:   0
size:   392126
left size:      1316
right size:     1316

カスタマイズ後の形態素解析結果を確認しておきます。

$ echo "eneloop proの単3形(4本入)の型番はBK-3HCD/4Hです。" | mecab -d ./dic/mecab-ipadic-alphanumeric
eneloop 名詞,英数字,*,*,*,*,*
pro     名詞,英数字,*,*,*,*,*
の      助詞,連体化,*,*,*,*,の,ノ,ノ
単      接頭詞,名詞接続,*,*,*,*,単,タン,タン
3       名詞,数,*,*,*,*,*
形      名詞,一般,*,*,*,*,形,カタチ,カタチ
(       記号,一般,*,*,*,*,*
4       名詞,数,*,*,*,*,*
本      名詞,接尾,助数詞,*,*,*,本,ホン,ホン
入      接頭詞,名詞接続,*,*,*,*,入,ニュウ,ニュー
)       記号,一般,*,*,*,*,*
の      助詞,連体化,*,*,*,*,の,ノ,ノ
型番    名詞,一般,*,*,*,*,型番,カタバン,カタバン
は      助詞,係助詞,*,*,*,*,は,ハ,ワ
BK-3HCD/4H      名詞,英数字,*,*,*,*,*
です    助動詞,*,*,*,特殊・デス,基本形,です,デス,デス
。      記号,句点,*,*,*,*,。,。,。
EOS

型番部分の BK-3HCD/4H が分割されずに 1 つのトークンにまとまるようになりました。

BK-3HCD/4H      名詞,英数字,*,*,*,*,*

おまけ

ここで、おやっ? と思ったそこのあなた...
気づいてしまいましたね :innocent:

カスタマイズ前の未知語処理の結果

eneloop 名詞,固有名詞,組織,*,*,*,*
pro     名詞,一般,*,*,*,*,*

がカスタマイズ後は

eneloop 名詞,英数字,*,*,*,*,*
pro     名詞,英数字,*,*,*,*,*

と雑な感じに劣化しています。

これは unk.def で定義されていた ALPHA の字種が担当していた部分をすべて ALPHANUMERIC に置き換えてしまったのが原因です。

# (前略)
ALPHANUMERIC,1204,1204,0,名詞,英数字,*,*,*,*,*
SYMBOL,1283,1283,17585,記号,一般,*,*,*,*,*
NUMERIC,1295,1295,27386,名詞,数,*,*,*,*,*
ALPHA,1285,1285,13398,名詞,一般,*,*,*,*,*
ALPHA,1293,1293,18706,名詞,固有名詞,地域,一般,*,*,*
ALPHA,1292,1292,13835,名詞,固有名詞,組織,*,*,*,*
ALPHA,1289,1289,18188,名詞,固有名詞,人名,一般,*,*,*
ALPHA,1288,1288,15673,名詞,固有名詞,一般,*,*,*,*
ALPHA,3,3,15235,感動詞,*,*,*,*,*,*
# (後略)

MeCab の用途が文字列をトークンに分割するだけであれば、このままでもさほど問題ではないのですが、少しだけ対策を実施してみます。ALPHANUMERICALPHA と同じように調整してもよいですが、ここではユーザー辞書への登録で改善してみようと思います。

まず、seed/mecab-ipadic-alphanumeric/user.csv (拡張子が .csv であればファイル名は任意で OK) を以下の内容 (文字コードは UTF-8) で作成します。

eneloop,1223,1223,6058,名詞,固有名詞,ブランド,*,*,*,eneloop,エネループ,エネループ
pro,1223,1223,6058,名詞,一般,,*,*,*,PRO,プロ,プロ

次に、seed/mecab-ipadic-alphanumeric/char.def に登録されている ALPHANUMERIC の定義を

ALPHANUMERIC   1 1 0

から

ALPHANUMERIC   0 1 0

に変更して、既知語として辞書に登録されている場合は未知語処理を動作させないようにします。

準備ができたので辞書をコンパイルしなおします。

macOS の場合

$ /opt/homebrew/Cellar/mecab/0.996/libexec/mecab/mecab-dict-index -f utf-8 -t utf-8 -d ./seed/mecab-ipadic-alphanumeric -o ./dic/mecab-ipadic-alphanumeric

Ubuntu の場合

$ /usr/lib/mecab/mecab-dict-index -f utf-8 -t utf-8 -d ./seed/mecab-ipadic-alphanumeric -o ./dic/mecab-ipadic-alphanumeric

形態素解析の結果を確認してみましょう。

$ echo "eneloop proの単3形(4本入)の型番はBK-3HCD/4Hです。" | mecab -d ./dic/mecab-ipadic-alphanumeric
eneloop 名詞,固有名詞,ブランド,*,*,*,eneloop,エネループ,エネループ
pro     名詞,一般,,*,*,*,PRO,プロ,プロ
の      助詞,連体化,*,*,*,*,の,ノ,ノ
単      接頭詞,名詞接続,*,*,*,*,単,タン,タン
3       名詞,数,*,*,*,*,*
形      名詞,一般,*,*,*,*,形,カタチ,カタチ
(       記号,一般,*,*,*,*,*
4       名詞,数,*,*,*,*,*
本      名詞,接尾,助数詞,*,*,*,本,ホン,ホン
入      接頭詞,名詞接続,*,*,*,*,入,ニュウ,ニュー
)       記号,一般,*,*,*,*,*
の      助詞,連体化,*,*,*,*,の,ノ,ノ
型番    名詞,一般,*,*,*,*,型番,カタバン,カタバン
は      助詞,係助詞,*,*,*,*,は,ハ,ワ
BK-3HCD/4H      名詞,英数字,*,*,*,*,*
です    助動詞,*,*,*,特殊・デス,基本形,です,デス,デス
。      記号,句点,*,*,*,*,。,。,。
EOS

enelooppro は未知語ではなく既知語になりました。

eneloop 名詞,固有名詞,ブランド,*,*,*,eneloop,エネループ,エネループ
pro     名詞,一般,,*,*,*,PRO,プロ,プロ

おわりに

この記事では MeCab の辞書をカスタマイズする一例として、未知語の英数字 (と一部の記号) の連続を 1 トークンにまとめる方法をご紹介しました。今回の例では IPA 辞書をカスタマイズしましたが、もちろん他の辞書でもカスタマイズは可能です。実際にオークファンのシステムでは mecab-ipadic-NEologd をカスタマイズして使用しています。

この他にも MeCab の公式ドキュメント には様々なカスタマイズ方法が紹介されています。記事では説明しなかったカスタマイズ内容の詳細は以下に記載されていますので、細かい設定値など気になる方は確認してみてください。おもしろいカスタマイズ方法を思いつくかもしれません :thumbsup:

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0