Free cookie consent management tool by TermsFeed Policy Generator

source: branches/DataAnalysis.ComplexityAnalyzer/HeuristicLab.Problems.DataAnalysis.Symbolic.Regression/3.4/MultiObjective/SymbolicRegressionMultiObjectiveTrainingBestSolutionAnalyzer.cs @ 11407

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

#2175: Merged trunk changes into complexity branch.

File size: 10.9 KB
Line 
1#region License Information
2/* HeuristicLab
3 * Copyright (C) 2002-2014 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.Collections.Generic;
23using System.Linq;
24using HeuristicLab.Analysis;
25using HeuristicLab.Common;
26using HeuristicLab.Core;
27using HeuristicLab.Data;
28using HeuristicLab.Encodings.SymbolicExpressionTreeEncoding;
29using HeuristicLab.Optimization;
30using HeuristicLab.Parameters;
31using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
32
33namespace HeuristicLab.Problems.DataAnalysis.Symbolic.Regression {
34  /// <summary>
35  /// An operator that analyzes the training best symbolic regression solution for multi objective symbolic regression problems.
36  /// </summary>
37  [Item("SymbolicRegressionMultiObjectiveTrainingBestSolutionAnalyzer", "An operator that analyzes the training best symbolic regression solution for multi objective symbolic regression problems.")]
38  [StorableClass]
39  public sealed class SymbolicRegressionMultiObjectiveTrainingBestSolutionAnalyzer : SymbolicDataAnalysisMultiObjectiveTrainingBestSolutionAnalyzer<ISymbolicRegressionSolution>,
40    ISymbolicDataAnalysisInterpreterOperator, ISymbolicDataAnalysisBoundedOperator {
41    private const string ProblemDataParameterName = "ProblemData";
42    private const string SymbolicDataAnalysisTreeInterpreterParameterName = "SymbolicDataAnalysisTreeInterpreter";
43    private const string EstimationLimitsParameterName = "EstimationLimits";
44    private const string MaximumSymbolicExpressionTreeLengthParameterName = "MaximumSymbolicExpressionTreeLength";
45
46    #region parameter properties
47    public ILookupParameter<IRegressionProblemData> ProblemDataParameter {
48      get { return (ILookupParameter<IRegressionProblemData>)Parameters[ProblemDataParameterName]; }
49    }
50    public ILookupParameter<ISymbolicDataAnalysisExpressionTreeInterpreter> SymbolicDataAnalysisTreeInterpreterParameter {
51      get { return (ILookupParameter<ISymbolicDataAnalysisExpressionTreeInterpreter>)Parameters[SymbolicDataAnalysisTreeInterpreterParameterName]; }
52    }
53    public IValueLookupParameter<DoubleLimit> EstimationLimitsParameter {
54      get { return (IValueLookupParameter<DoubleLimit>)Parameters[EstimationLimitsParameterName]; }
55    }
56    public ILookupParameter<IntValue> MaximumSymbolicExpressionTreeLengthParameter {
57      get { return (ILookupParameter<IntValue>)Parameters[MaximumSymbolicExpressionTreeLengthParameterName]; }
58    }
59    #endregion
60
61    [StorableConstructor]
62    private SymbolicRegressionMultiObjectiveTrainingBestSolutionAnalyzer(bool deserializing) : base(deserializing) { }
63    private SymbolicRegressionMultiObjectiveTrainingBestSolutionAnalyzer(SymbolicRegressionMultiObjectiveTrainingBestSolutionAnalyzer original, Cloner cloner) : base(original, cloner) { }
64    public SymbolicRegressionMultiObjectiveTrainingBestSolutionAnalyzer()
65      : base() {
66      Parameters.Add(new LookupParameter<IRegressionProblemData>(ProblemDataParameterName, "The problem data for the symbolic regression solution."));
67      Parameters.Add(new LookupParameter<ISymbolicDataAnalysisExpressionTreeInterpreter>(SymbolicDataAnalysisTreeInterpreterParameterName, "The symbolic data analysis tree interpreter for the symbolic expression tree."));
68      Parameters.Add(new ValueLookupParameter<DoubleLimit>(EstimationLimitsParameterName, "The lower and upper limit for the estimated values produced by the symbolic regression model."));
69      Parameters.Add(new LookupParameter<IntValue>(MaximumSymbolicExpressionTreeLengthParameterName, "Maximal length of the symbolic expression."));
70    }
71
72    [StorableHook(HookType.AfterDeserialization)]
73    private void AfterDeserialization() {
74      if (!Parameters.ContainsKey(MaximumSymbolicExpressionTreeLengthParameterName))
75        Parameters.Add(new LookupParameter<IntValue>(MaximumSymbolicExpressionTreeLengthParameterName, "Maximal length of the symbolic expression."));
76    }
77
78    public override IDeepCloneable Clone(Cloner cloner) {
79      return new SymbolicRegressionMultiObjectiveTrainingBestSolutionAnalyzer(this, cloner);
80    }
81
82    protected override ISymbolicRegressionSolution CreateSolution(ISymbolicExpressionTree bestTree, double[] bestQuality) {
83      var model = new SymbolicRegressionModel((ISymbolicExpressionTree)bestTree.Clone(), SymbolicDataAnalysisTreeInterpreterParameter.ActualValue, EstimationLimitsParameter.ActualValue.Lower, EstimationLimitsParameter.ActualValue.Upper);
84      if (ApplyLinearScalingParameter.ActualValue.Value) model.Scale(ProblemDataParameter.ActualValue);
85      return new SymbolicRegressionSolution(model, (IRegressionProblemData)ProblemDataParameter.ActualValue.Clone());
86    }
87
88    public override IOperation Apply() {
89      var operation = base.Apply();
90
91      var paretoFront = TrainingBestSolutionsParameter.ActualValue;
92
93      IResult result;
94      ScatterPlot qualityToTreeSize;
95      if (!ResultCollection.TryGetValue("Pareto Front Analysis", out result)) {
96        qualityToTreeSize = new ScatterPlot("Quality vs Tree Size", "");
97        qualityToTreeSize.VisualProperties.XAxisMinimumAuto = false;
98        qualityToTreeSize.VisualProperties.XAxisMaximumAuto = false;
99        qualityToTreeSize.VisualProperties.YAxisMinimumAuto = false;
100        qualityToTreeSize.VisualProperties.YAxisMaximumAuto = false;
101
102        qualityToTreeSize.VisualProperties.XAxisMinimumFixedValue = 0;
103        qualityToTreeSize.VisualProperties.XAxisMaximumFixedValue = MaximumSymbolicExpressionTreeLengthParameter.ActualValue.Value;
104        qualityToTreeSize.VisualProperties.YAxisMinimumFixedValue = 0;
105        qualityToTreeSize.VisualProperties.YAxisMaximumFixedValue = 2;
106        ResultCollection.Add(new Result("Pareto Front Analysis", qualityToTreeSize));
107      } else {
108        qualityToTreeSize = (ScatterPlot)result.Value;
109      }
110
111      var problemData = ProblemDataParameter.ActualValue;
112      var constantValue = problemData.Dataset.GetDoubleValues(problemData.TargetVariable, problemData.TrainingIndices).Average();
113      var constantSolution = CreateConstantSymbolicRegressionSolution(constantValue);
114
115      int previousTreeLength = constantSolution.Model.SymbolicExpressionTree.Length;
116      var sizeParetoFront = new LinkedList<ISymbolicRegressionSolution>();
117      sizeParetoFront.AddLast(constantSolution);
118
119      foreach (var solution in paretoFront.OrderBy(s => s.Model.SymbolicExpressionTree.Length)) {
120        int treeLength = solution.Model.SymbolicExpressionTree.Length;
121        if (!sizeParetoFront.Any()) sizeParetoFront.AddLast(solution);
122        if (solution.TrainingNormalizedMeanSquaredError < sizeParetoFront.Last.Value.TrainingNormalizedMeanSquaredError) {
123          if (treeLength == previousTreeLength)
124            sizeParetoFront.RemoveLast();
125          sizeParetoFront.AddLast(solution);
126        }
127        previousTreeLength = treeLength;
128      }
129
130      qualityToTreeSize.Rows.Clear();
131      var trainingRow = new ScatterPlotDataRow("Training NMSE", "", sizeParetoFront.Select(x => new Point2D<double>(x.Model.SymbolicExpressionTree.Length, x.TrainingNormalizedMeanSquaredError)));
132      trainingRow.VisualProperties.PointSize = 5;
133      var testRow = new ScatterPlotDataRow("Test NMSE", "", sizeParetoFront.Select(x => new Point2D<double>(x.Model.SymbolicExpressionTree.Length, x.TestNormalizedMeanSquaredError)));
134      testRow.VisualProperties.PointSize = 5;
135      qualityToTreeSize.Rows.Add(trainingRow);
136      qualityToTreeSize.Rows.Add(testRow);
137
138      double trainingHyperVolume, testHyperVolume;
139      CalculateNormalizedHyperVolume(sizeParetoFront, out trainingHyperVolume, out testHyperVolume);
140
141      DoubleValue trainingHyperVolumeResult, testHyperVolumeResult;
142      if (!ResultCollection.TryGetValue("HyperVolume training", out result)) {
143        trainingHyperVolumeResult = new DoubleValue();
144        ResultCollection.Add(new Result("HyperVolume training", trainingHyperVolumeResult));
145      } else trainingHyperVolumeResult = (DoubleValue)result.Value;
146
147      if (!ResultCollection.TryGetValue("HyperVolume test", out result)) {
148        testHyperVolumeResult = new DoubleValue();
149        ResultCollection.Add(new Result("HyperVolume test", testHyperVolumeResult));
150      } else testHyperVolumeResult = (DoubleValue)result.Value;
151
152      trainingHyperVolumeResult.Value = trainingHyperVolume;
153      testHyperVolumeResult.Value = testHyperVolume;
154
155      return operation;
156    }
157
158    private void CalculateNormalizedHyperVolume(IEnumerable<ISymbolicRegressionSolution> solutions, out double trainingHyperVolume, out double testHyperVolume) {
159      trainingHyperVolume = 0.0;
160      testHyperVolume = 0.0;
161
162      var prevX = 0;
163      var prevYTraining = 1.0;
164      var prevYTest = 1.0;
165      var treeSize = 0;
166
167      foreach (var solution in solutions) {
168        treeSize = solution.Model.SymbolicExpressionTree.Length;
169        trainingHyperVolume += (prevYTraining + solution.TrainingNormalizedMeanSquaredError) * (treeSize - prevX) / 2;
170        testHyperVolume += (prevYTest + solution.TestNormalizedMeanSquaredError) * (treeSize - prevX) / 2;
171        prevX = treeSize;
172        prevYTraining = solution.TrainingNormalizedMeanSquaredError;
173        prevYTest = solution.TestNormalizedMeanSquaredError;
174      }
175
176      trainingHyperVolume = trainingHyperVolume / treeSize;
177      testHyperVolume = testHyperVolume / treeSize;
178    }
179
180    private ISymbolicRegressionSolution CreateConstantSymbolicRegressionSolution(double constantValue) {
181      var grammar = new ArithmeticExpressionGrammar();
182      var rootNode = (SymbolicExpressionTreeTopLevelNode)grammar.ProgramRootSymbol.CreateTreeNode();
183      var startNode = (SymbolicExpressionTreeTopLevelNode)grammar.StartSymbol.CreateTreeNode();
184      var constantTreeNode = new ConstantTreeNode(new Constant()) { Value = constantValue };
185      rootNode.AddSubtree(startNode);
186      startNode.AddSubtree(constantTreeNode);
187      var tree = new SymbolicExpressionTree();
188      tree.Root = rootNode;
189
190      var model = new SymbolicRegressionModel(tree, SymbolicDataAnalysisTreeInterpreterParameter.ActualValue);
191      var solution = new SymbolicRegressionSolution(model, ProblemDataParameter.ActualValue);
192      return solution;
193    }
194  }
195}
Note: See TracBrowser for help on using the repository browser.