LoginSignup
11

More than 5 years have passed since last update.

MeCabの分かち書き(-Owakati)を基本形で行う

Last updated at Posted at 2016-02-08

 ★解決済み

記事にコメントをいただき、もっと簡単な方法を教えていただきました。

$ echo 私は荷物を持って家を出た。 | mecab -F"%f[6] " -U"%m " -E"\n"
私 は 荷物 を 持つ て 家 を 出る た 。

MeCabの分かち書きオプション(-Owakati)の出力は表層形になる。

mecab -Owakati の出力形式

out.txt
私 は 荷物 を 持っ て 家 を 出 た 。

MeCabの分かち書きを基本形で

下記のように、分かち書き、かつ、基本形(辞書の見出語)の出力が欲しかった。mecabのオプションではできないらしい。

out_lemma.txt
私 は 荷物 を 持つ て 家 を 出る た 。

http://kiyukuta.github.io/2013/09/04/mecab_wakati_lemma.html
↑こちらの記事でパッチを作ってる方がいるのだが、今回はパッチを当てないで処理したかったのでスクリプト書いた。mecabの未知語の品詞推定はOFFにしたいので、'unk-feature' => '未知語' を指定している。

mecab_wakati_lemma.pl
#!/usr/bin/env perl

use strict;
use warnings;
use utf8;
use Text::MeCab;

# MeCabインスタンス
my $mecab = Text::MeCab->new( { 'unk-feature' => '未知語', } );  # 未知語に対して品詞推定を行わず"未知語"を出力

# 未知語用ラベル
my $unk_class = '未知語';
utf8::encode($unk_class);

while (<>) {
    my $n = $mecab->parse($_);

    while ($n) {
        if ( $n->feature
            =~ /^(.*?),(.*?),(.*?),(.*?),(.*?),(.*?),(.*?),(.*?),(.*?)$/ )
        {
            my $class_1 = $1;
            my $class_2 = $2;
            my $class_3 = $3;
            my $class_4 = $4;
            my $class_5 = $5;
            my $class_6 = $6;
            my $kihonkei  = $7;
            my $yomi_1  = $8;
            my $yomi_2  = $9;

            if ( $class_1 !~ /^BOS\/EOS/ ) {    # BOS/EOS 以外のとき
                print "$kihonkei" . " ";
            }
        }
        elsif ( $n->feature eq $unk_class ) {    # 未知語のとき
            my $unknown = $n->surface;
            print "$unknown" . " ";
        }
        $n = $n->next;
    }
    print "\n";
}

処理

$ ./mecab_wakati_lemma.pl input.txt

私 は 荷物 を 持つ て 家 を 出る た 。

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
11