Merge branch 'master'
This commit is contained in:
commit
43752ed6e0
16
package-lock.json
generated
16
package-lock.json
generated
@ -61,9 +61,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/async": {
|
||||
"version": "2.6.3",
|
||||
"resolved": "https://registry.npmjs.org/async/-/async-2.6.3.tgz",
|
||||
"integrity": "sha512-zflvls11DCy+dQWzTW2dzuilv8Z5X/pjfmZOWba6TNIVDm+2UDaJmXSOXlasHKfNBs8oo3M0aT50fDEWfKZjXg==",
|
||||
"version": "2.6.4",
|
||||
"resolved": "https://registry.npmjs.org/async/-/async-2.6.4.tgz",
|
||||
"integrity": "sha512-mzo5dfJYwAn29PeiJ0zvwTo04zj8HDJj0Mn8TD7sno7q12prdbnasKJHhkm2c1LgrhlJ0teaea8860oxi51mGA==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"lodash": "^4.17.14"
|
||||
@ -1368,9 +1368,9 @@
|
||||
}
|
||||
},
|
||||
"async": {
|
||||
"version": "2.6.3",
|
||||
"resolved": "https://registry.npmjs.org/async/-/async-2.6.3.tgz",
|
||||
"integrity": "sha512-zflvls11DCy+dQWzTW2dzuilv8Z5X/pjfmZOWba6TNIVDm+2UDaJmXSOXlasHKfNBs8oo3M0aT50fDEWfKZjXg==",
|
||||
"version": "2.6.4",
|
||||
"resolved": "https://registry.npmjs.org/async/-/async-2.6.4.tgz",
|
||||
"integrity": "sha512-mzo5dfJYwAn29PeiJ0zvwTo04zj8HDJj0Mn8TD7sno7q12prdbnasKJHhkm2c1LgrhlJ0teaea8860oxi51mGA==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"lodash": "^4.17.14"
|
||||
@ -1499,6 +1499,7 @@
|
||||
},
|
||||
"buffer-from": {
|
||||
"version": "1.1.2",
|
||||
"integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==",
|
||||
"dev": true
|
||||
},
|
||||
"buffer-xor": {
|
||||
@ -2279,10 +2280,12 @@
|
||||
},
|
||||
"source-map": {
|
||||
"version": "0.6.1",
|
||||
"integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
|
||||
"dev": true
|
||||
},
|
||||
"source-map-support": {
|
||||
"version": "0.5.20",
|
||||
"integrity": "sha512-n1lZZ8Ve4ksRqizaBQgxXDgKwttHDhyfQjA6YZZn8+AroHbsIz+JjwxQDxbp+7y5OYCI8t1Yk7etjD9CRd2hIw==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"buffer-from": "^1.0.0",
|
||||
@ -2415,6 +2418,7 @@
|
||||
},
|
||||
"ws": {
|
||||
"version": "8.2.3",
|
||||
"integrity": "sha512-wBuoj1BDpC6ZQ1B7DWQBYVLphPWkm8i9Y0/3YdHjHKHiohOJ1ws+3OccDWtH+PoC9DZD5WOTrJvNbWvjS6JWaA==",
|
||||
"requires": {}
|
||||
},
|
||||
"xtend": {
|
||||
|
@ -1,4 +1,4 @@
|
||||
(defproject net.clojars.lspector/propeller "0.2.3"
|
||||
(defproject net.clojars.lspector/propeller "0.3.0"
|
||||
:description "Yet another Push-based genetic programming system in Clojure."
|
||||
:url "https://github.com/lspector/propeller"
|
||||
:license {:name "EPL-2.0 OR GPL-2.0-or-later WITH Classpath-exception-2.0"
|
||||
|
@ -13,7 +13,8 @@
|
||||
[propeller.push.instructions.numeric]
|
||||
[propeller.push.instructions.polymorphic]
|
||||
[propeller.push.instructions.string]
|
||||
[propeller.push.instructions.vector]))
|
||||
[propeller.push.instructions.vector]
|
||||
[propeller.selection :as selection]))
|
||||
|
||||
(defn report
|
||||
"Reports information each generation."
|
||||
@ -80,7 +81,10 @@
|
||||
(partial error-function argmap training-data)
|
||||
population))
|
||||
best-individual (first evaluated-pop)
|
||||
best-individual-passes-ds (and downsample? (<= (:total-error best-individual) solution-error-threshold))]
|
||||
best-individual-passes-ds (and downsample? (<= (:total-error best-individual) solution-error-threshold))
|
||||
argmap (if (= (:parent-selection argmap) :epsilon-lexicase)
|
||||
(assoc argmap :epsilons (selection/epsilon-list evaluated-pop))
|
||||
argmap)]
|
||||
(if (:custom-report argmap)
|
||||
((:custom-report argmap) evaluations evaluated-pop generation argmap)
|
||||
(report evaluations evaluated-pop generation argmap training-data))
|
||||
|
37
src/propeller/selection.cljc
Executable file → Normal file
37
src/propeller/selection.cljc
Executable file → Normal file
@ -1,4 +1,5 @@
|
||||
(ns propeller.selection)
|
||||
(ns propeller.selection
|
||||
(:require [propeller.tools.math :as math-tools]))
|
||||
|
||||
(defn tournament-selection
|
||||
"Selects an individual from the population using a tournament."
|
||||
@ -38,10 +39,42 @@
|
||||
(first individuals)
|
||||
(recur (+ tot (:fitness (first (rest individuals)))) (rest individuals))))))
|
||||
|
||||
(defn epsilon-list
|
||||
[pop]
|
||||
(let [error-list (map :errors pop)
|
||||
length (count (:errors (first pop)))]
|
||||
(loop [epsilons [] i 0]
|
||||
(if (= i length)
|
||||
epsilons
|
||||
(recur (conj epsilons
|
||||
(math-tools/median-absolute-deviation
|
||||
(map #(nth % i) error-list)))
|
||||
(inc i))))))
|
||||
|
||||
(defn epsilon-lexicase-selection
|
||||
"Selects an individual from the population using epsilon-lexicase selection."
|
||||
[pop argmap]
|
||||
(let [epsilons (:epsilons argmap)]
|
||||
(loop [survivors pop
|
||||
cases (shuffle (range (count (:errors (first pop)))))]
|
||||
(if (or (empty? cases)
|
||||
(empty? (rest survivors)))
|
||||
(rand-nth survivors)
|
||||
(let [min-err-for-case (apply min (map #(nth % (first cases))
|
||||
(map :errors survivors)))
|
||||
epsilon (nth epsilons (first cases))]
|
||||
(recur (filter #(<= (Math/abs (- (nth (:errors %)
|
||||
(first cases))
|
||||
min-err-for-case))
|
||||
epsilon)
|
||||
survivors)
|
||||
(rest cases)))))))
|
||||
|
||||
(defn select-parent
|
||||
"Selects a parent from the population using the specified method."
|
||||
[pop argmap]
|
||||
(case (:parent-selection argmap)
|
||||
:tournament (tournament-selection pop argmap)
|
||||
:lexicase (lexicase-selection pop argmap)
|
||||
:roulette (fitness-proportionate-selection pop argmap)))
|
||||
:roulette (fitness-proportionate-selection pop argmap)
|
||||
:epsilon-lexicase (epsilon-lexicase-selection pop argmap)))
|
||||
|
@ -3,8 +3,6 @@
|
||||
[propeller.gp :as gp]
|
||||
[propeller.selection :as selection]
|
||||
[propeller.variation :as variation]
|
||||
[propeller.problems.simple-regression :as regression]
|
||||
[propeller.problems.string-classification :as string-classif]
|
||||
[propeller.push.instructions :as instructions]
|
||||
[propeller.push.interpreter :as interpreter]
|
||||
[propeller.push.state :as state]))
|
||||
@ -15,143 +13,58 @@
|
||||
#_(interpreter/interpret-program
|
||||
'(1 2 :integer_add) (assoc state/empty-state :keep-history true) 1000)
|
||||
|
||||
;#_(interpreter/interpret-program
|
||||
; '(3 3 :integer_eq :exec_if (1 "yes") (2 "no"))
|
||||
; state/empty-state
|
||||
; 1000)
|
||||
;
|
||||
;#_(interpreter/interpret-program
|
||||
; '(:in1 :string_reverse 1 :string_take "?" :string_eq :exec_if
|
||||
; (:in1 " I am asking." :string_concat)
|
||||
; (:in1 " I am saying." :string_concat))
|
||||
; (assoc state/empty-state :input {:in1 "Can you hear me?"})
|
||||
; 1000)
|
||||
;
|
||||
;#_(interpreter/interpret-program
|
||||
; '(:in1 :string_reverse 1 :string_take "?" :string_eq :exec_if
|
||||
; (:in1 " I am asking." :string_concat)
|
||||
; (:in1 " I am saying." :string_concat))
|
||||
; (assoc state/empty-state :input {:in1 "I can hear you."})
|
||||
; 1000)
|
||||
;
|
||||
;#_(genome/plushy->push
|
||||
; (genome/make-random-plushy (instructions/get-stack-instructions #{:float :integer :exec :boolean}) 20))
|
||||
;
|
||||
;#_(gp/gp {:instructions propeller.problems.software.number-io/instructions
|
||||
; :error-function propeller.problems.software.number-io/error-function
|
||||
; :max-generations 500
|
||||
; :population-size 500
|
||||
; :max-initial-plushy-size 100
|
||||
; :step-limit 200
|
||||
; :parent-selection :lexicase
|
||||
; :tournament-size 5
|
||||
; :umad-rate 0.1
|
||||
; :variation {:umad 0.5 :crossover 0.5}
|
||||
; :elitism false})
|
||||
;
|
||||
;#_(gp/gp {:instructions propeller.problems.simple-regression/instructions
|
||||
; :error-function propeller.problems.simple-regression/error-function
|
||||
; :max-generations 500
|
||||
; :population-size 500
|
||||
; :max-initial-plushy-size 100
|
||||
; :step-limit 200
|
||||
; :parent-selection :tournament
|
||||
; :tournament-size 5
|
||||
; :umad-rate 0.01
|
||||
; :variation {:umad 1.0
|
||||
; :crossover 0.0}
|
||||
; :elitism false})
|
||||
;
|
||||
;#_(gp/gp {:instructions propeller.problems.simple-regression/instructions
|
||||
; :error-function propeller.problems.simple-regression/error-function
|
||||
; :max-generations 500
|
||||
; :population-size 500
|
||||
; :max-initial-plushy-size 100
|
||||
; :step-limit 200
|
||||
; :parent-selection :tournament
|
||||
; :tournament-size 5
|
||||
; :umad-rate 0.1
|
||||
; :variation {:umad 1.0
|
||||
; :crossover 0.0}
|
||||
; :elitism false})
|
||||
;
|
||||
;
|
||||
;#_(gp/gp {:instructions propeller.problems.simple-regression/instructions
|
||||
; :error-function propeller.problems.simple-regression/error-function
|
||||
; :max-generations 500
|
||||
; :population-size 500
|
||||
; :max-initial-plushy-size 100
|
||||
; :step-limit 200
|
||||
; :parent-selection :lexicase
|
||||
; :tournament-size 5
|
||||
; :umad-rate 0.1
|
||||
; :variation {:umad 1.0
|
||||
; :crossover 0.0}
|
||||
; :elitism false})
|
||||
;
|
||||
;#_(gp/gp {:instructions propeller.problems.simple-regression/instructions
|
||||
; :error-function propeller.problems.simple-regression/error-function
|
||||
; :max-generations 500
|
||||
; :population-size 500
|
||||
; :max-initial-plushy-size 100
|
||||
; :step-limit 200
|
||||
; :parent-selection :lexicase
|
||||
; :tournament-size 5
|
||||
; :umad-rate 0.1
|
||||
; :diploid-flip-rate 0.1
|
||||
; :variation {:umad 0.8
|
||||
; :diploid-flip 0.2}
|
||||
; :elitism false
|
||||
; :diploid true})
|
||||
;
|
||||
;
|
||||
;#_(gp/gp {:instructions propeller.problems.software.smallest/instructions
|
||||
; :error-function propeller.problems.software.smallest/error-function
|
||||
; :max-generations 500
|
||||
; :population-size 500
|
||||
; :max-initial-plushy-size 100
|
||||
; :step-limit 200
|
||||
; :parent-selection :lexicase
|
||||
; :tournament-size 5
|
||||
; :umad-rate 0.1
|
||||
; :diploid-flip-rate 0.1
|
||||
; :variation {;:umad 0.8
|
||||
; ;:diploid-flip 0.2
|
||||
; :umad 1
|
||||
; }
|
||||
; :elitism false
|
||||
; :diploid false})
|
||||
;
|
||||
;#_(gp/gp {:instructions propeller.problems.software.smallest/instructions
|
||||
; :error-function propeller.problems.software.smallest/error-function
|
||||
; :max-generations 500
|
||||
; :population-size 500
|
||||
; :max-initial-plushy-size 200 ;100
|
||||
; :step-limit 200
|
||||
; :parent-selection :lexicase
|
||||
; :tournament-size 5
|
||||
; :umad-rate 0.1
|
||||
; :diploid-flip-rate 0.1
|
||||
; :variation {:umad 0.8
|
||||
; :diploid-flip 0.2
|
||||
; ;:umad 1
|
||||
; }
|
||||
; :elitism false
|
||||
; :diploid true})
|
||||
;
|
||||
;
|
||||
;(gp/gp {:instructions propeller.problems.string-classification/instructions
|
||||
; :error-function propeller.problems.string-classification/error-function
|
||||
; :max-generations 500
|
||||
; :population-size 500
|
||||
; :max-initial-plushy-size 100
|
||||
; :step-limit 200
|
||||
; :parent-selection :lexicase
|
||||
; :tournament-size 5
|
||||
; :umad-rate 0.1
|
||||
; :diploid-flip-rate 0.1
|
||||
; :variation {:umad 0.8
|
||||
; :diploid-flip 0.2
|
||||
; }
|
||||
; :elitism false
|
||||
; :diploid true})
|
||||
#_(interpreter/interpret-program
|
||||
'(3 3 :integer_eq :exec_if (1 "yes") (2 "no"))
|
||||
state/empty-state
|
||||
1000)
|
||||
|
||||
#_(interpreter/interpret-program
|
||||
'(:in1 :string_reverse 1 :string_take "?" :string_eq :exec_if
|
||||
(:in1 " I am asking." :string_concat)
|
||||
(:in1 " I am saying." :string_concat))
|
||||
(assoc state/empty-state :input {:in1 "Can you hear me?"})
|
||||
1000)
|
||||
|
||||
#_(interpreter/interpret-program
|
||||
'(:in1 :string_reverse 1 :string_take "?" :string_eq :exec_if
|
||||
(:in1 " I am asking." :string_concat)
|
||||
(:in1 " I am saying." :string_concat))
|
||||
(assoc state/empty-state :input {:in1 "I can hear you."})
|
||||
1000)
|
||||
|
||||
#_(genome/plushy->push
|
||||
(genome/make-random-plushy (instructions/get-stack-instructions #{:float :integer :exec :boolean}) 20))
|
||||
|
||||
#_(require '[propeller.problems.simple-regression :as regression])
|
||||
|
||||
#_(gp/gp {:instructions regression/instructions
|
||||
:error-function regression/error-function
|
||||
:training-data (:train regression/train-and-test-data)
|
||||
:testing-data (:test regression/train-and-test-data)
|
||||
:max-generations 500
|
||||
:population-size 500
|
||||
:max-initial-plushy-size 100
|
||||
:step-limit 200
|
||||
:parent-selection :tournament
|
||||
:tournament-size 5
|
||||
:umad-rate 0.01
|
||||
:variation {:umad 1.0
|
||||
:crossover 0.0}
|
||||
:elitism false})
|
||||
|
||||
#_(require '[propeller.problems.string-classification :as sc])
|
||||
|
||||
#_(gp/gp {:instructions sc/instructions
|
||||
:error-function sc/error-function
|
||||
:training-data (:train sc/train-and-test-data)
|
||||
:testing-data (:test sc/train-and-test-data)
|
||||
:max-generations 500
|
||||
:population-size 500
|
||||
:max-initial-plushy-size 100
|
||||
:step-limit 200
|
||||
:parent-selection :lexicase
|
||||
:tournament-size 5
|
||||
:umad-rate 0.1
|
||||
:variation {:umad 0.5 :crossover 0.5}
|
||||
:elitism false})
|
||||
|
||||
|
22
src/propeller/tools/math.cljc
Executable file → Normal file
22
src/propeller/tools/math.cljc
Executable file → Normal file
@ -10,6 +10,28 @@
|
||||
"returns 1 if number is nonzero, 0 otherwise"
|
||||
[x]
|
||||
(if (zero? x) 0 1))
|
||||
(defn mean [coll]
|
||||
(let [sum (apply + coll)
|
||||
count (count coll)]
|
||||
(if (pos? count)
|
||||
(/ sum (float count))
|
||||
0.0)))
|
||||
|
||||
(defn median [coll]
|
||||
(let [sorted (sort coll)
|
||||
cnt (count sorted)
|
||||
halfway (quot cnt 2.0)]
|
||||
(if (odd? cnt)
|
||||
(nth sorted halfway)
|
||||
(let [bottom (dec halfway)
|
||||
bottom-val (nth sorted bottom)
|
||||
top-val (nth sorted halfway)]
|
||||
(mean [bottom-val top-val])))))
|
||||
|
||||
(defn median-absolute-deviation
|
||||
[coll]
|
||||
(let [median-val (median coll)]
|
||||
(median (map #(Math/abs (- % median-val)) coll))))
|
||||
|
||||
(defn abs
|
||||
"Returns the absolute value of a number."
|
||||
|
@ -60,4 +60,16 @@
|
||||
(t/is (m/approx= (m/tan (/ m/PI 4)) 1.0 0.00001))
|
||||
(t/is (= (m/tan 0) 0.0)))
|
||||
|
||||
(t/deftest mean-test
|
||||
(t/is (= (m/mean []) 0.0))
|
||||
(t/is (= (m/mean [1 2 3 4 5]) 3.0))
|
||||
(t/is (= (m/mean '(6 7 8 9 10)) 8.0) 8.0))
|
||||
|
||||
(t/deftest median-test
|
||||
(t/is (= (m/median [1 2 3 4 5]) 3))
|
||||
(t/is (= (m/median '(1 2 3 4 5 6)) 3.5)))
|
||||
|
||||
(t/deftest median-absolute-deviation-test
|
||||
(t/is (= (m/median-absolute-deviation [1 2 3 4 5]) 1))
|
||||
(t/is (= (m/median-absolute-deviation '(1 2 3 4 5 6)) 1.5)))
|
||||
|
||||
|
@ -21,9 +21,9 @@ assert@^1.1.1:
|
||||
util "0.10.3"
|
||||
|
||||
async@^2.6.2:
|
||||
version "2.6.3"
|
||||
resolved "https://registry.yarnpkg.com/async/-/async-2.6.3.tgz#d72625e2344a3656e3a3ad4fa749fa83299d82ff"
|
||||
integrity sha512-zflvls11DCy+dQWzTW2dzuilv8Z5X/pjfmZOWba6TNIVDm+2UDaJmXSOXlasHKfNBs8oo3M0aT50fDEWfKZjXg==
|
||||
version "2.6.4"
|
||||
resolved "https://registry.yarnpkg.com/async/-/async-2.6.4.tgz#706b7ff6084664cd7eae713f6f965433b5504221"
|
||||
integrity sha512-mzo5dfJYwAn29PeiJ0zvwTo04zj8HDJj0Mn8TD7sno7q12prdbnasKJHhkm2c1LgrhlJ0teaea8860oxi51mGA==
|
||||
dependencies:
|
||||
lodash "^4.17.14"
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user