Free cookie consent management tool by TermsFeed Policy Generator

Ignore:
Timestamp:
07/05/10 17:14:22 (14 years ago)
Author:
gkronber
Message:

Improved efficiency of analyzers and evaluators for regression problems. #1074

Location:
trunk/sources/HeuristicLab.Problems.DataAnalysis.Regression/3.3/Symbolic/Analyzers
Files:
1 added
2 edited

Legend:

Unmodified
Added
Removed
  • trunk/sources/HeuristicLab.Problems.DataAnalysis.Regression/3.3/Symbolic/Analyzers/BestSymbolicRegressionSolutionAnalyzer.cs

    r3925 r3996  
    9999          SymbolicExpressionTree[i]);
    100100        var solution = new SymbolicRegressionSolution(ProblemData, model, lowerEstimationLimit, upperEstimationLimit);
    101 
     101        solution.Name = BestSolutionParameterName;
     102        solution.Description = "Best solution on validation partition found over the whole run.";
    102103        BestSolutionParameter.ActualValue = solution;
    103104        BestSolutionQualityParameter.ActualValue = Quality[i];
    104 
    105         if (Results.ContainsKey(BestSolutionInputvariableCountResultName)) {
    106           Results[BestSolutionInputvariableCountResultName].Value = new IntValue(model.InputVariables.Count());
    107           Results[VariableImpactsResultName].Value = CalculateVariableImpacts();
    108         } else {
    109           Results.Add(new Result(BestSolutionInputvariableCountResultName, new IntValue(model.InputVariables.Count())));
    110           Results.Add(new Result(VariableImpactsResultName, CalculateVariableImpacts()));
    111         }
     105        BestSymbolicRegressionSolutionAnalyzer.UpdateSymbolicRegressionBestSolutionResults(solution, ProblemData, Results, VariableFrequencies);
    112106      }
    113107      return BestSolutionParameter.ActualValue;
    114108    }
    115109
    116     private DoubleMatrix CalculateVariableImpacts() {
    117       if (VariableFrequencies != null) {
    118         var impacts = new DoubleMatrix(VariableFrequencies.Rows.Count, 1, new string[] { "Impact" }, VariableFrequencies.Rows.Select(x => x.Name));
     110    public static void UpdateBestSolutionResults(SymbolicRegressionSolution bestSolution, DataAnalysisProblemData problemData, ResultCollection results, IntValue currentGeneration, DataTable variableFrequencies) {
     111      RegressionSolutionAnalyzer.UpdateBestSolutionResults(bestSolution, problemData, results, currentGeneration);
     112      UpdateSymbolicRegressionBestSolutionResults(bestSolution, problemData, results, variableFrequencies);
     113    }
     114
     115    private static void UpdateSymbolicRegressionBestSolutionResults(SymbolicRegressionSolution bestSolution, DataAnalysisProblemData problemData, ResultCollection results, DataTable variableFrequencies) {
     116      if (results.ContainsKey(BestSolutionInputvariableCountResultName)) {
     117        results[BestSolutionInputvariableCountResultName].Value = new IntValue(bestSolution.Model.InputVariables.Count());
     118        results[VariableImpactsResultName].Value = CalculateVariableImpacts(variableFrequencies);
     119      } else {
     120        results.Add(new Result(BestSolutionInputvariableCountResultName, new IntValue(bestSolution.Model.InputVariables.Count())));
     121        results.Add(new Result(VariableImpactsResultName, CalculateVariableImpacts(variableFrequencies)));
     122      }
     123    }
     124
     125
     126    private static DoubleMatrix CalculateVariableImpacts(DataTable variableFrequencies) {
     127      if (variableFrequencies != null) {
     128        var impacts = new DoubleMatrix(variableFrequencies.Rows.Count, 1, new string[] { "Impact" }, variableFrequencies.Rows.Select(x => x.Name));
    119129        impacts.SortableView = true;
    120130        int rowIndex = 0;
    121         foreach (var dataRow in VariableFrequencies.Rows) {
     131        foreach (var dataRow in variableFrequencies.Rows) {
    122132          string variableName = dataRow.Name;
    123133          double integral = 0;
     
    134144      } else return new DoubleMatrix(1, 1);
    135145    }
    136 
    137146  }
    138147}
  • trunk/sources/HeuristicLab.Problems.DataAnalysis.Regression/3.3/Symbolic/Analyzers/SymbolicRegressionModelQualityAnalyzer.cs

    r3710 r3996  
    4545  [Item("SymbolicRegressionModelQualityAnalyzer", "An operator for analyzing the quality of symbolic regression solutions symbolic expression tree encoding.")]
    4646  [StorableClass]
    47   public sealed class SymbolicRegressionModelQualityAnalyzer : AlgorithmOperator, ISymbolicRegressionAnalyzer {
     47  public sealed class SymbolicRegressionModelQualityAnalyzer : SingleSuccessorOperator, ISymbolicRegressionAnalyzer {
    4848    private const string SymbolicExpressionTreeInterpreterParameterName = "SymbolicExpressionTreeInterpreter";
    4949    private const string SymbolicExpressionTreeParameterName = "SymbolicExpressionTree";
     
    130130    }
    131131    #endregion
    132 
    133     [Storable]
    134     private UniformSubScopesProcessor subScopesProcessor;
    135     [Storable]
    136     private MinAverageMaxValueAnalyzer minAvgMaxTrainingMseAnalyzer;
    137     [Storable]
    138     private MinAverageMaxValueAnalyzer minAvgMaxTestMseAnalyzer;
    139     [Storable]
    140     private MinAverageMaxValueAnalyzer minAvgMaxTrainingRSquaredAnalyzer;
    141     [Storable]
    142     private MinAverageMaxValueAnalyzer minAvgMaxTestRSquaredAnalyzer;
    143     [Storable]
    144     private MinAverageMaxValueAnalyzer minAvgMaxTrainingRelErrorAnalyzer;
    145     [Storable]
    146     private MinAverageMaxValueAnalyzer minAvgMaxTestRelErrorAnalyzer;
     132    #region properties
     133    public DoubleValue UpperEstimationLimit {
     134      get { return UpperEstimationLimitParameter.ActualValue; }
     135    }
     136    public DoubleValue LowerEstimationLimit {
     137      get { return LowerEstimationLimitParameter.ActualValue; }
     138    }
     139    #endregion
    147140
    148141    public SymbolicRegressionModelQualityAnalyzer()
     
    161154      Parameters.Add(new ValueLookupParameter<DataTable>(RelativeErrorValuesParameterName, "The data table to collect relative error values."));
    162155      Parameters.Add(new LookupParameter<ResultCollection>(ResultsParameterName, "The result collection where the best symbolic regression solution should be stored."));
    163 
    164       #region operator initialization
    165       subScopesProcessor = new UniformSubScopesProcessor();
    166       SymbolicRegressionModelQualityCalculator trainingQualityCalculator = new SymbolicRegressionModelQualityCalculator();
    167       SymbolicRegressionModelQualityCalculator testQualityCalculator = new SymbolicRegressionModelQualityCalculator();
    168       minAvgMaxTrainingMseAnalyzer = new MinAverageMaxValueAnalyzer();
    169       minAvgMaxTestMseAnalyzer = new MinAverageMaxValueAnalyzer();
    170 
    171       minAvgMaxTrainingRSquaredAnalyzer = new MinAverageMaxValueAnalyzer();
    172       minAvgMaxTestRSquaredAnalyzer = new MinAverageMaxValueAnalyzer();
    173 
    174       minAvgMaxTrainingRelErrorAnalyzer = new MinAverageMaxValueAnalyzer();
    175       minAvgMaxTestRelErrorAnalyzer = new MinAverageMaxValueAnalyzer();
    176       #endregion
    177 
    178       #region parameter wiring
    179       subScopesProcessor.Depth.Value = SymbolicExpressionTreeParameter.Depth;
    180       trainingQualityCalculator.LowerEstimationLimitParameter.ActualName = LowerEstimationLimitParameter.Name;
    181       trainingQualityCalculator.ProblemDataParameter.ActualName = ProblemDataParameter.Name;
    182       trainingQualityCalculator.SamplesStartParameter.ActualName = TrainingSamplesStartParameter.Name;
    183       trainingQualityCalculator.SamplesEndParameter.ActualName = TrainingSamplesEndParameter.Name;
    184       trainingQualityCalculator.SymbolicExpressionTreeInterpreterParameter.ActualName = SymbolicExpressionTreeInterpreterParameter.Name;
    185       trainingQualityCalculator.SymbolicExpressionTreeParameter.ActualName = SymbolicExpressionTreeParameter.Name;
    186       trainingQualityCalculator.UpperEstimationLimitParameter.ActualName = UpperEstimationLimitParameter.Name;
    187       trainingQualityCalculator.AverageRelativeErrorQualityParameter.ActualName = TrainingAverageRelativeErrorQualityParameterName;
    188       trainingQualityCalculator.MeanSquaredErrorQualityParameter.ActualName = TrainingMeanSquaredErrorQualityParameterName;
    189       trainingQualityCalculator.RSquaredQualityParameter.ActualName = TrainingRSquaredQualityParameterName;
    190 
    191       testQualityCalculator.LowerEstimationLimitParameter.ActualName = LowerEstimationLimitParameter.Name;
    192       testQualityCalculator.ProblemDataParameter.ActualName = ProblemDataParameter.Name;
    193       testQualityCalculator.SamplesStartParameter.ActualName = TestSamplesStartParameter.Name;
    194       testQualityCalculator.SamplesEndParameter.ActualName = TestSamplesEndParameter.Name;
    195       testQualityCalculator.SymbolicExpressionTreeInterpreterParameter.ActualName = SymbolicExpressionTreeInterpreterParameter.Name;
    196       testQualityCalculator.SymbolicExpressionTreeParameter.ActualName = SymbolicExpressionTreeParameter.Name;
    197       testQualityCalculator.UpperEstimationLimitParameter.ActualName = UpperEstimationLimitParameter.Name;
    198       testQualityCalculator.AverageRelativeErrorQualityParameter.ActualName = TestAverageRelativeErrorQualityParameterName;
    199       testQualityCalculator.MeanSquaredErrorQualityParameter.ActualName = TestMeanSquaredErrorQualityParameterName;
    200       testQualityCalculator.RSquaredQualityParameter.ActualName = TestRSquaredQualityParameterName;
    201       #region training/test MSE
    202       minAvgMaxTrainingMseAnalyzer.ValueParameter.ActualName = TrainingMeanSquaredErrorQualityParameterName;
    203       minAvgMaxTrainingMseAnalyzer.ValueParameter.Depth = SymbolicExpressionTreeParameter.Depth;
    204       minAvgMaxTrainingMseAnalyzer.AverageValueParameter.ActualName = AverageTrainingMeanSquaredErrorQualityParameterName;
    205       minAvgMaxTrainingMseAnalyzer.MaxValueParameter.ActualName = MaxTrainingMeanSquaredErrorQualityParameterName;
    206       minAvgMaxTrainingMseAnalyzer.MinValueParameter.ActualName = MinTrainingMeanSquaredErrorQualityParameterName;
    207       minAvgMaxTrainingMseAnalyzer.ValuesParameter.ActualName = MeanSquaredErrorValuesParameterName;
    208       minAvgMaxTrainingMseAnalyzer.ResultsParameter.ActualName = ResultsParameter.Name;
    209       minAvgMaxTrainingMseAnalyzer.CollectMinValueInResultsParameter.Value = new BoolValue(false);
    210       minAvgMaxTrainingMseAnalyzer.CollectAverageValueInResultsParameter.Value = new BoolValue(false);
    211       minAvgMaxTrainingMseAnalyzer.CollectMaxValueInResultsParameter.Value = new BoolValue(false);
    212 
    213       minAvgMaxTestMseAnalyzer.ValueParameter.ActualName = TestMeanSquaredErrorQualityParameterName;
    214       minAvgMaxTestMseAnalyzer.ValueParameter.Depth = SymbolicExpressionTreeParameter.Depth;
    215       minAvgMaxTestMseAnalyzer.AverageValueParameter.ActualName = AverageTestMeanSquaredErrorQualityParameterName;
    216       minAvgMaxTestMseAnalyzer.MaxValueParameter.ActualName = MaxTestMeanSquaredErrorQualityParameterName;
    217       minAvgMaxTestMseAnalyzer.MinValueParameter.ActualName = MinTestMeanSquaredErrorQualityParameterName;
    218       minAvgMaxTestMseAnalyzer.ValuesParameter.ActualName = MeanSquaredErrorValuesParameterName;
    219       minAvgMaxTestMseAnalyzer.ResultsParameter.ActualName = ResultsParameter.Name;
    220       minAvgMaxTestMseAnalyzer.CollectMinValueInResultsParameter.Value = new BoolValue(false);
    221       minAvgMaxTestMseAnalyzer.CollectAverageValueInResultsParameter.Value = new BoolValue(false);
    222       minAvgMaxTestMseAnalyzer.CollectMaxValueInResultsParameter.Value = new BoolValue(false);
    223 
    224       #endregion
    225       #region training/test R²
    226       minAvgMaxTrainingRSquaredAnalyzer.ValueParameter.ActualName = TrainingRSquaredQualityParameterName;
    227       minAvgMaxTrainingRSquaredAnalyzer.ValueParameter.Depth = SymbolicExpressionTreeParameter.Depth;
    228       minAvgMaxTrainingRSquaredAnalyzer.AverageValueParameter.ActualName = AverageTrainingRSquaredQualityParameterName;
    229       minAvgMaxTrainingRSquaredAnalyzer.MaxValueParameter.ActualName = MaxTrainingRSquaredQualityParameterName;
    230       minAvgMaxTrainingRSquaredAnalyzer.MinValueParameter.ActualName = MinTrainingRSquaredQualityParameterName;
    231       minAvgMaxTrainingRSquaredAnalyzer.ValuesParameter.ActualName = RSquaredValuesParameterName;
    232       minAvgMaxTrainingRSquaredAnalyzer.ResultsParameter.ActualName = ResultsParameter.Name;
    233       minAvgMaxTrainingRSquaredAnalyzer.CollectMinValueInResultsParameter.Value = new BoolValue(false);
    234       minAvgMaxTrainingRSquaredAnalyzer.CollectAverageValueInResultsParameter.Value = new BoolValue(false);
    235       minAvgMaxTrainingRSquaredAnalyzer.CollectMaxValueInResultsParameter.Value = new BoolValue(false);
    236 
    237 
    238       minAvgMaxTestRSquaredAnalyzer.ValueParameter.ActualName = TestRSquaredQualityParameterName;
    239       minAvgMaxTestRSquaredAnalyzer.ValueParameter.Depth = SymbolicExpressionTreeParameter.Depth;
    240       minAvgMaxTestRSquaredAnalyzer.AverageValueParameter.ActualName = AverageTestRSquaredQualityParameterName;
    241       minAvgMaxTestRSquaredAnalyzer.MaxValueParameter.ActualName = MaxTestRSquaredQualityParameterName;
    242       minAvgMaxTestRSquaredAnalyzer.MinValueParameter.ActualName = MinTestRSquaredQualityParameterName;
    243       minAvgMaxTestRSquaredAnalyzer.ValuesParameter.ActualName = RSquaredValuesParameterName;
    244       minAvgMaxTestRSquaredAnalyzer.ResultsParameter.ActualName = ResultsParameter.Name;
    245       minAvgMaxTestRSquaredAnalyzer.CollectMinValueInResultsParameter.Value = new BoolValue(false);
    246       minAvgMaxTestRSquaredAnalyzer.CollectAverageValueInResultsParameter.Value = new BoolValue(false);
    247       minAvgMaxTestRSquaredAnalyzer.CollectMaxValueInResultsParameter.Value = new BoolValue(false);
    248 
    249       #endregion
    250       #region training/test avg. rel. error
    251       minAvgMaxTrainingRelErrorAnalyzer.ValueParameter.ActualName = TrainingAverageRelativeErrorQualityParameterName;
    252       minAvgMaxTrainingRelErrorAnalyzer.ValueParameter.Depth = SymbolicExpressionTreeParameter.Depth;
    253       minAvgMaxTrainingRelErrorAnalyzer.AverageValueParameter.ActualName = AverageTrainingAverageRelativeErrorQualityParameterName;
    254       minAvgMaxTrainingRelErrorAnalyzer.MaxValueParameter.ActualName = MaxTrainingAverageRelativeErrorQualityParameterName;
    255       minAvgMaxTrainingRelErrorAnalyzer.MinValueParameter.ActualName = MinTrainingAverageRelativeErrorQualityParameterName;
    256       minAvgMaxTrainingRelErrorAnalyzer.ValuesParameter.ActualName = RelativeErrorValuesParameterName;
    257       minAvgMaxTrainingRelErrorAnalyzer.ResultsParameter.ActualName = ResultsParameter.Name;
    258       minAvgMaxTrainingRelErrorAnalyzer.CollectMinValueInResultsParameter.Value = new BoolValue(false);
    259       minAvgMaxTrainingRelErrorAnalyzer.CollectAverageValueInResultsParameter.Value = new BoolValue(false);
    260       minAvgMaxTrainingRelErrorAnalyzer.CollectMaxValueInResultsParameter.Value = new BoolValue(false);
    261 
    262       minAvgMaxTestRelErrorAnalyzer.ValueParameter.ActualName = TestAverageRelativeErrorQualityParameterName;
    263       minAvgMaxTestRelErrorAnalyzer.ValueParameter.Depth = SymbolicExpressionTreeParameter.Depth;
    264       minAvgMaxTestRelErrorAnalyzer.AverageValueParameter.ActualName = AverageTestAverageRelativeErrorQualityParameterName;
    265       minAvgMaxTestRelErrorAnalyzer.MaxValueParameter.ActualName = MaxTestAverageRelativeErrorQualityParameterName;
    266       minAvgMaxTestRelErrorAnalyzer.MinValueParameter.ActualName = MinTestAverageRelativeErrorQualityParameterName;
    267       minAvgMaxTestRelErrorAnalyzer.ValuesParameter.ActualName = RelativeErrorValuesParameterName;
    268       minAvgMaxTestRelErrorAnalyzer.ResultsParameter.ActualName = ResultsParameter.Name;
    269       minAvgMaxTestRelErrorAnalyzer.CollectMinValueInResultsParameter.Value = new BoolValue(false);
    270       minAvgMaxTestRelErrorAnalyzer.CollectAverageValueInResultsParameter.Value = new BoolValue(false);
    271       minAvgMaxTestRelErrorAnalyzer.CollectMaxValueInResultsParameter.Value = new BoolValue(false);
    272       #endregion
    273       #endregion
    274 
    275       #region operator graph
    276       OperatorGraph.InitialOperator = subScopesProcessor;
    277       subScopesProcessor.Operator = trainingQualityCalculator;
    278       trainingQualityCalculator.Successor = testQualityCalculator;
    279       testQualityCalculator.Successor = null;
    280       subScopesProcessor.Successor = minAvgMaxTrainingMseAnalyzer;
    281       minAvgMaxTrainingMseAnalyzer.Successor = minAvgMaxTestMseAnalyzer;
    282       minAvgMaxTestMseAnalyzer.Successor = minAvgMaxTrainingRSquaredAnalyzer;
    283       minAvgMaxTrainingRSquaredAnalyzer.Successor = minAvgMaxTestRSquaredAnalyzer;
    284       minAvgMaxTestRSquaredAnalyzer.Successor = minAvgMaxTrainingRelErrorAnalyzer;
    285       minAvgMaxTrainingRelErrorAnalyzer.Successor = minAvgMaxTestRelErrorAnalyzer;
    286       minAvgMaxTestRelErrorAnalyzer.Successor = null;
    287       #endregion
    288 
    289       Initialize();
    290156    }
    291157
     
    293159    private SymbolicRegressionModelQualityAnalyzer(bool deserializing) : base() { }
    294160
    295     [StorableHook(HookType.AfterDeserialization)]
    296     private void Initialize() {
    297       SymbolicExpressionTreeParameter.DepthChanged += new EventHandler(SymbolicExpressionTreeParameter_DepthChanged);
    298     }
    299 
    300     public override IDeepCloneable Clone(Cloner cloner) {
    301       SymbolicRegressionModelQualityAnalyzer clone = (SymbolicRegressionModelQualityAnalyzer)base.Clone(cloner);
    302       clone.Initialize();
    303       return clone;
    304     }
    305 
    306     private void SymbolicExpressionTreeParameter_DepthChanged(object sender, EventArgs e) {
    307       subScopesProcessor.Depth.Value = SymbolicExpressionTreeParameter.Depth;
    308       minAvgMaxTrainingMseAnalyzer.ValueParameter.Depth = SymbolicExpressionTreeParameter.Depth;
    309       minAvgMaxTrainingRelErrorAnalyzer.ValueParameter.Depth = SymbolicExpressionTreeParameter.Depth;
    310       minAvgMaxTrainingRSquaredAnalyzer.ValueParameter.Depth = SymbolicExpressionTreeParameter.Depth;
    311       minAvgMaxTestMseAnalyzer.ValueParameter.Depth = SymbolicExpressionTreeParameter.Depth;
    312       minAvgMaxTestRelErrorAnalyzer.ValueParameter.Depth = SymbolicExpressionTreeParameter.Depth;
    313       minAvgMaxTestRSquaredAnalyzer.ValueParameter.Depth = SymbolicExpressionTreeParameter.Depth;
     161    public override IOperation Apply() {
     162      Analyze(SymbolicExpressionTreeParameter.ActualValue, SymbolicExpressionTreeInterpreterParameter.ActualValue,
     163        UpperEstimationLimit.Value, LowerEstimationLimit.Value, ProblemDataParameter.ActualValue,
     164        TrainingSamplesStartParameter.ActualValue.Value, TrainingSamplesEndParameter.ActualValue.Value,
     165        TestSamplesStartParameter.ActualValue.Value, TestSamplesEndParameter.ActualValue.Value,
     166        ResultsParameter.ActualValue);
     167      return base.Apply();
     168    }
     169
     170    public static void Analyze(IEnumerable<SymbolicExpressionTree> trees, ISymbolicExpressionTreeInterpreter interpreter,
     171      double upperEstimationLimit, double lowerEstimationLimit,
     172      DataAnalysisProblemData problemData, int trainingStart, int trainingEnd, int testStart, int testEnd, ResultCollection results) {
     173      int targetVariableIndex = problemData.Dataset.GetVariableIndex(problemData.TargetVariable.Value);
     174      IEnumerable<double> originalTrainingValues = problemData.Dataset.GetEnumeratedVariableValues(targetVariableIndex, trainingStart, trainingEnd);
     175      IEnumerable<double> originalTestValues = problemData.Dataset.GetEnumeratedVariableValues(targetVariableIndex, testStart, testEnd);
     176      List<double> trainingMse = new List<double>();
     177      List<double> trainingR2 = new List<double>();
     178      List<double> trainingRelErr = new List<double>();
     179      List<double> testMse = new List<double>();
     180      List<double> testR2 = new List<double>();
     181      List<double> testRelErr = new List<double>();
     182
     183      OnlineMeanSquaredErrorEvaluator mseEvaluator = new OnlineMeanSquaredErrorEvaluator();
     184      OnlineMeanAbsolutePercentageErrorEvaluator relErrEvaluator = new OnlineMeanAbsolutePercentageErrorEvaluator();
     185      OnlinePearsonsRSquaredEvaluator r2Evaluator = new OnlinePearsonsRSquaredEvaluator();
     186
     187      foreach (var tree in trees) {
     188        #region training
     189        var estimatedTrainingValues = interpreter.GetSymbolicExpressionTreeValues(tree, problemData.Dataset, Enumerable.Range(trainingStart, trainingEnd - trainingStart));
     190        mseEvaluator.Reset();
     191        r2Evaluator.Reset();
     192        relErrEvaluator.Reset();
     193        var estimatedEnumerator = estimatedTrainingValues.GetEnumerator();
     194        var originalEnumerator = originalTrainingValues.GetEnumerator();
     195        while (estimatedEnumerator.MoveNext() & originalEnumerator.MoveNext()) {
     196          double estimated = estimatedEnumerator.Current;
     197          if (double.IsNaN(estimated)) estimated = upperEstimationLimit;
     198          else estimated = Math.Min(upperEstimationLimit, Math.Max(lowerEstimationLimit, estimated));
     199          mseEvaluator.Add(originalEnumerator.Current, estimated);
     200          r2Evaluator.Add(originalEnumerator.Current, estimated);
     201          relErrEvaluator.Add(originalEnumerator.Current, estimated);
     202        }
     203        if (estimatedEnumerator.MoveNext() || originalEnumerator.MoveNext()) {
     204          throw new InvalidOperationException("Number of elements in estimated and original enumeration doesn't match.");
     205        }
     206        trainingMse.Add(mseEvaluator.MeanSquaredError);
     207        trainingR2.Add(r2Evaluator.RSquared);
     208        trainingRelErr.Add(relErrEvaluator.MeanAbsolutePercentageError);
     209        #endregion
     210        #region test
     211        var estimatedTestValues = interpreter.GetSymbolicExpressionTreeValues(tree, problemData.Dataset, Enumerable.Range(testStart, testEnd - testStart));
     212
     213        mseEvaluator.Reset();
     214        r2Evaluator.Reset();
     215        relErrEvaluator.Reset();
     216        estimatedEnumerator = estimatedTestValues.GetEnumerator();
     217        originalEnumerator = originalTestValues.GetEnumerator();
     218        while (estimatedEnumerator.MoveNext() & originalEnumerator.MoveNext()) {
     219          double estimated = estimatedEnumerator.Current;
     220          if (double.IsNaN(estimated)) estimated = upperEstimationLimit;
     221          else estimated = Math.Min(upperEstimationLimit, Math.Max(lowerEstimationLimit, estimated));
     222          mseEvaluator.Add(originalEnumerator.Current, estimated);
     223          r2Evaluator.Add(originalEnumerator.Current, estimated);
     224          relErrEvaluator.Add(originalEnumerator.Current, estimated);
     225        }
     226        if (estimatedEnumerator.MoveNext() || originalEnumerator.MoveNext()) {
     227          throw new InvalidOperationException("Number of elements in estimated and original enumeration doesn't match.");
     228        }
     229        testMse.Add(mseEvaluator.MeanSquaredError);
     230        testR2.Add(r2Evaluator.RSquared);
     231        testRelErr.Add(relErrEvaluator.MeanAbsolutePercentageError);
     232        #endregion
     233      }
     234
     235      AddResultTableValues(results, MeanSquaredErrorValuesParameterName, "mean squared error (training)", trainingMse.Min(), trainingMse.Average(), trainingMse.Max());
     236      AddResultTableValues(results, MeanSquaredErrorValuesParameterName, "mean squared error (test)", testMse.Min(), testMse.Average(), testMse.Max());
     237      AddResultTableValues(results, RelativeErrorValuesParameterName, "mean relative error (training)", trainingRelErr.Min(), trainingRelErr.Average(), trainingRelErr.Max());
     238      AddResultTableValues(results, RelativeErrorValuesParameterName, "mean relative error (test)", testRelErr.Min(), testRelErr.Average(), testRelErr.Max());
     239      AddResultTableValues(results, RSquaredValuesParameterName, "Pearson's R² (training)", trainingR2.Min(), trainingR2.Average(), trainingR2.Max());
     240      AddResultTableValues(results, RSquaredValuesParameterName, "Pearson's R² (test)", testR2.Min(), testR2.Average(), testR2.Max());
     241    }
     242
     243    private static void AddResultTableValues(ResultCollection results, string tableName, string valueName, double minValue, double avgValue, double maxValue) {
     244      if (!results.ContainsKey(tableName)) {
     245        results.Add(new Result(tableName, new DataTable(tableName)));
     246      }
     247      DataTable table = (DataTable)results[tableName].Value;
     248      AddValue(table, minValue, "Min. " + valueName, string.Empty);
     249      AddValue(table, avgValue, "Avg. " + valueName, string.Empty);
     250      AddValue(table, maxValue, "Max. " + valueName, string.Empty);
     251    }
     252
     253    private static void AddValue(DataTable table, double data, string name, string description) {
     254      DataRow row;
     255      table.Rows.TryGetValue(name, out row);
     256      if (row == null) {
     257        row = new DataRow(name, description);
     258        row.Values.Add(data);
     259        table.Rows.Add(row);
     260      } else {
     261        row.Values.Add(data);
     262      }
     263    }
     264
     265
     266    private static void SetResultValue(ResultCollection results, string name, double value) {
     267      if (results.ContainsKey(name))
     268        results[name].Value = new DoubleValue(value);
     269      else
     270        results.Add(new Result(name, new DoubleValue(value)));
    314271    }
    315272  }
Note: See TracChangeset for help on using the changeset viewer.