XSモジュール作る上で特に参考になったなんか

XS6日勉強しただけのど素人ですが、CPANにうpまでは行き着いたので、参考になったWebページ・動画など紹介したいと思います。

まず↓の2つでXSってなんぞやというのがなんとなーく分かると思います。

Shibuya Perl Mongersテクニカルトーク#9

  • Perl 5 internals の世界にようこそ – daisuke maki先生
  • はじめてのXS – ハマりどころはココだ – hirose31先生

ありがたいことに↓にニコニコ動画にテクニカルトークの動画あります。
http://www.nicovideo.jp/mylist/7281253

実際にXSを書き始めるにはひな形があると便利です。

自分は「Module::Setup」のデフォルトのXS flavorを使ってひな形を生成しました。

実際にXS書くにあたってまず参照しまくるのは↓の3つ

C++で書く場合は、http://www.johnkeiser.com/perl-xs-c++.html が参考になります。

XSを書く前に、XSUB, xsubpp, typemap もぞれぞれ何か調べておくと良いです。
あと、興味のあるXSモジュールを適宜参照してお手本にするといいかも。

typemap は最初見たときは「なんじゃこりゃー!」状態でしたが、Livedoor ブログのホームページから「XS site:http://blog.livedoor.jp/kurt0027/」で検索したら出てくるperlxs入門というのを、さっきの3つのperlguts, perlapi, perlxs のpodを参照しつつ確実に理解しながら読んでいくと理解できます。

理解できると、C++の vector< map<string, string> > をPerlのハッシュリファレンスの配列へのリファレンス(であってるかな?)にして返すこともできます。使い回しができるので、Perlの構造体からC構造体への変換、あるいはその逆の変換とかは全部typemapに書いておくと便利。

初めてtypemap書くと多分メモリリークが発生してしまいます。作ったプログラムに大量の入力を食わせつつ、別のとこで「ps u」とかコマンド打てば簡易的にメモリリークのチェックができます。(あまりLinux詳しくないので他にもっといいやりかたがありそう)

メモリリークの発生しない(しにくい)書き方は Xslateでお馴染み(?)の gfx先生の「XS基礎文法最速マスター」や「XSでメモリークを避けるたった一つの方法」が参考になります。

メモリリークの場所の特定法も、gfx先生の「Perlのメモリリークを見つける方法」が詳しいです。

printfデバッグは PerlIO_printf(PerlIO_stderr(), “hoge”); で出来ます。

Makefile.PLを書くときは「Module::Install::XSUtil 」を使うと便利。

なんかよくわからん動作するなというときは、makeしたら生成されるコードとxsのコードを見比べる良いです。

こんなもんか。

他のモジュールに継承されるかもしれない(してほしい)モジュールを作る場合は、さらに魔法を使うといいようです。(詳しくはMAGIC 構造体とかで ggrks です)

KyTeaのPerlラッパー「Text::KyTea」をCPANにうpしました

まだmetacpanにしか反映されていないけど。
https://metacpan.org/module/PAWAPAWA/Text-KyTea-0.01/lib/Text/KyTea.pm

卒研の評価実験するとか言ってたけど、PerlからKyTeaを使いたくなったので、今週はひたすらXSの勉強していました。

kyTeaというのは、公式サイトから引用すると「日本語など、単語(または形態素)分割を必要とする言語のための一般的なテキスト解析器」です。MeCabとの違いは、文脈によって読みを変えてくれるところ。「WEB+DB PRESS vol.64」によると「読みがなを適切に推定しれくれるツールはKyTea以前にはありませんでした」とのこと。

Ruby / Python は「Mykytea」というのを使えば使えるみたいだけど、Perl用のはCPANで探してもGitHubで探しても見当たらなかったので、XSで書きました。ちゃんとメモリリークも潰したので、インストールさえ成功すればガンガン使えるはずです。

モデルはいろいろ使えるようです。現時点で公開されているUTF-8のモデルを全部テストして、Text::KyTea上で適切に動くのを確認しました。

KyTea自体はVer.0.3.2でしかテストしていないので、古いバージョンでは動かない可能性ありです。

使い方はSYNOPSISを見れば一目瞭然です。cpan.orgにはまだ反映されていませんが、すでに反映されているmetacpanではなぜか文字化けしてます・・・。(文字化け解消法教えて ><)

↓のようなプログラムを書くと・・・
(追記:最新版のText::KyTeaでは↓のコードでは動きません)

#!/usr/bin/env perl

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

