Merge branch 'biased-downsampling-exp' into auto-ds-size

This commit is contained in:
Ryan Boldi 2022-10-13 09:27:25 -04:00
commit 7467f638a7
10 changed files with 558 additions and 19 deletions

View File

@ -646,7 +646,7 @@ _..^g2_\r~Ck,11
"}Guj<7\nk}\,\nK3jb",32 "}Guj<7\nk}\,\nK3jb",32
AT:c'0)bz3p`',21 AT:c'0)bz3p`',21
* .],0 * .],0
">9j4p8""S]0%\n%.7hH",21 ">9j4p8""S]0%\n%.7hH",20
.JX\nKF9\nP3W;b._DDS.(,40 .JX\nKF9\nP3W;b._DDS.(,40
" ~1\n}w!""",4 " ~1\n}w!""",4
\npnjy+{\nw,20 \npnjy+{\nw,20

1 input1 output1
646 }Guj<7\nk}\,\nK3jb 32
647 AT:c'0)bz3p`' 21
648 * .] 0
649 >9j4p8"S]0%\n%.7hH 21 20
650 .JX\nKF9\nP3W;b._DDS.( 40
651 ~1\n}w!" 4
652 \npnjy+{\nw 20

View File

@ -0,0 +1,78 @@
(ns propeller.problems.PSB1.count-odds
(:require [psb2.core :as psb2]
[propeller.genome :as genome]
[propeller.push.interpreter :as interpreter]
[propeller.problems.data-creation :as dc]
[propeller.utils :as utils]
[propeller.push.instructions :refer [get-stack-instructions]]
[propeller.push.state :as state]
[propeller.tools.math :as math]
[propeller.gp :as gp]
#?(:cljs [cljs.reader :refer [read-string]])))
(def train-data (dc/read-data-formatted "count-odds" "train"))
(def test-data (dc/read-data-formatted "count-odds" "test"))
; Random integer between -100 and 100 (from smallest)
(defn random-int [] (- (rand-int 201) 100))
(def instructions
(utils/not-lazy
(concat
;;; stack-specific instructions
(get-stack-instructions #{:exec :integer :boolean :vector_integer :print})
;;; input instructions
(list :in1)
;;; close
(list 'close)
;;; ERCs (constants)
(list random-int 0 1 2))))
(defn error-function
[argmap data individual]
(let [program (genome/plushy->push (:plushy individual) argmap)
inputs (map (fn [i] (get i :input1)) data)
correct-outputs (map (fn [i] (get i :output1)) data)
outputs (map (fn [input]
(state/peek-stack
(interpreter/interpret-program
program
(assoc state/empty-state :input {:in1 input})
(:step-limit argmap))
:integer))
inputs)
errors (map (fn [correct-output output]
(if (= output :no-stack-item)
1000000
(math/abs (- correct-output output))))
correct-outputs
outputs)]
(assoc individual
:behaviors outputs
:errors errors
:total-error #?(:clj (apply +' errors)
:cljs (apply + errors)))))
(defn -main
"Runs propel-gp, giving it a map of arguments."
[& args]
(gp/gp
(merge
{:instructions instructions
:error-function error-function
:training-data train-data
:testing-data test-data
:case-t-size (count train-data)
:ds-parent-rate 0
:ds-parent-gens 1
:max-generations 300
:population-size 1000
:max-initial-plushy-size 250
:step-limit 2000
:parent-selection :lexicase
:tournament-size 5
:umad-rate 0.1
:variation {:umad 1.0 :crossover 0.0}
:elitism false}
(apply hash-map (map #(if (string? %) (read-string %) %) args))))
(#?(:clj shutdown-agents)))

View File

@ -0,0 +1,97 @@
(ns propeller.problems.PSB1.grade
(:require [propeller.genome :as genome]
[propeller.push.interpreter :as interpreter]
[propeller.problems.data-creation :as dc]
[propeller.push.state :as state]
[propeller.push.instructions :refer [get-stack-instructions]]
[propeller.utils :as utils]
[propeller.tools.metrics :as metrics]
[propeller.gp :as gp]
#?(:cljs [cljs.reader :refer [read-string]])))
;"“Student has a ”, “ grade.”, “A”, “B”, “C”, “D”, “F”, integer ERC"
(def train-data (dc/read-data-formatted "grade" "train"))
(def test-data (dc/read-data-formatted "grade" "test"))
(def outputs (map (fn [i] (get i :output1)) train-data))
outputs
(defn map-vals-input
"Returns all the input values of a map"
[i]
(vals (select-keys i [:input1 :input2 :input3 :input4 :input5])))
(defn get-output
"returns the outputs of the grade function with JUST the letter grade"
[i]
(str (nth i 14)))
; Random integer between -100 and 100
(defn random-int [] (- (rand-int 201) 100))
(def instructions
(utils/not-lazy
(concat
;; stack-specific instructions
(get-stack-instructions #{:boolean :exec :integer :string :print})
;; input instructions
(list :in1 :in2 :in3 :in4 :in5)
;;close
(list 'close)
;; ERCs (constants)
(list "A" "B" "C" "D" "F" random-int))))
(defn error-function
[argmap data individual]
(let [program (genome/plushy->push (:plushy individual) argmap)
inputs (map (fn [i] (map-vals-input i)) data)
correct-outputs (map (fn [i] (get-output (get i :output1))) data)
outputs (map (fn [input]
(state/peek-stack
(interpreter/interpret-program
program
(assoc state/empty-state :input {:in1 (nth input 0)
:in2 (nth input 1)
:in3 (nth input 2)
:in4 (nth input 3)
:in5 (nth input 4)})
(:step-limit argmap))
:print))
inputs)
errors (map (fn [correct-output output]
(if (= output :no-stack-item)
1000000.0
(metrics/levenshtein-distance correct-output output)))
correct-outputs
outputs)]
(assoc individual
:behaviors outputs
:errors errors
:total-error #?(:clj (apply +' errors)
:cljs (apply + errors)))))
(defn -main
"Runs propel-gp, giving it a map of arguments."
[& args]
(gp/gp
(merge
{:instructions instructions
:error-function error-function
:training-data train-data
:testing-data test-data
:case-t-size (count train-data)
:ds-parent-rate 0
:ds-parent-gens 1
:max-generations 300
:population-size 1000
:max-initial-plushy-size 250
:step-limit 2000
:parent-selection :lexicase
:tournament-size 5
:umad-rate 0.1
:variation {:umad 1.0 :crossover 0.0}
:elitism false}
(apply hash-map (map #(if (string? %) (read-string %) %) args))))
(#?(:clj shutdown-agents)))

View File

@ -0,0 +1,148 @@
(ns propeller.problems.PSB1.scrabble-score
(:require [psb2.core :as psb2]
[propeller.genome :as genome]
[propeller.push.interpreter :as interpreter]
[clojure.string :as string]
[propeller.tools.math :as math]
[propeller.problems.data-creation :as dc]
[propeller.utils :as utils]
[propeller.push.instructions :refer [get-stack-instructions]]
[propeller.push.state :as state]
[propeller.tools.metrics :as metrics]
[propeller.gp :as gp]
#?(:cljs [cljs.reader :refer [read-string]])))
(def train-data (dc/scrabble-score-read-data-formatted "scrabble-score" "train"))
(def test-data (dc/scrabble-score-read-data-formatted "scrabble-score" "test"))
(def scrabble-letter-values
(let [scrabble-map {\a 1
\b 3
\c 3
\d 2
\e 1
\f 4
\g 2
\h 4
\i 1
\j 8
\k 5
\l 1
\m 3
\n 1
\o 1
\p 3
\q 10
\r 1
\s 1
\t 1
\u 1
\v 4
\w 4
\x 8
\y 4
\z 10}
visible-chars (map char (range 0 127))]
(vec (for [c visible-chars]
(get scrabble-map (first (string/lower-case c)) 0)))))
;; scrabble-letter-values
;; (def program '(0 :in1 :string_iterate (:integer_from_char [0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 3 3 2 1 4 2 4 1 8 5 1 3 1 1 3 10 1 1 1 1 4 4 8 4 10 0 0 0 0 0 0 1 3 3 2 1 4 2 4 1 8 5 1 3 1 1 3 10 1 1 1 1 4 4 8 4 10 0 0 0 0] :vector_integer_nth :integer_add)))
;; (def inputs (map (fn [i] (get i :input1)) test-data))
;; test-data
;; (def correct-outputs (map (fn [i] (get i :output1)) test-data))
;; correct-outputs
;; inputs
;; (def outputs (map (fn [input]
;; (state/peek-stack
;; (interpreter/interpret-program
;; program
;; (assoc state/empty-state :input {:in1 input})
;; 200)
;; :integer))
;; inputs))
;; outputs
;; correct-outputs
;; (def errors (map (fn [correct-output output]
;; (if (= output :no-stack-item)
;; 1000000
;; (math/abs (- correct-output output))))
;; correct-outputs
;; outputs))
;; (apply + errors)
;; (defn index-of [item coll]
;; (count (take-while (partial not= item) coll)))
;; (index-of 1 errors)
;; (nth inputs 647)
;; (nth outputs 647)
;; (nth correct-outputs 647)
(def instructions
(utils/not-lazy
(concat
;;; stack-specific instructions
(get-stack-instructions #{:exec :integer :boolean :char :vector_integer :string})
;;; input instructions
(list :in1)
;;; close
(list 'close)
;;; ERCs (constants)
(list scrabble-letter-values))))
(defn error-function
[argmap data individual]
(let [program (genome/plushy->push (:plushy individual) argmap)
inputs (map (fn [i] (get i :input1)) data)
correct-outputs (map (fn [i] (get i :output1)) data)
outputs (map (fn [input]
(state/peek-stack
(interpreter/interpret-program
program
(assoc state/empty-state :input {:in1 input})
(:step-limit argmap))
:integer))
inputs)
errors (map (fn [correct-output output]
(if (= output :no-stack-item)
1000000
(math/abs (- correct-output output))))
correct-outputs
outputs)]
(assoc individual
:behaviors outputs
:errors errors
:total-error #?(:clj (apply +' errors)
:cljs (apply + errors)))))
(defn -main
"Runs propel-gp, giving it a map of arguments."
[& args]
(gp/gp
(merge
{:instructions instructions
:error-function error-function
:training-data train-data
:testing-data test-data
:case-t-size (count train-data)
:ds-parent-rate 0
:ds-parent-gens 1
:max-generations 300
:population-size 1000
:max-initial-plushy-size 250
:step-limit 2000
:parent-selection :lexicase
:tournament-size 5
:umad-rate 0.1
:variation {:umad 1.0 :crossover 0.0}
:elitism false}
(apply hash-map (map #(if (string? %) (read-string %) %) args))))
(#?(:clj shutdown-agents)))

View File

@ -0,0 +1,80 @@
(ns propeller.problems.PSB1.small-or-large
(:require [psb2.core :as psb2]
[propeller.genome :as genome]
[propeller.push.interpreter :as interpreter]
[propeller.problems.data-creation :as dc]
[propeller.utils :as utils]
[propeller.push.instructions :refer [get-stack-instructions]]
[propeller.push.state :as state]
[propeller.tools.metrics :as metrics]
[propeller.gp :as gp]
#?(:cljs [cljs.reader :refer [read-string]])))
(def train-data (dc/read-data-formatted "small-or-large" "train"))
(def test-data (dc/read-data-formatted "small-or-large" "test"))
; Random integer between -100 and 100
(defn random-int [] (- (rand-int 201) 100))
(def instructions
(utils/not-lazy
(concat
;;; stack-specific instructions
(get-stack-instructions #{:exec :integer :boolean :string :print})
;;; input instructions
(list :in1)
;;; close
(list 'close)
;;; ERCs (constants)
(list "" "small" "large" random-int))))
(defn error-function
[argmap data individual]
(let [program (genome/plushy->push (:plushy individual) argmap)
inputs (map (fn [i] (get i :input1)) data)
correct-outputs (map (fn [i] (get i :output1)) data)
outputs (map (fn [input]
(state/peek-stack
(interpreter/interpret-program
program
(assoc state/empty-state :input {:in1 input})
(:step-limit argmap))
:string))
inputs)
errors (map (fn [correct-output output]
(if (= output :no-stack-item)
10000
(metrics/levenshtein-distance correct-output output)))
correct-outputs
outputs)]
(assoc individual
:behaviors outputs
:errors errors
:total-error #?(:clj (apply +' errors)
:cljs (apply + errors)))))
(defn -main
"Runs propel-gp, giving it a map of arguments."
[& args]
(gp/gp
(merge
{:instructions instructions
:error-function error-function
:training-data train-data
:testing-data test-data
:case-t-size (count train-data)
:ds-parent-rate 0
:ds-parent-gens 1
:max-generations 300
:population-size 1000
:max-initial-plushy-size 250
:step-limit 2000
:parent-selection :lexicase
:tournament-size 5
:umad-rate 0.1
:variation {:umad 1.0 :crossover 0.0}
:elitism false}
(apply hash-map (map #(if (string? %) (read-string %) %) args))))
(#?(:clj shutdown-agents)))

View File

@ -0,0 +1,107 @@
(ns propeller.problems.PSB2.find-pair
(:require [psb2.core :as psb2]
[propeller.genome :as genome]
[propeller.push.interpreter :as interpreter]
[propeller.problems.data-creation :as dc]
[propeller.utils :as utils]
[propeller.push.instructions :refer [def-instruction get-stack-instructions]]
[propeller.push.state :as state]
[propeller.tools.math :as math]
[propeller.gp :as gp]
#?(:cljs [cljs.reader :refer [read-string]])))
(def train-data (dc/read-data-formatted "find-pair" "train"))
(def test-data (dc/read-data-formatted "find-pair" "test"))
(defn random-int [] (- (rand-int 201) 100))
(defn map-vals-input
"Returns all the input values of a map"
[i]
(vals (select-keys i [:input1 :input2])))
(defn map-vals-output
"Returns the output values of a map"
[i]
(vals (select-keys i [:output1 :output2])))
(def-instruction :output-one
^{:stacks #{:integer :output}}
(fn [state]
(if (empty? (:integer state))
state
(let [top-int (state/peek-stack state :integer)]
(assoc-in state [:output :out1] top-int)))))
(def-instruction :output-two
^{:stacks #{:integer :output}}
(fn [state]
(if (empty? (:integer state))
state
(let [top-int (state/peek-stack state :integer)]
(assoc-in state [:output :out2] top-int)))))
(def instructions
(utils/not-lazy
(concat
;;; stack-specific instructions
(get-stack-instructions #{:exec :integer :vector_integer :boolean})
(list :output-one :output-two)
;;; input instructions
(list :in1 :in2)
;;; close
(list 'close)
;;; ERCs (constants)
(list -1 0 1 2 random-int))))
(defn error-function
[argmap data individual]
(let [program (genome/plushy->push (:plushy individual) argmap)
inputs (map (fn [i] (map-vals-input i)) data)
correct-outputs (map (fn [i] (map-vals-output i)) data)
outputs (map (fn [input]
(:output
(interpreter/interpret-program
program
(assoc state/empty-state :input {:in1 (nth input 0)
:in2 (nth input 1)})
(:step-limit argmap))))
inputs)
outputs-1 (map #(:out1 %) outputs)
outputs-2 (map #(:out2 %) outputs)
;_ (prn {:o1 outputs-1 :o2 outputs-2})
errors (map (fn [correct-output output-1 output-2]
(if (not (and (number? output-2) (number? output-1)))
100000
(+ (math/abs (- (first correct-output) output-1))
(math/abs (- (second correct-output) output-2)))))
correct-outputs outputs-1 outputs-2)]
(assoc individual
:behavior outputs
:errors errors
:total-error #?(:clj (apply +' errors)
:cljs (apply + errors)))))
(defn -main
"Runs propel-gp, giving it a map of arguments."
[& args]
(gp/gp
(merge
{:instructions instructions
:error-function error-function
:training-data train-data
:testing-data test-data
:case-t-size (count train-data)
:ds-parent-rate 0
:ds-parent-gens 1
:max-generations 300
:population-size 1000
:max-initial-plushy-size 250
:step-limit 2000
:parent-selection :lexicase
:tournament-size 5
:umad-rate 0.1
:variation {:umad 1.0 :crossover 0.0}
:elitism false}
(apply hash-map (map #(if (string? %) (read-string %) %) args))))
(#?(:clj shutdown-agents)))

View File

@ -2,6 +2,7 @@
(:require [psb2.core :as psb2] (:require [psb2.core :as psb2]
[propeller.genome :as genome] [propeller.genome :as genome]
[propeller.push.interpreter :as interpreter] [propeller.push.interpreter :as interpreter]
[propeller.problems.data-creation :as dc]
[propeller.utils :as utils] [propeller.utils :as utils]
[propeller.push.instructions :refer [get-stack-instructions]] [propeller.push.instructions :refer [get-stack-instructions]]
[propeller.push.state :as state] [propeller.push.state :as state]
@ -19,7 +20,9 @@
; Source: https://arxiv.org/pdf/2106.06086.pdf ; Source: https://arxiv.org/pdf/2106.06086.pdf
; ============================================================ ; ============================================================
(def train-and-test-data (psb2/fetch-examples "data" "fizz-buzz" 200 2000)) (def train-data (dc/read-data-formatted "fizz-buzz" "train"))
(def test-data (dc/read-data-formatted "fizz-buzz" "test"))
(def instructions (def instructions
(utils/not-lazy (utils/not-lazy
@ -66,11 +69,11 @@
(merge (merge
{:instructions instructions {:instructions instructions
:error-function error-function :error-function error-function
:training-data (:train train-and-test-data) :training-data train-data
:testing-data (:test train-and-test-data) :testing-data test-data
:case-t-size (count (:train train-and-test-data)) :case-t-size (count train-data)
:case-parent-rate 0 :ds-parent-rate 0
:case-parent-gens 1 :ds-parent-gens 1
:max-generations 300 :max-generations 300
:population-size 1000 :population-size 1000
:max-initial-plushy-size 250 :max-initial-plushy-size 250

View File

@ -20,8 +20,8 @@
; Source: https://arxiv.org/pdf/2106.06086.pdf ; Source: https://arxiv.org/pdf/2106.06086.pdf
; ============================================================ ; ============================================================
(def train-data (dc/read-data-that-has-no-strings "fuel-cost" "train")) (def train-data (dc/read-data-formatted "fuel-cost" "train"))
(def test-data (dc/read-data-that-has-no-strings "fuel-cost" "test")) (def test-data (dc/read-data-formatted "fuel-cost" "test"))
; Random integer between -100 and 100 (from smallest) ; Random integer between -100 and 100 (from smallest)
(defn random-int [] (- (rand-int 201) 100)) (defn random-int [] (- (rand-int 201) 100))

View File

@ -2,6 +2,7 @@
(:require [psb2.core :as psb2] (:require [psb2.core :as psb2]
[propeller.genome :as genome] [propeller.genome :as genome]
[propeller.push.interpreter :as interpreter] [propeller.push.interpreter :as interpreter]
[propeller.problems.data-creation :as dc]
[propeller.utils :as utils] [propeller.utils :as utils]
[propeller.push.instructions :refer [get-stack-instructions]] [propeller.push.instructions :refer [get-stack-instructions]]
[propeller.push.state :as state] [propeller.push.state :as state]
@ -17,7 +18,10 @@
; Source: https://arxiv.org/pdf/2106.06086.pdf ; Source: https://arxiv.org/pdf/2106.06086.pdf
; ================================================================== ; ==================================================================
(def train-and-test-data (psb2/fetch-examples "data" "gcd" 200 2000)) ;(def train-and-test-data (psb2/fetch-examples "data" "gcd" 200 2000))
(def train-data (dc/read-data-formatted "gcd" "train"))
(def test-data (dc/read-data-formatted "gcd" "test"))
(defn random-int [] (- (rand-int 201) 100)) (defn random-int [] (- (rand-int 201) 100))
@ -76,11 +80,11 @@
(merge (merge
{:instructions instructions {:instructions instructions
:error-function error-function :error-function error-function
:training-data (:train train-and-test-data) :training-data train-data
:testing-data (:test train-and-test-data) :testing-data test-data
:case-t-size (count (:train train-and-test-data)) :case-t-size (count train-data)
:case-parent-rate 0 :ds-parent-rate 0
:case-parent-gens 1 :ds-parent-gens 1
:max-generations 300 :max-generations 300
:population-size 1000 :population-size 1000
:max-initial-plushy-size 250 :max-initial-plushy-size 250

View File

@ -1,7 +1,8 @@
(ns propeller.problems.data-creation (ns propeller.problems.data-creation
(:require [psb2.core :as psb2] (:require [psb2.core :as psb2]
[clojure.data.csv :as csv] [clojure.data.csv :as csv]
[clojure.java.io :as io])) [clojure.java.io :as io]
[clojure.string :as s]))
(defn generate-data [problem train-or-test] (defn generate-data [problem train-or-test]
(let [train-and-test-data (psb2/fetch-examples "data" problem 200 1000) (let [train-and-test-data (psb2/fetch-examples "data" problem 200 1000)
@ -71,11 +72,32 @@
"grade" "grade"
"count-odds"])) "count-odds"]))
(defn read-data-that-has-no-strings [problem train-or-test] (defn read-string-and-convert [elem]
(if (= elem "")
""
(let [before (read-string elem)]
(if (symbol? before)
elem
before))))
(defn read-data-formatted [problem train-or-test]
(apply list (with-open [reader (io/reader (str "picked/" problem "-" train-or-test ".csv"))] (apply list (with-open [reader (io/reader (str "picked/" problem "-" train-or-test ".csv"))]
(let [csv-data (csv/read-csv reader)] (let [csv-data (csv/read-csv reader)]
(mapv zipmap (mapv zipmap
(->> (first csv-data) ;; First row is the header (->> (first csv-data) ;; First row is the header
(map keyword) ;; Drop if you want string keys instead (map keyword) ;; Drop if you want string keys instead
repeat) repeat)
(map (fn [elem] (map #(read-string %) elem)) (rest csv-data))))))) (map (fn [elem] (map #(read-string-and-convert %) elem)) (rest csv-data)))))))
;scrabble-score doesn't play nice with read-string, hacky solution below
(defn scrabble-score-read-data-formatted [problem train-or-test]
(apply list (with-open [reader (io/reader (str "picked/" problem "-" train-or-test ".csv"))]
(let [csv-data (csv/read-csv reader)]
(prn {:csv-data csv-data})
(mapv zipmap
(->> (first csv-data) ;; First row is the header
(map keyword) ;; Drop if you want string keys instead
repeat)
(map (fn [elem] (list (s/replace (first elem) "\\n" "\n") (read-string (second elem)))) (rest csv-data)))))))