001    package org.jaga.fitnessEvaluation.proteinLocation;
002    
003    import org.jaga.individualRepresentation.proteinLocation.*;
004    import org.jaga.definitions.*;
005    import org.jaga.selection.*;
006    
007    /**
008     * TODO: Complete these comments.
009     *
010     * <p><u>Project:</u> JAGA - Java API for Genetic Algorithms.</p>
011     *
012     * <p><u>Company:</u> University College London and JAGA.Org
013     *    (<a href="http://www.jaga.org" target="_blank">http://www.jaga.org</a>).
014     * </p>
015     *
016     * <p><u>Copyright:</u> (c) 2004 by G. Paperin.<br/>
017     *    This program is free software; you can redistribute it and/or modify
018     *    it under the terms of the GNU General Public License as published by
019     *    the Free Software Foundation, ONLY if you include a note of the original
020     *    author(s) in any redistributed/modified copy.<br/>
021     *    This program is distributed in the hope that it will be useful,
022     *    but WITHOUT ANY WARRANTY; without even the implied warranty of
023     *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
024     *    GNU General Public License for more details.<br/>
025     *    You should have received a copy of the GNU General Public License
026     *    along with this program; if not, write to the Free Software
027     *    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
028     *    or see http://www.gnu.org/licenses/gpl.html</p>
029     *
030     * @author Greg Paperin (greg@jaga.org)
031     *
032     * @version JAGA public release 1.0 beta
033     */
034    
035    public class ProteinLocationTrainer implements FitnessEvaluationAlgorithm {
036    
037            private ProteinGroup positiveGroup = null;
038            private ProteinGroup negativeGroup = null;
039            private int minOverlap = 3;
040    
041            private ProteinLocationClassifier best = null;
042    
043            private ProteinLocationTrainer() {}
044    
045            public ProteinLocationTrainer(ProteinGroup positiveGroup, ProteinGroup negativeGroup, int minOverlap) {
046                    this.positiveGroup = positiveGroup;
047                    this.negativeGroup = negativeGroup;
048                    this.minOverlap = minOverlap;
049            }
050    
051            public Class getApplicableClass() {
052                    return ProteinLocationClassifier.class;
053            }
054    
055            public void setPositiveGroup(ProteinGroup pGroup) {
056                    if (null == pGroup)
057                            throw new NullPointerException("Group cannot be null.");
058                    this.positiveGroup = pGroup;
059            }
060    
061            public ProteinGroup getPositiveGroup() {
062                    return this.positiveGroup;
063            }
064    
065            public void setNegativeGroup(ProteinGroup nGroup) {
066                    if (null == nGroup)
067                            throw new NullPointerException("Group cannot be null.");
068                    this.negativeGroup = nGroup;
069            }
070    
071            public ProteinGroup getNegativeGroup() {
072                    return this.negativeGroup;
073            }
074    
075            public int getMinOverlap() {
076                    return minOverlap;
077            }
078    
079            public void setMinOverlap(int minOverlap) {
080                    this.minOverlap = minOverlap;
081            }
082    
083            public Fitness evaluateFitness(Individual individual, int age, Population population, GAParameterSet params) {
084                    ProteinLocationClassifier classifier = (ProteinLocationClassifier) individual;
085                    PolypeptidePattern pattern = classifier.getPattern();
086    
087                    int truePositives = positiveGroup.align(pattern, minOverlap);
088                    int falsePositives = negativeGroup.align(pattern, minOverlap);
089                    int falseNegatives = positiveGroup.size() - truePositives;
090                    int trueNegatives = negativeGroup.size() - falsePositives;
091    
092                    double sensitivity, specificity, fitVal;
093    
094                    // Sensitivity (% of positives recognised correctly):
095                    if (0 == truePositives + falseNegatives)
096                            sensitivity = 1.;
097                    else
098                            sensitivity = ((double) truePositives) / ((double) (truePositives + falseNegatives));
099    
100                    // Specificity (in medical sence, i.e. % of negatives recognised correctly):
101                    if (0 == trueNegatives + falsePositives)
102                            specificity = 1.;
103                    else
104                            specificity = ((double) trueNegatives) / ((double) (trueNegatives + falsePositives));
105    
106    /*
107                    if (10 > age) {
108                            best = (ProteinLocationClassifier) individual;
109                            fitVal = sensitivity + specificity;
110                            Fitness fit = new ClassifierFitness(truePositives, trueNegatives,
111                                                                             falsePositives, falseNegatives,
112                                                                             sensitivity, specificity,
113                                                                             fitVal);
114                            return fit;
115    
116                    }
117    
118                    ClassifierFitness bfit = (ClassifierFitness) best.getFitness();
119                    double r = bfit.getSensitivity() / bfit.getSpecificity();
120                    if (0 == r)
121                            r = 1;
122                    fitVal = sensitivity + specificity * r;
123                    if (0 == sensitivity || 0 == specificity)
124                            fitVal = 0;
125                    Fitness fit = new ClassifierFitness(truePositives, trueNegatives,
126                                                                             falsePositives, falseNegatives,
127                                                                             sensitivity, specificity,
128                                                                             fitVal);
129                    if (fit.isBetter(bfit)) {
130                            best = (ProteinLocationClassifier) individual;
131                    }
132                    return fit;
133    */
134    /*
135    return new ClassifierFitness(truePositives, trueNegatives,
136                                                                             falsePositives, falseNegatives,
137                                                                             sensitivity, specificity,
138                                                                             sensitivity + specificity);
139                                                                             */
140    
141              double prod = (double) (truePositives + trueNegatives)
142                                            * (double) (trueNegatives + falsePositives)
143                                            * (double) (truePositives + falseNegatives)
144                                            * (double) (truePositives + falsePositives);
145              double denom = Math.sqrt(prod);
146              double mcc = 0;
147              if (denom != 0)
148                      mcc = (truePositives * trueNegatives - falseNegatives * falsePositives)
149                                    / denom;
150    
151              return new ClassifierFitness(truePositives, trueNegatives,
152                                                                             falsePositives, falseNegatives,
153                                                                             sensitivity, specificity,
154                                                                             mcc);
155    
156            }
157    }