murawaki の雑記

はてなグループから移転してきました

JUMAN メモ

黒橋研究室で開発している日本語形態素解析JUMAN についてのメモ。

以前は研究室のページに置いていたもの。長く放置していて内容的に古くなっていたが、最近になって突然晒された。*1文書に日付を入れていなかったのが敗因。この機会に雑記に移すことにした。古くなっても日付を言い訳に使えるし。

以前は中の人だった。どこを直すかという問題意識があった。今は所属も変わって、しばらくはそういうのはいいかなという気分。かわりに、使っている人向けにぼちぼち書き換えようかと考えている。論文には書きにくい小ネタなども。

タスク: 日本語の形態素解析

形態素解析と言っているのは、以下の3つのタスクの同時処理。

  • 分割 (segmentation)
  • 品詞タグ付け (POS tagging)
  • 見出し語化 (lemmatization)

分割は、テキストを形態素に区切ること。形態素というとおっかないが、単語だと思っておけば良い。品詞は「名詞」や「動詞」など。見出し語化という表現は聞き慣れないが、「走れ」のように活用変化した形を基本形の「走る」に戻すこと。

世の中一般的には、形態素解析は分割 + 品詞タグ付け と説明されることが多いが、見出し語化にも触れた方が良いと思う。ここが語形変化のない中国語の処理と決定的に違うところ。中国語の処理と違って辞書ベースの手法が主流なのも、これが大きい。

「X分割」という表現は混乱している。word segmentation の場合、X は分割後の状態だが、text segmentation や query segmentation だと分割対象。

入出力フォーマット

  • 入力は1行1文
  • 出力は1行1形態素
    • 最後の行は EOS (end of sentence)

子ども こども 子ども 名詞 6 普通名詞 1 * 0 * 0 "カテゴリ:人 代表表記:子供/こども"
は は は 助詞 9 副助詞 2 * 0 * 0 NIL
リンゴ りんご リンゴ 名詞 6 普通名詞 1 * 0 * 0 "カテゴリ:植物:人工物-食べ物 ドメイン:料理・食事 代表表記:林檎/りんご"
が が が 助詞 9 格助詞 1 * 0 * 0 NIL
すきだ すきだ すきだ 形容詞 3 * 0 ナ形容詞 21 基本形 2 "代表表記:好きだ/すきだ"
EOS

形態素解析は非常に局所的な文脈しか見ないので、別に複数文を一度に入れてもあまり問題にならない。構文解析でそれをやると、計算量が爆発するし、結果が気持ち悪いことになる。

英数字記号は全角で入力されることを期待している。UTF-8 化 (後述) にあわせて半角入力でもそれなりに処理するようになった。しかし全角に変換しておくことを勧める。出力時のエスケーピングをちゃんとやっていないので、特に記号がらみで事故が起きやすい。

エンコーディング

長らく EUC-JP だった。外部の人が UTF-8 版を作ってくれた。しばらく放置されていたが、時代の流れに逆らえず正式に UTF-8 に移行した。

速度

MeCab とくらべると圧倒的に遅い。しかし中の人には「cat 状態」と認識されている。一般に、形態素解析の結果を受けて何かをしようとすると、後段の処理の方が比較にならないほど遅い。だから JUMAN の速度を改善する動機はとぼしい。

というか MeCab が頑張りすぎである。下手な英語の tokenizer よりもよっぽど速い。気合が違う。

解析結果をルールでゴリゴリ処理するようなアプリケーションを作っている人なら、JUMAN の速度は気にならないはず。でも、KNP で構文解析までやると遅い思う場合は、

juman | knp -tab -assignf

がお勧め。文節まとめあげ + 各種 feature 付与までで打ち切って構文解析をやらない。KNP が吐く feature をうまく使えば、解析結果に対するルールの再発明が減るはず。

内容物

  • プログラム
  • デフォルトの文法辞書
  • デフォルトの形態素辞書

プログラムは古色蒼然としてる。C で書いてある。辞書のデータ構造は、パトリシア木を ChaSen から借りてきたり、double array を MeCab から借りてきたり。

連濁対応などでプログラムの更新もたまにあるが、実質的に辞書のみの更新。

文法辞書と形態素辞書は利用者が自由に定義できるとマニュアルではうたっている。しかしデフォルト以外の辞書が配布されている例を知らない。

