Free cookie consent management tool by TermsFeed Policy Generator

source: branches/DataAnalysis/HeuristicLab.Problems.DataAnalysis/3.3/Operators/CovariantParsimonyPressure.cs @ 11987

Last change on this file since 11987 was 5275, checked in by gkronber, 13 years ago

Merged changes from trunk to data analysis exploration branch and added fractional distance metric evaluator. #1142

File size: 12.1 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;
23using System.Linq;
24using HeuristicLab.Core;
25using HeuristicLab.Data;
26using HeuristicLab.Operators;
27using HeuristicLab.Optimization;
28using HeuristicLab.Parameters;
29using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
30using HeuristicLab.Encodings.SymbolicExpressionTreeEncoding;
31using System.Collections.Generic;
32using HeuristicLab.Problems.DataAnalysis.Evaluators;
33using HeuristicLab.Analysis;
34using HeuristicLab.Common;
35
36namespace HeuristicLab.Problems.DataAnalysis.Operators {
37  [Item("Covariant Parsimony Pressure", "Covariant Parsimony Pressure.")]
38  [StorableClass]
39  public class CovariantParsimonyPressure : SingleSuccessorOperator {
40    public IScopeTreeLookupParameter<SymbolicExpressionTree> SymbolicExpressionTreeParameter {
41      get { return (IScopeTreeLookupParameter<SymbolicExpressionTree>)Parameters["SymbolicExpressionTree"]; }
42    }
43    public IScopeTreeLookupParameter<DoubleValue> QualityParameter {
44      get { return (IScopeTreeLookupParameter<DoubleValue>)Parameters["Quality"]; }
45    }
46    public IScopeTreeLookupParameter<DoubleValue> AdjustedQualityParameter {
47      get { return (IScopeTreeLookupParameter<DoubleValue>)Parameters["AdjustedQuality"]; }
48    }
49    public ILookupParameter<BoolValue> MaximizationParameter {
50      get { return (ILookupParameter<BoolValue>)Parameters["Maximization"]; }
51    }
52    public IValueLookupParameter<DoubleValue> KParameter {
53      get { return (IValueLookupParameter<DoubleValue>)Parameters["K"]; }
54    }
55    public ILookupParameter<DoubleValue> CParameter {
56      get { return (ILookupParameter<DoubleValue>)Parameters["C"]; }
57    }
58    public ILookupParameter<IntValue> GenerationsParameter {
59      get { return (ILookupParameter<IntValue>)Parameters["Generations"]; }
60    }
61    public IValueLookupParameter<IntValue> FirstGenerationParameter {
62      get { return (IValueLookupParameter<IntValue>)Parameters["FirstGenerationParameter"]; }
63    }
64    public IValueLookupParameter<BoolValue> ApplyParsimonyPressureParameter {
65      get { return (IValueLookupParameter<BoolValue>)Parameters["ApplyParsimonyPressure"]; }
66    }
67    public ILookupParameter<DoubleValue> LengthCorrelationParameter {
68      get { return (ILookupParameter<DoubleValue>)Parameters["Correlation(Length, AdjustedFitness)"]; }
69    }
70    public ILookupParameter<DoubleValue> FitnessCorrelationParameter {
71      get { return (ILookupParameter<DoubleValue>)Parameters["Correlation(Fitness, AdjustedFitness)"]; }
72    }
73    public IValueLookupParameter<PercentValue> ComplexityAdaptionParameter {
74      get { return (IValueLookupParameter<PercentValue>)Parameters["ComplexityAdaption"]; }
75    }
76    public IValueLookupParameter<BoolValue> InvertComplexityAdaptionParameter {
77      get { return (IValueLookupParameter<BoolValue>)Parameters["InvertComplexityAdaption"]; }
78    }
79    public IValueLookupParameter<DoubleValue> MinAverageSizeParameter {
80      get { return (IValueLookupParameter<DoubleValue>)Parameters["MinAverageSize"]; }
81    }
82
83    protected CovariantParsimonyPressure(bool deserializing) : base(deserializing) { }
84    protected CovariantParsimonyPressure(CovariantParsimonyPressure original, Cloner clone) : base(original, clone) { }
85    public CovariantParsimonyPressure()
86      : base() {
87      Parameters.Add(new ScopeTreeLookupParameter<SymbolicExpressionTree>("SymbolicExpressionTree"));
88      Parameters.Add(new ScopeTreeLookupParameter<DoubleValue>("Quality"));
89      Parameters.Add(new ScopeTreeLookupParameter<DoubleValue>("AdjustedQuality"));
90      Parameters.Add(new LookupParameter<BoolValue>("Maximization"));
91      Parameters.Add(new ValueLookupParameter<DoubleValue>("K", new DoubleValue(1.0)));
92      Parameters.Add(new LookupParameter<IntValue>("Generations"));
93      Parameters.Add(new ValueLookupParameter<IntValue>("FirstGenerationParameter", new IntValue(1)));
94      Parameters.Add(new ValueLookupParameter<BoolValue>("ApplyParsimonyPressure"));
95      Parameters.Add(new ValueLookupParameter<PercentValue>("ComplexityAdaption", new PercentValue(-0.01)));
96      Parameters.Add(new LookupParameter<DoubleValue>("Correlation(Length, AdjustedFitness)"));
97      Parameters.Add(new LookupParameter<DoubleValue>("Correlation(Fitness, AdjustedFitness)"));
98      Parameters.Add(new ValueLookupParameter<DoubleValue>("MinAverageSize", new DoubleValue(15)));
99      Parameters.Add(new LookupParameter<DoubleValue>("C"));
100      Parameters.Add(new ValueLookupParameter<BoolValue>("InvertComplexityAdaption"));
101    }
102
103    public override IDeepCloneable Clone(Cloner cloner) {
104      return new CovariantParsimonyPressure(this, cloner);
105    }
106
107
108    [StorableHook(Persistence.Default.CompositeSerializers.Storable.HookType.AfterDeserialization)]
109    private void AfterDeserialization() {
110      if (!Parameters.ContainsKey("Maximization"))
111        Parameters.Add(new LookupParameter<BoolValue>("Maximization"));
112      if (!Parameters.ContainsKey("K"))
113        Parameters.Add(new ValueLookupParameter<DoubleValue>("K", new DoubleValue(1.0)));
114      if (!Parameters.ContainsKey("AdjustedQuality")) {
115        Parameters.Add(new ScopeTreeLookupParameter<DoubleValue>("AdjustedQuality"));
116      }
117      if (!Parameters.ContainsKey("Generations")) {
118        Parameters.Add(new LookupParameter<IntValue>("Generations"));
119      }
120      if (!Parameters.ContainsKey("FirstGenerationParameter")) {
121        Parameters.Add(new ValueLookupParameter<IntValue>("FirstGenerationParameter", new IntValue(1)));
122      }
123      if (!Parameters.ContainsKey("ApplyParsimonyPressure")) {
124        Parameters.Add(new ValueLookupParameter<BoolValue>("ApplyParsimonyPressure"));
125      }
126      if (!Parameters.ContainsKey("ComplexityAdaption")) {
127        Parameters.Add(new ValueLookupParameter<PercentValue>("ComplexityAdaption", new PercentValue(-0.01)));
128      }
129      if (!Parameters.ContainsKey("MinAverageSize")) {
130        Parameters.Add(new ValueLookupParameter<DoubleValue>("MinAverageSize", new DoubleValue(15)));
131      }
132      if (!Parameters.ContainsKey("C")) {
133        Parameters.Add(new LookupParameter<DoubleValue>("C"));
134      }
135      if (!Parameters.ContainsKey("InvertComplexityAdaption")) {
136        Parameters.Add(new ValueLookupParameter<BoolValue>("InvertComplexityAdaption"));
137      }
138    }
139
140    public override IOperation Apply() {
141      ItemArray<SymbolicExpressionTree> trees = SymbolicExpressionTreeParameter.ActualValue;
142      ItemArray<DoubleValue> qualities = QualityParameter.ActualValue;
143      // always apply Parsimony pressure if overfitting has been detected
144      // otherwise appliy PP only when we are currently overfitting
145      if (GenerationsParameter.ActualValue != null && GenerationsParameter.ActualValue.Value >= FirstGenerationParameter.ActualValue.Value &&
146           ApplyParsimonyPressureParameter.ActualValue.Value == true) {
147        var lengths = from tree in trees
148                      select tree.Size;
149        double k = KParameter.ActualValue.Value;
150
151        // calculate cov(f, l) and cov(l, l^k)
152        OnlineCovarianceEvaluator lengthFitnessCovEvaluator = new OnlineCovarianceEvaluator();
153        OnlineCovarianceEvaluator lengthAdjLengthCovEvaluator = new OnlineCovarianceEvaluator();
154        OnlineMeanAndVarianceCalculator lengthMeanCalculator = new OnlineMeanAndVarianceCalculator();
155        OnlineMeanAndVarianceCalculator fitnessMeanCalculator = new OnlineMeanAndVarianceCalculator();
156        OnlineMeanAndVarianceCalculator adjLengthMeanCalculator = new OnlineMeanAndVarianceCalculator();
157        var lengthEnumerator = lengths.GetEnumerator();
158        var qualityEnumerator = qualities.GetEnumerator();
159        while (lengthEnumerator.MoveNext() & qualityEnumerator.MoveNext()) {
160          double fitness = qualityEnumerator.Current.Value;
161          if (!MaximizationParameter.ActualValue.Value) {
162            // use f = 1 / (1 + quality) for minimization problems
163            fitness = 1.0 / (1.0 + fitness);
164          }
165          lengthFitnessCovEvaluator.Add(lengthEnumerator.Current, fitness);
166          lengthAdjLengthCovEvaluator.Add(lengthEnumerator.Current, Math.Pow(lengthEnumerator.Current, k));
167          lengthMeanCalculator.Add(lengthEnumerator.Current);
168          fitnessMeanCalculator.Add(fitness);
169          adjLengthMeanCalculator.Add(Math.Pow(lengthEnumerator.Current, k));
170        }
171
172        //double sizeAdaption = lengthMeanCalculator.Mean * ComplexityAdaptionParameter.ActualValue.Value;
173        double sizeAdaption = 100.0 * ComplexityAdaptionParameter.ActualValue.Value;
174        if (InvertComplexityAdaptionParameter.ActualValue != null && InvertComplexityAdaptionParameter.ActualValue.Value) {
175          sizeAdaption = -sizeAdaption;
176        }
177        if (lengthMeanCalculator.Mean + sizeAdaption < MinAverageSizeParameter.ActualValue.Value)
178          sizeAdaption = MinAverageSizeParameter.ActualValue.Value - lengthMeanCalculator.Mean;
179
180        //            cov(l, f) - (g(t+1) - mu(t)) avgF
181        // c(t) =  --------------------------------------------
182        //           cov(l, l^k) - (g(t+1) - mu(t)) E[l^k]
183        double c = lengthFitnessCovEvaluator.Covariance - sizeAdaption * fitnessMeanCalculator.Mean;
184        c /= lengthAdjLengthCovEvaluator.Covariance - sizeAdaption * adjLengthMeanCalculator.Mean;
185
186        CParameter.ActualValue = new DoubleValue(c);
187
188        // adjust fitness
189        bool maximization = MaximizationParameter.ActualValue.Value;
190
191        lengthEnumerator = lengths.GetEnumerator();
192        qualityEnumerator = qualities.GetEnumerator();
193        int i = 0;
194        ItemArray<DoubleValue> adjQualities = new ItemArray<DoubleValue>(qualities.Length);
195
196        while (lengthEnumerator.MoveNext() & qualityEnumerator.MoveNext()) {
197          adjQualities[i++] = new DoubleValue(qualityEnumerator.Current.Value - c * Math.Pow(lengthEnumerator.Current, k));
198        }
199        AdjustedQualityParameter.ActualValue = adjQualities;
200        double[] lengthArr = lengths.Select(x => (double)x).ToArray<double>();
201
202        double[] adjFitess = (from f in AdjustedQualityParameter.ActualValue
203                              select f.Value).ToArray<double>();
204        double[] fitnessArr = (from f in QualityParameter.ActualValue
205                               let normFit = maximization ? f.Value : 1.0 / (1.0 + f.Value)
206                               select normFit).ToArray<double>();
207
208        LengthCorrelationParameter.ActualValue = new DoubleValue(alglib.spearmancorr2(lengthArr, adjFitess, lengthArr.Length));
209        FitnessCorrelationParameter.ActualValue = new DoubleValue(alglib.spearmancorr2(fitnessArr, adjFitess, lengthArr.Length));
210
211      } else {
212        CParameter.ActualValue = new DoubleValue(0.0);
213        // adjusted fitness is equal to fitness
214        AdjustedQualityParameter.ActualValue = (ItemArray<DoubleValue>)QualityParameter.ActualValue.Clone();
215        FitnessCorrelationParameter.ActualValue = new DoubleValue(1.0);
216
217        double[] lengths = (from tree in trees
218                            select (double)tree.Size).ToArray<double>();
219
220        double[] fitess = (from f in AdjustedQualityParameter.ActualValue
221                           select f.Value).ToArray<double>();
222
223        LengthCorrelationParameter.ActualValue = new DoubleValue(alglib.spearmancorr2(lengths, fitess, lengths.Length));
224      }
225      return base.Apply();
226    }
227  }
228}
Note: See TracBrowser for help on using the repository browser.