File: dll.lisp

package info (click to toggle)
cl-aima 20020509-2
  • links: PTS
  • area: main
  • in suites: lenny
  • size: 1,188 kB
  • ctags: 1,574
  • sloc: lisp: 6,593; makefile: 57; sh: 28
file content (80 lines) | stat: -rw-r--r-- 2,767 bytes parent folder | download | duplicates (3)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
;;; 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)))