001 /* 002 * Created on Aug 2, 2005 003 * 004 */ 005 package aima.learning.learners; 006 007 import java.util.List; 008 009 import aima.learning.framework.DataSet; 010 import aima.learning.framework.Example; 011 import aima.learning.framework.Learner; 012 import aima.learning.inductive.DLTest; 013 import aima.learning.inductive.DLTestFactory; 014 import aima.learning.inductive.DecisionList; 015 016 /** 017 * @author Ravi Mohan 018 * 019 */ 020 021 public class DecisionListLearner implements Learner { 022 public static final String FAILURE = "Failure"; 023 024 private DecisionList decisionList; 025 026 private String positive, negative; 027 028 private DLTestFactory testFactory; 029 030 public DecisionListLearner(String positive, String negative, 031 DLTestFactory testFactory) { 032 this.positive = positive; 033 this.negative = negative; 034 this.testFactory = testFactory; 035 } 036 037 public void train(DataSet ds) { 038 this.decisionList = decisionListLearning(ds); 039 } 040 041 public String predict(Example e) { 042 if (decisionList == null) { 043 throw new RuntimeException( 044 "learner has not been trained with dataset yet!"); 045 } 046 return decisionList.predict(e); 047 } 048 049 public int[] test(DataSet ds) { 050 int[] results = new int[] { 0, 0 }; 051 052 for (Example e : ds.examples) { 053 if (e.targetValue().equals(decisionList.predict(e))) { 054 results[0] = results[0] + 1; 055 } else { 056 results[1] = results[1] + 1; 057 } 058 } 059 return results; 060 } 061 062 private DecisionList decisionListLearning(DataSet ds) { 063 if (ds.size() == 0) { 064 return new DecisionList(positive, negative); 065 } 066 List<DLTest> possibleTests = testFactory 067 .createDLTestsWithAttributeCount(ds, 1); 068 DLTest test = getValidTest(possibleTests, ds); 069 if (test == null) { 070 return new DecisionList(null, FAILURE); 071 } 072 // at this point there is a test that classifies some subset of examples 073 // with the same target value 074 DataSet matched = test.matchedExamples(ds); 075 DecisionList list = new DecisionList(positive, negative); 076 list.add(test, matched.getExample(0).targetValue()); 077 return list.mergeWith(decisionListLearning(test.unmatchedExamples(ds))); 078 } 079 080 private DLTest getValidTest(List<DLTest> possibleTests, DataSet ds) { 081 for (DLTest test : possibleTests) { 082 DataSet matched = test.matchedExamples(ds); 083 if (!(matched.size() == 0)) { 084 if (allExamplesHaveSameTargetValue(matched)) { 085 return test; 086 } 087 } 088 089 } 090 return null; 091 } 092 093 private boolean allExamplesHaveSameTargetValue(DataSet matched) { 094 // assumes at least i example in dataset 095 String targetValue = matched.getExample(0).targetValue(); 096 for (Example e : matched.examples) { 097 if (!(e.targetValue().equals(targetValue))) { 098 return false; 099 } 100 } 101 return true; 102 } 103 104 /** 105 * @return Returns the decisionList. 106 */ 107 public DecisionList getDecisionList() { 108 return decisionList; 109 } 110 111 }