ぽこひでブログ

ほのぼの大学4年をやってる [ぽこひで] の学生エンジニアブログ?

Rubyでm * n行列をかっこよく作って足してみた

こんばんは。
火曜日は1,2限に「パターン認識学」の講義があって、今日は2とか9とかのこんな感じのパターンを学習させて未知のパターンの数字を認識させる、みたいな講義でした。
f:id:hdye82647:20150428231902g:plain
やることは簡単で、まずこの5つの9のデータ白が0、黒が1だとしてそれを5*5行列として読み込んでそいつのセルごとの総和をプロトタイプ(5*5)として、未知の数値を判断してみよーって感じでした。

このデータの表現方法は自由だったので、僕は左上の9を
01110 01001 01111 00001 00011 (実際にスペースはないけど見やすそうなので)
といった感じに左上から右下に順に走査していく感じで表現して、この文字列をプログラム内で行列化してやろー的な目論見でこれが最初のコード。

def matrix(str)
  mat = Array.new(5,0).map{Array.new(5,0)}
  i = 0
  while str[i]
  for j in 0...5
    for k in 0...5
      mat[j][k] = str[i]
    end
  end
  i+=1
  end
end

みたいな感じで冗長すぎてruby使う意味が一切感じられないクソみたいなコードでした。。これはあまりにもかっこ悪いってことでStringクラスとかもう一回復習してみて、かなり改善したのがこれ。

def matrix(str,m,n)
  exit unless str.size == m*n
  return str.split("").map(&:to_i).each_slice(m).to_a
end

しかもm*n行列に対応できました。ただ、サイズがm*nじゃなかったら帰れ!ってことにして勝手に入力が整数文字列に限定していますが、整数文字列を1文字ずつsplit("")で分解して、それぞれをto_iで整数にします。この時点では
[1,2,3,4,5,6,7,8,9]
こんな感じのただの整数配列。こいつをm文字でスライスして配列に変換してやると1行でいい感じになりました!
試しに最初の9のデータを入れてやると

str = "0111001001011110000100011"
p str.split("").map(&:to_i).each_slice(5).to_a  
    #=>[[0, 1, 1, 1, 0], [0, 1, 0, 0, 1], [0, 1, 1, 1, 1], [0, 0, 0, 0, 1], [0, 0, 0, 1, 1]]

と一発で5*5行列に変換してくれました。
あとそのm*n行列同士の和を計算したかったので、これはどっかのサイトさんのコメントを参考(ほぼパクリ?)にして

  def sum(mat1,mat2)
    return [mat1.flatten,mat2.flatten].transpose.map{|a| a.inject(:+)}.each_slice(m).to_a
  end

この1行で行列の加算が完了しました。

x = [[0, 0, 1, 1, 1], [0, 1, 0, 0, 1], [1, 1, 1, 1, 1], [0, 0, 0, 1, 1], [0, 0, 0, 1, 0]]
y = [[0, 1, 1, 1, 0], [0, 1, 0, 0, 1], [0, 1, 1, 1, 1], [0, 0, 0, 0, 1], [0, 0, 0, 1, 1]]
sum(x,y)
#=>[[0, 1, 2, 2, 1], [0, 2, 0, 0, 2], [1, 2, 2, 2, 2], [0, 0, 0, 1, 2], [0, 0, 0, 2, 1]]

とうまくいきました。どちらも1行で綺麗にかけたので満足でした。講義のレポートはまだ終わってないんですが。。。こうやって綺麗にかけるとなんかやっぱruby楽しい!ってなりますね。行列計算とか綺麗に書きたい方の参考になったらなと思います。

「寄生獣 完結編」見てきた(^O^)/

こんばんは。
今日は寄生獣の完結編を見てきました!
映画は好きなんですが、あんまり邦画は映画館で見たことなかったので前編も映画館で見る気はなかったんですが、先週くらいに完結編の前売りを買ったら500円で前編を復習上映ってことでもう一度観れる機会があったので、ついつい見ちゃいました!
っていっても、お目当ては寄生獣前編ではなかったんですがw

寄生獣 完結編の主題歌「コロニー」のPVが映画館の劇場でフルで観れる!ってことでBUMP好きとしてはうれしい限りで滅多にない事だったので見に行ってきました。てなわけで完結編の前売りも買っちゃったことだしってことで今日見に行ってきた次第です。

こっからは個人的な感想なのでもしかしたら気分を害するかもしれません。↓

前編も見て感じた事なんですが、何というか全体的に静かな感じの映画なのに異常なくらいBGMが大きい!これこそ反感を買う言い方でしょうが、静かなシーンとかを無理にBGMで盛り上げようとしている感じがして、そこは見てて気になっちゃいました。
それと、役柄の設定的に寄生虫に取り憑かれてる人たちがでて喋ったりしてるんですが、その設定のせいで言葉が拙い。まぁこれは役柄上仕方ないのでしょうが、なんか話のテンポがゆったりしすぎて逆に会話が聞き取りにくかったりしました。他にも、話に結構矛盾点というかおかしな点がいくつかあったり、橋本愛はなんで動物園に行ったとわかったのかとか、なぜ市役所が寄生獣の溜まり場だと警察がわかったのかとか、なぜか殺人犯が最後にシャバに出ていて、橋本愛を襲ったり。。。そういうの突っ込まなければ見てて楽しかったです!w

浅野忠信と染谷との一騎打ちのシーンの直後に染谷と橋本愛のベッドシーンがあったり、展開が早すぎてベッドシーン終わったらまた浅野忠信との一騎打ち再び!って感じでなんでベッドシーンはさんだwってなりましたw まぁ橋本愛のベッドシーン見れたのは貴重だったので網膜に焼き付けときました。そして、最後に「えっこんなシーンいるか?w」っていうシーンが出てきたのですが、映画見終わった後にグーグル先生で監督の「山崎貴」って調べてみたら最後のシーンを撮りたかった意図がなんとなくわかってつい笑っちゃいましたw

批評ばっかになっちゃいましたが、映画館の雰囲気が好きなので、これから邦画も映画館で見ていきたいなって思いました。進撃の巨人の実写は見るの正直怖いですがw 予告編に巨人がCGと丸わかりのCGで襲ってくるシーンがあるのですが、そのシーンがあまりに一瞬で、映画中に巨人がしっかり写ってるシーンが少なそうだなーってのが第一印象でした。近づいたら見に行くか決めたいですね。

映画もとったことない奴の生意気な批評?でした。(笑)

人工無能で会話してみた n-gram編(1)

はじめまして。大学の前期授業も始まって今年から人工知能の講義があったので、試しに図書館にあったこの「はじめてのAIプログラミング」を読んでみました!

はじめてのAIプログラミング―C言語で作る人工知能と人工無能

はじめてのAIプログラミング―C言語で作る人工知能と人工無能

実装はC言語なんですが、年明けからRubyを勉強し始めてからC言語の冗長性になんか嫌気がさしてしまったので、自分なりに拙いプログラムながらRubyで実装してみました。

読んでみると「はじめて」とうたってるだけあって、最初の方はかなりわかりやすくて読んでいて楽しかったです。その内容を少しずつ紹介できたらなと思います。

基本的にこの本の7割近くは人工無能の話で、人間と対話するにあたってどのような技術が使われてきたかをCのソース付きで解説してくれています。その中でも、最初に紹介されていたn-gram法とマルコフ連鎖を今日は自分のメモがてらここに。

簡単な人工無能で会話するために、まず学習させる文章を用意します。夏目漱石とか古い感じの書籍だと著作権が切れてて無料でインターネットに載ってたりするので今回はそれを活用する。

まず、その文章をn-gram法といって、n文字ずつのまとまりに区切ってその表れ方を解析する方法で、文章の特徴を知ります。例えば2-gram法で

    「明日は晴れだ。」-> [明日],[日は],[は晴],[晴れ],[れだ],[だ。]

と区切れます。この方法で区切ったこの2文字列を何か配列に格納して、2文字列が文章内に何回出現したかを記録していきます。これをつたないプログラムで書くと

@list = {}
def ngram(n, text)
 i = 0
 while(text[i+n-1]) do
  @list[text[i,n]]? (@list[text[i,n] += 1) : (@list[text[i,n]] = 1)
  i += 1
 end
end

となります。何らかの文章(text)と何文字ごとに分解するか(n)を引数で渡して、例えば3文字なら、3文字先の文字が存在しなくなるまで、while文で繰り返して、もし既にその3文字列が存在すれば+1を、まだ存在しなかったら1回出現したので1を格納する。といった動作をします。

実際に実行してみると

ngram(2,"私は日本人です。私は中国人です。あなたは何人ですか?")
#=> {"私は"=>2, "は日"=>1, "日本"=>1, "本人"=>1, "人で"=>3, "です"=>3, "す。"=>2, "。私"=>1, "は中"=>1, "中国"=>1, "国人"=>1, "。あ"=>1, "あな"=>1, "なた"=>1, "たは"=>1, "は何"=>1, "何人"=>1, "すか"=>1, "か?"=>1}

と@listに格納されるので、とりあずこれでn-gram法は完成ということで。
次回はこのn-gram法で作ったn文字列をマルコフ連鎖で繋げてそれっぽい?会話をできる人工無能を頑張って作りますっb