パーセプトロンの練習

最近、機械学習に興味を持ち始めていて、SVMを実装してみようと思ったら、挫折したのでやはり段階を踏むべきであろうということでパーセプトロンから試してみた。

komamitsu/ocaml-perceptron · GitHub

  • perceptron.ml
let ($) f g = f g

let print x =
  Hashtbl.iter (fun k v -> Printf.printf "%s => %d    " k v) x;
  print_newline ()

let inner_prod w x =
  Hashtbl.fold (fun wk wv a -> a + wv * (Hashtbl.find x wk)) w 0

let classify w x =
  if inner_prod w x >= 0 then 1 else -1

let learn w x y =
  if classify w x != y then
    Hashtbl.iter
    (fun xk xv ->
      let wv = Hashtbl.find w xk in
      Hashtbl.replace w xk $ wv + xv * y) x

let learn_all n w set_of_x_y =
  for i = 1 to n do
    List.iter (fun (x, y) -> learn w x y) set_of_x_y 
  done;
  w

これがパーセプトロンで学習したり分類したりするもので、何というか手順をそのままコードに落としただけ。

  • sample.ml
(* 
 * ocamlc -c perceptron.ml && ocaml perceptron.cmo sample.ml
 *)
let ($) f g = f g

let vec_of_assoc assoc =
  List.fold_left (fun w (k, v) -> Hashtbl.replace w k v; w) (Hashtbl.create 4) assoc 

let train_src =
  List.rev $
    List.fold_left
      (fun train_src (assoc, y) ->
        let x = vec_of_assoc assoc in
        (x, y)::train_src) [] [
          ([("R", 255); ("G",   0); ("B",   0); ("bias", 1)], 1);
          ([("R",   0); ("G", 255); ("B", 255); ("bias", 1)], -1);
          ([("R",   0); ("G", 255); ("B",   0); ("bias", 1)], -1);
          ([("R", 255); ("G",   0); ("B", 255); ("bias", 1)], 1);
          ([("R",   0); ("G",   0); ("B", 255); ("bias", 1)], -1);
          ([("R", 255); ("G", 255); ("B",   0); ("bias", 1)], 1);
        ]

let print_result x =
  let s = if x = 1 then "warm" else "cool" in
  print_endline s

let _ =
  let init = vec_of_assoc [("R", 0); ("G", 0); ("B", 0); ("bias", 1)] in
  let w = Perceptron.learn_all 10 init train_src in
  Perceptron.print w;
  let x = vec_of_assoc [("R", 200); ("G", 100); ("B", 100); ("bias", 1)] in
  print_result $ Perceptron.classify w x;
  let x = vec_of_assoc [("R", 100); ("G", 200); ("B", 200); ("bias", 1)] in
  print_result $ Perceptron.classify w x

で、こちらがそれを利用するサンプルで、機械学習超入門III 〜機械学習の基礎、パーセプトロンを30分で作って学ぶ〜 - EchizenBlog-Zweiの暖色・寒色の例を使わせて頂きました。

実行するとこんな感じに。

komamitsu@carrot:~/lab/ocaml/perceptron$ ocamlc -c perceptron.ml && ocaml perceptron.cmo sample.ml
bias => 0    B => -255    R => 255    G => -255
warm
cool

それはそうと、OCamlでHashtblを簡単に構築できるリテラルPerlとかRubyみたいやつ)が欲しいなぁと思いました。camlp4を使った何かがあるのかなぁ。