灯で形態素解析もどき&マルコフ連鎖で文章作成
タイトル通りのことをやってみました。
形態素解析もどきの関数はJavaScript で形態素解析もどき - エブログを、
重み付きランダム選択の関数は重み付きランダム - 永字八法を参考にしました。
array simple_analyzer(string _s) { string _regex = "([一-龠々〆ヵヶ]+|[ぁ-ん]+|[ァ-ヴー]+|[a-zA-Z0-9]+|[a-zA-Z0-9]+|[,.、。!!??()()「」『』]+|[ ]+)"; string _joshi = "(でなければ|について|ならば|までを|までの|くらい|なのか|として|とは|なら|から|まで|して|だけ|より|ほど|など|って|では|は|で|を|の|が|に|へ|と|て)"; array _token; array _result; array _rep_joshi = _strsplit(_regex_replace(_s,_joshi,"$1"+_bytechar(1)),_bytechar(1)); for (int i = 0;i < _aryvn(_rep_joshi);i++) { _token = _strsplit(_regex_replace(_rep_joshi[i],_regex,"$1"+_bytechar(1)),_bytechar(1)); if (_aryvn(_token) != 0) { for (int j = 0;j < _aryvn(_token)-1;j++) { _result += _token[j]; } } } return _result; } int random(int _min,int _q) { int _number = _q + 1; int _result; while(1) { _result = _rand()%_number; if(_result >= _min) break; } return _result; } string weight_choice(dict _weighted) { int _max = 0; int _count = _dicvn(_weighted); int _res; array _keylist = _dickeyget(_weighted); for(int i = 0;i < _count;i++) { if (_max < _weighted[_keylist[i]]) _max = _weighted[_keylist[i]]; } _max--; while(1) { _res = random(0,_count-1); if(_weighted[_keylist[_res]] > random(0,_max)) break; } return _keylist[_res]; } string malkovChainString() { string _raw = "メロスは激怒した。必ず、かの邪智暴虐の王を除かなければならぬと決意した。メロスには政治がわからぬ。メロスは、村の牧人である。笛を吹き、羊と遊んで暮して来た。けれども邪悪に対しては、人一倍に敏感であった。きょう未明メロスは村を出発し、野を越え山越え、十里はなれたこのシラクスの市にやって来た。メロスには父も、母も無い。女房も無い。十六の、内気な妹と二人暮しだ。この妹は、村の或る律気な一牧人を、近々、花婿として迎える事になっていた。結婚式も間近かなのである。メロスは、それゆえ、花嫁の衣裳やら祝宴の御馳走やらを買いに、はるばる市にやって来たのだ。先ず、その品々を買い集め、それから都の大路をぶらぶら歩いた。メロスには竹馬の友があった。セリヌンティウスである。今は此のシラクスの市で、石工をしている。その友を、これから訪ねてみるつもりなのだ。久しく逢わなかったのだから、訪ねて行くのが楽しみである。歩いているうちにメロスは、まちの様子を怪しく思った。ひっそりしている。もう既に日も落ちて、まちの暗いのは当りまえだが、けれども、なんだか、夜のせいばかりでは無く、市全体が、やけに寂しい。のんきなメロスも、だんだん不安になって来た。路で逢った若い衆をつかまえて、何かあったのか、二年まえに此の市に来たときは、夜でも皆が歌をうたって、まちは賑やかであった筈だが、と質問した。若い衆は、首を振って答えなかった。しばらく歩いて老爺に逢い、こんどはもっと、語勢を強くして質問した。老爺は答えなかった。メロスは両手で老爺のからだをゆすぶって質問を重ねた。老爺は、あたりをはばかる低声で、わずか答えた。"; string _nexttoken = _bytechar(2); string _result; dict _malkov; array _analyzed = simple_analyzer(_raw); array _token; _analyzed += _bytechar(2); _analyzed += _bytechar(2); for(int i = 0;;i++) { if (_analyzed[i] == _bytechar(2) && _analyzed[i+1] == _bytechar(2)) break; else if (_malkov[_analyzed[i]+_bytechar(1)+_analyzed[i+1]] == nil) _malkov += $(_analyzed[i]+_bytechar(1)+_analyzed[i+1],${$(_analyzed[i+2],1)}); else if (_malkov[_analyzed[i]+_bytechar(1)+_analyzed[i+1]][_analyzed[i+2]] == nil) _malkov[_analyzed[i]+_bytechar(1)+_analyzed[i+1]] += $(_analyzed[i+2],1); else _malkov[_analyzed[i]+_bytechar(1)+_analyzed[i+1]][_analyzed[i+2]]++; } _token = {_analyzed[0],_analyzed[1]}; for (;;) { if(_token[0] == _bytechar(2) && _token[1] == _bytechar(2)) break; _result += _token[0]; _nexttoken = weight_choice(_malkov[_token[0]+_bytechar(1)+_token[1]]); _token = {_token[1],_nexttoken}; } return _result; }
関数malkovChainStringを実行するとこんな感じに走れメロスを分割して繋ぎ直します。
それだけですけどね。