Changeset 11145 for stable/HeuristicLab.Problems.DataAnalysis.Symbolic
- Timestamp:
- 07/08/14 19:29:00 (10 years ago)
- Location:
- stable
- Files:
-
- 6 edited
- 2 copied
Legend:
- Unmodified
- Added
- Removed
-
stable
- Property svn:mergeinfo changed
/trunk/sources merged: 10368,10375,10378,10414,10417-10418,10428,10469-10470,11013,11025-11027
- Property svn:mergeinfo changed
-
stable/HeuristicLab.Problems.DataAnalysis.Symbolic
- Property svn:mergeinfo changed
/trunk/sources/HeuristicLab.Problems.DataAnalysis.Symbolic merged: 10368,10375,10378,10414,10417,10428,10469-10470,11013,11025-11027
- Property svn:mergeinfo changed
-
stable/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Analyzers/SymbolicDataAnalysisSingleObjectivePruningAnalyzer.cs
r10368 r11145 1 using System; 1 #region License Information 2 3 /* HeuristicLab 4 * Copyright (C) 2002-2014 Heuristic and Evolutionary Algorithms Laboratory (HEAL) 5 * 6 * This file is part of HeuristicLab. 7 * 8 * HeuristicLab is free software: you can redistribute it and/or modify 9 * it under the terms of the GNU General Public License as published by 10 * the Free Software Foundation, either version 3 of the License, or 11 * (at your option) any later version. 12 * 13 * HeuristicLab is distributed in the hope that it will be useful, 14 * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 * GNU General Public License for more details. 17 * 18 * You should have received a copy of the GNU General Public License 19 * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>. 20 */ 21 22 #endregion 23 24 using System; 2 25 using System.Linq; 3 26 using HeuristicLab.Analysis; … … 5 28 using HeuristicLab.Core; 6 29 using HeuristicLab.Data; 7 using HeuristicLab. Encodings.SymbolicExpressionTreeEncoding;8 using HeuristicLab.Optimization ;30 using HeuristicLab.Operators; 31 using HeuristicLab.Optimization.Operators; 9 32 using HeuristicLab.Parameters; 10 33 using HeuristicLab.Persistence.Default.CompositeSerializers.Storable; … … 14 37 [Item("SymbolicDataAnalysisSingleObjectivePruningAnalyzer", "An analyzer that prunes introns from trees in single objective symbolic data analysis problems.")] 15 38 public abstract class SymbolicDataAnalysisSingleObjectivePruningAnalyzer : SymbolicDataAnalysisSingleObjectiveAnalyzer { 39 #region parameter names 16 40 private const string ProblemDataParameterName = "ProblemData"; 17 private const string InterpreterParameterName = "SymbolicExpressionTreeInterpreter";18 19 41 private const string UpdateIntervalParameterName = "UpdateInverval"; 20 42 private const string UpdateCounterParameterName = "UpdateCounter"; 21 22 43 private const string PopulationSliceParameterName = "PopulationSlice"; 23 44 private const string PruningProbabilityParameterName = "PruningProbability"; 24 25 private const string NumberOfPrunedSubtreesParameterName = "PrunedSubtrees"; 26 private const string NumberOfPrunedTreesParameterName = "PrunedTrees"; 27 45 private const string TotalNumberOfPrunedSubtreesParameterName = "Number of pruned subtrees"; 46 private const string TotalNumberOfPrunedTreesParameterName = "Number of pruned trees"; 28 47 private const string RandomParameterName = "Random"; 29 private const string EstimationLimitsParameterName = "EstimationLimits";30 31 48 private const string PruneOnlyZeroImpactNodesParameterName = "PruneOnlyZeroImpactNodes"; 32 49 private const string NodeImpactThresholdParameterName = "ImpactThreshold"; 33 34 private bool reentry; 35 [Storable] 36 protected ISymbolicDataAnalysisSolutionImpactValuesCalculator impactValuesCalculator; 50 private const string PruningOperatorParameterName = "PruningOperator"; 51 private const string ResultsParameterName = "Results"; 52 private const string PopulationSizeParameterName = "PopulationSize"; 53 #endregion 54 55 #region private members 56 private DataReducer prunedSubtreesReducer; 57 private DataReducer prunedTreesReducer; 58 private DataTableValuesCollector valuesCollector; 59 private ResultsCollector resultsCollector; 60 #endregion 37 61 38 62 #region parameter properties 63 public IValueParameter<SymbolicDataAnalysisExpressionPruningOperator> PruningOperatorParameter { 64 get { return (IValueParameter<SymbolicDataAnalysisExpressionPruningOperator>)Parameters[PruningOperatorParameterName]; } 65 } 39 66 public IFixedValueParameter<BoolValue> PruneOnlyZeroImpactNodesParameter { 40 67 get { return (IFixedValueParameter<BoolValue>)Parameters[PruneOnlyZeroImpactNodesParameterName]; } … … 43 70 get { return (IFixedValueParameter<DoubleValue>)Parameters[NodeImpactThresholdParameterName]; } 44 71 } 45 public ILookupParameter<DoubleLimit> EstimationLimitsParameter {46 get { return (ILookupParameter<DoubleLimit>)Parameters[EstimationLimitsParameterName]; }47 }48 72 public ILookupParameter<IRandom> RandomParameter { 49 73 get { return (ILookupParameter<IRandom>)Parameters[RandomParameterName]; } 50 74 } 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 75 public IFixedValueParameter<IntValue> UpdateIntervalParameter { 76 get { return (IFixedValueParameter<IntValue>)Parameters[UpdateIntervalParameterName]; } 77 } 78 public IFixedValueParameter<IntValue> UpdateCounterParameter { 79 get { return (IFixedValueParameter<IntValue>)Parameters[UpdateCounterParameterName]; } 80 } 81 public IFixedValueParameter<DoubleRange> PopulationSliceParameter { 82 get { return (IFixedValueParameter<DoubleRange>)Parameters[PopulationSliceParameterName]; } 83 } 84 public IFixedValueParameter<DoubleValue> PruningProbabilityParameter { 85 get { return (IFixedValueParameter<DoubleValue>)Parameters[PruningProbabilityParameterName]; } 86 } 87 public ILookupParameter<IntValue> PopulationSizeParameter { 88 get { return (ILookupParameter<IntValue>)Parameters[PopulationSizeParameterName]; } 89 } 90 #endregion 91 76 92 #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 93 protected SymbolicDataAnalysisExpressionPruningOperator PruningOperator { get { return PruningOperatorParameter.Value; } } 94 protected int UpdateInterval { get { return UpdateIntervalParameter.Value.Value; } } 95 96 protected int UpdateCounter { 97 get { return UpdateCounterParameter.Value.Value; } 98 set { UpdateCounterParameter.Value.Value = value; } 99 } 100 101 protected double PopulationSliceStart { 102 get { return PopulationSliceParameter.Value.Start; } 103 set { PopulationSliceParameter.Value.Start = value; } 104 } 105 106 protected double PopulationSliceEnd { 107 get { return PopulationSliceParameter.Value.End; } 108 set { PopulationSliceParameter.Value.End = value; } 109 } 110 111 protected double PruningProbability { 112 get { return PruningProbabilityParameter.Value.Value; } 113 set { PruningProbabilityParameter.Value.Value = value; } 114 } 115 116 protected bool PruneOnlyZeroImpactNodes { 117 get { return PruneOnlyZeroImpactNodesParameter.Value.Value; } 118 set { PruneOnlyZeroImpactNodesParameter.Value.Value = value; } 119 } 120 protected double NodeImpactThreshold { 121 get { return NodeImpactThresholdParameter.Value.Value; } 122 set { NodeImpactThresholdParameter.Value.Value = value; } 123 } 124 #endregion 125 126 #region IStatefulItem members 127 public override void InitializeState() { 128 base.InitializeState(); 129 UpdateCounter = 0; 130 } 131 public override void ClearState() { 132 base.ClearState(); 133 UpdateCounter = 0; 134 } 135 #endregion 136 137 [StorableConstructor] 138 protected SymbolicDataAnalysisSingleObjectivePruningAnalyzer(bool deserializing) : base(deserializing) { } 139 90 140 protected SymbolicDataAnalysisSingleObjectivePruningAnalyzer(SymbolicDataAnalysisSingleObjectivePruningAnalyzer original, Cloner cloner) 91 141 : base(original, cloner) { 92 impactValuesCalculator = original.impactValuesCalculator; 93 } 142 if (original.prunedSubtreesReducer != null) 143 this.prunedSubtreesReducer = (DataReducer)original.prunedSubtreesReducer.Clone(); 144 if (original.prunedTreesReducer != null) 145 this.prunedTreesReducer = (DataReducer)original.prunedTreesReducer.Clone(); 146 if (original.valuesCollector != null) 147 this.valuesCollector = (DataTableValuesCollector)original.valuesCollector.Clone(); 148 if (original.resultsCollector != null) 149 this.resultsCollector = (ResultsCollector)original.resultsCollector.Clone(); 150 } 151 152 [StorableHook(HookType.AfterDeserialization)] 153 private void AfterDeserialization() { 154 if (!Parameters.ContainsKey(PopulationSizeParameterName)) { 155 Parameters.Add(new LookupParameter<IntValue>(PopulationSizeParameterName, "The population of individuals.")); 156 } 157 if (Parameters.ContainsKey(UpdateCounterParameterName)) { 158 var fixedValueParameter = Parameters[UpdateCounterParameterName] as FixedValueParameter<IntValue>; 159 if (fixedValueParameter == null) { 160 var valueParameter = (ValueParameter<IntValue>)Parameters[UpdateCounterParameterName]; 161 Parameters.Remove(UpdateCounterParameterName); 162 Parameters.Add(new FixedValueParameter<IntValue>(UpdateCounterParameterName, valueParameter.Value)); 163 } 164 } 165 if (Parameters.ContainsKey(UpdateIntervalParameterName)) { 166 var fixedValueParameter = Parameters[UpdateIntervalParameterName] as FixedValueParameter<IntValue>; 167 if (fixedValueParameter == null) { 168 var valueParameter = (ValueParameter<IntValue>)Parameters[UpdateIntervalParameterName]; 169 Parameters.Remove(UpdateIntervalParameterName); 170 Parameters.Add(new FixedValueParameter<IntValue>(UpdateIntervalParameterName, valueParameter.Value)); 171 } 172 } 173 if (Parameters.ContainsKey(PopulationSliceParameterName)) { 174 var fixedValueParameter = Parameters[PopulationSliceParameterName] as FixedValueParameter<DoubleRange>; 175 if (fixedValueParameter == null) { 176 var valueParameter = (ValueParameter<DoubleRange>)Parameters[PopulationSliceParameterName]; 177 Parameters.Remove(PopulationSliceParameterName); 178 Parameters.Add(new FixedValueParameter<DoubleRange>(PopulationSliceParameterName, valueParameter.Value)); 179 } 180 } 181 if (Parameters.ContainsKey(PruningProbabilityParameterName)) { 182 var fixedValueParameter = Parameters[PruningProbabilityParameterName] as FixedValueParameter<DoubleValue>; 183 if (fixedValueParameter == null) { 184 var valueParameter = (ValueParameter<DoubleValue>)Parameters[PruningProbabilityParameterName]; 185 Parameters.Remove(PruningProbabilityParameterName); 186 Parameters.Add(new FixedValueParameter<DoubleValue>(PruningProbabilityParameterName, valueParameter.Value)); 187 } 188 } 189 } 190 94 191 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))); 192 #region add parameters 193 Parameters.Add(new FixedValueParameter<DoubleRange>(PopulationSliceParameterName, "The slice of the population where pruning should be applied.", new DoubleRange(0.75, 1))); 194 Parameters.Add(new FixedValueParameter<DoubleValue>(PruningProbabilityParameterName, "The probability for pruning an individual.", new DoubleValue(0.5))); 195 Parameters.Add(new FixedValueParameter<IntValue>(UpdateIntervalParameterName, "The interval in which the tree length analysis should be applied.", new IntValue(1))); 196 Parameters.Add(new FixedValueParameter<IntValue>(UpdateCounterParameterName, "The value which counts how many times the operator was called", new IntValue(0))); 197 Parameters.Add(new LookupParameter<IRandom>(RandomParameterName, "The random number generator.")); 198 Parameters.Add(new LookupParameter<IDataAnalysisProblemData>(ProblemDataParameterName, "The problem data.")); 199 Parameters.Add(new FixedValueParameter<DoubleValue>(NodeImpactThresholdParameterName, "The impact threshold below which an individual should be pruned.", new DoubleValue(0.0))); 200 Parameters.Add(new FixedValueParameter<BoolValue>(PruneOnlyZeroImpactNodesParameterName, "Switch to determine of only zero impact individuals should be pruned.", new BoolValue(false))); 201 Parameters.Add(new LookupParameter<IntValue>(PopulationSizeParameterName, "The population of individuals.")); 202 #endregion 203 } 204 205 // 206 /// <summary> 207 /// Computes the closed interval bounding the portion of the population that is to be pruned. 208 /// </summary> 209 /// <returns>Returns an int range [start, end]</returns> 210 private IntRange GetSliceBounds() { 211 if (PopulationSliceStart < 0 || PopulationSliceEnd < 0) throw new ArgumentOutOfRangeException("The slice bounds cannot be negative."); 212 if (PopulationSliceStart > 1 || PopulationSliceEnd > 1) throw new ArgumentOutOfRangeException("The slice bounds should be expressed as unit percentages."); 213 var count = PopulationSizeParameter.ActualValue.Value; 214 var start = (int)Math.Round(PopulationSliceStart * count); 215 var end = (int)Math.Round(PopulationSliceEnd * count); 216 if (end > count) end = count; 217 218 if (start >= end) throw new ArgumentOutOfRangeException("Invalid PopulationSlice bounds."); 219 return new IntRange(start, end); 220 } 221 222 private IOperation CreatePruningOperation() { 223 var operations = new OperationCollection { Parallel = true }; 224 var range = GetSliceBounds(); 225 var qualities = Quality.Select(x => x.Value).ToArray(); 226 var indices = Enumerable.Range(0, qualities.Length).ToArray(); 227 Array.Sort(qualities, indices); 228 if (!Maximization.Value) Array.Reverse(indices); 229 230 var subscopes = ExecutionContext.Scope.SubScopes; 231 var random = RandomParameter.ActualValue; 232 233 var empty = new EmptyOperator(); 234 235 for (int i = 0; i < subscopes.Count; ++i) { 236 IOperator @operator; 237 if (range.Start <= i && i < range.End && random.NextDouble() <= PruningProbability) 238 @operator = PruningOperator; 239 else @operator = empty; 240 var index = indices[i]; 241 var subscope = subscopes[index]; 242 operations.Add(ExecutionContext.CreateChildOperation(@operator, subscope)); 243 } 244 return operations; 109 245 } 110 246 111 247 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); 248 UpdateCounter++; 249 if (UpdateCounter != UpdateInterval) return base.Apply(); 250 UpdateCounter = 0; 251 252 if (prunedSubtreesReducer == null || prunedTreesReducer == null || valuesCollector == null || resultsCollector == null) { InitializeOperators(); } 253 254 var prune = CreatePruningOperation(); 255 var reducePrunedSubtrees = ExecutionContext.CreateChildOperation(prunedSubtreesReducer); 256 var reducePrunedTrees = ExecutionContext.CreateChildOperation(prunedTreesReducer); 257 var collectValues = ExecutionContext.CreateChildOperation(valuesCollector); 258 var collectResults = ExecutionContext.CreateChildOperation(resultsCollector); 259 260 return new OperationCollection { prune, reducePrunedSubtrees, reducePrunedTrees, collectValues, collectResults, base.Apply() }; 261 } 262 263 private void InitializeOperators() { 264 prunedSubtreesReducer = new DataReducer(); 265 prunedSubtreesReducer.ParameterToReduce.ActualName = PruningOperator.PrunedSubtreesParameter.ActualName; 266 prunedSubtreesReducer.ReductionOperation.Value = new ReductionOperation(ReductionOperations.Sum); // sum all the pruned subtrees parameter values 267 prunedSubtreesReducer.TargetOperation.Value = new ReductionOperation(ReductionOperations.Assign); // asign the sum to the target parameter 268 prunedSubtreesReducer.TargetParameter.ActualName = TotalNumberOfPrunedSubtreesParameterName; 269 270 prunedTreesReducer = new DataReducer(); 271 prunedTreesReducer.ParameterToReduce.ActualName = PruningOperator.PrunedTreesParameter.ActualName; 272 prunedTreesReducer.ReductionOperation.Value = new ReductionOperation(ReductionOperations.Sum); 273 prunedTreesReducer.TargetOperation.Value = new ReductionOperation(ReductionOperations.Assign); 274 prunedTreesReducer.TargetParameter.ActualName = TotalNumberOfPrunedTreesParameterName; 275 276 valuesCollector = new DataTableValuesCollector(); 277 valuesCollector.CollectedValues.Add(new LookupParameter<IntValue>(TotalNumberOfPrunedSubtreesParameterName)); 278 valuesCollector.CollectedValues.Add(new LookupParameter<IntValue>(TotalNumberOfPrunedTreesParameterName)); 279 valuesCollector.DataTableParameter.ActualName = "Population pruning"; 280 281 resultsCollector = new ResultsCollector(); 282 resultsCollector.CollectedValues.Add(new LookupParameter<DataTable>("Population pruning")); 283 resultsCollector.ResultsParameter.ActualName = ResultsParameterName; 284 } 174 285 } 175 286 } -
stable/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/HeuristicLab.Problems.DataAnalysis.Symbolic-3.4.csproj
r10910 r11145 112 112 </ItemGroup> 113 113 <ItemGroup> 114 <Compile Include="Analyzers\SymbolicDataAnalysisSingleObjectivePruningAnalyzer.cs" /> 114 115 <Compile Include="Analyzers\SymbolicDataAnalysisSingleObjectiveValidationParetoBestSolutionAnalyzer.cs" /> 115 116 <Compile Include="Analyzers\SymbolicDataAnalysisSingleObjectiveTrainingParetoBestSolutionAnalyzer.cs" /> … … 125 126 <SubType>Code</SubType> 126 127 </Compile> 128 <Compile Include="SymbolicDataAnalysisExpressionPruningOperator.cs" /> 127 129 <Compile Include="Analyzers\SymbolicDataAnalysisVariableFrequencyAnalyzer.cs" /> 128 130 <Compile Include="Analyzers\SymbolicDataAnalysisAlleleFrequencyAnalyzer.cs" /> -
stable/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Interfaces/ISymbolicDataAnalysisImpactValuesCalculator.cs
r8946 r11145 1 1 using System.Collections.Generic; 2 using HeuristicLab.Core; 2 3 using HeuristicLab.Encodings.SymbolicExpressionTreeEncoding; 3 4 4 5 namespace HeuristicLab.Problems.DataAnalysis.Symbolic { 5 public interface ISymbolicDataAnalysisSolutionImpactValuesCalculator {6 public interface ISymbolicDataAnalysisSolutionImpactValuesCalculator : IItem { 6 7 double CalculateReplacementValue(ISymbolicDataAnalysisModel model, ISymbolicExpressionTreeNode node, IDataAnalysisProblemData problemData, IEnumerable<int> rows); 7 8 double CalculateImpactValue(ISymbolicDataAnalysisModel model, ISymbolicExpressionTreeNode node, IDataAnalysisProblemData problemData, IEnumerable<int> rows, double originalQuality = double.NaN); 9 void CalculateImpactAndReplacementValues(ISymbolicDataAnalysisModel model, ISymbolicExpressionTreeNode node, IDataAnalysisProblemData problemData, 10 IEnumerable<int> rows, out double impactValue, out double replacementValue, double originalQuality = double.NaN); 8 11 } 9 12 } -
stable/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Plugin.cs.frame
r10032 r11145 38 38 [PluginDependency("HeuristicLab.Operators", "3.3")] 39 39 [PluginDependency("HeuristicLab.Optimization", "3.3")] 40 [PluginDependency("HeuristicLab.Optimization.Operators", "3.3")] 40 41 [PluginDependency("HeuristicLab.Parameters", "3.3")] 41 42 [PluginDependency("HeuristicLab.Persistence", "3.3")] -
stable/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/SymbolicDataAnalysisExpressionPruningOperator.cs
r10368 r11145 34 34 [StorableClass] 35 35 [Item("SymbolicExpressionTreePruningOperator", "An operator that replaces introns with constant values in a symbolic expression tree.")] 36 public class SymbolicDataAnalysisExpressionPruningOperator : SingleSuccessorOperator { 37 private const string NumberOfPrunedSubtreesParameterName = "PrunedSubtrees"; 38 private const string NumberOfPrunedTreesParameterName = "PrunedTrees"; 36 public abstract class SymbolicDataAnalysisExpressionPruningOperator : SingleSuccessorOperator { 37 #region parameter names 38 private const string ProblemDataParameterName = "ProblemData"; 39 private const string SymbolicDataAnalysisModelParameterName = "SymbolicDataAnalysisModel"; 40 private const string ImpactValuesCalculatorParameterName = "ImpactValuesCalculator"; 41 private const string PrunedSubtreesParameterName = "PrunedSubtrees"; 42 private const string PrunedTreesParameterName = "PrunedTrees"; 43 private const string FitnessCalculationPartitionParameterName = "FitnessCalculationPartition"; 44 private const string NodeImpactThresholdParameterName = "ImpactThreshold"; 45 private const string PruneOnlyZeroImpactNodesParameterName = "PruneOnlyZeroImpactNodes"; 46 private const string SymbolicExpressionTreeParameterName = "SymbolicExpressionTree"; // the tree to be pruned 47 private const string QualityParameterName = "Quality"; // the quality 48 private const string EstimationLimitsParameterName = "EstimationLimits"; 49 private const string InterpreterParameterName = "SymbolicExpressionTreeInterpreter"; 50 #endregion 51 39 52 #region parameter properties 40 public ILookupParameter< DoubleValue> NumberOfPrunedSubtreesParameter {41 get { return (ILookupParameter< DoubleValue>)Parameters[NumberOfPrunedSubtreesParameterName]; }53 public ILookupParameter<ISymbolicExpressionTree> SymbolicExpressionTreeParameter { 54 get { return (ILookupParameter<ISymbolicExpressionTree>)Parameters[SymbolicExpressionTreeParameterName]; } 42 55 } 43 public ILookupParameter<DoubleValue> NumberOfPrunedTreesParameter { 44 get { return (ILookupParameter<DoubleValue>)Parameters[NumberOfPrunedTreesParameterName]; } 56 public ILookupParameter<DoubleValue> QualityParameter { 57 get { return (ILookupParameter<DoubleValue>)Parameters[QualityParameterName]; } 58 } 59 public ILookupParameter<IDataAnalysisProblemData> ProblemDataParameter { 60 get { return (ILookupParameter<IDataAnalysisProblemData>)Parameters[ProblemDataParameterName]; } 61 } 62 public IValueParameter<ISymbolicDataAnalysisSolutionImpactValuesCalculator> ImpactValuesCalculatorParameter { 63 get { return (IValueParameter<ISymbolicDataAnalysisSolutionImpactValuesCalculator>)Parameters[ImpactValuesCalculatorParameterName]; } 64 } 65 public ILookupParameter<IntRange> FitnessCalculationPartitionParameter { 66 get { return (ILookupParameter<IntRange>)Parameters[FitnessCalculationPartitionParameterName]; } 67 } 68 public ILookupParameter<IntValue> PrunedSubtreesParameter { 69 get { return (ILookupParameter<IntValue>)Parameters[PrunedSubtreesParameterName]; } 70 } 71 public ILookupParameter<IntValue> PrunedTreesParameter { 72 get { return (ILookupParameter<IntValue>)Parameters[PrunedTreesParameterName]; } 73 } 74 public IFixedValueParameter<DoubleValue> NodeImpactThresholdParameter { 75 get { return (IFixedValueParameter<DoubleValue>)Parameters[NodeImpactThresholdParameterName]; } 76 } 77 public IFixedValueParameter<BoolValue> PruneOnlyZeroImpactNodesParameter { 78 get { return (IFixedValueParameter<BoolValue>)Parameters[PruneOnlyZeroImpactNodesParameterName]; } 79 } 80 public ILookupParameter<DoubleLimit> EstimationLimitsParameter { 81 get { return (ILookupParameter<DoubleLimit>)Parameters[EstimationLimitsParameterName]; } 82 } 83 public ILookupParameter<ISymbolicDataAnalysisExpressionTreeInterpreter> InterpreterParameter { 84 get { return (ILookupParameter<ISymbolicDataAnalysisExpressionTreeInterpreter>)Parameters[InterpreterParameterName]; } 45 85 } 46 86 #endregion 87 47 88 #region properties 48 private DoubleValue PrunedSubtrees { get { return NumberOfPrunedSubtreesParameter.ActualValue; } } 49 private DoubleValue PrunedTrees { get { return NumberOfPrunedTreesParameter.ActualValue; } } 89 protected IDataAnalysisProblemData ProblemData { get { return ProblemDataParameter.ActualValue; } } 90 protected ISymbolicDataAnalysisSolutionImpactValuesCalculator ImpactValuesCalculator { get { return ImpactValuesCalculatorParameter.Value; } } 91 protected IntRange FitnessCalculationPartition { get { return FitnessCalculationPartitionParameter.ActualValue; } } 92 protected bool PruneOnlyZeroImpactNodes { 93 get { return PruneOnlyZeroImpactNodesParameter.Value.Value; } 94 set { PruneOnlyZeroImpactNodesParameter.Value.Value = value; } 95 } 96 protected double NodeImpactThreshold { 97 get { return NodeImpactThresholdParameter.Value.Value; } 98 set { NodeImpactThresholdParameter.Value.Value = value; } 99 } 100 protected ISymbolicExpressionTree SymbolicExpressionTree { get { return SymbolicExpressionTreeParameter.ActualValue; } } 101 protected DoubleValue Quality { get { return QualityParameter.ActualValue; } } 102 protected DoubleLimit EstimationLimits { get { return EstimationLimitsParameter.ActualValue; } } 103 protected ISymbolicDataAnalysisExpressionTreeInterpreter Interpreter { get { return InterpreterParameter.ActualValue; } } 50 104 #endregion 51 public override IDeepCloneable Clone(Cloner cloner) { 52 return new SymbolicDataAnalysisExpressionPruningOperator(this, cloner); 53 } 54 private SymbolicDataAnalysisExpressionPruningOperator(SymbolicDataAnalysisExpressionPruningOperator original, Cloner cloner) 55 : base(original, cloner) { 105 106 [StorableConstructor] 107 protected SymbolicDataAnalysisExpressionPruningOperator(bool deserializing) : base(deserializing) { } 108 protected SymbolicDataAnalysisExpressionPruningOperator(SymbolicDataAnalysisExpressionPruningOperator original, Cloner cloner) 109 : base(original, cloner) { } 110 111 protected SymbolicDataAnalysisExpressionPruningOperator() { 112 #region add parameters 113 Parameters.Add(new LookupParameter<IDataAnalysisProblemData>(ProblemDataParameterName)); 114 Parameters.Add(new LookupParameter<ISymbolicDataAnalysisModel>(SymbolicDataAnalysisModelParameterName)); 115 Parameters.Add(new LookupParameter<IntRange>(FitnessCalculationPartitionParameterName)); 116 Parameters.Add(new LookupParameter<IntValue>(PrunedSubtreesParameterName, "A counter of how many subtrees were replaced.")); 117 Parameters.Add(new LookupParameter<IntValue>(PrunedTreesParameterName, "A counter of how many trees were pruned.")); 118 Parameters.Add(new FixedValueParameter<BoolValue>(PruneOnlyZeroImpactNodesParameterName, "Specify whether or not only zero impact nodes should be pruned.")); 119 Parameters.Add(new FixedValueParameter<DoubleValue>(NodeImpactThresholdParameterName, "Specifies an impact value threshold below which nodes should be pruned.")); 120 Parameters.Add(new LookupParameter<DoubleLimit>(EstimationLimitsParameterName)); 121 Parameters.Add(new LookupParameter<ISymbolicDataAnalysisExpressionTreeInterpreter>(InterpreterParameterName)); 122 Parameters.Add(new LookupParameter<ISymbolicExpressionTree>(SymbolicExpressionTreeParameterName)); 123 Parameters.Add(new LookupParameter<DoubleValue>(QualityParameterName)); 124 #endregion 56 125 } 57 126 58 public SymbolicDataAnalysisExpressionPruningOperator() { 59 Parameters.Add(new LookupParameter<DoubleValue>(NumberOfPrunedSubtreesParameterName)); 60 Parameters.Add(new LookupParameter<DoubleValue>(NumberOfPrunedTreesParameterName)); 61 } 127 protected abstract ISymbolicDataAnalysisModel CreateModel(); 62 128 63 public ISymbolicDataAnalysisModel Model { get; set; } 64 public IDataAnalysisProblemData ProblemData { get; set; } 65 public ISymbolicDataAnalysisSolutionImpactValuesCalculator ImpactsCalculator { get; set; } 66 public IRandom Random { get; set; } 67 68 public bool PruneOnlyZeroImpactNodes { get; set; } 69 public double NodeImpactThreshold { get; set; } 129 protected abstract double Evaluate(IDataAnalysisModel model); 70 130 71 131 public override IOperation Apply() { 72 int prunedSubtrees = 0; 132 var model = CreateModel(); 133 var nodes = SymbolicExpressionTree.Root.GetSubtree(0).GetSubtree(0).IterateNodesPrefix().ToList(); 134 var rows = Enumerable.Range(FitnessCalculationPartition.Start, FitnessCalculationPartition.Size); 135 var prunedSubtrees = 0; 136 var prunedTrees = 0; 73 137 74 var nodes = Model.SymbolicExpressionTree.Root.GetSubtree(0).GetSubtree(0).IterateNodesPrefix().ToList();138 double quality = Evaluate(model); 75 139 76 for (int j = 0; j < nodes.Count; ++j) {77 var node = nodes[ j];140 for (int i = 0; i < nodes.Count; ++i) { 141 var node = nodes[i]; 78 142 if (node is ConstantTreeNode) continue; 79 143 80 var impact = ImpactsCalculator.CalculateImpactValue(Model, node, ProblemData, ProblemData.TrainingIndices); 144 double impactValue, replacementValue; 145 ImpactValuesCalculator.CalculateImpactAndReplacementValues(model, node, ProblemData, rows, out impactValue, out replacementValue, quality); 81 146 82 147 if (PruneOnlyZeroImpactNodes) { 83 if (!impact .IsAlmost(0.0)) continue;84 } else {85 if (NodeImpactThreshold < impact)continue;148 if (!impactValue.IsAlmost(0.0)) continue; 149 } else if (NodeImpactThreshold < impactValue) { 150 continue; 86 151 } 87 152 88 var replacementValue = ImpactsCalculator.CalculateReplacementValue(Model, node, ProblemData, ProblemData.TrainingIndices); 89 var constantNode = new ConstantTreeNode(new Constant()) { Value = replacementValue }; 153 var constantNode = (ConstantTreeNode)node.Grammar.GetSymbol("Constant").CreateTreeNode(); 154 constantNode.Value = replacementValue; 155 90 156 ReplaceWithConstant(node, constantNode); 91 j += node.GetLength() - 1; // skip subtrees under the node that was folded 157 i += node.GetLength() - 1; // skip subtrees under the node that was folded 158 159 quality -= impactValue; 92 160 93 161 prunedSubtrees++; 94 162 } 95 163 96 if (prunedSubtrees > 0) {97 lock (PrunedSubtrees) { PrunedSubtrees.Value += prunedSubtrees; }98 lock (PrunedTrees) { PrunedTrees.Value += 1; }99 } 164 if (prunedSubtrees > 0) prunedTrees = 1; 165 PrunedSubtreesParameter.ActualValue = new IntValue(prunedSubtrees); 166 PrunedTreesParameter.ActualValue = new IntValue(prunedTrees); 167 100 168 return base.Apply(); 101 169 } 170 102 171 private static void ReplaceWithConstant(ISymbolicExpressionTreeNode original, ISymbolicExpressionTreeNode replacement) { 103 172 var parent = original.Parent; -
stable/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/SymbolicDataAnalysisSolutionImpactValuesCalculator.cs
r9456 r11145 22 22 using System.Collections.Generic; 23 23 using HeuristicLab.Common; 24 using HeuristicLab.Core; 24 25 using HeuristicLab.Encodings.SymbolicExpressionTreeEncoding; 26 using HeuristicLab.Persistence.Default.CompositeSerializers.Storable; 25 27 26 28 namespace HeuristicLab.Problems.DataAnalysis.Symbolic { 27 public abstract class SymbolicDataAnalysisSolutionImpactValuesCalculator : ISymbolicDataAnalysisSolutionImpactValuesCalculator { 29 [StorableClass] 30 [Item("SymbolicDataAnalysisSolutionImpactValuesCalculator", "Calculates the impact values and replacements values for symbolic expression tree nodes.")] 31 public abstract class SymbolicDataAnalysisSolutionImpactValuesCalculator : Item, ISymbolicDataAnalysisSolutionImpactValuesCalculator { 32 protected SymbolicDataAnalysisSolutionImpactValuesCalculator() { } 33 34 protected SymbolicDataAnalysisSolutionImpactValuesCalculator(SymbolicDataAnalysisSolutionImpactValuesCalculator original, Cloner cloner) 35 : base(original, cloner) { } 36 [StorableConstructor] 37 protected SymbolicDataAnalysisSolutionImpactValuesCalculator(bool deserializing) : base(deserializing) { } 28 38 public abstract double CalculateReplacementValue(ISymbolicDataAnalysisModel model, ISymbolicExpressionTreeNode node, IDataAnalysisProblemData problemData, IEnumerable<int> rows); 29 39 public abstract double CalculateImpactValue(ISymbolicDataAnalysisModel model, ISymbolicExpressionTreeNode node, IDataAnalysisProblemData problemData, IEnumerable<int> rows, double originalQuality = double.NaN); 40 public abstract void CalculateImpactAndReplacementValues(ISymbolicDataAnalysisModel model, ISymbolicExpressionTreeNode node, IDataAnalysisProblemData problemData, IEnumerable<int> rows, out double impactValue, out double replacementValue, double originalQuality = double.NaN); 30 41 31 42 protected static double CalculateReplacementValue(ISymbolicExpressionTreeNode node, ISymbolicExpressionTree sourceTree, ISymbolicDataAnalysisExpressionTreeInterpreter interpreter,
Note: See TracChangeset
for help on using the changeset viewer.