(defun iterative-dichotomize (n tbl &key splitter) (labels ((trainer (tbl cautions egs) (id-trainer tbl :splitter splitter)) (tester (tbl cautions model one) (cons (isa one tbl) (id-tester one model)))) (n-way n tbl :trainer #'trainer :tester #'tester))) (defun id-tester (eg tree) (id-tester1 eg (node-kids tree))) (defun id-tester1 (eg trees) (cond ((null trees) nil) ((node-p trees) (rest (node-key trees))) (t (let* ((tree (first trees)) (pair (node-key tree)) (kids (node-kids tree)) (feature (first pair)) (range (rest pair))) (if kids (if (eql (nth feature eg) range) (id-tester1 eg (node-kids tree)) (id-tester1 eg (rest trees))) range))))) (defun id-trainer (tbl &key splitter (min 4) (condense #'table-majority-class)) (make-node :key 'root :kids (id-trainer1 tbl splitter min condense))) (defun id-trainer1 (tbl splitter min condense) (let ((before (table-height tbl))) (if (< before min) (make-node :key (cons 'then (funcall condense tbl))) (let* ((x (cross-index tbl)) (split (funcall splitter x)) (egs (table-egs tbl)) (names (xindex-feature-names x))) (mapcar #'(lambda (range) (id-trainer2 range x egs split splitter min tbl before condense)) (xindex-feature split x)))))) (defun id-trainer2 (range x egs split splitter min tbl before condense) (let (some) (dolist (eg egs) (if (eql range (nth split eg)) (push eg some))) (if (< (1+ (length some)) before) (make-node :key (cons split range) :kids (id-trainer1 (table-copy tbl some) splitter min condense)) (make-node :key (cons 'then (funcall condense tbl))))))