ChaSenMeCab は配布のレベルで、プログラムと辞書を分離している。それらに対する辞書としては IPADIC, NAIST jdic, UniDicなどがある。

ライセンス

マニュアルには3条項BSDライセンスが書いてある。このライセンスがプログラムだけでなく辞書に及んでいるかなどはよく分からない。中の人もあまりちゃんと決めていない。

よく分からない問題はいろいろある。最近 Wikipedia を加工して辞書を作っているんだけど、この辞書のライセンスはどうなるのか。テキストの解析結果には辞書の情報が大量に埋め込まれているけど、解析結果を配布するときどうなのかとか。頼まれて以前調べたけど、法律の専門家でも何でもないので私には正解が分からない。詳しい人に教えてほしい。

品詞体系

  • いわゆる益岡・田窪文法
    • 基礎日本語文法』の記述に結構忠実
    • 学校文法 (橋本文法) 系の ipadic の IPA 品詞体系も異なる
      • 相互の変換は困難
    • unidic は unidic で IPA 品詞体系とも違うらしい
      • KyTea のデフォルトモデルは、unidic の品詞の大分類 & 「語尾」(活用語の変化する部分を切り出したもの)

益岡・田窪文法に慣れると IPA 品詞体系には拒否反応が出る。ただ、ナ形容詞と判定詞の区別は微妙。活用変化がほとんど同じなので。

つべこべ言わずに統一してくれよという声はよく聞く。

処理内容

  1. 入力に対して、形態素辞書を引いて出力 (形態素列) の候補を列挙
  2. コストにより最適な候補を選択

候補の列挙

  • 辞書を引く
  • 未知語候補をその場で生成
  • 連濁候補は基本形に戻して辞書を引く
  • 反復型オノマトペはパターンにマッチするものをその場で生成
  • 非標準表記を標準表記に戻して引く

ChaSenMeCab は最初の2つしかやっていない。残りは JUMAN でも比較的新しく入った機能。MeCab だとチューニングしすぎていて入れにくそうな機能。そのうちちゃんと説明するかも。

候補の選択

  • 形態素辞書と連接辞書により、形態素と、形態素同士の連接にコストを付与
  • コスト最小のパスを選択

パラメータ (コスト)

このご時世に人手で設定している。まさに職人芸。単語の生起コストはいい加減でもわりと大丈夫。連接コストは頑張って調整してある。

ChaSen/MeCab はそれぞれ隠れマルコフモデル (HMM)、条件付き確率場 (CRF) により訓練データからコストを学習する。単語の長さがいろいろなので、hidden semi-Markov model や semi-CRF と言ったほうが正確かもしれない。

JUMAN、ChaSenMeCab とも、解候補は同じ構造 (lattice) で表現できる。解探索のアルゴリズムも同じ。コストの決め方に関する考え方が違うだけ。KyTea はまったく異なる。

精度は完全に MeCab に負けている。

ちなみに日本語版 Wikipedia は、長い間、JUMAN は「隠れマルコフモデル」を使っているという誤った説明をしていた。生暖かく見守っていたら、中の人によって修正されてしまった。

人手による連接コストには利点もある。ありえない連接が候補から除外できる。そもそも付属語の連接にはかなりの程度文法的な制約があって、可能な連接は限られている。

一方、MeCab は完全にコーパスから学習するので、あらゆる連接が可能。もちろん変な連接には大きなコストが設定されるので、普段は問題が顕在化しない。しかし、未知語が入ってきたときなどに、どう考えてもありえない解析結果を吐いたりする。MeCab も連接制約のホワイトリストブラックリストを作って入れたらいいのに。

ただ、特に文頭の連接制約はきつすぎて、くだけたテキストの解析がつらい。

同形

  • コストが同じ複数の候補は同形として出力
  • @ から始まる出力行があるもの
    • 出力は単に辞書引きの順番なので、どちらが正しいというわけでもない
    • 方針として、JUMAN は曖昧性の候補を列挙するのみ; 選択は KNP で行う

