source: trunk/sources/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Analyzers/SymbolicDataAnalysisSingleObjectivePruningAnalyzer.cs @ 10368

Last change on this file since 10368 was 10368, checked in by bburlacu, 8 years ago

#2143: Implemented symbolic data analysis pruning operator and analyzers.

File size: 9.7 KB
Line 
1using System;
2using System.Linq;
3using HeuristicLab.Analysis;
4using HeuristicLab.Common;
5using HeuristicLab.Core;
6using HeuristicLab.Data;
7using HeuristicLab.Encodings.SymbolicExpressionTreeEncoding;
8using HeuristicLab.Optimization;
9using HeuristicLab.Parameters;
10using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
11
12namespace HeuristicLab.Problems.DataAnalysis.Symbolic {
13  [StorableClass]
14  [Item("SymbolicDataAnalysisSingleObjectivePruningAnalyzer", "An analyzer that prunes introns from trees in single objective symbolic data analysis problems.")]
15  public abstract class SymbolicDataAnalysisSingleObjectivePruningAnalyzer : SymbolicDataAnalysisSingleObjectiveAnalyzer {
16    private const string ProblemDataParameterName = "ProblemData";
17    private const string InterpreterParameterName = "SymbolicExpressionTreeInterpreter";
18
19    private const string UpdateIntervalParameterName = "UpdateInverval";
20    private const string UpdateCounterParameterName = "UpdateCounter";
21
22    private const string PopulationSliceParameterName = "PopulationSlice";
23    private const string PruningProbabilityParameterName = "PruningProbability";
24
25    private const string NumberOfPrunedSubtreesParameterName = "PrunedSubtrees";
26    private const string NumberOfPrunedTreesParameterName = "PrunedTrees";
27
28    private const string RandomParameterName = "Random";
29    private const string EstimationLimitsParameterName = "EstimationLimits";
30
31    private const string PruneOnlyZeroImpactNodesParameterName = "PruneOnlyZeroImpactNodes";
32    private const string NodeImpactThresholdParameterName = "ImpactThreshold";
33
34    private bool reentry;
35    [Storable]
36    protected ISymbolicDataAnalysisSolutionImpactValuesCalculator impactValuesCalculator;
37
38    #region parameter properties
39    public IFixedValueParameter<BoolValue> PruneOnlyZeroImpactNodesParameter {
40      get { return (IFixedValueParameter<BoolValue>)Parameters[PruneOnlyZeroImpactNodesParameterName]; }
41    }
42    public IFixedValueParameter<DoubleValue> NodeImpactThresholdParameter {
43      get { return (IFixedValueParameter<DoubleValue>)Parameters[NodeImpactThresholdParameterName]; }
44    }
45    public ILookupParameter<DoubleLimit> EstimationLimitsParameter {
46      get { return (ILookupParameter<DoubleLimit>)Parameters[EstimationLimitsParameterName]; }
47    }
48    public ILookupParameter<IRandom> RandomParameter {
49      get { return (ILookupParameter<IRandom>)Parameters[RandomParameterName]; }
50    }
51    private ILookupParameter<IDataAnalysisProblemData> ProblemDataParameter {
52      get { return (ILookupParameter<IDataAnalysisProblemData>)Parameters[ProblemDataParameterName]; }
53    }
54    private ILookupParameter<ISymbolicDataAnalysisExpressionTreeInterpreter> InterpreterParameter {
55      get { return (ILookupParameter<ISymbolicDataAnalysisExpressionTreeInterpreter>)Parameters[InterpreterParameterName]; }
56    }
57    public IValueParameter<IntValue> UpdateIntervalParameter {
58      get { return (IValueParameter<IntValue>)Parameters[UpdateIntervalParameterName]; }
59    }
60    public IValueParameter<IntValue> UpdateCounterParameter {
61      get { return (IValueParameter<IntValue>)Parameters[UpdateCounterParameterName]; }
62    }
63    public IValueParameter<DoubleRange> PopulationSliceParameter {
64      get { return (IValueParameter<DoubleRange>)Parameters[PopulationSliceParameterName]; }
65    }
66    public IValueParameter<DoubleValue> PruningProbabilityParameter {
67      get { return (IValueParameter<DoubleValue>)Parameters[PruningProbabilityParameterName]; }
68    }
69    public IFixedValueParameter<DoubleValue> NumberOfPrunedSubtreesParameter {
70      get { return (IFixedValueParameter<DoubleValue>)Parameters[NumberOfPrunedSubtreesParameterName]; }
71    }
72    public IFixedValueParameter<DoubleValue> NumberOfPrunedTreesParameter {
73      get { return (IFixedValueParameter<DoubleValue>)Parameters[NumberOfPrunedTreesParameterName]; }
74    }
75    #endregion
76    #region properties
77    protected IDataAnalysisProblemData ProblemData { get { return ProblemDataParameter.ActualValue; } }
78    protected ISymbolicDataAnalysisExpressionTreeInterpreter Interpreter { get { return InterpreterParameter.ActualValue; } }
79    protected IntValue UpdateInterval { get { return UpdateIntervalParameter.Value; } }
80    protected IntValue UpdateCounter { get { return UpdateCounterParameter.Value; } }
81    protected DoubleRange PopulationSlice { get { return PopulationSliceParameter.Value; } }
82    protected DoubleValue PruningProbability { get { return PruningProbabilityParameter.Value; } }
83    protected DoubleValue PrunedSubtrees { get { return NumberOfPrunedSubtreesParameter.Value; } }
84    protected DoubleValue PrunedTrees { get { return NumberOfPrunedTreesParameter.Value; } }
85    protected DoubleLimit EstimationLimits { get { return EstimationLimitsParameter.ActualValue; } }
86    protected IRandom Random { get { return RandomParameter.ActualValue; } }
87    protected DoubleValue NodeImpactThreshold { get { return NodeImpactThresholdParameter.Value; } }
88    protected BoolValue PruneOnlyZeroImpactNodes { get { return PruneOnlyZeroImpactNodesParameter.Value; } }
89    #endregion
90    protected SymbolicDataAnalysisSingleObjectivePruningAnalyzer(SymbolicDataAnalysisSingleObjectivePruningAnalyzer original, Cloner cloner)
91      : base(original, cloner) {
92      impactValuesCalculator = original.impactValuesCalculator;
93    }
94    protected SymbolicDataAnalysisSingleObjectivePruningAnalyzer() {
95      Parameters.Add(new ValueParameter<DoubleRange>(PopulationSliceParameterName, new DoubleRange(0.75, 1)));
96      Parameters.Add(new ValueParameter<DoubleValue>(PruningProbabilityParameterName, new DoubleValue(0.5)));
97      // analyzer parameters
98      Parameters.Add(new ValueParameter<IntValue>(UpdateIntervalParameterName, "The interval in which the tree length analysis should be applied.", new IntValue(1)));
99      Parameters.Add(new ValueParameter<IntValue>(UpdateCounterParameterName, "The value which counts how many times the operator was called", new IntValue(0)));
100      Parameters.Add(new LookupParameter<IRandom>(RandomParameterName));
101      Parameters.Add(new LookupParameter<IDataAnalysisProblemData>(ProblemDataParameterName));
102      Parameters.Add(new LookupParameter<ISymbolicDataAnalysisExpressionTreeInterpreter>(InterpreterParameterName));
103
104      Parameters.Add(new FixedValueParameter<DoubleValue>(NumberOfPrunedSubtreesParameterName, new DoubleValue(0)));
105      Parameters.Add(new FixedValueParameter<DoubleValue>(NumberOfPrunedTreesParameterName, new DoubleValue(0)));
106      Parameters.Add(new LookupParameter<DoubleLimit>(EstimationLimitsParameterName));
107      Parameters.Add(new FixedValueParameter<DoubleValue>(NodeImpactThresholdParameterName, new DoubleValue(0.0)));
108      Parameters.Add(new FixedValueParameter<BoolValue>(PruneOnlyZeroImpactNodesParameterName, new BoolValue(false)));
109    }
110
111    public override IOperation Apply() {
112      if (reentry) {
113        UpdateCounter.Value++;
114
115        if (UpdateCounter.Value != UpdateInterval.Value) return base.Apply();
116        UpdateCounter.Value = 0;
117
118        var trees = SymbolicExpressionTreeParameter.ActualValue.ToList();
119        var qualities = QualityParameter.ActualValue.ToList();
120
121        var population = trees.Zip(qualities, (tree, quality) => new { Tree = tree, Quality = quality }).ToList();
122        Func<double, double, int> compare = (a, b) => Maximization.Value ? a.CompareTo(b) : b.CompareTo(a);
123        population.Sort((a, b) => compare(a.Quality.Value, b.Quality.Value));
124
125        var start = (int)Math.Round(PopulationSlice.Start * trees.Count);
126        var end = (int)Math.Round(PopulationSlice.End * trees.Count);
127
128        if (end == population.Count) end--;
129
130        if (start >= end || end >= population.Count) throw new Exception("Invalid PopulationSlice bounds.");
131
132        PrunedSubtrees.Value = 0;
133        PrunedTrees.Value = 0;
134
135        reentry = false;
136
137        var operations = new OperationCollection { Parallel = true };
138        foreach (var p in population.Skip(start).Take(end)) {
139          if (Random.NextDouble() > PruningProbability.Value) continue;
140          var op = new SymbolicDataAnalysisExpressionPruningOperator {
141            Model = CreateModel(p.Tree, Interpreter, EstimationLimits.Lower, EstimationLimits.Upper),
142            ImpactsCalculator = impactValuesCalculator,
143            ProblemData = ProblemData,
144            Random = Random,
145            PruneOnlyZeroImpactNodes = PruneOnlyZeroImpactNodes.Value,
146            NodeImpactThreshold = NodeImpactThreshold.Value
147          };
148          operations.Add(ExecutionContext.CreateChildOperation(op, ExecutionContext.Scope));
149        }
150        return new OperationCollection { operations, ExecutionContext.CreateOperation(this) };
151      }
152
153      DataTable table;
154
155      if (ResultCollection.ContainsKey("Population Pruning")) {
156        table = (DataTable)ResultCollection["Population Pruning"].Value;
157      } else {
158        table = new DataTable("Population Pruning");
159        table.Rows.Add(new DataRow("Pruned Trees") { VisualProperties = { StartIndexZero = true } });
160        table.Rows.Add(new DataRow("Pruned Subtrees") { VisualProperties = { StartIndexZero = true } });
161        ResultCollection.Add(new Result("Population Pruning", table));
162      }
163
164      table.Rows["Pruned Trees"].Values.Add(PrunedTrees.Value);
165      table.Rows["Pruned Subtrees"].Values.Add(PrunedSubtrees.Value);
166
167      reentry = true;
168
169      return base.Apply();
170    }
171
172    protected abstract ISymbolicDataAnalysisModel CreateModel(ISymbolicExpressionTree tree, ISymbolicDataAnalysisExpressionTreeInterpreter interpreter,
173      double lowerEstimationLimit = double.MinValue, double upperEstimationLimit = double.MaxValue);
174  }
175}
Note: See TracBrowser for help on using the repository browser.