人工無能を作ってみるよみようとしてみるよ。

大学の自然言語処理の講義で、課題が出された。「自然言語処理についてのレポートを書くor人工無脳プログラムを作成する」の好きな方を選択してください、と。
最初は「伺か」的な、仕込んである特定のワードが出てきたら、それに反応するみたいな無能さんしか考えられなかった。
どうでもいいけど「伺か」のゴースト作って「自作の人工無脳です。テキストの他、マウスによるコミュニケーションも可能です。フレームワークとして、フリーソフト伺かを使用しました」とか言って提出したら不可もらうんだろうな。いや意外と可ぐらいくれねーかな。
でまあ講義が進んで、形態素解析のやり方、そして形態素解析フリーソフト「Juman」、「Chasen」などが簡単に紹介された。
というわけでフリーの形態素解析エンジン、MeCabを使用してみよう。

前置き。情報系の大学で落ちこぼれてるレベルの俺が書く程度の内容です。
まず大学の計算機(Vine Linux)にインストールしてみる。sf.jpからmecab-0.93.tar.gzと、mecab-ipadic-2.7.0-20060707.tar.gzをダウンロードしてきて

$ tar -zxf mecab-0.93.tar.gz
$ cd mecab-0.93
$ ./configure --prefix=$HOME
$ make
$ make install
$ cd ..
$ tar -zxf mecab-ipadic-2.7.0-20060707.tar.gz
$ cd mecab-ipadic-2.7.0-20060707
以下同様...

インストールできたっぽい。--prefix=$HOMEつけてあんのは、ユーザ権限しか無いから。ホームディレクトリ以下にポコポコbinやらlibやらできるのが嫌な人は--prefix=$HOME/localとかするといいんじゃないかな。
よし試してみよう。

$ mecab
こんばんは
こんばんは      感動詞,*,*,*,*,*,こんばんは,コンバンハ,コンバンワ
EOS
ええっ、これが噂の冷凍庫というやつですか。
え      フィラー,*,*,*,*,*,え,エ,エ
えっ    感動詞,*,*,*,*,*,えっ,エッ,エッ
、      記号,読点,*,*,*,*,、,、,、
これ    名詞,代名詞,一般,*,*,*,これ,コレ,コレ
が      助詞,格助詞,一般,*,*,*,が,ガ,ガ
噂      名詞,サ変接続,*,*,*,*,噂,ウワサ,ウワサ
の      助詞,連体化,*,*,*,*,の,ノ,ノ
冷凍庫  名詞,一般,*,*,*,*,冷凍庫,レイトウコ,レイトーコ
という  助詞,格助詞,連語,*,*,*,という,トイウ,トユウ
やつ    名詞,代名詞,一般,*,*,*,やつ,ヤツ,ヤツ
です    助動詞,*,*,*,特殊・デス,基本形,です,デス,デス
か      助詞,副助詞/並立助詞/終助詞,*,*,*,*,か,カ,カ
。      記号,句点,*,*,*,*,。,。,。
EOS

「こんばんは」と「ええっ、これが噂の冷凍庫というやつですか。」というのが入力。その下のゴチャゴチャしたのが出力。出力の形式は選ぶこともできる。

$ mecab -Owakati
そんなこと言われたって、もうどうしようもないだろう
そんな こと 言わ れ た って 、 もう どう しよう も ない だろ う

わかち書き(語のくぎりを分けた書き方)形式の出力もできる。-OchasenChasen互換の形式でも出力できるらしいけど、ChasenMeCabも同じくらい知らないのでパス。

すっげえ、なんかうまいこと認識してくれるんですけど! なんだか遊べそうなんですけど!! みたいな気分になりましたね。

なんかまあ、とりあえずPerlからいじってみますか。昔HelloWorldレベルのスクリプト書いて遊んだりしたこともあることだし。
sf.jpからmecab-perlを落として、

$ tar -zxf mecab-perl-0.93.tar.gz
$ cd mecab-perl-0.93
$ perl Makefile.PL
$ make

んで、ユーザ権限でのperlライブラリの入れ方調べるのめんどくさかったので、このディレクトリで色々書いてみた。

追記:ユーザ権限でのPerlライブラリの入れ方

$ perl Makefile.PL PREFIX=$HOME
$ make
$ make install

して、環境変数のPERL5LIBに$HOME/lib/perl5/site_perlとかでいける。bashとかなら.profile、cshとかなら.cshrcに書いておけば良い。

$ cat record.pl
#!/usr/bin/perl
use lib $ENV{PWD} . "/blib/lib";
use lib $ENV{PWD} . "/blib/arch";
use MeCab;

my $cmd = new MeCab::Tagger (join " ", @ARGV);
my $recfile = "bot.dic";

open(HF, ">>".$recfile)||die("file open error ");
while(<STDIN>){
  my $parse = $cmd->parse($_);
  print HF $parse;
  print $parse;
}
close(HF);
$ cat genstr.pl
#!/usr/bin/perl -w

my @buf;
open(DIC, "bot.dic");
while(<DIC>){
  #my $word = (split(" ", $_))[0];
  my $word = $_;
  if(/EOS/){next;}
  elsif(/。/){next;}

  push(@buf, $word)
}
close(DIC);
my $cnt = @buf;

print $cnt." words\n";
while(rand() < 0.8){
  print((split(" ", @buf[int(rand($cnt))]))[0] ." ");
}

print "\n";

record.plは入力した内容をそのままMeCabに渡す。その結果を標準出力とbot.dicというファイルに追加書き込みで出力。
genstr.plはbot.dicの中身から適当に文字を選んで、適当な個数繋げて出力します。ちゃんとした文章を出力できたら奇跡です。
使い方。record.plを呼んで、適当に文章を書いて辞書に登録させます。飽きたらgenstr.plを呼んで、変な文字列を出力させて喜びます。以上。

しばらく適当に入力した後、genstr.pl10連続呼び出し!

78 words
を 
78 words
でき 生成 だけ こんにちは に ランダム 
78 words
とか 並べ 
78 words
元気 
78 words
成熟 基本 に とか が 雨 嘘 エンジン の 重み 
78 words

78 words

78 words

78 words

78 words
に て の 重み こんにちは を ん 

こんなもんですよね。
ちなみにwhile(rand() <0.8)は平均で約4回程繰り返されます。perl -e '$sum=0;$n=0;while($n<100000){$i=0;while(rand() <0.8){++$i}$sum+=$i;++$n}print $sum/$n."\n"'を走らせた結果によると。
\sum_{n=1}^{\infty}{0.8^n}です。

なんか役にたちそうなサイトめも
人工無脳は考える
長岡技術科学大学 電気系 自然言語処理研究室
google先生、マルコフなんとかの文章生成方法を教えておくれ

test