かぜ かぜ かぜ 名詞 6 普通名詞 1 * 0 * 0 "漢字読み:訓 カテゴリ:抽象物 代表表記:風/かぜ"
@ かぜ かぜ かぜ 名詞 6 普通名詞 1 * 0 * 0 "カテゴリ:抽象物 ドメイン:健康・医学 代表表記:風邪/かぜ"
で で で 助詞 9 格助詞 1 * 0 * 0 NIL
おくれた おくれた おくれる 動詞 2 * 0 母音動詞 1 タ形 10 "可能動詞:送る/おくる 代表表記:送れる/おくれる"
@ おくれた おくれた おくれる 動詞 2 * 0 母音動詞 1 タ形 10 "付属動詞候補(基本) 自他動詞:他:遅らせる/おくらせる 自他動詞:他:遅らす/おくらす 代表表記:遅れる/おくれる"
EOS

  • 同形が出力されるのは分割とコストが同じ場合のみという微妙仕様 (e.g., おさない == 幼い != 押さない) だが、結構使える
  • 同じコストになるのはコストを人手で調整しているから
  • くる:子音動詞ラ行 (繰る) と くる:カ変動詞 (来る) のように品詞が一部違っても同形になる

MeCab は同形の曖昧性を考慮せずにパラメータを推定しているので、どちらとも言えないような場合でも、とにかく一つの解に決めてしまう。N-best にすれば複数の解を出力するが、N をいくつにすれば良いかは事前にはわからない。 そもそも同形の曖昧性解消を N-gram の情報で行うのが適当とも思えないから、JUMAN/KNP の方針は妥当だろう 「おくれた」のような用言の曖昧性解消は、KNP が格フレームを使って行う。修士論文の成果だったと思う。最近の格フレームでどれぐらい正しく曖昧性解消できているかは誰もちゃんと調べていないはず。

辞書の整備方針

  • 形態素数は削減する方向
    • 基本語彙のみを人手で整備し、残りは自動獲得したい
    • 基本語彙には人手で様々な意味情報を付与
      • 意味情報: 形態素解析そのものでは使わないが、係り受け解析や応用処理で使う知識
      • e.g. 代表表記, カテゴリ, ドメイン, 可能動詞, 付属動詞候補(基本) など
  • 新聞記事に出てこない難しい単語や固有名詞などは、IPADIC の方が豊富
    • JUMAN/KNP を用いた日本語固有表現認識の論文でも、精度を上げるために MeCab の解析結果を参照するという変態的な処理をやっている
  • それ以外にも、なぜ登録されているのか不思議な形態素が辞書に残っていたりする

大人が読むテキストには普通出てこないようなひらがな表記も結構登録されている。「かぐ」(家具) とか。おそらく、小学生向けの辞書からの情報抽出を昔やっていたなごり。副作用も結構あって、「茄子」に対する「な子」のような変な混ぜ書きが悪さする。

代表表記

  • 基本語彙に付与されている
  • 表記ゆれをある程度吸収する
    • 風邪, かぜ -> 代表表記:風邪/かぜ
      • 代表表記は単なるキー
      • これが標準的な表記と主張しているわけではない

形態素よりも長いキーフレーズレベルでの表現の揺れの吸収は『キーワード蒸留型クラスタリングによる大規模ウェブ情報の俯瞰』が詳しい (ヒューリスティクスの塊)。解析に使う分には代表表記は便利。ユーザがいる問題設定だと、こんなものをユーザに見せるわけにはいかないので、処理中に、標準的な表記を代表表記といっしょに保持しておかないといけない。

カテゴリ・ドメイン

  • カテゴリは荒っぽい抽象化の単位
  • 付与されたカテゴリの半分ぐらいが「抽象物」
    • 卒論の成果
    • 設計ミスまがいだが、細分化しても取り分がなさそうだから放置してある

カテゴリ・ドメインは言葉の大雑把な分類。この2軸を組み合わせれば、大雑把な分類としては十分ではないかという見通しだったらしい。 他には、シソーラスを使うと権利の問題がややこしいから、独自に作ったとか。

カテゴリは省略解析などで実際に使われている。

かつて、カテゴリ (のサブセット) を自動分類しようとしてひどい目にあった。いまでもトラウマ。そもそも意味的な情報を形態素という単位に与えるところに無理がある。人間の作業者が、直感に基づいて適当に割り当てる分には良いかもしれないが、データに基づいて決めさせようとすると、そのいい加減さに計算機が耐えられない。

その他の意味情報

  • 付属動詞候補(基本)
  • 可能動詞
    • 元の動詞 (戻せる -> 戻す)
  • 自他動詞などの対応関係
    • 自動詞や他動詞、形容詞派生など

