‘Perl’ カテゴリーのアッー!カイブ

Text::KyTea Ver.0.30

KyTeaの開発関係者様から精度向上に関するアドバイスをいただいたので大幅更新。

1つ前のデベロッパーリリースではKyTea Ver.0.4.x しかテストをパスできませんでしたが、train-kyteaをユーザ側にさせることでVer.0.3.x でも Ver.0.4.x でも動く(テストをパスする)ようにしました。

表面的な変更はそれと h2z というテキストを全角にするオプションを加えただけです。

学習コーパスは全角なので、全角で parse($text) したほうが精度が向上すると助言をいただきました。
結果を返すときには全角に変換したものを元の形に戻します。

具体例を示すと以下の通り。
(入力:「2012年の8月」 KyTea Ver.0.4.0 モデルはデフォルト)

Text::KyTea Ver.0.30 より前

2/名詞/UNK 0/名詞/UNK 1/名詞/UNK 2/名詞/UNK 年/接尾辞/ねん の/助詞/の 8/名詞/UNK 月/接尾辞/がつ

Text::KyTea Ver.0.30

2012	 名詞/0.35774895512058	 にせんじゅうに/100
年	 接尾辞/2.32244382990404	 ねん/3.0526800626215
の	 助詞/3.62850370738557	 の/100
8	 名詞/3.99453840124872	 8/100
月	 接尾辞/2.92844001637078	 がつ/2.26476897940319

とまあこんな感じで半角文字の単語分割・読み推定ともに良くなるようです。

さあ、そろそろ院活しなくては!
まずは何やりたいのか明確にしたい。

プロセス監視

したくなちゃった♥

daemontoolsとかよく聞くけど、「Monit」と「Growl for Windows」と「Perl」と「Gmail」で組みました。(無駄に多い)
監視対象はほぼ24時間稼動のUbuntuのPC内で動いているPerlプログラム。

monitrcは↓のような感じ

set daemon 60 # 60秒おきに監視
set logfile syslog facility log_daemon
set mailserver smtp.gmail.com port 465 username "hoge@gmail.com" password "hoge" using SSLV3

set mail-format {
from: hoge@monit
subject: $HOST : $SERVICE - $EVENT
message: Monit
ACTION: $ACTION
$DESCRIPTION
at $DATE on $HOST.
}

set alert hoge@gmail.com

