Raw File
scaled_errors.clj
(ns clojush.experimental.scaled-errors
  (:require [clojure.math.numeric-tower :as math]))

(defn scaled-errors
  "A utility function for use in error functions, to implement error-scaling as described
   by Maarten Keijzer in Scaled Symbolic Regression, in Genetic Programming and Evolvable
   Machines 5(3), pp. 259-269, September 2004. This returns a sequence of scaled errors given
   a sequence of outputs, a sequence of targets, and a penalty. If there are any non-numeric
   items in the outputs, or if all of the outputs are the same, then all of the scaled errors
   will be equal to the penalty -- note that this means that you cannot use this method
   to solve a problem for which all targets are the same. An optional fourth argument,
   if true, causes the scaling slope and intercept to be printed; this is necessary for
   unscaling outputs of an evolved solution -- see examples/scaled_sextic.clj for an
   example."
  ([outputs targets penalty]
    (scaled-errors outputs targets penalty false))
  ([outputs targets penalty print-slope-and-intercept]
    (if (or (some #(not (number? %)) outputs) (apply = outputs))
      (doall (repeat (count outputs) penalty))
      (let [average-output (/ (reduce +' outputs) (count outputs))
            average-target (/ (reduce +' targets) (count targets))
            slope (/ 
                    (reduce +' 
                            (map (fn [target output]
                                   (*' (-' target average-target) 
                                       (-' output average-output)))
                                 targets
                                 outputs))
                    (reduce +'
                            (map (fn [output] (math/expt (-' output average-output) 2))
                                 outputs)))
            intercept (-' average-target  (*' slope average-output))]
        (when print-slope-and-intercept 
          (println "slope " slope ", intercept " intercept))
        (doall (map (fn [target output]
                      (math/expt (float (-' target (+' intercept (*' slope output)))) 2))
                    targets
                    outputs))))))
back to top