my $kytea = Text::KyTea->new;

my $results = $kytea->parse("金さんを売ると5000円の金を得られます");
print_result($results);

$results = $kytea->parse("長野県から来ました長野久義です。");
print_result($results);

$results = $kytea->parse("「かたなし」さんじゃなくて、小鳥遊さんです!");
print_result($results);

sub print_result
{
    my $results = shift;

    for my $result (@{$results})
    {
        print $result->{pron};
    }
    print "\n";
}

↓のような出力になります

きんさんをうるとUNKUNKUNKUNKえんのかねをえられます
ながのけんからきましたちょうのひさよしです。
「かたなし」さんじゃなくて、たかなしさんです!

MeCabよりはマシという感じなので、過度な期待はしないほうがいいです。
一番の上の文は金の玉にすると「かねのたま」になります。

UNKはうんこ・・・じゃなくてUNKNOWの略のはず。

Perlということで、Webプログラムで使うのも簡単だと思います。

なんというか・・・疲れた!

Perlでメモリリークと戦うとは思わなかった。

かなり知識得たので、参考にした記事とか動画とかも紹介していくかもです!

追記:
反映されました↓
http://search.cpan.org/~pawapawa/Text-KyTea-0.02/lib/Text/KyTea.pm

Ver.0.02 でparseメソッドの説明の追加とSYNOPSISの文字化けを解消しておきました。
(thanks to tokuhirom)

JavaScript 第5版 リリカルどくは なわけですが

最近「長島☆自演乙☆雄一郎」さんのコスプレが胸きゅんサプリで、早く入院したほうがいいような気がしてきたpawaです。

卒研の第一段階として作ったプログラムをCPANizeして迎えた研究会も終わり、「評価実験してもええよ★」という空気になりました。
そんなわけで、さっさと評価実験して今の研究を収束させて次のメインの研究に移ります。

読み進めていた、JavaScript 第5版もようやく読み終わりました。昔に比べて大分マシになったものの、jQuery(今やったらCoffeeScriptか)とか使わないとまだまだブラウザ間の互換性に問題あるんやなという印象。

まだまだ読んでおきたい本はあるけど、9月19日まで図書館閉まっててどうしようもないので、卒研に移行です。

今日は、評価実験の前に雑用を片付けようと思って、大学で出た就活の課題をしていました。進学でも進学の後の進路も書けということらしい。意外と企業の名前がでません。出てもあまり企業のサービスで遊んだりせずに資格取得・数学・プログラミングの勉強ばかりしてきたからか、よく聞くほげほげというサービスの実際のところがわからなかったり・・・。

使ってみたら良いけど、就活のために興味ある企業のサービスについて調べるのは逆なような気がする。自分が使ってる・自分が好きなサービスを提供してる・開発できそうなところじゃないと人生捧げられへんよな。(こんな学歴でこんなこといえるのか知らんけど)

最近インプット中心ですが、アウトプットはMA7でするかもです。今度はキモくないWebアプリをつくります(?)

JSに調教されたい

昔、ステータスバーに謎の文字列を流したり、「n回目の訪問ですね。初訪問からm日が経過しました」とか何の意味あるのか分からんメッセージを訪問者に通知するのに使われてたアレです。

JavaScript 第5版

「jQuery」出てから結構使うようになりました。なんとなく書いてもJavaScriptは動くけど、やはり一度ちゃんと学びたいと思って「JavaScript 第5版」始めました。

ページはPerlベストプラクティスをも超える600ページオーバー。1日150ページ進めたら4日+αで終わるやん。8月末までに読めたら嬉しいけど、さすがにキツいですね。

13時間/day ぐらいで進めていきます。

本の中でやたらめったら「JavaScriptクイックリファレンス」勧めてくるのがちょっとアレですね。4200円もするんだからクイックリファレンスも引っ張ったら取れるような感じでつけて欲しい。

適当に書いたコード↓

var ニャンコ先生 = "ねこカフェでぷりちーな私を愛でろ";

for (var i = 0; i < 10; ++i)
    document.write(ニャンコ先生 + "<br>");

アウトプット↓

ねこカフェでぷりちーな私を愛でろ
ねこカフェでぷりちーな私を愛でろ
ねこカフェでぷりちーな私を愛でろ
ねこカフェでぷりちーな私を愛でろ
ねこカフェでぷりちーな私を愛でろ
ねこカフェでぷりちーな私を愛でろ
ねこカフェでぷりちーな私を愛でろ
ねこカフェでぷりちーな私を愛でろ
ねこカフェでぷりちーな私を愛でろ
ねこカフェでぷりちーな私を愛でろ

