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    }