001 /** 002 * Houses4.java 003 * jCOLIBRI2 framework. 004 * @author Juan A. Recio-García. 005 * GAIA - Group for Artificial Intelligence Applications 006 * http://gaia.fdi.ucm.es 007 * 23/10/2007 008 */ 009 package jcolibri.test.recommenders.rec4; 010 011 import java.util.Collection; 012 import java.util.HashMap; 013 import java.util.Map; 014 015 import jcolibri.casebase.LinealCaseBase; 016 import jcolibri.cbraplications.StandardCBRApplication; 017 import jcolibri.cbrcore.Attribute; 018 import jcolibri.cbrcore.CBRCase; 019 import jcolibri.cbrcore.CBRCaseBase; 020 import jcolibri.cbrcore.CBRQuery; 021 import jcolibri.cbrcore.Connector; 022 import jcolibri.connector.PlainTextConnector; 023 import jcolibri.exception.ExecutionException; 024 import jcolibri.extensions.recommendation.casesDisplay.DisplayCasesTableMethod; 025 import jcolibri.extensions.recommendation.casesDisplay.UserChoice; 026 import jcolibri.extensions.recommendation.conditionals.BuyOrQuit; 027 import jcolibri.extensions.recommendation.conditionals.ContinueOrFinish; 028 import jcolibri.extensions.recommendation.conditionals.DisplayCasesIfNumber; 029 import jcolibri.extensions.recommendation.navigationByAsking.InformationGain; 030 import jcolibri.extensions.recommendation.navigationByAsking.ObtainQueryWithAttributeQuestionMethod; 031 import jcolibri.method.retrieve.FilterBasedRetrieval.FilterBasedRetrievalMethod; 032 import jcolibri.method.retrieve.FilterBasedRetrieval.FilterConfig; 033 import jcolibri.method.retrieve.FilterBasedRetrieval.predicates.Equal; 034 import jcolibri.test.recommenders.rec4.housesData.HouseDescription; 035 036 /** 037 * Conversational (type B) flats recommender using Navigation by Asking and Filter retrieval. 038 * <br> 039 * This recommender applies the Navigation by Asking strategy to obtain the user requirements. 040 * This strategy selects an attribute of the items to be asked to the user each iteration. Depending on 041 * the values of these attributes a retrieval set is obtained using filtering. 042 * If the retrieval set is small enough it is presented to the user. If it is too big or 043 * the user does not find the desired item, the recommender uses again the Navigation by 044 * Asking strategy to improve the user requirements. 045 * <br>Summary: 046 * <ul> 047 * <li>Type: Conversational B. 048 * <li>Case base: houses2 (price moved to the solution and priceRange in the description). 049 * <li>One off Preference Elicitation: Navigation by Asking using Information Gain. 050 * <li>Retrieval: Filter (in NbA only Equal() predicates are allowed). 051 * <li>Display Condition: number of cases (not showing messages). 052 * <li>Display: In table. "Edit Query" enabled if there are more attributes to ask. 053 * <li>Iterated Preference Elicitation: Navigation by Asking using Information Gain. 054 * </ul> 055 * This recommender implements the following template:<br> 056 * <center><img src="../Template4_Cycle.jpg"/></center> 057 * 058 * <br>Read the documentation of the recommenders extension for details about templates 059 * and recommender strategies: {@link jcolibri.extensions.recommendation} 060 * 061 * @see jcolibri.extensions.recommendation.navigationByAsking.ObtainQueryWithAttributeQuestionMethod 062 * @see jcolibri.extensions.recommendation.navigationByAsking.InformationGain 063 * @see jcolibri.method.retrieve.FilterBasedRetrieval.FilterBasedRetrievalMethod 064 * @see jcolibri.extensions.recommendation.conditionals.DisplayCasesIfNumber 065 * @see jcolibri.extensions.recommendation.casesDisplay.DisplayCasesTableMethod 066 * 067 * @author Juan A. Recio-Garcia 068 * @author Developed at University College Cork (Ireland) in collaboration with Derek Bridge. 069 * @version 1.0 070 */ 071 public class Houses4 implements StandardCBRApplication 072 { 073 /** Connector object */ 074 Connector _connector; 075 /** CaseBase object */ 076 CBRCaseBase _caseBase; 077 078 /** Configuration object for Filter based retrieval */ 079 FilterConfig filterConfig; 080 /** Configuration object for Attribute Question */ 081 Map<Attribute,String> labels; 082 083 public void configure() throws ExecutionException 084 { 085 // Create a data base connector 086 _connector = new PlainTextConnector(); 087 // Init the ddbb connector with the config file 088 _connector.initFromXMLfile(jcolibri.util.FileIO 089 .findFile("jcolibri/test/recommenders/rec4/housesData/plaintextconfig.xml")); 090 // Create a Lineal case base for in-memory organization 091 _caseBase = new LinealCaseBase(); 092 093 //Configure the Filter 094 filterConfig = new FilterConfig(); 095 filterConfig.addPredicate(new Attribute("area", HouseDescription.class), new Equal()); 096 filterConfig.addPredicate(new Attribute("beds", HouseDescription.class), new Equal()); 097 filterConfig.addPredicate(new Attribute("priceRange", HouseDescription.class), new Equal()); 098 filterConfig.addPredicate(new Attribute("furnished", HouseDescription.class), new Equal()); 099 filterConfig.addPredicate(new Attribute("type", HouseDescription.class), new Equal()); 100 filterConfig.addPredicate(new Attribute("baths", HouseDescription.class), new Equal()); 101 102 //Configure labels for attribute question 103 labels = new HashMap<Attribute,String>(); 104 } 105 106 public void cycle(CBRQuery query) throws ExecutionException 107 { 108 // Select attribute 109 Collection<CBRCase> workingCases = _caseBase.getCases(); 110 Attribute att = InformationGain.getMoreIGattribute(workingCases,true, _caseBase.getCases()); 111 // If there are not more attributes to ask, the method resturn null. 112 // And the ObtainQueryWithAttributeQuestion method receives that null and shows nothing. 113 // In that case, ObtainQueryWithAttributeQuestion returns false; 114 115 // Ask for the attribute 116 boolean _continue = ObtainQueryWithAttributeQuestionMethod.obtainQueryWithAttributeQuestion(query, att, labels, workingCases); 117 118 sequence1(query, _continue); 119 } 120 121 122 public void sequence1(CBRQuery query, boolean _continue) throws ExecutionException 123 { 124 // Retrieve cases 125 Collection<CBRCase> workingCases = FilterBasedRetrievalMethod.filterCases(_caseBase.getCases(), query, filterConfig); 126 127 // Display? 128 if(DisplayCasesIfNumber.displayCases(50, 1, workingCases,false)) 129 sequence2(query, workingCases, _continue); 130 else 131 sequence3(query, workingCases); 132 133 134 } 135 136 public void sequence2(CBRQuery query, Collection<CBRCase> workingCases, boolean _continue) throws ExecutionException 137 { 138 // Display in cases. The chosen method depends on the AttributeSelection algorithm. 139 UserChoice choice; 140 if(_continue) 141 choice = DisplayCasesTableMethod.displayCasesInTableEditQuery(workingCases); 142 else 143 choice = DisplayCasesTableMethod.displayCasesInTableBasic(workingCases); 144 145 146 if(ContinueOrFinish.continueOrFinish(choice)) 147 sequence3(query,workingCases); 148 else 149 sequence4(choice, workingCases); 150 } 151 152 public void sequence3(CBRQuery query, Collection<CBRCase> workingCases) throws ExecutionException 153 { 154 //Select attribute 155 Attribute att = InformationGain.getMoreIGattribute(workingCases,false, _caseBase.getCases()); 156 157 //Ask attribute 158 boolean _continue = ObtainQueryWithAttributeQuestionMethod.obtainQueryWithAttributeQuestion(query, att, labels,workingCases); 159 160 sequence1(query, _continue); 161 } 162 163 public void sequence4(UserChoice choice, Collection<CBRCase> workingCases) throws ExecutionException 164 { 165 if(BuyOrQuit.buyOrQuit(choice)) 166 System.out.println("Finish - User Buys: "+choice.getSelectedCase()); 167 168 else 169 System.out.println("Finish - User Quits"); 170 } 171 172 public void postCycle() throws ExecutionException 173 { 174 } 175 176 public CBRCaseBase preCycle() throws ExecutionException 177 { 178 // Load cases from connector into the case base 179 _caseBase.init(_connector); 180 // Print the cases 181 java.util.Collection<CBRCase> cases = _caseBase.getCases(); 182 for(CBRCase c: cases) 183 System.out.println(c); 184 return _caseBase; 185 } 186 187 public static void main(String[] args) { 188 StandardCBRApplication recommender = new Houses4(); 189 try 190 { 191 recommender.configure(); 192 193 recommender.preCycle(); 194 195 CBRQuery query = new CBRQuery(); 196 197 HouseDescription hd = new HouseDescription(); 198 199 query.setDescription(hd); 200 201 recommender.cycle(query); 202 203 recommender.postCycle(); 204 205 //System.exit(0); 206 } catch (Exception e) 207 { 208 org.apache.commons.logging.LogFactory.getLog(Houses4.class).error(e); 209 210 } 211 212 213 } 214 215 }