001    package jcolibri.method.reuse.classification;
002    
003    import java.util.Collection;
004    import java.util.HashMap;
005    import java.util.Map;
006    
007    import jcolibri.extensions.classification.ClassificationSolution;
008    import jcolibri.method.retrieve.RetrievalResult;
009    
010    /**
011     * Provides the ability to classify a query by predicting its
012     * solution from supplied cases. Classification is done by 
013     * majority voting, so the predicted class is the one that
014     * has the highest number of votes.
015     * 
016     * @author Derek Bridge
017     * @author Lisa Cummins
018     * 16/05/07
019     */
020    public class MajorityVotingMethod extends AbstractKNNClassificationMethod
021    {
022    
023        /**
024         * Predicts the class that has the highest number of votes
025         * among the k most similar cases.
026         * If several classes receive the same highest vote, the class that
027         * has the lowest hash code is taken as the prediction. 
028         * @param cases
029         *            an ordered list of cases along with similarity scores.
030         * @return Returns the predicted solution.
031         */
032        public ClassificationSolution getPredictedSolution(Collection<RetrievalResult> cases)
033        {
034            Map<Object, Integer> votes = new HashMap<Object, Integer>();
035            Map<Object, ClassificationSolution> values = new HashMap<Object, ClassificationSolution>();
036            
037            for (RetrievalResult result: cases)
038            {
039                ClassificationSolution solution = (ClassificationSolution)result.get_case().getSolution();
040                
041                Object classif = solution.getClassification();
042                
043                if (votes.containsKey(classif))
044                {
045                    votes.put(classif, votes.get(classif) + 1);
046                }
047                else
048                {
049                    votes.put(classif, 1);
050                }
051                values.put(classif, solution);
052            }
053            
054            int highestVoteSoFar = 0;
055            Object predictedClass = null;
056            for (Map.Entry<Object, Integer> e : votes.entrySet())
057            {
058                if (e.getValue() >= highestVoteSoFar)
059                {
060                    highestVoteSoFar = e.getValue();
061                    predictedClass = e.getKey();
062                }
063            }
064            
065            
066            return values.get(predictedClass);
067        }
068    }