KiyuHub

メシと寝所と呼吸と

このエントリーをはてなブックマークに追加

MeCabの分かち書きの出力を基本形で行う

<訂正>

こちらの記事に,同じ話題をより良い方法で実現する方法があると教えていただきました.

MeCabの出力フォーマット - 唯物是真 @Scaled_Wurm

公式の 出力フォーマット一覧 も改めて見たらちゃんと乗ってました,流し読みしてしまっていた...

必要になったので,MeCabの分かち書き(-Owakati)での出力を, 表層形でなく基本形として出力するオプション(-Owakati_lemma)を追加で書いてみました.

% echo "諦めんなよ!" | mecab -Owakati
諦めん な よ !
% echo "諦めんなよ!" | mecab -Owakati_lemma
諦める な よ !

MeCab

自然言語処理界隈で知らない人はいないであろう,オープンソースの形態素解析エンジン.

Wikipedia記事: http://ja.wikipedia.org/wiki/MeCab

公式ページ: http://mecab.googlecode.com/svn/trunk/mecab/doc/index.html

自然言語処理関係者でなくても,テキストを使ったウェブアプリを 開発している人たちにも広く利用されていると思う,

例として”MeCabで形態素解析を行うとこうなる.”という文をMeCabにかけると

% echo "MeCabで形態素解析を行うとこうなる." | mecab
MeCab      名詞,一般,*,*,*,*,*
で      助詞,格助詞,一般,*,*,*,で,デ,デ
形態素  名詞,一般,*,*,*,*,形態素,ケイタイソ,ケイタイソ
解析    名詞,サ変接続,*,*,*,*,解析,カイセキ,カイセキ
を      助詞,格助詞,一般,*,*,*,を,ヲ,ヲ
行う    動詞,自立,*,*,五段・ワ行促音便,基本形,行う,オコナウ,オコナウ
と      助詞,接続助詞,*,*,*,*,と,ト,ト
こう    副詞,助詞類接続,*,*,*,*,こう,コウ,コー
なる    動詞,自立,*,*,五段・ラ行,基本形,なる,ナル,ナル
.      記号,句点,*,*,*,*,.,.,.
EOS

という結果が得られる. echoで渡さずに,単に mecabとコマンドラインに打っても実行できる. この場合は入力待ち状態になるので,好きな文を入力するとすぐさま結果が出力される.

そして, 分かち書き とは,上の結果まで詳細に品詞などの情報は必要なく, 単に文が形態素で区切られた形だけ欲しいという時に使える.

具体的には,実行時に”-Owakati”という出力形式のオプションを渡せばOK. (出力形式は他にも”-Ochasen”,”-Oyomi” などもある他,ユーザで定義することもできる)

% echo "MeCabで形態素解析を行うとこうなる." | mecab -Owakati
MeCab で 形態素 解析 を 行う と こう なる .

このように,形態素が半角スペースで区切られた文が出力される.

なぜ分かち書き?

英語のテキストはデフォルトで半角スペース区切りされているので, 英語用に開発されたソフトウェアには,入力として生の英語テキストを入力としたもの存在する.

つまり 単語が半角スペースで区切られた文たち を入力として受け取るシステム.

そんな時に分かち書きを使うと,日本語テキストを,そのシステムに入れるための形に 変換するためのスクリプトをわざわざ書かずに,コマンドライン上で解決することができます.

% meacb -Owakati < ja.txt > ja_wakati.txt

このように,リダイレクションを用いて分かち書きされたコーパスに変換できます.

なぜ見出語?

文中に出てきた表現は格変化などが起きるが,もちろん辞書中にはそれに対応する基本形 が存在します.(辞書の”見出し語”と言うことも.)

MeCabの標準的な出力では,コンマ区切りの7番目の要素にこの情報が含まれます.