車輪の再実装

CPANには既に「Algorithm::NaiveBayes」があるけど、勉強のため、オレオレナイーブベイズ分類器を自前で実装しました。

コード↓
https://github.com/pawa-/NaiveBayes-Classifier/blob/master/lib/Algorithm/MyNaiveBayes.pm

多項モデル・最大事後確率推定のナイーブベイズ分類器です。

ナイーブベイズ分類器を実装するより、「オブジェクト指向PerlでCPAN形式で作る」というのに数倍時間取られた。どのモジュール使えば良いかわからんし、Makefile.PLってなんやねん状態。

オークション(普通に買う金がなかったので)でゲットした「モダンPerl 入門」でも情報が足りなかった。

オブジェクト指向PerlはAny::MooseというMooseとMouseを適切に使い分けてくれるやつを利用して書きました。

自作ナイーブベイズ分類器使ってて気づいたけど、多項モデル・最大事後確率推定だと学習させまくると物凄く小さい値同士で比較しないといけなくなるんだけど、これであってるんか?

頻度1000ぐらいにするとアンダーフローするのでbignumモジュール読み込ませたけど、このモジュール使うと「Math::BigFloat」オブジェクトになるせいか、結果をData::Dumperとかでダンプするとおかしいことになります。
しかし、他にモデル変える以外でイイ方法知らんので妥協。

#!/usr/bin/env perl

use strict;
use warnings;
use Algorithm::MyNaiveBayes;

my $nb = Algorithm::MyNaiveBayes->new;

$nb->init;

$nb->add_instance( label => 'プラス',   attributes => { 'イイ'           => 3, '悪い'           => 1                        } );
$nb->add_instance( label => 'プラス',   attributes => { 'エキサイティン' => 2                                               } );
$nb->add_instance( label => 'プラス',   attributes => { 'イイ'           => 2, 'エキサイティン' => 1, '退屈'           => 1 } );
$nb->add_instance( label => 'マイナス', attributes => { '悪い'           => 1, '退屈'           => 3, 'ホビロン'       => 1 } );
$nb->add_instance( label => 'マイナス', attributes => { '悪い'           => 2, 'イイ'           => 1                        } );
$nb->add_instance( label => 'マイナス', attributes => { '悪い'           => 2, '退屈'           => 1, 'エキサイティン' => 1 } );

$nb->train;

my $result = $nb->classify( attributes => { 'ホビロン' => 3, 'エキサイティン' => 1 } );

for my $key (sort { $result->{$b} <=> $result->{$a} } keys %{$result})
{
    print $key . " " . $result->{$key} . "\n";
}
アウトプット
マイナス 0.0000957842937704289939057243088564552627483291627255420792375570215873852085104345072496737347493444762395086265729576992616467714706481004777241651800146071048
プラス 0.00003950617283950617283950617283950617283951703703703703703703703703703703703703703807407407407407407407407407407407407407411604938271604938271604938271604938271605

思った以上に勉強になりました。

研究で使ってるWebマイニングプログラムも結構イイ精度出てるのでCPAN形式のモジュールにしておきます。

have a break, have a git add

は○なのインターンシップに落ちたので、金はないけど時間はあるpawaです。

自然言語処理の本を1冊読みきって、Perlのオブジェクト指向の復習してGitの入門書も結構読めたので、githubを使って車輪(ナイーブベイズ分類器)の再実装しています。

私のgithubのページ:https://github.com/pawa-

他にも大量の顔文字集めて「Regexp::Assemble」使って正規表現を生成したらどうなるんやろ?とか思って遊んだりしてたけどカオスなことになりました。(並の人間では解読不能 恐らく集めた顔文字以外の顔文字にはほとんどマッチしないであろう正規表現ががが・・・)

時間はあるのでバリバリgit commitします。

リップルさん発見

リップル

$0.99 なのでもちろんiPhone制御したりしてくれないけど、かわいいですね。

YouTubeとかニコニコ動画にも探せばプレイ(?)動画出てきます。

日本のiPhoneでは残念ながら普通には入手できません。(日本のゲームのなのになんで?)

勉強のほうは、JSダイバージェンスからJSというと女子小学生だよなぁとか思いつつ女子小学生についてググったりでグダグダ勉強してますが、徐々にペースアップしています。

画像処理よりはるかに数学使ってるような気がしますわ。