日本テレビ東京で学ぶMeCabのコスト計算
概要
「日本テレビ東京」
この実際には存在しない、どこで切り分ければ良いのかよく分からない言葉を、あなたが形態素解析するとしたら、どんな風に分かちますか?
おそらく以下の3つのどれかを考えるのではないでしょうか。
日本テレビ | 東京
日本 | テレビ東京
日本 | テレビ | 東京
今回はこの言葉の解析をMeCab+NAIST辞書にお願いして、結果を分析することで、MeCabが行っているコスト計算について勉強してみたいと思います。
この実際には存在しない、どこで切り分ければ良いのかよく分からない言葉を、あなたが形態素解析するとしたら、どんな風に分かちますか?
おそらく以下の3つのどれかを考えるのではないでしょうか。
日本テレビ | 東京
日本 | テレビ東京
日本 | テレビ | 東京
今回はこの言葉の解析をMeCab+NAIST辞書にお願いして、結果を分析することで、MeCabが行っているコスト計算について勉強してみたいと思います。
バージョン情報
本コンテンツで使用しているMeCabと辞書のバージョンは以下になります。
・MeCab 0.98pre
・NAIST辞書 0.6.1-20090630
・MeCab 0.98pre
・NAIST辞書 0.6.1-20090630
注意事項
相変わらず、勉強がてらに書いてます。コストの算出方法については、この記事を書きながらリアルタイムで勉強していたりするので、内容の正確さについては若干の不安があります。
ただその分、入門者の方にとっては読みやすい内容になっているのではないかと思います。
もし本記事の内容に間違いなどがありましたら、こちらのフォームよりご指摘頂けるとありがたいです。
ただその分、入門者の方にとっては読みやすい内容になっているのではないかと思います。
もし本記事の内容に間違いなどがありましたら、こちらのフォームよりご指摘頂けるとありがたいです。
まずは実行してみる
さて、まずはさっそくMeCabに「日本テレビ東京」を解析してもらいましょう。
「日本 | テレビ東京」と分けていますね。視聴率的には負けていますが、NAIST辞書的には日本テレビよりもテレビ東京が優先されたようです。
ちなみに「フジテレビ東京」ではどうなるでしょうか。
これでNAIST辞書的な順位は、「フジテレビ > テレビ東京 > 日本テレビ」ということになりました。
では、「日本テレビ vs テレビ東京」の場合で、解析する文字列が「日本テレビ東京支部」だった場合はどうなるでしょう。
ところで、上の例は全て最良の解のみを出力していますが、MeCabには良いと思った解析方法を上位から指定件数出力する機能があります。試しに上位3件を出力するように引数を設定して、「日本テレビ東京」を解析すると、どうなるでしょう。
echo 日本テレビ東京 | mecab
日本 名詞,固有名詞,地域,国,*,*,日本,ニッポン,ニッポン,,
テレビ東京 名詞,固有名詞,組織,*,*,*,テレビ東京,テレビトウキョウ,テレビトーキョー,,
EOS
テレビ東京、WIN!「日本 | テレビ東京」と分けていますね。視聴率的には負けていますが、NAIST辞書的には日本テレビよりもテレビ東京が優先されたようです。
ちなみに「フジテレビ東京」ではどうなるでしょうか。
echo フジテレビ東京 | mecab
フジテレビ 名詞,固有名詞,組織,*,*,*,フジテレビ,フジテレビ,フジテレビ,,
東京 名詞,固有名詞,地域,一般,*,*,東京,トウキョウ,トーキョー,,
EOS
フジテレビ、WIN!これでNAIST辞書的な順位は、「フジテレビ > テレビ東京 > 日本テレビ」ということになりました。
では、「日本テレビ vs テレビ東京」の場合で、解析する文字列が「日本テレビ東京支部」だった場合はどうなるでしょう。
echo 日本テレビ東京支部 | mecab
日本テレビ 名詞,固有名詞,組織,*,*,*,日本テレビ,ニホンテレビ,ニホンテレビ,,
東京 名詞,固有名詞,地域,一般,*,*,東京,トウキョウ,トーキョー,,
支部 名詞,一般,*,*,*,*,支部,シブ,シブ,,
EOS
ちゃんと人間が考えるような、「日本テレビ | 東京 | 支部」に解析してくれました。頭いいですね。ところで、上の例は全て最良の解のみを出力していますが、MeCabには良いと思った解析方法を上位から指定件数出力する機能があります。試しに上位3件を出力するように引数を設定して、「日本テレビ東京」を解析すると、どうなるでしょう。
echo 日本テレビ東京 | mecab -N3
日本 名詞,固有名詞,地域,国,*,*,日本,ニッポン,ニッポン,,
テレビ東京 名詞,固有名詞,組織,*,*,*,テレビ東京,テレビトウキョウ,テレビトーキョー,,
EOS
日本テレビ 名詞,固有名詞,組織,*,*,*,日本テレビ,ニホンテレビ,ニホンテレビ,,
東京 名詞,固有名詞,地域,一般,*,*,東京,トウキョウ,トーキョー,,
EOS
日本 名詞,固有名詞,地域,国,*,*,日本,ニッポン,ニッポン,,
テレビ 名詞,一般,*,*,*,*,テレビ,テレビ,テレビ,,
東京 名詞,固有名詞,地域,一般,*,*,東京,トウキョウ,トーキョー,,
EOS
惚れ惚れするような結果ですね。最初に私が提示した「人間が考えそうな3つの分け方」を見事に答えてくれました。単語ごとのコストに関する説明
MeCabは辞書ファイルに設定されたコスト値を読み取り、指定された文章の解析可能なパターンの中で、最もコストが低い順序を採用することで単語を分割しています。
では、各テレビ局名のコスト値は、辞書ファイルの中ではどう設定されているのでしょう。
各単語のコスト値は、NAIST辞書では以下のファイルに記載されています。
/usr/local/lib/mecab/dic/naist-jdic/naist-jdic.csv
上記ファイルから関連がありそうな文字を引っ張り出してみると、下記のような設定になっていました。
コスト値は低いものほど優先されるはずですが、意外なことに上で解析した時に最も優先度が低かったはずの日本テレビが一番コスト値が低く(2988)なっています。
では、各テレビ局名のコスト値は、辞書ファイルの中ではどう設定されているのでしょう。
各単語のコスト値は、NAIST辞書では以下のファイルに記載されています。
/usr/local/lib/mecab/dic/naist-jdic/naist-jdic.csv
上記ファイルから関連がありそうな文字を引っ張り出してみると、下記のような設定になっていました。
テレビ東京,1352,1352,4752,名詞,固有名詞,組織,*,*,*,テレビ東京,テレビトウキョウ
日本テレビ,1352,1352,2988,名詞,固有名詞,組織,*,*,*,日本テレビ,ニホンテレビ
フジテレビ,1352,1352,4146,名詞,固有名詞,組織,*,*,*,フジテレビ,フジテレビ
テレビ,1345,1345,3307,名詞,一般,*,*,*,*,テレビ,テレビ
日本,1354,1354,3606,名詞,固有名詞,地域,国,*,*,日本,ニッポン
フジ,1345,1345,5226,名詞,一般,*,*,*,*,フジ,フジ
フジ,1352,1352,3572,名詞,固有名詞,組織,*,*,*,フジ,フジ
東京,1353,1353,3188,名詞,固有名詞,地域,一般,*,*,東京,トウキョウ
コスト値は4つ目のフィールド、テレビ東京なら4752(証券コードみたいですね)に記述されています。コスト値は低いものほど優先されるはずですが、意外なことに上で解析した時に最も優先度が低かったはずの日本テレビが一番コスト値が低く(2988)なっています。
連接コストに関する説明
どうしてコスト的に低いはずの日本テレビよりも、テレビ東京が優先される結果が返って来たのか。
その理由は連接コストという要素が絡んでくるからです。連接コストは、その単語と隣の単語の左文脈IDと右文脈IDを見て、繋がりやすさからコストを上下させる機能です。
例えば「姓」の後には「名」が来やすい(連接コスト、-6659)けど、「名」の後に「姓」が来るパターンはそれほど多くはない(連接コスト、41)と設定されているとか、「国」の後には「地域」が来やすい(連接コスト、-6966)など、各文脈IDごとにコストが割り振られています。
実際に連結コストにどのような値が割り振られているかは、下記パスを参照してください。
/usr/local/lib/mecab/dic/naist-jdic/matrix.def
以下はmatrix.defから「姓」(1350)と「名」(1351)の連結コストを抜き出したものです。
matrix.def
1350 1351 -6659
1351 1350 41
また、「国」(1354)と「地域」(1363)の連結コストは以下のようになっています。
matrix.def
1354 1363 -6966
1363 1354 1062
地域 → 国の順序で連結するケースはかなり少ないものと見て設定されているようです。
ちなみにNAIST辞書の文脈IDは、1377個あります。で、それぞれのIDがそれぞれのID(自身を含む)に対する連接コストを設定しなければならないので、matrix.defに設定してある対応関係は「1377 * 1377 = 1896129個」になります。
ひゃくはちじゅうまん……。とりあえず手動ではとても管理できないボリュームです。
その理由は連接コストという要素が絡んでくるからです。連接コストは、その単語と隣の単語の左文脈IDと右文脈IDを見て、繋がりやすさからコストを上下させる機能です。
例えば「姓」の後には「名」が来やすい(連接コスト、-6659)けど、「名」の後に「姓」が来るパターンはそれほど多くはない(連接コスト、41)と設定されているとか、「国」の後には「地域」が来やすい(連接コスト、-6966)など、各文脈IDごとにコストが割り振られています。
実際に連結コストにどのような値が割り振られているかは、下記パスを参照してください。
/usr/local/lib/mecab/dic/naist-jdic/matrix.def
以下はmatrix.defから「姓」(1350)と「名」(1351)の連結コストを抜き出したものです。
matrix.def
1350 1351 -6659
1351 1350 41
また、「国」(1354)と「地域」(1363)の連結コストは以下のようになっています。
matrix.def
1354 1363 -6966
1363 1354 1062
地域 → 国の順序で連結するケースはかなり少ないものと見て設定されているようです。
ちなみにNAIST辞書の文脈IDは、1377個あります。で、それぞれのIDがそれぞれのID(自身を含む)に対する連接コストを設定しなければならないので、matrix.defに設定してある対応関係は「1377 * 1377 = 1896129個」になります。
ひゃくはちじゅうまん……。とりあえず手動ではとても管理できないボリュームです。
コストが見える引数を指定して結果を見てみる
MeCabにはその単語を解析するのにかかったコストを表示してくれる機能があります。
フォーマット用パラメータの以下の子たちがそうです。
%pw : 単語生起コスト。上で説明した「naist-jdic.csv」に書いてあるコスト値と同じ。
%pc : 連接コスト + 単語生起コスト (文頭から累積)。詳細は後述。
%pn : 連接コスト + 単語生起コスト (その形態素単独)
フォーマットの詳しい話は、こちらが参考になります。
http://mecab.sourceforge.net/format.html
というわけで、その辺りを設定してMeCabを実行してみます。
フォーマットは「%m,%phl,%phr,%pw,%pc,%pn\n」を設定します。これを設定すると、「表層文字,左ID,右ID」の後ろに、上で説明した3つのコストが出力されます。また、解析結果は2つまで表示しています。
解析結果1
ついでに、各単語のコスト設定と、連接コストについても表にしてみます。
単語設定 (naist-jdic.csv)
単語設定の「日本」と「テレビ東京」の単語生起コストが、解析結果1の値と等しくなっていることが分かります。
連接コストは、1354, 1352以外に0も必要になります。0はBOS/EOS。つまり文頭と文末を意味します。文頭の言葉(今回は日本)は、自身の左に文脈IDが0の値がいるものとして計算されます。
連接コスト (matrix.dev)
連接コストも計算にいれて、「日本」の「連接+生起」コストを計算すると、3606 + -996 = 2610になります。これは「解析結果1」に表示されている「日本」の「連接+生起」コストと等しいことが分かります。
次に「テレビ東京」の「連接+生起」コストは、テレビ東京自身の単語生起コストの4752に、「1354 → 1352」の連結コスト-2758を足すことになるので、4752 + -2758 = 1994になります。「解析結果1」の「連接+生起(単独)」と等しい値になっていますね。
また「テレビ東京」の「連接+生起(累計)」は「日本」と「テレビ東京」のコストを足した、「2610 + 1994 = 4604」になっています。
最後に、これは「解析結果1」の出力には表示されていませんが、EOS(文末)への遷移もコストに加える必要があります。EOSの単語生起コストは0なので、文脈ID「1352 → 0」の遷移の分だけ加算します。
というわけで、最終的なコストは「4604 + -941 = 3663」になります。
計算式まとめ
「日本の生起コスト」 + 「文脈ID 0 → 1354の連結コスト」 = 「日本までのコスト」
3606 + -996 = 2610
「テレビ東京の生起コスト」 + 「文脈ID 1354 → 1352の連結コスト」 = 「テレビ東京のコスト」
4752 + -2758 = 1994
「BOS/EOSのコスト」 + 「文脈ID 1352 → 0の連結コスト」 = 「文末のコスト」
0 + -941 = -941
3つのコストを加算したものが、そのルートの総コスト
2610 + 1994 + -941 = 3663
では、次善の解析結果、「日本テレビ | 東京」に分割する場合のコストはどうなるでしょう。
解析結果2
単語生起コスト(naist-jdic.csvに記述)は、「解析結果2」の「単語生起コスト」と同じだということが分かっているので省きます。
連接コスト (matrix.dev)
以上のデータがあれば、計算可能ですね。
解析結果2の回答は少し下に書きますので、興味がある方は先に自身で計算をして答え合わせをしてみてください。
フォーマット用パラメータの以下の子たちがそうです。
%pw : 単語生起コスト。上で説明した「naist-jdic.csv」に書いてあるコスト値と同じ。
%pc : 連接コスト + 単語生起コスト (文頭から累積)。詳細は後述。
%pn : 連接コスト + 単語生起コスト (その形態素単独)
フォーマットの詳しい話は、こちらが参考になります。
http://mecab.sourceforge.net/format.html
というわけで、その辺りを設定してMeCabを実行してみます。
フォーマットは「%m,%phl,%phr,%pw,%pc,%pn\n」を設定します。これを設定すると、「表層文字,左ID,右ID」の後ろに、上で説明した3つのコストが出力されます。また、解析結果は2つまで表示しています。
echo 日本テレビ東京 | mecab -F"%m,%phl,%phr,%pb,%pw,%pc,%pn\n" -N2
日本,1354,1354,3606,2610,2610
テレビ東京,1352,1352,4752,4604,1994
EOS
日本テレビ,1352,1352,2988,1969,1969
東京,1353,1353,3188,4383,2414
EOS
上のままだと見づらいので、結果を表にしてみましょう。解析結果1
| 表層文字列 | 左文脈ID | 右文脈ID | 単語生起コスト | 連接+生起(累積) | 連接+生起(単独) |
|---|---|---|---|---|---|
| 日本 | 1354 | 1354 | 3606 | 2610 | 2610 |
| テレビ東京 | 1352 | 1352 | 4752 | 4604 | 1994 |
ついでに、各単語のコスト設定と、連接コストについても表にしてみます。
単語設定 (naist-jdic.csv)
| 表層文字 | 左文脈ID | 右文脈ID | 単語生起コスト |
|---|---|---|---|
| 日本 | 1354 | 1354 | 3606 |
| テレビ東京 | 1352 | 1352 | 4752 |
単語設定の「日本」と「テレビ東京」の単語生起コストが、解析結果1の値と等しくなっていることが分かります。
連接コストは、1354, 1352以外に0も必要になります。0はBOS/EOS。つまり文頭と文末を意味します。文頭の言葉(今回は日本)は、自身の左に文脈IDが0の値がいるものとして計算されます。
連接コスト (matrix.dev)
| 左文脈ID | 右文脈ID | 連接コスト |
|---|---|---|
| 0 | 1354 | -996 |
| 1354 | 1352 | -2758 |
| 1352 | 0 | -941 |
連接コストも計算にいれて、「日本」の「連接+生起」コストを計算すると、3606 + -996 = 2610になります。これは「解析結果1」に表示されている「日本」の「連接+生起」コストと等しいことが分かります。
次に「テレビ東京」の「連接+生起」コストは、テレビ東京自身の単語生起コストの4752に、「1354 → 1352」の連結コスト-2758を足すことになるので、4752 + -2758 = 1994になります。「解析結果1」の「連接+生起(単独)」と等しい値になっていますね。
また「テレビ東京」の「連接+生起(累計)」は「日本」と「テレビ東京」のコストを足した、「2610 + 1994 = 4604」になっています。
最後に、これは「解析結果1」の出力には表示されていませんが、EOS(文末)への遷移もコストに加える必要があります。EOSの単語生起コストは0なので、文脈ID「1352 → 0」の遷移の分だけ加算します。
というわけで、最終的なコストは「4604 + -941 = 3663」になります。
計算式まとめ
「日本の生起コスト」 + 「文脈ID 0 → 1354の連結コスト」 = 「日本までのコスト」
3606 + -996 = 2610
「テレビ東京の生起コスト」 + 「文脈ID 1354 → 1352の連結コスト」 = 「テレビ東京のコスト」
4752 + -2758 = 1994
「BOS/EOSのコスト」 + 「文脈ID 1352 → 0の連結コスト」 = 「文末のコスト」
0 + -941 = -941
3つのコストを加算したものが、そのルートの総コスト
2610 + 1994 + -941 = 3663
では、次善の解析結果、「日本テレビ | 東京」に分割する場合のコストはどうなるでしょう。
解析結果2
| 表層文字列 | 左文脈ID | 右文脈ID | 単語生起コスト | 連接+生起(累積) | 連接+生起(単独) |
|---|---|---|---|---|---|
| 日本テレビ | 1352 | 1352 | 2988 | 1969 | 1969 |
| 東京 | 1353 | 1353 | 3188 | 4383 | 2414 |
単語生起コスト(naist-jdic.csvに記述)は、「解析結果2」の「単語生起コスト」と同じだということが分かっているので省きます。
連接コスト (matrix.dev)
| 左文脈ID | 右文脈ID | 連接コスト |
|---|---|---|
| 0 | 1352 | -1019 |
| 1352 | 1353 | -774 |
| 1353 | 0 | -658 |
以上のデータがあれば、計算可能ですね。
解析結果2の回答は少し下に書きますので、興味がある方は先に自身で計算をして答え合わせをしてみてください。
以下、解析結果2のコスト計算結果です。
もう少々スクロールしてください。
もう少々スクロールしてください。
解析結果2のコスト
日本テレビのコスト
2988 + -1019 = 1969
東京のコスト
3188 + -774 = 2414
文末のコスト
0 + -658 = -658
総コスト
1969 + 2414 + -658 = 3725
というわけで、解析結果2の総コストは3725でした。解析結果1が3663だったので、僅かに結果1の方がコストが低くなっています。
4回も計算しなくても、4383 - 658で一発じゃないかと思った方。その通りです。ただ、上のようにやった方が計算のイメージがつきやすいかなぁと思ってこう書きました。
実際にはMeCabさんはこの2つだけでなく、「日 | 本 | テ | レ | ビ | 東 | 京 」とか「日本 | テレビ | 東 | 京」など、考えられる全てのパターンを探索してくれています。
MeCabがどのレベルまでパターンを考えているか体感したい場合は、以下のコマンドが有効です。
echo 日本テレビ東京 | mecab -Odump
大量の解析に関わるdumpが出力されます。
2988 + -1019 = 1969
東京のコスト
3188 + -774 = 2414
文末のコスト
0 + -658 = -658
総コスト
1969 + 2414 + -658 = 3725
というわけで、解析結果2の総コストは3725でした。解析結果1が3663だったので、僅かに結果1の方がコストが低くなっています。
4回も計算しなくても、4383 - 658で一発じゃないかと思った方。その通りです。ただ、上のようにやった方が計算のイメージがつきやすいかなぁと思ってこう書きました。
実際にはMeCabさんはこの2つだけでなく、「日 | 本 | テ | レ | ビ | 東 | 京 」とか「日本 | テレビ | 東 | 京」など、考えられる全てのパターンを探索してくれています。
MeCabがどのレベルまでパターンを考えているか体感したい場合は、以下のコマンドが有効です。
echo 日本テレビ東京 | mecab -Odump
大量の解析に関わるdumpが出力されます。
まとめ
以上、「日本テレビ東京で学ぶMeCabのコスト計算」でした。
筆者はこれまでMeCabを使う際に、漠然とコストが関わってるのだなぁとしか考えておらず、どの数値をどう計算しているかも知らなかった為、この記事を書いて勉強になりました。
MeCabの計算はこれだけではなく、引数に「-l2」を付けると素敵な素敵な周辺確率の世界にも突入できますが、その辺りはまた、別の機会にということで。
本記事がこれからMeCabに入門する方の一助となれば幸いです。
筆者はこれまでMeCabを使う際に、漠然とコストが関わってるのだなぁとしか考えておらず、どの数値をどう計算しているかも知らなかった為、この記事を書いて勉強になりました。
MeCabの計算はこれだけではなく、引数に「-l2」を付けると素敵な素敵な周辺確率の世界にも突入できますが、その辺りはまた、別の機会にということで。
本記事がこれからMeCabに入門する方の一助となれば幸いです。