% echo "形態素解析すりゃいいだろ!!\n形態素解析しろや!!!" | mecab
形態素  名詞,一般,*,*,*,*,形態素,ケイタイソ,ケイタイソ
解析    名詞,サ変接続,*,*,*,*,解析,カイセキ,カイセキ
すりゃ  動詞,自立,*,*,サ変・スル,仮定縮約1,する,スリャ,スリャ
いい    形容詞,非自立,*,*,形容詞・イイ,基本形,いい,イイ,イイ
だろ    助動詞,*,*,*,特殊・ダ,未然形,だ,ダロ,ダロ
!      記号,一般,*,*,*,*,!,!,!
!      記号,一般,*,*,*,*,!,!,!
EOS
形態素  名詞,一般,*,*,*,*,形態素,ケイタイソ,ケイタイソ
解析    名詞,サ変接続,*,*,*,*,解析,カイセキ,カイセキ
しろ    動詞,自立,*,*,サ変・スル,命令ro,する,シロ,シロ
や      助詞,接続助詞,*,*,*,*,や,ヤ,ヤ
!      記号,一般,*,*,*,*,!,!,!
!      記号,一般,*,*,*,*,!,!,!
!      記号,一般,*,*,*,*,!,!,!
EOS

上の文で すりゃしろ も,基本形は する であり, コンマで区切られた7番目の要素を見ると,基本形の する が記されていることが分かります.

一般に,これらは全部 する なわけですから,全部 する にしてしまってから 処理してしまったほうが良いです. する , しろ , すりゃ ,という別々の単語が 一回ずつでた,と考えるよりも, する が3回出たと扱うわけです.

ですが,デフォルトの分かち書きオプションでは,表層形を分かち書きしたものが出力されるので, 分かち書きした上で見出語に変換してあると助かります.

イメージしやすいように,仮想のオプション-Owakati_lemmaを導入すると.

% echo "諦めんなよ!" | mecab -Owakati
諦めん な よ !
% echo "諦めんなよ!" | mecab -Owakati_lemma
諦める な よ !

といった機能があると,助かったりします.

wakati_lemmaを導入するパッチを書いた

こちらのGist にあげているので,当て方や使い方はそこのREADMEを参照して下さい.

処理としては,まず未知語(辞書に未登録野語,読みや基本形が”*”)かチェックし, 未知語なら表層形をそのまま出力し, そうでない場合は,文字列の後ろから”,”を手がかりにして,基本形に該当する部分文字列を取得しています.

おまけ1 パッチの作り方

パッチの作り方については以下の記事が参考になりました.

[機械学習]LibSVMのcross validationオプションでprecision/recallを出力する

基本的には,この記事と同じです.簡単! ただし,今回はヘッダーファイルにも変更を加えているため,二つパッチを用意するのかー? と思ったが,試したら以下のように追加で書き込むだけで大丈夫だった.

% diff -u writer.cpp writer-new.cpp > writer.patch
% diff -u writer.h writer-new.h >> writer.patch

おまけ2,awkで基本形辞書

コーパスから,そこに含まれている単語に通し番号をつけるという処理もよく必要になります.

% mecab < corpus.txt | cut -f1 | sort | uniq -c | sort -nr | awk '{print NR"\t"$2}' > dic.txt

たとえば,こうやってパイプでつないでいくと,出現頻度順に並んだ, 番号付きの単語一覧ファイルdic.txtが出来上がります.

ただしこれは,表層形で辞書を作っているので, この時に,wakati_lemmaと同じように,未知語以外は基本形に直すという処理に変更すると,

% mecab < test.txt | awk -F"\t|," '{print $8 == "*" ? $1 : $8}' | sort | uniq -c | sort -nr | awk '{print NR"\t"$2}' > dic3.txt

たとえばこう書けます.たまに使うけどawk便利.

これで,基本形での分かち書きされたテキストコーパスと, そのコーパスに出現した通しid付きの辞書ができたので, コーパスをid列に変換するみたいな,後の処理に使えます.

このエントリーをはてなブックマークに追加