はじめに
突然ですが、次の文章を 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 名詞,英数字,*,*,*,*,*
おまけ
ここで、おやっ? と思ったそこのあなた...
気づいてしまいましたね
カスタマイズ前の未知語処理の結果
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 の用途が文字列をトークンに分割するだけであれば、このままでもさほど問題ではないのですが、少しだけ対策を実施してみます。ALPHANUMERIC
を ALPHA
と同じように調整してもよいですが、ここではユーザー辞書への登録で改善してみようと思います。
まず、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
eneloop
と pro
は未知語ではなく既知語になりました。
eneloop 名詞,固有名詞,ブランド,*,*,*,eneloop,エネループ,エネループ
pro 名詞,一般,,*,*,*,PRO,プロ,プロ
おわりに
この記事では MeCab の辞書をカスタマイズする一例として、未知語の英数字 (と一部の記号) の連続を 1 トークンにまとめる方法をご紹介しました。今回の例では IPA 辞書をカスタマイズしましたが、もちろん他の辞書でもカスタマイズは可能です。実際にオークファンのシステムでは mecab-ipadic-NEologd をカスタマイズして使用しています。
この他にも MeCab の公式ドキュメント には様々なカスタマイズ方法が紹介されています。記事では説明しなかったカスタマイズ内容の詳細は以下に記載されていますので、細かい設定値など気になる方は確認してみてください。おもしろいカスタマイズ方法を思いつくかもしれません