Skip to content

Instantly share code, notes, and snippets.

@jackrusher
Created February 22, 2013 16:49
Show Gist options
  • Save jackrusher/5014834 to your computer and use it in GitHub Desktop.
Save jackrusher/5014834 to your computer and use it in GitHub Desktop.
Convert a learnt decision tree into a nice, readable core.match program.
;; Converts a learnt decision tree produced by
;; https://gist.github.com/jackrusher/4971531
;; into a core.match program. A nice way to convert a set of data points into a
;; readable set of rules. I haven't looked at the code, but I assume core.match
;; compiles the rules into a decision tree.
(defn tree-to-match-clauses [t p]
(let [children (keys t)]
(if (keyword? (first children))
(conj p (first (vals t)))
(mapcat #(tree-to-match-clauses (t %) (conj p %)) children))))
(defn tree-to-match [dec-tree]
(let [data (tree-to-match-clauses dec-tree [])
params (distinct (remove nil? (map #(when (vector? %) (first %)) data)))
template (zipmap params (repeat '_))
rules (for [[a b] (partition 2 (partition-by #(when (keyword? %) %) data))]
(vector (reduce #(assoc %1 (first %2) (second %2)) template a) (first b)))]
(concat
(list 'match (into [] (map #(symbol (subs (str %) 1)) params)))
(interleave
(map (fn [r] (into [] (map #(get (first r) % (template %)) params))) rules)
(map second rules))
'(:else nil))))
(tree-to-match (make-decision-tree weekend-data))
;; =>
(comment
(match [weather money parents]
[:rainy :rich _] :stay-in
[:rainy :poor _] :cinema
[:windy :rich :no] :shopping
[:windy :poor :no] :cinema
[:windy :rich :yes] :cinema
[:sunny _ :no] :tennis
[:sunny _ :yes] :cinema
:else nil))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment