source: branches/GP.Symbols (TimeLag, Diff, Integral)/HeuristicLab.Problems.DataAnalysis.Regression/3.3/Symbolic/Evaluators/SymbolicRegressionConditionalPearsonsRSquaredEvaluator.cs @ 5076

Last change on this file since 5076 was 5076, checked in by mkommend, 10 years ago

Corrected persistence of VariableCondition and conditional evaluator (ticket #1256).

File size: 5.4 KB
Line 
1#region License Information
2/* HeuristicLab
3 * Copyright (C) 2002-2010 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
23using System;
24using System.Collections.Generic;
25using HeuristicLab.Common;
26using HeuristicLab.Core;
27using HeuristicLab.Data;
28using HeuristicLab.Encodings.SymbolicExpressionTreeEncoding;
29using HeuristicLab.Parameters;
30using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
31using HeuristicLab.Problems.DataAnalysis.Evaluators;
32using HeuristicLab.Problems.DataAnalysis.Symbolic;
33
34namespace HeuristicLab.Problems.DataAnalysis.Regression.Symbolic.Evaluators {
35  [Item("SymbolicRegressionConditionalPearsonsRSquaredEvaluator", "Evaluates a symbolic regression solution.")]
36  [StorableClass]
37  public class SymbolicRegressionConditionalPearsonsRSquaredEvaluator : SingleObjectiveSymbolicRegressionEvaluator {
38    private const string ConditionVariableParameterName = "ConditionVariable";
39
40    public IValueParameter<StringValue> ConditionVariableParameter {
41      get { return (IValueParameter<StringValue>)Parameters[ConditionVariableParameterName]; }
42    }
43    public StringValue ConditionVariable {
44      get { return ConditionVariableParameter.Value; }
45    }
46
47    public SymbolicRegressionConditionalPearsonsRSquaredEvaluator()
48      : base() {
49      Parameters.Add(new ValueLookupParameter<StringValue>(ConditionVariableParameterName, "The variable name that states which samples should be skipped for evaluation."));
50    }
51    [StorableConstructor]
52    protected SymbolicRegressionConditionalPearsonsRSquaredEvaluator(bool deserializing) : base(deserializing) { }
53    protected SymbolicRegressionConditionalPearsonsRSquaredEvaluator(SymbolicRegressionConditionalPearsonsRSquaredEvaluator original, Cloner cloner)
54      : base(original, cloner) {
55    }
56    public override IDeepCloneable Clone(Cloner cloner) {
57      return new SymbolicRegressionConditionalPearsonsRSquaredEvaluator(this, cloner);
58    }
59
60    public override double Evaluate(ISymbolicExpressionTreeInterpreter interpreter, SymbolicExpressionTree solution, double lowerEstimationLimit, double upperEstimationLimit, Dataset dataset, string targetVariable, IEnumerable<int> rows) {
61      double mse = Calculate(interpreter, solution, lowerEstimationLimit, upperEstimationLimit, dataset, targetVariable, rows, ConditionVariable.Value);
62      return mse;
63    }
64
65    public static double Calculate(ISymbolicExpressionTreeInterpreter interpreter, SymbolicExpressionTree solution, double lowerEstimationLimit, double upperEstimationLimit, Dataset dataset, string targetVariable, IEnumerable<int> rows, string conditionVariable) {
66      IEnumerable<double> estimatedValues = interpreter.GetSymbolicExpressionTreeValues(solution, dataset, rows);
67      IEnumerable<double> originalValues = dataset.GetEnumeratedVariableValues(targetVariable, rows);
68      IEnumerator<double> originalEnumerator = originalValues.GetEnumerator();
69      IEnumerator<double> estimatedEnumerator = estimatedValues.GetEnumerator();
70      IEnumerator<int> rowsEnumerator = rows.GetEnumerator();
71      OnlinePearsonsRSquaredEvaluator r2Evaluator = new OnlinePearsonsRSquaredEvaluator();
72
73      int minLag = GetMinimumLagFromTree(solution.Root);
74
75      while (originalEnumerator.MoveNext() && estimatedEnumerator.MoveNext() && rowsEnumerator.MoveNext()) {
76        double estimated = estimatedEnumerator.Current;
77        double original = originalEnumerator.Current;
78        int row = rowsEnumerator.Current;
79
80        bool evaluate = true;
81        for (int i = minLag; i <= 0 && evaluate; i++) {
82          evaluate = evaluate && dataset[conditionVariable, row - i].IsAlmost(0.0);
83        }
84
85        if (evaluate) {
86          if (double.IsNaN(estimated))
87            estimated = upperEstimationLimit;
88          else
89            estimated = Math.Min(upperEstimationLimit, Math.Max(lowerEstimationLimit, estimated));
90          r2Evaluator.Add(original, estimated);
91        }
92      }
93
94      if (estimatedEnumerator.MoveNext() || originalEnumerator.MoveNext() || rowsEnumerator.MoveNext()) {
95        throw new ArgumentException("Number of elements in original and estimated enumeration doesn't match.");
96      } else return r2Evaluator.RSquared;
97    }
98
99    protected static int GetMinimumLagFromTree(SymbolicExpressionTreeNode node) {
100      if (node == null) return 0;
101      int lag = 0;
102
103      var laggedTreeNode = node as ILaggedTreeNode;
104      if (laggedTreeNode != null) lag += laggedTreeNode.Lag;
105
106      int subtreeLag = 0;
107      foreach (var subtree in node.SubTrees) {
108        subtreeLag = Math.Min(subtreeLag, GetMinimumLagFromTree(subtree));
109      }
110      return lag + subtreeLag;
111    }
112
113
114  }
115}
Note: See TracBrowser for help on using the repository browser.