;;; decision list learning algorithm (Rivest) ;;; returns a decision list, each element of which is ;;; a test of the form (x .term), where each term is ;;; of the form ((a1 . v1) (a2 . v2) ... (an . vn)). ;;; The last element is the test (0). ;;; only works for purely boolean attributes. (defun decision-list-learning (k problem) (dll k (learning-problem-examples problem) (learning-problem-attributes problem) (first (learning-problem-goals problem)))) (defun dll (k examples attributes goal) (if (null examples) (list (list 0)) (multiple-value-bind (test subset) (select-test k examples attributes goal) (if test (cons test (dll k (set-difference examples subset :test #'eq) attributes goal)) (error "Cannot find a consistent decision list"))))) ;;; select-test finds a test of size at most k that picks out a set of ;;; examples with uniform classification. Returns test and subset. (defun select-test (k examples attributes goal) (dotimes (i (1+ k) (values nil nil)) (let ((test (select-k-test i examples attributes goal nil))) (when test (return (values test (remove-if-not #'(lambda (e) (passes e test)) examples))))))) (defun select-k-test (k examples attributes goal test-attributes) (cond ((= 0 k) (dolist (term (generate-terms test-attributes) nil) (let ((subset (remove-if-not #'(lambda (e) (passes e (cons 0 term))) examples))) (when (and subset (uniform-classification subset goal)) (return (cons (attribute-value goal (first subset)) term)))))) (t (dolist (f attributes nil) (let ((test (select-k-test (- k 1) examples (remove f attributes :test #'eq) goal (cons f test-attributes)))) (when test (return test))))))) (defun generate-terms (attributes) ;;; generate all labellings (if (null attributes) (list nil) (let ((rest (generate-terms (cdr attributes)))) (nconc (mapcar #'(lambda (test) (cons (cons (car attributes) 0) test)) rest) (mapcar #'(lambda (test) (cons (cons (car attributes) 1) test)) rest))))) (defun uniform-classification (examples goal) (every #'(lambda (e) (eq (attribute-value goal e) (attribute-value goal (first examples)))) (rest examples))) (defun passes (example test) (every #'(lambda (av) (eq (attribute-value (car av) example) (cdr av))) (cdr test))) ;;; dlpredict is the standard "performance element" that ;;; interfaces with the example-generation and learning-curve functions (defun dlpredict (dl example) (if (every #'(lambda (av) (eq (attribute-value (car av) example) (cdr av))) (cdar dl)) (list (caar dl)) (dlpredict (cdr dl) example)))