001 /** 002 * Houses1.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.rec1; 010 011 import java.util.Collection; 012 013 import jcolibri.casebase.LinealCaseBase; 014 import jcolibri.cbraplications.StandardCBRApplication; 015 import jcolibri.cbrcore.Attribute; 016 import jcolibri.cbrcore.CBRCase; 017 import jcolibri.cbrcore.CBRCaseBase; 018 import jcolibri.cbrcore.CBRQuery; 019 import jcolibri.cbrcore.Connector; 020 import jcolibri.connector.PlainTextConnector; 021 import jcolibri.exception.ExecutionException; 022 import jcolibri.extensions.recommendation.casesDisplay.DisplayCasesTableMethod; 023 import jcolibri.extensions.recommendation.casesDisplay.UserChoice; 024 import jcolibri.extensions.recommendation.conditionals.BuyOrQuit; 025 import jcolibri.method.gui.formFilling.ObtainQueryWithFormMethod; 026 import jcolibri.method.retrieve.RetrievalResult; 027 import jcolibri.method.retrieve.NNretrieval.NNConfig; 028 import jcolibri.method.retrieve.NNretrieval.NNScoringMethod; 029 import jcolibri.method.retrieve.NNretrieval.similarity.global.Average; 030 import jcolibri.method.retrieve.NNretrieval.similarity.local.Equal; 031 import jcolibri.method.retrieve.NNretrieval.similarity.local.Table; 032 import jcolibri.method.retrieve.NNretrieval.similarity.local.recommenders.InrecaLessIsBetter; 033 import jcolibri.method.retrieve.NNretrieval.similarity.local.recommenders.McSherryMoreIsBetter; 034 import jcolibri.method.retrieve.selection.SelectCases; 035 import jcolibri.test.recommenders.housesData.HouseDescription; 036 037 /** 038 * Simple Single-Shot flats recommender using form-filling, Nearest Neighbour retrieval and top k selection . 039 * <br> 040 * This recommender allows user to define his/her requirements using a form. 041 * Then, it retrieves the k most similar cases using Nearest Neighbour retrieval. 042 * These k cases are displayed to the user in a table and the system finishes. 043 * <br>Summary: 044 * <ul> 045 * <li>Type: Single-Shot 046 * <li>Case base: houses 047 * <li>One off Preference Elicitation: Form Filling with initial values 048 * <li>Retrieval: NearestNeigbour + topKselection 049 * <li>Display: In table 050 * </ul> 051 * This recommender implements the following template:<br> 052 * <center><img src="../Template1_Cycle.jpg"/></center> 053 * 054 * <br>Read the documentation of the recommenders extension for details about templates 055 * and recommender strategies: {@link jcolibri.extensions.recommendation} 056 * 057 * @see jcolibri.method.gui.formFilling.ObtainQueryWithFormMethod 058 * @see jcolibri.method.retrieve.NNretrieval.NNScoringMethod 059 * @see jcolibri.method.retrieve.selection.SelectCases 060 * @see jcolibri.extensions.recommendation.casesDisplay.DisplayCasesTableMethod 061 * 062 * @author Juan A. Recio-Garcia 063 * @author Developed at University College Cork (Ireland) in collaboration with Derek Bridge. 064 * @version 1.0 065 * 066 */ 067 public class Houses1 implements StandardCBRApplication 068 { 069 /** Connector object */ 070 Connector _connector; 071 /** CaseBase object */ 072 CBRCaseBase _caseBase; 073 074 /** KNN config */ 075 NNConfig simConfig; 076 077 public void configure() throws ExecutionException 078 { 079 // Create a data base connector 080 _connector = new PlainTextConnector(); 081 // Init the ddbb connector with the config file 082 _connector.initFromXMLfile(jcolibri.util.FileIO 083 .findFile("jcolibri/test/recommenders/housesData/plaintextconfig.xml")); 084 // Create a Lineal case base for in-memory organization 085 _caseBase = new LinealCaseBase(); 086 087 simConfig = new NNConfig(); 088 // Set the average() global similarity function for the description of the case 089 simConfig.setDescriptionSimFunction(new Average()); 090 simConfig.addMapping(new Attribute("area", HouseDescription.class), new Table("jcolibri/test/recommenders/housesData/area.csv")); 091 simConfig.addMapping(new Attribute("beds", HouseDescription.class), new McSherryMoreIsBetter(0,0)); 092 simConfig.addMapping(new Attribute("price", HouseDescription.class), new InrecaLessIsBetter(2000, 0.5)); 093 simConfig.addMapping(new Attribute("furnished", HouseDescription.class), new Equal()); 094 simConfig.addMapping(new Attribute("type", HouseDescription.class), new Equal()); 095 simConfig.addMapping(new Attribute("baths", HouseDescription.class), new McSherryMoreIsBetter(7,1)); 096 097 098 } 099 100 public void cycle(CBRQuery query) throws ExecutionException 101 { 102 // Obtain query 103 ObtainQueryWithFormMethod.obtainQueryWithInitialValues(query,null,null); 104 105 // Execute KNN 106 Collection<RetrievalResult> eval = NNScoringMethod.evaluateSimilarity(_caseBase.getCases(), query, simConfig); 107 108 // Select cases 109 Collection<CBRCase> retrievedCases = SelectCases.selectTopK(eval, 5); 110 111 // Display cases 112 UserChoice choice = DisplayCasesTableMethod.displayCasesInTableBasic(retrievedCases);//DisplayCasesMethod.displayCases(retrievedCases); 113 114 // Buy or Quit 115 if(BuyOrQuit.buyOrQuit(choice)) 116 System.out.println("Finish - User Buys: "+choice.getSelectedCase()); 117 118 else 119 System.out.println("Finish - User Quits"); 120 121 } 122 123 public void postCycle() throws ExecutionException 124 { 125 _connector.close(); 126 } 127 128 public CBRCaseBase preCycle() throws ExecutionException 129 { 130 // Load cases from connector into the case base 131 _caseBase.init(_connector); 132 // Print the cases 133 java.util.Collection<CBRCase> cases = _caseBase.getCases(); 134 for(CBRCase c: cases) 135 System.out.println(c); 136 return _caseBase; 137 } 138 139 140 public static void main(String[] args) { 141 142 StandardCBRApplication recommender = new Houses1(); 143 try 144 { 145 recommender.configure(); 146 147 recommender.preCycle(); 148 149 CBRQuery query = new CBRQuery(); 150 151 HouseDescription hd = new HouseDescription(); 152 hd.setArea(HouseDescription.Area.Hampstead); 153 hd.setBaths(1); 154 hd.setBeds(HouseDescription.Beds.two); 155 hd.setFurnished(true); 156 hd.setPrice(500); 157 hd.setType(HouseDescription.Type.Flat); 158 query.setDescription(hd); 159 160 recommender.cycle(query); 161 162 recommender.postCycle(); 163 164 } catch (Exception e) 165 { 166 org.apache.commons.logging.LogFactory.getLog(Houses1.class).error(e); 167 168 } 169 170 } 171 172 }