「可能動詞」ラベルは、可能で使われる可能性があることを示すだけで、文中の個々の形態素が可能動詞の用法で使われているとは主張していない。これに限らず、JUMAN/KNP では、可能性があるために付与されている情報と、解析の結果 (いくつかの可能性の中から選択された結果) 付与された情報があまり整理されないまま混在している。

自他の対応などは、構文レベルの表現のゆれの吸収を目的に付与してある。

読み

辞書に代表的な読みが書いてある。解析時には辞書引きした結果を表示しているだけ。テキスト中での正しい読みを当てる気はない。数字の読み、音・訓の区別、表記に反映されない連濁の区別は間違っている可能性が高い。

だから転写や音声合成には使えない。UniDic はこのあたりもちゃんとやる方針らしい。いまの形態素解析器が使っている手がかりだけで正しく判別できるのか疑問だけど。

形態素の単位

以前辞書を整理した際に、構成的な語を削除しまくったらしい。それでも単位の不統一は残っている。

テキストの分割方法として、これが正しい単位だという基準が設定できない。辞書に載っているということが一種の基準になってしまっている。

「揺れの少ない斉一な単位」をうたう UniDic でも、直感に反して、「寿司屋」と「家具屋」で分割が違うらしい (未確認)。漢語と和語で扱いが違うとのこと。UniDic は踏み込みたくない領域に踏み込んでいる。

可能性に基づく品詞体系

「可能性に基づく品詞体系」という用語は IPADIC で使われているもの。JUMAN のデフォルトの品詞体系はこうは説明されない。しかし実質的に同じことをやっている。

例えば、「今年」は「今年の目標」であれば名詞として振舞っているが、「今年起きた事件」では連用修飾を行っており副詞的。辞書は「今年」に「名詞 - 時相名詞」という品詞を割り振っている。どちらの文の「今年」に対しても、この品詞を割り振っておしまい。IPADic は、その点を明確にしていて「名詞 - 副詞可能」という品詞が割り当ててある。名詞としても振る舞うし、副詞としても振る舞うということ。

文中でどのような振る舞いをしているかを当てに行くのをはなから放棄している。要するにインチキ。英語の品詞タグ付けとは大違い。

誰が名詞用法と副詞用法を区別しているかというと、文節まとめあげや係り受け解析で暗黙的に行っている。

一応区別はしているものの精度が悲惨な例もある。「で」の曖昧性問題。「京都は大学の町で観光地でもあります。」という例文では、「町で」の「で」は判定詞だが、「大学の街で観光した。」だと格助詞。いまの形態素解析器が見ているような局所的な手がかりでは区別しようがない。

動詞の連用名詞化

動詞の連用名詞化は、IPADIC では「可能性に基づく品詞」を採用していないけど、JUMAN では採用している。例えば動詞「遊ぶ」の連用形「遊び」。「外で遊び家に帰る」だと動詞用法だけど、「遊びを楽しむ」だと名詞用法。IPADIC では、動詞と名詞の両方が辞書登録してある。しかし MeCab の解析結果は不安定。「買いに行く」の「買い」をいろんな動詞に入れ替えてみると、名詞と解析されたり、動詞と解析されたり。

JUMAN はいずれの用法でも動詞の「基本連用形」とする。名詞用法のものは KNP が名詞に変換するという運用。この変換はちょっと面倒。名詞にすると活用しない扱いなので、見出し語 (JUMAN 用語では原形) もあわせて「遊ぶ」から「遊び」に変更しないといけないとか。こういう変換処理がプログラム内にベタ書きしてある。

JUMAN 的には KNP の担当になっているが、名詞用法の判定は難しい。上記の「外で遊び家に帰る」なら「遊び家」という複合名詞はありえない。「彼を操り人形にした」なら「操り人形」という複合名詞を採用する解釈が自然。「彼を操って人形にした」という解釈も可能だけど。KNP はどう処理しているかというと、明らかなものはルールで決め、残りはウェブコーパスから作った共起の統計量をもとに判定している。

京大テキストコーパスは KNP 仕様で、名詞と動詞の用法を区別している。MeCab のもととなった CRF モデルの論文の比較実験が、このあたりをどう処理したのか、いまだに把握していない。

その他の雑多な問題

悩ましい問題はいろいろあって、京大テキストコーパスアノテーションガイドで言及されている。形態素関連は3節。

コーパスアノテーションガイドはいろんな知見がつまっていて面白い。みんなもっと読んだらいいのにと思う。

*1:Internet Archive によると2009年1月には移設前の状態だったみたい。