001    /**
002     * Test16.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     * 02/08/2007
008     */
009    package jcolibri.test.test16;
010    
011    import java.awt.BorderLayout;
012    import java.awt.Component;
013    import java.awt.Dimension;
014    import java.awt.GridLayout;
015    import java.awt.event.ActionEvent;
016    import java.awt.event.ActionListener;
017    
018    import javax.swing.BorderFactory;
019    import javax.swing.BoxLayout;
020    import javax.swing.ButtonGroup;
021    import javax.swing.JButton;
022    import javax.swing.JComponent;
023    import javax.swing.JFileChooser;
024    import javax.swing.JFrame;
025    import javax.swing.JLabel;
026    import javax.swing.JPanel;
027    import javax.swing.JRadioButton;
028    import javax.swing.JSpinner;
029    import javax.swing.JTextField;
030    import javax.swing.SpinnerNumberModel;
031    import javax.swing.UIManager;
032    
033    import jcolibri.cbrcore.CBRCaseBase;
034    import jcolibri.evaluation.EvaluationReport;
035    import jcolibri.evaluation.Evaluator;
036    import jcolibri.evaluation.evaluators.HoldOutEvaluator;
037    import jcolibri.evaluation.evaluators.LeaveOneOutEvaluator;
038    import jcolibri.evaluation.evaluators.NFoldEvaluator;
039    import jcolibri.evaluation.evaluators.SameSplitEvaluator;
040    import jcolibri.exception.ExecutionException;
041    import jcolibri.extensions.textual.IE.common.StopWordsDetector;
042    import jcolibri.extensions.textual.IE.common.TextStemmer;
043    import jcolibri.extensions.textual.IE.opennlp.OpennlpSplitter;
044    import jcolibri.extensions.visualization.CasesVisualization;
045    import jcolibri.method.retrieve.NNretrieval.similarity.LocalSimilarityFunction;
046    import jcolibri.method.retrieve.NNretrieval.similarity.local.textual.CosineCoefficient;
047    import jcolibri.method.retrieve.NNretrieval.similarity.local.textual.DiceCoefficient;
048    import jcolibri.method.retrieve.NNretrieval.similarity.local.textual.JaccardCoefficient;
049    import jcolibri.method.retrieve.NNretrieval.similarity.local.textual.OverlapCoefficient;
050    import jcolibri.method.retrieve.NNretrieval.similarity.local.textual.compressionbased.CompressionBased;
051    import jcolibri.method.retrieve.NNretrieval.similarity.local.textual.compressionbased.GZipCompressor;
052    import jcolibri.method.retrieve.NNretrieval.similarity.local.textual.compressionbased.NormalisedCompression;
053    import jcolibri.method.reuse.classification.KNNClassificationMethod;
054    import jcolibri.method.reuse.classification.MajorityVotingMethod;
055    import jcolibri.method.reuse.classification.SimilarityWeightedVotingMethod;
056    import jcolibri.method.reuse.classification.UnanimousVotingMethod;
057    import jcolibri.test.main.SwingProgressBar;
058    import jcolibri.util.ProgressController;
059    import jcolibri.util.ProgressListener;
060    
061    /**
062     * This test shows how to evaluate the textual similarity functions using classification.
063     * It uses a corpus of email (divided into ham and spam messages) and also allows to 
064     * visualize the case base using a chosen similarity function.
065     * <br>
066     * The corpus is packed into the lib\textual\spamcorpus\spamcorpus.jar file and was extracted
067     * from the Apache Spamassassin project (http://spamassassin.apache.org/publiccorpus/).
068     * @author Juan A. Recio-Garcia
069     * @version 1.0
070     * @see jcolibri.method.retrieve.NNretrieval.similarity.local.textual
071     * @see jcolibri.method.reuse.classification
072     * @see jcolibri.evaluation
073     */
074    public class Test16 extends JFrame
075    {
076        private static final long serialVersionUID = 1L;
077    
078        JRadioButton corpus300;
079    
080        JRadioButton corpus600;
081    
082        JRadioButton leaveOneOut;
083    
084        JRadioButton holdOutFixed10;
085    
086        JRadioButton holdOutFixed20;
087    
088        JRadioButton holdOutFixed30;
089        
090        JRadioButton sameSplit;
091            
092        JRadioButton sameSplitGenerate;
093    
094        JButton saveSplit;
095    
096        JTextField sameSplitGenerateFile;
097        
098        JRadioButton sameSplitReuse;
099    
100        JButton loadSplit;
101    
102        JTextField sameSplitReuseFile;
103        
104        JLabel sameSplitGeneratePercent;
105        
106        SpinnerNumberModel sameSplitPercent;
107    
108        JSpinner sameSplitGeneratePercentSpinner;
109    
110        JRadioButton holdOut;
111    
112        JLabel holdOutLabel1;
113    
114        SpinnerNumberModel holdOutPercent;
115    
116        JSpinner holdOutPercentSpinner;
117    
118        JLabel holdOutLabel2;
119    
120        SpinnerNumberModel holdOutRepetitions;
121    
122        JSpinner holdOutRepetitionsSpinner;
123    
124        JRadioButton nFold;
125    
126        JLabel nFoldLabel1;
127    
128        SpinnerNumberModel nFoldFolds;
129    
130        JSpinner nFoldFoldsSpinner;
131    
132        JLabel nFoldLabel2;
133    
134        SpinnerNumberModel nFoldRepetitions;
135    
136        JSpinner nFoldRepetitionsSpinner;
137    
138        JRadioButton compressionBased;
139    
140        JRadioButton normalizedCompression;
141    
142        JRadioButton cosine;
143    
144        JRadioButton dice;
145    
146        JRadioButton jaccard;
147    
148        JRadioButton overlap;
149    
150        JRadioButton majorityVoting;
151    
152        JRadioButton weightedVoting;
153    
154        JRadioButton unanimousVoting;
155        
156        SpinnerNumberModel kValue;
157    
158        JSpinner kValueSpinner;
159    
160        JButton evaluate;
161    
162        JButton visualize;
163    
164        
165        
166        
167        public Test16()
168        {
169            configure();
170        }
171    
172        public void configure()
173        {
174            try
175            {
176                UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
177            } catch (Exception e)
178            {
179            }
180            
181            /** ****** Corpus Panel ************ */
182    
183            JPanel corpusPanel = new JPanel();
184            corpusPanel.setLayout(new GridLayout(2, 1));
185            corpusPanel.setBorder(BorderFactory.createTitledBorder("Corpus"));
186    
187            corpus300 = new JRadioButton("Corpus - 300 emails");
188            corpus600 = new JRadioButton("Corpus - 600 emails");
189    
190            ButtonGroup corpusGroup = new ButtonGroup();
191            corpusGroup.add(corpus300);
192            corpusGroup.add(corpus600);
193    
194            corpusPanel.add(corpus300);
195            corpusPanel.add(corpus600);
196    
197            corpus300.setSelected(true);
198    
199            /** ****** Evaluator Panel ************ */
200    
201            JPanel evaluatorPanel = new JPanel();
202            evaluatorPanel.setBorder(BorderFactory.createTitledBorder("Evaluator"));
203            evaluatorPanel.setLayout(new BoxLayout(evaluatorPanel, BoxLayout.Y_AXIS));
204    
205            leaveOneOut = new JRadioButton("Leave One Out");
206            leaveOneOut.addActionListener(new ActionListener() {
207                public void actionPerformed(ActionEvent e)
208                {
209                    enableGroup("none");
210                }
211            });
212    
213            holdOutFixed10 = new JRadioButton("Hold Out - Query Set Fixed 10%");
214            holdOutFixed10.addActionListener(new ActionListener() {
215                public void actionPerformed(ActionEvent e)
216                {
217                    enableGroup("none");
218                }
219            });
220            holdOutFixed20 = new JRadioButton("Hold Out - Query Set Fixed 20%");
221            holdOutFixed20.addActionListener(new ActionListener() {
222                public void actionPerformed(ActionEvent e)
223                {
224                    enableGroup("none");
225                }
226            });
227            holdOutFixed30 = new JRadioButton("Hold Out - Query Set Fixed 30%");
228            holdOutFixed30.addActionListener(new ActionListener() {
229                public void actionPerformed(ActionEvent e)
230                {
231                    enableGroup("none");
232                }
233            });
234    
235            
236            sameSplit = new JRadioButton("Hold Out - Query Set Custom");
237            sameSplit.addActionListener(new ActionListener() {
238                public void actionPerformed(ActionEvent e)
239                {
240                    enableGroup("samesplit");
241                }
242            });
243            
244            JPanel sameSplitPanel = new JPanel();
245            sameSplitPanel.setLayout(new BoxLayout(sameSplitPanel, BoxLayout.Y_AXIS));
246            sameSplitPanel.setBorder(BorderFactory.createEmptyBorder(2,15,2,2));
247            
248            JPanel sameSplitPanel1 = new JPanel();
249            sameSplitGenerate = new JRadioButton("Generate New Query Set & Evaluate");
250            sameSplitGenerate.addActionListener(new ActionListener() {
251                public void actionPerformed(ActionEvent e)
252                {
253                    loadSplit.setEnabled(false);
254                    sameSplitReuseFile.setEnabled(false);
255                    saveSplit.setEnabled(true);
256                    sameSplitGenerateFile.setEnabled(true);
257                    sameSplitGeneratePercentSpinner.setEnabled(true);
258                    sameSplitGeneratePercent.setEnabled(true);
259                }
260            });
261            saveSplit = new JButton("Save Query Set");      
262            sameSplitGenerateFile = new JTextField(20);
263            saveSplit.addActionListener(new ActionListener() {
264                public void actionPerformed(ActionEvent e)
265                {
266                    JFileChooser jfc = new JFileChooser(".");
267                    int returnVal = jfc.showSaveDialog(null);
268                    if(returnVal == JFileChooser.APPROVE_OPTION)
269                        sameSplitGenerateFile.setText(jfc.getSelectedFile().toString());
270                }
271            });
272    
273            JPanel sameSplitPanel1b = new JPanel();
274            sameSplitGeneratePercent = new JLabel("Query Set percent:");
275            sameSplitPercent = new SpinnerNumberModel(10, 5, 95, 5);
276            sameSplitGeneratePercentSpinner = new JSpinner(sameSplitPercent);
277            
278            
279            JPanel sameSplitPanel2 = new JPanel();  
280            sameSplitReuse = new JRadioButton("Evaluate Using Existing Query Set");
281            sameSplitReuse.addActionListener(new ActionListener() {
282                public void actionPerformed(ActionEvent e)
283                {
284                    loadSplit.setEnabled(true);
285                    sameSplitReuseFile.setEnabled(true);
286                    saveSplit.setEnabled(false);
287                    sameSplitGenerateFile.setEnabled(false);
288                    sameSplitGeneratePercentSpinner.setEnabled(false);
289                    sameSplitGeneratePercent.setEnabled(false);
290                }
291            });
292            loadSplit = new JButton("Open Query Set");
293            sameSplitReuseFile = new JTextField(20);
294            loadSplit.addActionListener(new ActionListener() {
295                public void actionPerformed(ActionEvent e)
296                {
297                    JFileChooser jfc = new JFileChooser(".");
298                    int returnVal = jfc.showOpenDialog(null);
299                    if(returnVal == JFileChooser.APPROVE_OPTION)
300                        sameSplitReuseFile.setText(jfc.getSelectedFile().toString());
301                }
302            });
303    
304    
305            sameSplitPanel1.add(saveSplit);
306            sameSplitPanel1.add(sameSplitGenerateFile);
307            sameSplitPanel1b.add(sameSplitGeneratePercent);
308            sameSplitPanel1b.add(sameSplitGeneratePercentSpinner);
309            sameSplitPanel2.add(loadSplit);
310            sameSplitPanel2.add(sameSplitReuseFile);
311            
312            sameSplitPanel.add(sameSplitGenerate);
313            sameSplitPanel.add(sameSplitPanel1);
314            sameSplitPanel.add(sameSplitPanel1b);
315            sameSplitPanel.add(sameSplitReuse);
316            sameSplitPanel.add(sameSplitPanel2);
317            sameSplitPanel1.setAlignmentX(JComponent.LEFT_ALIGNMENT);
318            sameSplitPanel2.setAlignmentX(JComponent.LEFT_ALIGNMENT);
319            sameSplitPanel1b.setAlignmentX(JComponent.LEFT_ALIGNMENT);
320            
321            ButtonGroup sameSplitGroup = new ButtonGroup();
322            sameSplitGroup.add(sameSplitGenerate);
323            sameSplitGroup.add(sameSplitReuse);
324            
325            sameSplitGenerate.setSelected(true);
326            loadSplit.setEnabled(false);
327            sameSplitReuseFile.setEnabled(false);
328            
329            holdOut = new JRadioButton("Hold Out - Query Set Random");
330            holdOut.addActionListener(new ActionListener() {
331                public void actionPerformed(ActionEvent e)
332                {
333                    enableGroup("holdout");
334                }
335            });
336    
337            JPanel holdOutOptions = new JPanel();
338            holdOutLabel1 = new JLabel("Query Set Percent");
339            holdOutOptions.add(holdOutLabel1);
340            holdOutPercent = new SpinnerNumberModel(10, 5, 95, 5);
341            holdOutPercentSpinner = new JSpinner(holdOutPercent);
342            holdOutOptions.add(holdOutPercentSpinner);
343            holdOutLabel2 = new JLabel("Repetitions");
344            holdOutOptions.add(holdOutLabel2);
345            holdOutRepetitions = new SpinnerNumberModel(1, 1, 10, 1);
346            holdOutRepetitionsSpinner = new JSpinner(holdOutRepetitions);
347            holdOutOptions.add(holdOutRepetitionsSpinner);
348    
349            nFold = new JRadioButton("N-Fold - Random");
350            nFold.addActionListener(new ActionListener() {
351                public void actionPerformed(ActionEvent e)
352                {
353                    enableGroup("nfold");
354                }
355            });
356    
357            JPanel nFoldOptions = new JPanel();
358            nFoldLabel1 = new JLabel("Folds");
359            nFoldOptions.add(nFoldLabel1);
360            nFoldFolds = new SpinnerNumberModel(4, 2, 10, 1);
361            nFoldFoldsSpinner = new JSpinner(nFoldFolds);
362            nFoldOptions.add(nFoldFoldsSpinner);
363            nFoldLabel2 = new JLabel("Repetitions");
364            nFoldOptions.add(nFoldLabel2);
365            nFoldRepetitions = new SpinnerNumberModel(1, 1, 10, 1);
366            nFoldRepetitionsSpinner = new JSpinner(nFoldRepetitions);
367            nFoldOptions.add(nFoldRepetitionsSpinner);
368    
369            ButtonGroup evaluatorGroup = new ButtonGroup();
370            evaluatorGroup.add(leaveOneOut);
371            evaluatorGroup.add(holdOutFixed10);
372            evaluatorGroup.add(holdOutFixed20);
373            evaluatorGroup.add(holdOutFixed30);
374            evaluatorGroup.add(sameSplit);
375            evaluatorGroup.add(holdOut);
376            evaluatorGroup.add(nFold);
377    
378            evaluatorPanel.add(leaveOneOut);
379            evaluatorPanel.add(holdOutFixed10);
380            evaluatorPanel.add(holdOutFixed20);
381            evaluatorPanel.add(holdOutFixed30);
382            evaluatorPanel.add(holdOut);
383            evaluatorPanel.add(holdOutOptions);
384            evaluatorPanel.add(nFold);
385            evaluatorPanel.add(nFoldOptions);
386            evaluatorPanel.add(sameSplit);
387            evaluatorPanel.add(sameSplitPanel);
388    
389            leaveOneOut.setAlignmentX(Component.LEFT_ALIGNMENT);
390            holdOutFixed10.setAlignmentX(Component.LEFT_ALIGNMENT);
391            holdOutFixed20.setAlignmentX(Component.LEFT_ALIGNMENT);
392            holdOutFixed30.setAlignmentX(Component.LEFT_ALIGNMENT);
393            sameSplit.setAlignmentX(Component.LEFT_ALIGNMENT);
394            sameSplitPanel.setAlignmentX(Component.LEFT_ALIGNMENT);
395            holdOut.setAlignmentX(Component.LEFT_ALIGNMENT);
396            holdOutOptions.setAlignmentX(Component.LEFT_ALIGNMENT);
397            nFold.setAlignmentX(Component.LEFT_ALIGNMENT);
398            nFoldOptions.setAlignmentX(Component.LEFT_ALIGNMENT);
399    
400    
401            
402            leaveOneOut.setSelected(true);
403    
404            this.setEnabledHoldOut(false);
405            this.setEnabledNFold(false);
406            this.setEnabledSameSplit(false);
407    
408            /** ****** Similarity Panel ************ */
409    
410            JPanel similPanel = new JPanel();
411            similPanel.setBorder(BorderFactory.createTitledBorder("Similarity Function"));
412            similPanel.setLayout(new GridLayout(6, 1));
413    
414            compressionBased = new JRadioButton("Compression");
415            normalizedCompression = new JRadioButton("Normalized Compression");
416            cosine = new JRadioButton("Cosine Coefficient");
417            dice = new JRadioButton("Dice Coefficient");
418            jaccard = new JRadioButton("Jaccard Coefficient");
419            overlap = new JRadioButton("Overlap Coefficient");
420    
421            ButtonGroup similGroup = new ButtonGroup();
422            similGroup.add(compressionBased);
423            similGroup.add(normalizedCompression);
424            similGroup.add(cosine);
425            similGroup.add(dice);
426            similGroup.add(jaccard);
427            similGroup.add(overlap);
428    
429            similPanel.add(compressionBased);
430            similPanel.add(normalizedCompression);
431            similPanel.add(cosine);
432            similPanel.add(dice);
433            similPanel.add(jaccard);
434            similPanel.add(overlap);
435    
436            compressionBased.setSelected(true);
437    
438            /** ****** Classification Panel ************ */
439    
440            JPanel clasifPanel = new JPanel();
441            clasifPanel.setBorder(BorderFactory.createTitledBorder("KNN Classification Method"));
442            clasifPanel.setLayout(new GridLayout(4, 1));
443    
444            majorityVoting = new JRadioButton("Majority Voting Method");
445            weightedVoting = new JRadioButton("Weighted Voting Method");
446            unanimousVoting = new JRadioButton("Unanimous Voting Method");
447    
448            JPanel kPanel = new JPanel();
449            kPanel.add(new JLabel("K value"));
450            kValue = new SpinnerNumberModel(3, 1, 10, 1);
451            kValueSpinner = new JSpinner(kValue);
452            kPanel.add(kValueSpinner);
453    
454            ButtonGroup clasifGroup = new ButtonGroup();
455            clasifGroup.add(majorityVoting);
456            clasifGroup.add(weightedVoting);
457            clasifGroup.add(unanimousVoting);
458    
459            clasifPanel.add(kPanel);
460            clasifPanel.add(weightedVoting);
461            clasifPanel.add(majorityVoting);
462            clasifPanel.add(unanimousVoting);
463    
464    
465            weightedVoting.setSelected(true);
466    
467            /** ********* Buttons ********** */
468    
469            JPanel buttons = new JPanel();
470    
471            evaluate = new JButton("Evaluate Application");
472            visualize = new JButton("Visualize Case Base using Similarity Function");
473    
474            buttons.add(evaluate);
475            buttons.add(visualize);
476    
477            evaluate.addActionListener(new ActionListener() {
478                public void actionPerformed(ActionEvent e)
479                {
480                    evaluate();
481                }
482            });
483    
484            visualize.addActionListener(new ActionListener() {
485                public void actionPerformed(ActionEvent e)
486                {
487                    visualize();
488                }
489            });
490    
491            /************ Progress Listener ****************/
492            //SwingProgressBar shows the progress
493            ProgressListener listener =  new SwingProgressBar();
494            ProgressController.clear();
495            ProgressController.register(listener, CasesVisualization.class);
496            ProgressController.register(listener, LeaveOneOutEvaluator.class);
497            ProgressController.register(listener, NFoldEvaluator.class);
498            ProgressController.register(listener, SameSplitEvaluator.class);
499            ProgressController.register(listener, HoldOutEvaluator.class);
500            ProgressController.register(listener, OpennlpSplitter.class);
501            ProgressController.register(listener, StopWordsDetector.class);
502            ProgressController.register(listener, TextStemmer.class);
503    
504            
505            /** ********* Main Panel ********** */
506    
507            JPanel central = new JPanel();
508            central.setLayout(new BoxLayout(central, BoxLayout.X_AXIS));
509            central.add(corpusPanel);
510            central.add(similPanel);
511            central.add(evaluatorPanel);
512            central.add(clasifPanel);
513    
514            JPanel main = new JPanel();
515            main.setLayout(new BorderLayout());
516    
517            main.add(central, BorderLayout.CENTER);
518            main.add(buttons, BorderLayout.SOUTH);
519    
520            this.getContentPane().add(main);
521            this.pack();
522    
523            this.setTitle("Spam Filter Toy");
524            Dimension screenSize = java.awt.Toolkit.getDefaultToolkit().getScreenSize();
525            setBounds((screenSize.width - this.getWidth()) / 2, (screenSize.height - this.getHeight()) / 2, getWidth(),
526                    getHeight());
527    
528    //        this.addWindowListener(new WindowAdapter() 
529    //        {   public void windowClosing(WindowEvent arg0) 
530    //            {   
531    //              System.exit(0);
532    //            }
533    //        });
534        }
535    
536        void enableGroup(String group)
537        {
538            if (group.equals("nfold"))
539            {
540                setEnabledNFold(true);
541                setEnabledHoldOut(false);
542                setEnabledSameSplit(false);
543            } else if (group.equals("holdout"))
544            {
545                setEnabledNFold(false);
546                setEnabledSameSplit(false);
547                setEnabledHoldOut(true);
548            }
549            else if (group.equals("samesplit"))
550            {
551                setEnabledNFold(false);
552                setEnabledSameSplit(true);
553                setEnabledHoldOut(false);
554            }
555            else if(group.equals("none"))
556            {
557                setEnabledNFold(false);
558                setEnabledSameSplit(false);
559                setEnabledHoldOut(false);
560            }
561        }
562    
563    
564        private void setEnabledSameSplit(boolean enabled)
565        {
566            this.sameSplitGenerate.setEnabled(enabled);
567            this.sameSplitReuse.setEnabled(enabled);
568            if(!enabled)
569            {
570                this.saveSplit.setEnabled(enabled);
571                this.loadSplit.setEnabled(enabled);
572                this.sameSplitGenerateFile.setEnabled(enabled);
573                this.sameSplitReuseFile.setEnabled(enabled);
574                this.sameSplitGeneratePercentSpinner.setEnabled(enabled);
575                this.sameSplitGeneratePercent.setEnabled(enabled);
576            }
577            else
578            {
579                
580                if(sameSplitGenerate.isSelected())
581                {
582                    saveSplit.setEnabled(true);
583                    sameSplitGenerateFile.setEnabled(true);
584                    sameSplitGeneratePercentSpinner.setEnabled(true);
585                    sameSplitGeneratePercent.setEnabled(true);
586                }
587                else
588                {
589                    loadSplit.setEnabled(true);
590                    sameSplitReuseFile.setEnabled(true);
591                }
592            }
593        }
594        
595        private void setEnabledNFold(boolean enabled)
596        {
597            nFoldLabel1.setEnabled(enabled);
598            nFoldLabel2.setEnabled(enabled);
599            nFoldFoldsSpinner.setEnabled(enabled);
600            nFoldRepetitionsSpinner.setEnabled(enabled);
601        }
602    
603        private void setEnabledHoldOut(boolean enabled)
604        {
605            holdOutLabel1.setEnabled(enabled);
606            holdOutLabel2.setEnabled(enabled);
607            holdOutPercentSpinner.setEnabled(enabled);
608            holdOutRepetitionsSpinner.setEnabled(enabled);
609        }
610    
611        void setButtonsEnabled(boolean enabled)
612        {
613            visualize.setEnabled(enabled);
614            evaluate.setEnabled(enabled);
615        }
616        
617        void evaluate()
618        {
619            SpamFilterApp app = configureApp();
620            Thread thread = new Thread(new Evaluation(app));
621            thread.start();
622        }
623    
624        /**
625             * Thread for running the Visualization
626             * 
627             * @author Juan A. Recio-Garcia
628             * @version 1.0
629             */
630        class Evaluation implements Runnable
631        {
632            SpamFilterApp app;
633    
634            Evaluation(SpamFilterApp app)
635            {
636                this.app = app;
637            }
638    
639            public void run()
640            {
641                setButtonsEnabled(false);
642                try
643                {
644                    if (leaveOneOut.isSelected())
645                    {
646                        LeaveOneOutEvaluator eval = new LeaveOneOutEvaluator();
647                        eval.init(app);
648                        eval.LeaveOneOut(); 
649                    } 
650                    else if(sameSplit.isSelected())
651                    {
652                        SameSplitEvaluator eval = new SameSplitEvaluator();
653                        eval.init(app);
654                        if(sameSplitGenerate.isSelected())
655                        {
656                            String file = sameSplitGenerateFile.getText();
657                            int percent = sameSplitPercent.getNumber().intValue();
658                            eval.generateSplit(percent, file);
659                            eval.HoldOutfromFile(file);
660                        }
661                        else if(sameSplitReuse.isSelected())
662                        {
663                            eval.HoldOutfromFile(sameSplitReuseFile.getText());
664                        }
665                    } 
666                    else if (holdOut.isSelected())
667                    {
668                        HoldOutEvaluator eval = new HoldOutEvaluator();
669                        eval.init(app);
670                        int testPercent = holdOutPercent.getNumber().intValue();
671                        int repetitions = holdOutRepetitions.getNumber().intValue();
672                        eval.HoldOut(testPercent, repetitions);
673                    } 
674                    else if (nFold.isSelected())
675                    {
676                        NFoldEvaluator eval = new NFoldEvaluator();
677                        eval.init(app);
678                        int folds = nFoldFolds.getNumber().intValue();
679                        int repetitions = nFoldRepetitions.getNumber().intValue();
680                        eval.NFoldEvaluation(folds, repetitions);
681                    } 
682                    else
683                    {
684                        String filename = "jcolibri/test/test16/splits/corpus";
685                        if(corpus300.isSelected())
686                            filename+="300-";
687                        else
688                            filename+="600-";
689                        
690                        if(holdOutFixed10.isSelected())
691                            filename+="10.split";
692                        else if(holdOutFixed20.isSelected())
693                            filename+="20.split";
694                        else if(holdOutFixed30.isSelected())
695                            filename+="30.split";
696                            
697                        SameSplitEvaluator eval = new SameSplitEvaluator();
698                        eval.init(app);
699                        eval.HoldOutfromFile(filename);
700                        
701                    }
702    
703                    double tp = app.getTruePositives();
704                    double fp = app.getFalsePositives();
705                    double fn = app.getFalseNegatives();
706                    double tn = app.getTrueNegatives();
707                    double precision = tp / (tp + fp);
708                    double recall    = tp / (tp + fn);
709    
710                    EvaluationReport report = Evaluator.getEvaluationReport();
711                    report.putOtherData("Precision", String.valueOf(precision));
712                    report.putOtherData("Recall", String.valueOf(recall));
713                    report.putOtherData("True Spam", String.valueOf(tp));
714                    report.putOtherData("True Ham", String.valueOf(tn));
715                    report.putOtherData("False Spam", String.valueOf(fp));
716                    report.putOtherData("False Ham", String.valueOf(fn));
717    
718                    System.out.println(report);
719                    jcolibri.evaluation.tools.EvaluationResultGUI.show(report, "Spam Filter Toy - Evaluation", false);
720    
721                } catch (Exception e)
722                {
723                    org.apache.commons.logging.LogFactory.getLog(SpamFilterApp.class).error(e);
724    
725                }
726                setButtonsEnabled(true);
727            }
728        }
729        
730        void visualize()
731        {
732            SpamFilterApp app = configureApp();
733            Thread thread = new Thread(new Visualization(app));
734            thread.start();
735        }
736        
737        /**
738             * Thread for running the Visualization
739             * 
740             * @author Juan A. Recio-Garcia
741             * @version 1.0
742             */
743        class Visualization implements Runnable
744        {
745            SpamFilterApp app;
746            Visualization(SpamFilterApp app)
747            {
748                this.app = app;
749            }
750            
751            public void run()
752            {
753                setButtonsEnabled(false);
754                    try
755                    {
756                        app.configure();
757                        CBRCaseBase _caseBase = app.preCycle();
758                        jcolibri.extensions.visualization.CasesVisualization.visualize(_caseBase.getCases(), app.getKNNConfig());
759                    } catch (ExecutionException e)
760                    {
761                        org.apache.commons.logging.LogFactory.getLog(SpamFilterApp.class).error(e);
762                        
763                    }
764                setButtonsEnabled(true);
765    
766            }
767        }
768        
769        private SpamFilterApp configureApp()
770        {
771            // Connector
772            String corpusFile = null;
773            if(this.corpus300.isSelected())
774                corpusFile = "jcolibri/test/test16/corpus300.zip";
775            else if(this.corpus600.isSelected())
776                corpusFile = "jcolibri/test/test16/corpus600.zip";
777            
778            // Simil function
779            LocalSimilarityFunction similFunc = null;
780            if(this.compressionBased.isSelected())
781                similFunc = new CompressionBased(new GZipCompressor());
782            else if(this.normalizedCompression.isSelected())
783                similFunc = new NormalisedCompression(new GZipCompressor());
784            else if(this.cosine.isSelected())
785                similFunc = new CosineCoefficient();
786            else if(this.dice.isSelected())
787                similFunc = new DiceCoefficient();
788            else if(this.jaccard.isSelected())
789                similFunc = new JaccardCoefficient();
790            else if(this.overlap.isSelected())
791                similFunc = new OverlapCoefficient();
792            
793            // Classification method
794            KNNClassificationMethod classifMethod = null;
795            if(this.majorityVoting.isSelected())
796                classifMethod = new MajorityVotingMethod();
797            else if(this.weightedVoting.isSelected())
798                classifMethod = new SimilarityWeightedVotingMethod();
799            else if(this.unanimousVoting.isSelected())
800                classifMethod = new UnanimousVotingMethod(EmailSolution.SPAM);
801            
802            //K
803            int k = this.kValue.getNumber().intValue();
804            
805            SpamFilterApp app = new SpamFilterApp(corpusFile);
806            app.setSimilFunc(similFunc);
807            app.setClasifMethod(classifMethod);
808            app.setK(k);
809            
810            return app;
811        }
812        
813        public static void main(String[] args) 
814        {
815            Test16 test = new Test16();
816            test.setVisible(true);
817        }
818    }