1  #region License Information


2  /* HeuristicLab


3  * Copyright (C) 20022008 Heuristic and Evolutionary Algorithms Laboratory (HEAL)


4  *


5  * This file is part of HeuristicLab.


6  *


7  * HeuristicLab is free software: you can redistribute it and/or modify


8  * it under the terms of the GNU General Public License as published by


9  * the Free Software Foundation, either version 3 of the License, or


10  * (at your option) any later version.


11  *


12  * HeuristicLab is distributed in the hope that it will be useful,


13  * but WITHOUT ANY WARRANTY; without even the implied warranty of


14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the


15  * GNU General Public License for more details.


16  *


17  * You should have received a copy of the GNU General Public License


18  * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.


19  */


20  #endregion


21 


22  using System;


23  using System.Collections.Generic;


24  using System.Linq;


25  using System.Text;


26  using HeuristicLab.Core;


27  using HeuristicLab.Data;


28  using HeuristicLab.GP.StructureIdentification;


29 


30  namespace HeuristicLab.GP.StructureIdentification.Classification {


31  public class ConfusionMatrixEvaluator : GPEvaluatorBase {


32  private const double EPSILON = 1.0E6;


33  private double[] classesArr;


34  private double[] thresholds;


35  private IntMatrixData matrix;


36  public override string Description {


37  get {


38  return @"Calculates the classifcation matrix of the model.";


39  }


40  }


41 


42  public ConfusionMatrixEvaluator()


43  : base() {


44  AddVariableInfo(new VariableInfo("ConfusionMatrix", "The confusion matrix of the model", typeof(IntMatrixData), VariableKind.New));


45  AddVariableInfo(new VariableInfo("TargetClassValues", "The original class values of target variable (for instance negative=0 and positive=1).", typeof(ItemList<DoubleData>), VariableKind.In));


46  }


47 


48  public override IOperation Apply(IScope scope) {


49  ItemList<DoubleData> classes = GetVariableValue<ItemList<DoubleData>>("TargetClassValues", scope, true);


50  classesArr = new double[classes.Count];


51  for(int i = 0; i < classesArr.Length; i++) classesArr[i] = classes[i].Data;


52  Array.Sort(classesArr);


53  thresholds = new double[classes.Count  1];


54  for(int i = 0; i < classesArr.Length  1; i++) {


55  thresholds[i] = (classesArr[i] + classesArr[i + 1]) / 2.0;


56  }


57 


58  matrix = GetVariableValue<IntMatrixData>("ConfusionMatrix", scope, false, false);


59  if(matrix == null) {


60  matrix = new IntMatrixData(new int[classesArr.Length, classesArr.Length]);


61  scope.AddVariable(new HeuristicLab.Core.Variable(scope.TranslateName("ConfusionMatrix"), matrix));


62  }


63  return base.Apply(scope);


64  }


65 


66  public override void Evaluate(int start, int end) {


67  int nSamples = end  start;


68  for(int sample = start; sample < end; sample++) {


69  double est = GetEstimatedValue(sample);


70  double origClass = GetOriginalValue(sample);


71  int estClassIndex = 1;


72  // if estimation is lower than the smallest threshold value > estimated class is the lower class


73  if(est < thresholds[0]) estClassIndex = 0;


74  // if estimation is larger (or equal) than the largest threshold value > estimated class is the upper class


75  else if(est >= thresholds[thresholds.Length  1]) estClassIndex = classesArr.Length  1;


76  else {


77  // otherwise the estimated class is the class which upper threshold is larger than the estimated value


78  for(int k = 0; k < thresholds.Length; k++) {


79  if(thresholds[k] > est) {


80  estClassIndex = k;


81  break;


82  }


83  }


84  }


85  SetOriginalValue(sample, classesArr[estClassIndex]);


86 


87  int origClassIndex = 1;


88  for(int i = 0; i < classesArr.Length; i++) {


89  if(IsEqual(origClass, classesArr[i])) origClassIndex = i;


90  }


91  matrix.Data[origClassIndex, estClassIndex]++;


92  }


93  }


94 


95  private bool IsEqual(double x, double y) {


96  return Math.Abs(x  y) < EPSILON;


97  }


98  }


99  }

