1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

PRML1.1をClojureで書いてみた

Posted at

Qiitaに新規登録させていただいたので、とっても恥ずかしいレベルですが、PRMLの1章の始めのところをClojureで書いてみたものを共有します(まだ、ここまでしか進んでいません)。たぶん、もっとずっと綺麗な書き方があると思いますが、大目に見てください。

prml1_1.clj
(ns prml.prml1-1)

(use 'clojure.set)   ; incanter対策
(use '(incanter core charts))

; データ作成
(defn test-func [x] (sin (* 2 Math/PI x)))
(def x-values [0.0, 0.111111, 0.222222, 0.333333, 0.444444, 0.555556, 0.666667, 0.777778, 0.888889, 1.0])
(def true-y-values (map #'test-func x-values))
(def observed-y-values [0.349486, 0.830839, 1.007332, 0.971507, 0.133066, 0.166823, -0.848307, -0.445686, -0.563567, 0.261502])



; 式 1.1
; 係数がw-listであるようなxについての多項式。w-listの最初の項は定数項、次数は(- (count w-list) 1)
(defn func-y [x, w-list]
    (reduce + (map #(* (nth w-list %) (Math/pow x %))  (range 0 (count w-list)))))


; 式 1.2
; func-yについての二乗誤差関数。x-listは観測値のベクタ、t-listが真の値のベクタ。 w-listは係数項のベクタ。
(defn func-error [x-list, w-list, t-list]
  (if (== (count x-list) (count t-list))
    (* 0.5
       (reduce +
         (map #(Math/pow (- (func-y (nth x-list %) w-list) (nth t-list %)) 2.0)
           (range 0 (count x-list)))))
    nil
  )
)


; 式 1.4
; func-yについての二乗誤差関数を正則化。x-listは観測値のベクタ、t-listが真の値のベクタ。 w-listは係数項のベクタ。
; lambdaは罰金項
(defn func-error-with-penalty [x-list, w-list, t-list, lambda]
  (if (== (count x-list) (count t-list))
    (+ (* 0.5
       (reduce +
         (map #(Math/pow (- (func-y (nth x-list %) w-list) (nth t-list %)) 2.0)
           (range 0 (count x-list)))))
       (* 0.5 lambda (reduce + (map #(* (nth w-list %) (nth w-list %)) (range 0 (count w-list)))))
    )
      nil
  )
)


; 式 1.123
; 参考	http://d.hatena.ne.jp/aidiary/20100327/1269657354
; 多項式近似の解の計算(演習1.1)
(defn calc-a-sub [x-list, i, j]
  (reduce + (map #(Math/pow (nth x-list %) (+ i j)) (range 0 (count x-list)))))

(defn calc-a [x-list, m]
  (matrix (for [i (range 0 (inc m))]
                (for [j (range 0 (inc m))]
                  (calc-a-sub x-list i j)))))

(defn calc-a-with-penalty [x-list, m, lambda]
  (matrix (for [i (range 0 (inc m))]
                (for [j (range 0 (inc m))]
                  (if (= i j)
                    (+ (calc-a-sub x-list i j) lambda)
                    (calc-a-sub x-list i j)
                  )))))

(defn calc-t-sub [x-list, t-list, i]
  (reduce + (map #(* (Math/pow (nth x-list %) i) (nth t-list %))(range 0 (count x-list)))))

(defn calc-t [x-list, t-list, m]
   (matrix (map #(calc-t-sub x-list t-list %) (range 0 (inc m)))))

; 係数項ベクタの推定
(defn estimate [x-list, t-list m]
  (solve (calc-a x-list m) (calc-t x-list t-list m)))

(defn estimate-with-penalty [x-list, t-list m lambda]
   (solve (calc-a-with-penalty x-list m lambda) (calc-t x-list t-list m)))


; 誤差確認
(println "観測値に対する誤差確認")
(println (func-error x-values (to-vect (estimate x-values observed-y-values 3))  observed-y-values))
(println (func-error x-values (to-vect (estimate x-values observed-y-values 5))  observed-y-values))
(println (func-error x-values (to-vect (estimate x-values observed-y-values 9))  observed-y-values))
(println (func-error x-values (to-vect (estimate-with-penalty x-values observed-y-values 9 (Math/exp -18)))  observed-y-values))

(println "理論値に対する誤差確認")
(println (func-error x-values (to-vect (estimate x-values observed-y-values 3))  true-y-values))
(println (func-error x-values (to-vect (estimate x-values observed-y-values 5))  true-y-values))
(println (func-error x-values (to-vect (estimate x-values observed-y-values 9))  true-y-values))
(println (func-error x-values (to-vect (estimate-with-penalty x-values observed-y-values 9 (Math/exp -18)))  true-y-values))


; グラフ描画
(def plot (scatter-plot x-values observed-y-values :title "PRML1.1" :y-label "y value" :x-label "x value"))
(add-function plot test-func 0.0 1.0)
(add-points plot x-values true-y-values)
(add-function plot #(func-y % (to-vect (estimate x-values observed-y-values 9)))  0.0 1.0)
(add-function plot #(func-y % (to-vect (estimate-with-penalty x-values observed-y-values 9 (Math/exp -18))))  0.0 1.0)
(set-theme plot :dark)

(view plot)
1
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?