include /home/hoge/conf.d/*.conf

*.conf↓

check file tekito-na-program /home/hoge/pid/tekito-na-log
start = "/home/hoge/perl5/perlbrew/perls/perl-5.14.1/bin/perl /home/hoge/hoge.pl"
stop  = "/bin/bash -c 'kill `head -n 1 /home/hoge/pid/tekito-na-log`'"
if timestamp > 10 minutes then restart

という感じで書くと予期していた動きをしてくれました。

tekito-na-log には先頭行にプロセスID(hoge.plから書き込まれる)があって、先頭行以降はhoge.plからタイムスタンプが押されるファイルです。

これで10分以上更新されなかったら再起動してhoge@gmail.comにアラートが送られます(たぶん!)。
で、これをWindowsにも通知して欲しいので、GrowlとPerlでやりました。
Gmailのメールを通知するものが既にあるけど、通知するものを細かくフィルタリングしたかったのであえてPerlを使った)

「Growl for Windows」をインストールしてCPANモジュールの「AnyEvent::Gmail::Feed」と「Growl::Any」を組み合わせる(Strawberry Perl for WindowsのCPANを利用した)と↓のような感じでPCの画面の右上にピョコッと通知が出てきました。
(アイコンはリャマで画像検索して出てきたかわいいやつ)
Growl

「AnyEvent::Gmail::Feed」と「Growl::Any」で作ったPerlの通知プログラムはウィンドウが邪魔だったので「sexe」でサービス化しておきました。
(ファイルをPerlの絶対パス、起動時オプションを通知プログラムのパスにすればおk)

通知見忘れても時間でソートして見れるようでよかった。
Growlのログ

さらにmonitrcをいじるとブラウザで監視プロセス一覧が見れます。
Monit

同じような処理をcronでやってたけど、cronでやるより少し楽って感じです。
cronより細かく通知できるし見た目がイイ!
こういう方面は詳しくないんやけど、プロセス監視はこんな感じでいいんかな?

はじめての Kansai.pm

Text::KyTea のダメ出ししてもらいたいと思って、極度のあがり症の自分が無謀にも(?)通常トラックで発表しました。

一応口頭でも言ったけど、もっと本格的に分野のモデル作りたい場合は辞書追加したら、さらに精度あがるようです。

後ろのほうは聞こえづらかったようで申し訳ないです。ただでさえ声小さいほうなのにPC画面かなり凝視してしまっていて後悔。3月の学会発表ではガッチリ修正して、あのとき発表しておいて良かったと思えるようにせな。

誰かのスライドにちょこっと出てたけど、「pdca() while 1;」ですね。過去のせいにするな!

学会発表する分野は情報抽出です。海外の論文まで詳しく見る余裕なかったので、そのへんだけ不安です。

他の人の発表では、コードの自動生成が面白かった。

チャンスにチャレンジしてチェンジ

コスプレが本業の自演乙さんの校長のお言葉。

http://atnd.org/events/17949

で発表予定です。

ちょうど今日東京の勉強会で有名な方(確か准教授)のKyTeaの発表があったみたいですが、自分はもっと利用者向けのトークをする予定です。

KyTeaでツイート文形態素解析

Twitterのツイートを形態素解析できるモデルをチマチマチマチマとアノテーションして作りました。

とりあえず1000ツイートで学習させてみた結果↓

#!/usr/bin/env perl

use strict;
use warnings;
use Text::KyTea;

my $kytea = Text::KyTea->new(
    model  => 'twitter.mod',
    tagmax => 1,
);

while(<>)
{
    chomp;

    my $results = $kytea->parse($_);

    for my $result (@{$results})
    {
        print $result->{surface};

        for my $tags (@{$result->{tags}})
        {
            for my $tag (@{$tags})
            {
                print " ", $tag->{feature}, "/", $tag->{score};
            }
        }

        print "\n";
    }
}
おっぱいにも反応する…だとっ⁈\(^o^)/ぷるんぷるん!
おっぱい 名詞/1.58335520873588 おっぱい/100
に 助詞/0.582811764656452 に/100
も 助詞/2.56389603440279 も/100
反応 名詞/2.34565862532488 はんのう/100
する 動詞/3.24311969207749 する/100
… 補助記号/2.40081284738731 ・・・/2.61874614767905
だ 助動詞/3.14589428692411 だ/1.16998970505133
と 助詞/3.72388497325535 と/100
っ 語尾/1.57412493707867 っ/1.67440946485952
⁈ 補助記号/2.15166862072831 UNK/0
\(^o^)/ 顔文字/1.05802739830047 UNK/100
ぷるん 副詞/0.280931170551133 ぷるん/100
ぷるん 名詞/0.626540476457221 ぷるん/100
! 補助記号/3.33701371125112 !/100

(゚∀゚)o彡°おっぱい!おっぱい!
(゚∀゚)o彡 名詞/0.517448128267009 UNK/0
° 補助記号/2.32375812800788 UNK/0
おっぱい 名詞/1.80126948031546 おっぱい/100
! 補助記号/1.75798222256127 !/100
おっぱい 名詞/0.852339326477309 おっぱい/100
! 補助記号/2.51003707544082 !/100

ゴキブリもキライ(>_<)蚊も〜!!でも最大級は蛇。イヤ〜(ノ><)ノ
ゴキブリ 名詞/2.34331903441433 ごきぶり/100
も 助詞/4.05532730969976 も/100
キライ 名詞/1.43248054361402 きらい/100
(>_<) 顔文字/0.581317302582793 UNK/0
蚊 名詞/1.8817667808525 か/100
も 助詞/3.86853083949933 も/100
〜 補助記号/3.13874484501798 〜/100
! 補助記号/2.11586427709402 !/100
! 補助記号/1.90916550259136 !/100
で 助詞/2.33454157212243 で/100
も 助詞/3.10415455201607 も/100
最大 名詞/3.13286800717966 さいだい/100
級 接尾辞/2.22219138387336 きゅう/100
は 助詞/3.93302389402384 は/100
蛇 名詞/1.39660588253989 へび/100
。 補助記号/2.97742575533521 。/100
イヤ 名詞/0.457700740181369 いや/100
〜 補助記号/2.64583994777037 〜/100
(ノ><)ノ 名詞/0.171666624852277 UNK/0

もう少し鍛えれば顔文字抽出器としても使えそうです。

それにしてもLIBLINEAR速いですな。

さくらのレンタル鯖でText::KyTea

Text::KyTea をバージョンアップして、Text::KyTea Ver.0.22 からルート権限がなくてもカンチコチンにインストールできるようになりました。

KyTea のインストール時に「./configure –prefix=/home/USERNAME/local」みたいな感じでインストールしたとしましょう。
(インストール時にメモリ制限に起因するエラーが出ましたが、10回ぐらい繰り返したら入りました)

Text::KyTeaを「cpan」か「cpanm –interactive」か「cpanm -v」でインストールすると、「Path to lib directory of KyTea [/usr/local/lib]」「Path to include directory of KyTea [/usr/local/include]」というメッセージが出てきて入力できるので、前者には「/home/USERNAME/local/lib」、後者には「/home/USERNAME/local/include」と指定するとインストールできます。できるはずです。[]内の値はデフォルト値で、そのままエンター押せばデフォルト値が使われますが、今回はデフォルト値は使いません。
(インストールできなかったらここのコメント欄かGithubのIssuesにでもどうぞ)

適当にコード書くと↓のような感じで動きます
動作画面

かなりメモリ食うと思うので、モデルはKyTeaの公式サイトで配布されている圧縮SVM(UTF-8)がオススメです。

Lingua::JA::WordNet 封印解除

日本語WordNetのデータが必要になったので「WordNet::Multi」をインストールしました。
しかし、使いにくい・・・というわけでOOインターフェースで再実装してCPANにうpしました。

↓のような感じで使えます。

#!/usr/bin/env perl

use strict;
use warnings;
use feature qw/say/;
use Lingua::JA::WordNet;

my $wn = Lingua::JA::WordNet->new('./wnjpn.db');

my ($synset)      = $wn->Synset('コウモリ', 'jpn');
my ($mprt_synset) = $wn->Rel($synset, 'mprt');
my ($mprt)        = $wn->Word($mprt_synset, 'jpn');

say $mprt;
# -> ウイング

my ($def) = $wn->Def($mprt_synset, 'jpn');
say $def;
# -> 飛ぶための可動器官(一組のうちの1つ)

($synset)         = $wn->Synset('相撲', 'jpn');
my ($hype_synset) = $wn->Rel($synset, 'hype');
my ($hype)        = $wn->Word($hype_synset, 'jpn');

my $my_favorite_sport = 'パンツ' . $hype;

say $my_favorite_sport;
# -> パンツレスリング

パンツレスリングというと最近は↓の動画がお気に入りです。