Free cookie consent management tool by TermsFeed Policy Generator

source: trunk/HeuristicLab.Problems.DataAnalysis.Symbolic.Regression/3.4/SingleObjective/ParameterOptimizationAnalyzer.cs @ 18132

Last change on this file since 18132 was 18132, checked in by gkronber, 2 years ago

#3140: merged r18091:18131 from branch to trunk

File size: 9.1 KB
Line 
1#region License Information
2/* HeuristicLab
3 * Copyright (C) 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;
23using System.Linq;
24using HeuristicLab.Analysis;
25using HeuristicLab.Common;
26using HeuristicLab.Core;
27using HeuristicLab.Data;
28using HeuristicLab.Optimization;
29using HeuristicLab.Parameters;
30using HEAL.Attic;
31
32namespace HeuristicLab.Problems.DataAnalysis.Symbolic.Regression {
33  /// <summary>
34  /// An operator that optimizes the parameters for the best symbolic expression tress in the current generation.
35  /// </summary>
36  [Item("ParameterOptimizationAnalyzer", "An operator that performs a parameter optimization on the best symbolic expression trees.")]
37  [StorableType("9FB87E7B-A9E2-49DD-A92A-78BD9FC17916")]
38  public sealed class ParameterOptimizationAnalyzer : SymbolicDataAnalysisSingleObjectiveAnalyzer, IStatefulItem {
39    private const string PercentageOfBestSolutionsParameterName = "PercentageOfBestSolutions";
40    private const string ParameterOptimizationEvaluatorParameterName = "ParameterOptimizationOperator";
41
42    private const string DataTableNameParameterOptimizationImprovement = "Parameter Optimization Improvement";
43    private const string DataRowNameMinimumImprovement = "Minimum improvement";
44    private const string DataRowNameMedianImprovement = "Median improvement";
45    private const string DataRowNameAverageImprovement = "Average improvement";
46    private const string DataRowNameMaximumImprovement = "Maximum improvement";
47
48    #region parameter properties
49    public IFixedValueParameter<PercentValue> PercentageOfBestSolutionsParameter {
50      get { return (IFixedValueParameter<PercentValue>)Parameters[PercentageOfBestSolutionsParameterName]; }
51    }
52
53    public IFixedValueParameter<SymbolicRegressionParameterOptimizationEvaluator> ParameterOptimizationEvaluatorParameter {
54      get { return (IFixedValueParameter<SymbolicRegressionParameterOptimizationEvaluator>)Parameters[ParameterOptimizationEvaluatorParameterName]; }
55    }
56    #endregion
57
58    #region properties
59    public SymbolicRegressionParameterOptimizationEvaluator ParameterOptimizationEvaluator {
60      get { return ParameterOptimizationEvaluatorParameter.Value; }
61    }
62    public double PercentageOfBestSolutions {
63      get { return PercentageOfBestSolutionsParameter.Value.Value; }
64    }
65
66    private DataTable ParameterOptimizationImprovementDataTable {
67      get {
68        IResult result;
69        ResultCollection.TryGetValue(DataTableNameParameterOptimizationImprovement, out result);
70        if (result == null) return null;
71        return (DataTable)result.Value;
72      }
73    }
74    private DataRow MinimumImprovement {
75      get { return ParameterOptimizationImprovementDataTable.Rows[DataRowNameMinimumImprovement]; }
76    }
77    private DataRow MedianImprovement {
78      get { return ParameterOptimizationImprovementDataTable.Rows[DataRowNameMedianImprovement]; }
79    }
80    private DataRow AverageImprovement {
81      get { return ParameterOptimizationImprovementDataTable.Rows[DataRowNameAverageImprovement]; }
82    }
83    private DataRow MaximumImprovement {
84      get { return ParameterOptimizationImprovementDataTable.Rows[DataRowNameMaximumImprovement]; }
85    }
86    #endregion
87
88    [StorableConstructor]
89    private ParameterOptimizationAnalyzer(StorableConstructorFlag _) : base(_) { }
90    private ParameterOptimizationAnalyzer(ParameterOptimizationAnalyzer original, Cloner cloner) : base(original, cloner) { }
91    public override IDeepCloneable Clone(Cloner cloner) { return new ParameterOptimizationAnalyzer(this, cloner); }
92    public ParameterOptimizationAnalyzer()
93      : base() {
94      Parameters.Add(new FixedValueParameter<PercentValue>(PercentageOfBestSolutionsParameterName, "The percentage of the top solutions which should be analyzed.", new PercentValue(0.1)));
95      Parameters.Add(new FixedValueParameter<SymbolicRegressionParameterOptimizationEvaluator>(ParameterOptimizationEvaluatorParameterName, "The operator used to perform the parameter optimization"));
96
97      //Changed the ActualName of the EvaluationPartitionParameter so that it matches the parameter name of symbolic regression problems.
98      ParameterOptimizationEvaluator.EvaluationPartitionParameter.ActualName = "FitnessCalculationPartition";
99    }
100
101    [StorableHook(HookType.AfterDeserialization)]
102    private void AfterDeserialization() {
103      if (!Parameters.ContainsKey(ParameterOptimizationEvaluatorParameterName)) {
104        if (Parameters.ContainsKey("ConstantOptimizationOperator")) {
105          Parameters.Add(new FixedValueParameter<SymbolicRegressionParameterOptimizationEvaluator>(ParameterOptimizationEvaluatorParameterName, "The operator used to perform the parameter optimization"));
106          Parameters.Remove("ConstantOptimizationOperator");
107        } else {
108          Parameters.Add(new FixedValueParameter<SymbolicRegressionParameterOptimizationEvaluator>(ParameterOptimizationEvaluatorParameterName, "The operator used to perform the parameter optimization"));
109        }
110      }
111    }
112
113
114    private double[] qualitiesBeforeCoOp = null;
115    private int[] scopeIndexes = null;
116    void IStatefulItem.InitializeState() {
117      qualitiesBeforeCoOp = null;
118      scopeIndexes = null;
119    }
120    void IStatefulItem.ClearState() {
121      qualitiesBeforeCoOp = null;
122      scopeIndexes = null;
123    }
124
125    public override IOperation Apply() {
126      //code executed in the first call of analyzer
127      if (qualitiesBeforeCoOp == null) {
128        double[] trainingQuality;
129        // sort is ascending and we take the first n% => order so that best solutions are smallest
130        // sort order is determined by maximization parameter
131        if (Maximization.Value) {
132          // largest values must be sorted first
133          trainingQuality = Quality.Select(x => -x.Value).ToArray();
134        } else {
135          // smallest values must be sorted first
136          trainingQuality = Quality.Select(x => x.Value).ToArray();
137        }
138        // sort trees by training qualities
139        int topN = (int)Math.Max(trainingQuality.Length * PercentageOfBestSolutions, 1);
140        scopeIndexes = Enumerable.Range(0, trainingQuality.Length).ToArray();
141        Array.Sort(trainingQuality, scopeIndexes);
142        scopeIndexes = scopeIndexes.Take(topN).ToArray();
143        qualitiesBeforeCoOp = scopeIndexes.Select(x => Quality[x].Value).ToArray();
144
145        OperationCollection operationCollection = new OperationCollection();
146        operationCollection.Parallel = true;
147        foreach (var scopeIndex in scopeIndexes) {
148          var childOperation = ExecutionContext.CreateChildOperation(ParameterOptimizationEvaluator, ExecutionContext.Scope.SubScopes[scopeIndex]);
149          operationCollection.Add(childOperation);
150        }
151
152        return new OperationCollection { operationCollection, ExecutionContext.CreateOperation(this) };
153      }
154
155      //code executed to analyze results of parameter optimization
156      double[] qualitiesAfterCoOp = scopeIndexes.Select(x => Quality[x].Value).ToArray();
157      var qualityImprovement = qualitiesBeforeCoOp.Zip(qualitiesAfterCoOp, (b, a) => a - b).ToArray();
158
159      if (!ResultCollection.ContainsKey(DataTableNameParameterOptimizationImprovement)) {
160        var dataTable = new DataTable(DataTableNameParameterOptimizationImprovement);
161        ResultCollection.Add(new Result(DataTableNameParameterOptimizationImprovement, dataTable));
162        dataTable.VisualProperties.YAxisTitle = "R²";
163
164        dataTable.Rows.Add(new DataRow(DataRowNameMinimumImprovement));
165        MinimumImprovement.VisualProperties.StartIndexZero = true;
166
167        dataTable.Rows.Add(new DataRow(DataRowNameMedianImprovement));
168        MedianImprovement.VisualProperties.StartIndexZero = true;
169
170        dataTable.Rows.Add(new DataRow(DataRowNameAverageImprovement));
171        AverageImprovement.VisualProperties.StartIndexZero = true;
172
173        dataTable.Rows.Add(new DataRow(DataRowNameMaximumImprovement));
174        MaximumImprovement.VisualProperties.StartIndexZero = true;
175      }
176
177      MinimumImprovement.Values.Add(qualityImprovement.Min());
178      MedianImprovement.Values.Add(qualityImprovement.Median());
179      AverageImprovement.Values.Add(qualityImprovement.Average());
180      MaximumImprovement.Values.Add(qualityImprovement.Max());
181
182      qualitiesBeforeCoOp = null;
183      scopeIndexes = null;
184      return base.Apply();
185    }
186  }
187}
Note: See TracBrowser for help on using the repository browser.