source: trunk/sources/HeuristicLab.Problems.DataAnalysis.Regression/3.3/Symbolic/Analyzers/BestSymbolicRegressionSolutionAnalyzer.cs @ 4125

Last change on this file since 4125 was 4125, checked in by gkronber, 10 years ago

Made variable frequency analyzer more efficient and removed subtraction of base line (variable impacts are now in the range 0..1 instead of -1 .. 1) #1011

File size: 7.6 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
22using System.Linq;
23using HeuristicLab.Analysis;
24using HeuristicLab.Core;
25using HeuristicLab.Data;
26using HeuristicLab.Encodings.SymbolicExpressionTreeEncoding;
27using HeuristicLab.Optimization;
28using HeuristicLab.Parameters;
29using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
30using HeuristicLab.Problems.DataAnalysis.Symbolic;
31
32namespace HeuristicLab.Problems.DataAnalysis.Regression.Symbolic.Analyzers {
33  [Item("BestSymbolicRegressionSolutionAnalyzer", "An operator for analyzing the best solution of symbolic regression problems given in symbolic expression tree encoding.")]
34  [StorableClass]
35  public sealed class BestSymbolicRegressionSolutionAnalyzer : RegressionSolutionAnalyzer, ISymbolicRegressionAnalyzer {
36    private const string SymbolicExpressionTreeParameterName = "SymbolicExpressionTree";
37    private const string SymbolicExpressionTreeInterpreterParameterName = "SymbolicExpressionTreeInterpreter";
38    private const string BestSolutionInputvariableCountResultName = "Variables used by best solution";
39    private const string VariableFrequenciesParameterName = "VariableFrequencies";
40    private const string VariableImpactsResultName = "Integrated variable frequencies";
41    private const string BestSolutionParameterName = "BestSolution";
42
43    #region parameter properties
44    public ScopeTreeLookupParameter<SymbolicExpressionTree> SymbolicExpressionTreeParameter {
45      get { return (ScopeTreeLookupParameter<SymbolicExpressionTree>)Parameters[SymbolicExpressionTreeParameterName]; }
46    }
47    public IValueLookupParameter<ISymbolicExpressionTreeInterpreter> SymbolicExpressionTreeInterpreterParameter {
48      get { return (IValueLookupParameter<ISymbolicExpressionTreeInterpreter>)Parameters[SymbolicExpressionTreeInterpreterParameterName]; }
49    }
50    public ILookupParameter<SymbolicRegressionSolution> BestSolutionParameter {
51      get { return (ILookupParameter<SymbolicRegressionSolution>)Parameters[BestSolutionParameterName]; }
52    }
53    public ILookupParameter<DataTable> VariableFrequenciesParameter {
54      get { return (ILookupParameter<DataTable>)Parameters[VariableFrequenciesParameterName]; }
55    }
56    #endregion
57    #region properties
58    public ISymbolicExpressionTreeInterpreter SymbolicExpressionTreeInterpreter {
59      get { return SymbolicExpressionTreeInterpreterParameter.ActualValue; }
60    }
61    public ItemArray<SymbolicExpressionTree> SymbolicExpressionTree {
62      get { return SymbolicExpressionTreeParameter.ActualValue; }
63    }
64    public DataTable VariableFrequencies {
65      get { return VariableFrequenciesParameter.ActualValue; }
66    }
67    #endregion
68
69    public BestSymbolicRegressionSolutionAnalyzer()
70      : base() {
71      Parameters.Add(new ScopeTreeLookupParameter<SymbolicExpressionTree>(SymbolicExpressionTreeParameterName, "The symbolic expression trees to analyze."));
72      Parameters.Add(new ValueLookupParameter<ISymbolicExpressionTreeInterpreter>(SymbolicExpressionTreeInterpreterParameterName, "The interpreter that should be used for the analysis of symbolic expression trees."));
73      Parameters.Add(new LookupParameter<DataTable>(VariableFrequenciesParameterName, "The variable frequencies table to use for the calculation of variable impacts"));
74      Parameters.Add(new LookupParameter<SymbolicRegressionSolution>(BestSolutionParameterName, "The best symbolic regression solution."));
75    }
76
77    [StorableHook(HookType.AfterDeserialization)]
78    private void Initialize() {
79      if (!Parameters.ContainsKey(VariableFrequenciesParameterName)) {
80        Parameters.Add(new LookupParameter<DataTable>(VariableFrequenciesParameterName, "The variable frequencies table to use for the calculation of variable impacts"));
81      }
82    }
83
84    protected override DataAnalysisSolution UpdateBestSolution() {
85      double upperEstimationLimit = UpperEstimationLimit != null ? UpperEstimationLimit.Value : double.PositiveInfinity;
86      double lowerEstimationLimit = LowerEstimationLimit != null ? LowerEstimationLimit.Value : double.NegativeInfinity;
87
88      int i = Quality.Select((x, index) => new { index, x.Value }).OrderBy(x => x.Value).First().index;
89
90      if (BestSolutionQualityParameter.ActualValue == null || BestSolutionQualityParameter.ActualValue.Value > Quality[i].Value) {
91        var model = new SymbolicRegressionModel((ISymbolicExpressionTreeInterpreter)SymbolicExpressionTreeInterpreter.Clone(),
92          SymbolicExpressionTree[i]);
93        var solution = new SymbolicRegressionSolution(ProblemData, model, lowerEstimationLimit, upperEstimationLimit);
94        solution.Name = BestSolutionParameterName;
95        solution.Description = "Best solution on validation partition found over the whole run.";
96        BestSolutionParameter.ActualValue = solution;
97        BestSolutionQualityParameter.ActualValue = Quality[i];
98        BestSymbolicRegressionSolutionAnalyzer.UpdateSymbolicRegressionBestSolutionResults(solution, ProblemData, Results, VariableFrequencies);
99      }
100      return BestSolutionParameter.ActualValue;
101    }
102
103    public static void UpdateBestSolutionResults(SymbolicRegressionSolution bestSolution, DataAnalysisProblemData problemData, ResultCollection results, IntValue currentGeneration, DataTable variableFrequencies) {
104      RegressionSolutionAnalyzer.UpdateBestSolutionResults(bestSolution, problemData, results, currentGeneration);
105      UpdateSymbolicRegressionBestSolutionResults(bestSolution, problemData, results, variableFrequencies);
106    }
107
108    private static void UpdateSymbolicRegressionBestSolutionResults(SymbolicRegressionSolution bestSolution, DataAnalysisProblemData problemData, ResultCollection results, DataTable variableFrequencies) {
109      if (results.ContainsKey(BestSolutionInputvariableCountResultName)) {
110        results[BestSolutionInputvariableCountResultName].Value = new IntValue(bestSolution.Model.InputVariables.Count());
111        results[VariableImpactsResultName].Value = CalculateVariableImpacts(variableFrequencies);
112      } else {
113        results.Add(new Result(BestSolutionInputvariableCountResultName, new IntValue(bestSolution.Model.InputVariables.Count())));
114        results.Add(new Result(VariableImpactsResultName, CalculateVariableImpacts(variableFrequencies)));
115      }
116    }
117
118
119    private static DoubleMatrix CalculateVariableImpacts(DataTable variableFrequencies) {
120      if (variableFrequencies != null) {
121        var impacts = new DoubleMatrix(variableFrequencies.Rows.Count, 1, new string[] { "Impact" }, variableFrequencies.Rows.Select(x => x.Name));
122        impacts.SortableView = true;
123        int rowIndex = 0;
124        foreach (var dataRow in variableFrequencies.Rows) {
125          string variableName = dataRow.Name;
126          impacts[rowIndex++, 0] = dataRow.Values.Average();
127        }
128        return impacts;
129      } else return new DoubleMatrix(1, 1);
130    }
131  }
132}
Note: See TracBrowser for help on using the repository browser.