Ignore:
Timestamp:
07/01/14 10:53:46 (5 years ago)
Author:
mkommend
Message:

#2206: Updated data preprocessing branch with trunk changes.

Location:
branches/DataPreprocessing
Files:
4 edited

Legend:

Unmodified
Added
Removed
  • branches/DataPreprocessing

  • branches/DataPreprocessing/HeuristicLab.Problems.DataAnalysis.Symbolic

  • branches/DataPreprocessing/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Analyzers/SymbolicDataAnalysisSingleObjectivePruningAnalyzer.cs

    r11009 r11064  
    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
     24using System;
    225using System.Linq;
    326using HeuristicLab.Analysis;
     
    2750    private const string PruningOperatorParameterName = "PruningOperator";
    2851    private const string ResultsParameterName = "Results";
    29     #endregion
     52    private const string PopulationSizeParameterName = "PopulationSize";
     53    #endregion
     54
    3055    #region private members
    3156    private DataReducer prunedSubtreesReducer;
     
    3358    private DataTableValuesCollector valuesCollector;
    3459    private ResultsCollector resultsCollector;
    35     private EmptyOperator emptyOp;
    36     #endregion
     60    #endregion
     61
    3762    #region parameter properties
    3863    public IValueParameter<SymbolicDataAnalysisExpressionPruningOperator> PruningOperatorParameter {
     
    4873      get { return (ILookupParameter<IRandom>)Parameters[RandomParameterName]; }
    4974    }
    50     private ILookupParameter<IDataAnalysisProblemData> ProblemDataParameter {
    51       get { return (ILookupParameter<IDataAnalysisProblemData>)Parameters[ProblemDataParameterName]; }
    52     }
    53     public IValueParameter<IntValue> UpdateIntervalParameter {
    54       get { return (IValueParameter<IntValue>)Parameters[UpdateIntervalParameterName]; }
    55     }
    56     public IValueParameter<IntValue> UpdateCounterParameter {
    57       get { return (IValueParameter<IntValue>)Parameters[UpdateCounterParameterName]; }
    58     }
    59     public IValueParameter<DoubleRange> PopulationSliceParameter {
    60       get { return (IValueParameter<DoubleRange>)Parameters[PopulationSliceParameterName]; }
    61     }
    62     public IValueParameter<DoubleValue> PruningProbabilityParameter {
    63       get { return (IValueParameter<DoubleValue>)Parameters[PruningProbabilityParameterName]; }
    64     }
    65     #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
    6692    #region properties
    6793    protected SymbolicDataAnalysisExpressionPruningOperator PruningOperator { get { return PruningOperatorParameter.Value; } }
    68     protected IDataAnalysisProblemData ProblemData { get { return ProblemDataParameter.ActualValue; } }
    69     protected IntValue UpdateInterval { get { return UpdateIntervalParameter.Value; } }
    70     protected IntValue UpdateCounter { get { return UpdateCounterParameter.Value; } }
    71     protected DoubleRange PopulationSlice { get { return PopulationSliceParameter.Value; } }
    72     protected DoubleValue PruningProbability { get { return PruningProbabilityParameter.Value; } }
    73     protected IRandom Random { get { return RandomParameter.ActualValue; } }
    74     protected DoubleValue NodeImpactThreshold { get { return NodeImpactThresholdParameter.Value; } }
    75     protected BoolValue PruneOnlyZeroImpactNodes { get { return PruneOnlyZeroImpactNodesParameter.Value; } }
    76     #endregion
     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
    77126    #region IStatefulItem members
    78127    public override void InitializeState() {
    79128      base.InitializeState();
    80       UpdateCounter.Value = 0;
     129      UpdateCounter = 0;
    81130    }
    82131    public override void ClearState() {
    83132      base.ClearState();
    84       UpdateCounter.Value = 0;
     133      UpdateCounter = 0;
    85134    }
    86135    #endregion
     
    88137    [StorableConstructor]
    89138    protected SymbolicDataAnalysisSingleObjectivePruningAnalyzer(bool deserializing) : base(deserializing) { }
     139
    90140    protected SymbolicDataAnalysisSingleObjectivePruningAnalyzer(SymbolicDataAnalysisSingleObjectivePruningAnalyzer original, Cloner cloner)
    91141      : base(original, cloner) {
     
    99149        this.resultsCollector = (ResultsCollector)original.resultsCollector.Clone();
    100150    }
     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
    101191    protected SymbolicDataAnalysisSingleObjectivePruningAnalyzer() {
    102192      #region add parameters
    103       Parameters.Add(new ValueParameter<DoubleRange>(PopulationSliceParameterName, new DoubleRange(0.75, 1)));
    104       Parameters.Add(new ValueParameter<DoubleValue>(PruningProbabilityParameterName, new DoubleValue(0.5)));
    105       Parameters.Add(new ValueParameter<IntValue>(UpdateIntervalParameterName, "The interval in which the tree length analysis should be applied.", new IntValue(1)));
    106       Parameters.Add(new ValueParameter<IntValue>(UpdateCounterParameterName, "The value which counts how many times the operator was called", new IntValue(0)));
    107       Parameters.Add(new LookupParameter<IRandom>(RandomParameterName));
    108       Parameters.Add(new LookupParameter<IDataAnalysisProblemData>(ProblemDataParameterName));
    109       Parameters.Add(new FixedValueParameter<DoubleValue>(NodeImpactThresholdParameterName, new DoubleValue(0.0)));
    110       Parameters.Add(new FixedValueParameter<BoolValue>(PruneOnlyZeroImpactNodesParameterName, new BoolValue(false)));
     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."));
    111202      #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;
     245    }
     246
     247    public override IOperation Apply() {
     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() };
    112261    }
    113262
     
    133282      resultsCollector.CollectedValues.Add(new LookupParameter<DataTable>("Population pruning"));
    134283      resultsCollector.ResultsParameter.ActualName = ResultsParameterName;
    135 
    136       emptyOp = new EmptyOperator();
    137     }
    138 
    139     //
    140     /// <summary>
    141     /// Computes the closed interval bounding the portion of the population that is to be pruned.
    142     /// </summary>
    143     /// <returns>Returns an int range [start, end]</returns>
    144     private IntRange GetSliceBounds() {
    145       var count = ExecutionContext.Scope.SubScopes.Count;
    146       var start = (int)Math.Round(PopulationSlice.Start * count);
    147       var end = (int)Math.Round(PopulationSlice.End * count);
    148       if (end > count) end = count;
    149 
    150       if (PopulationSlice.Start > 1 || PopulationSlice.End > 1) throw new ArgumentOutOfRangeException("The slice bounds should be expressed as unit percentages.");
    151       if (start >= end) throw new ArgumentOutOfRangeException("Invalid PopulationSlice bounds.");
    152       return new IntRange(start, end);
    153     }
    154 
    155     private IOperation CreatePruningOperation() {
    156       var oc = new OperationCollection { Parallel = true };
    157       var range = GetSliceBounds();
    158       var qualities = Quality.Select(x => x.Value).ToArray();
    159       var indices = Enumerable.Range(0, qualities.Length).ToArray();
    160       Array.Sort(qualities, indices);
    161       if (!Maximization.Value) Array.Reverse(indices);
    162 
    163       var subscopes = ExecutionContext.Scope.SubScopes;
    164 
    165       for (int i = 0; i < subscopes.Count; ++i) {
    166         IOperator op;
    167         if (range.Start <= i && i < range.End && Random.NextDouble() <= PruningProbability.Value)
    168           op = PruningOperator;
    169         else op = emptyOp;
    170         var index = indices[i];
    171         var subscope = subscopes[index];
    172         oc.Add(ExecutionContext.CreateChildOperation(op, subscope));
    173       }
    174       return oc;
    175     }
    176 
    177     public override IOperation Apply() {
    178       UpdateCounter.Value++;
    179       if (UpdateCounter.Value != UpdateInterval.Value) return base.Apply();
    180       UpdateCounter.Value = 0;
    181 
    182       if (prunedSubtreesReducer == null || prunedTreesReducer == null || valuesCollector == null || resultsCollector == null) { InitializeOperators(); }
    183 
    184       var prune = CreatePruningOperation();
    185       var reducePrunedSubtrees = ExecutionContext.CreateChildOperation(prunedSubtreesReducer);
    186       var reducePrunedTrees = ExecutionContext.CreateChildOperation(prunedTreesReducer);
    187       var collectValues = ExecutionContext.CreateChildOperation(valuesCollector);
    188       var collectResults = ExecutionContext.CreateChildOperation(resultsCollector);
    189 
    190       return new OperationCollection { prune, reducePrunedSubtrees, reducePrunedTrees, collectValues, collectResults, base.Apply() };
    191284    }
    192285  }
  • branches/DataPreprocessing/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/SymbolicDataAnalysisExpressionPruningOperator.cs

    r10538 r11064  
    8585    }
    8686    #endregion
     87
    8788    #region properties
    8889    protected IDataAnalysisProblemData ProblemData { get { return ProblemDataParameter.ActualValue; } }
    8990    protected ISymbolicDataAnalysisSolutionImpactValuesCalculator ImpactValuesCalculator { get { return ImpactValuesCalculatorParameter.Value; } }
    9091    protected IntRange FitnessCalculationPartition { get { return FitnessCalculationPartitionParameter.ActualValue; } }
    91     protected BoolValue PruneOnlyZeroImpactNodes { get { return PruneOnlyZeroImpactNodesParameter.Value; } }
    92     protected DoubleValue NodeImpactThreshold { get { return NodeImpactThresholdParameter.Value; } }
     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    }
    93100    protected ISymbolicExpressionTree SymbolicExpressionTree { get { return SymbolicExpressionTreeParameter.ActualValue; } }
    94101    protected DoubleValue Quality { get { return QualityParameter.ActualValue; } }
     
    117124      #endregion
    118125    }
     126
     127    protected abstract ISymbolicDataAnalysisModel CreateModel();
     128
     129    protected abstract double Evaluate(IDataAnalysisModel model);
     130
    119131    public override IOperation Apply() {
    120132      var model = CreateModel();
    121133      var nodes = SymbolicExpressionTree.Root.GetSubtree(0).GetSubtree(0).IterateNodesPrefix().ToList();
    122       var rows = Enumerable.Range(FitnessCalculationPartition.Start, FitnessCalculationPartition.Size).ToList();
    123 
     134      var rows = Enumerable.Range(FitnessCalculationPartition.Start, FitnessCalculationPartition.Size);
    124135      var prunedSubtrees = 0;
    125136      var prunedTrees = 0;
     
    134145        ImpactValuesCalculator.CalculateImpactAndReplacementValues(model, node, ProblemData, rows, out impactValue, out replacementValue, quality);
    135146
    136         if (PruneOnlyZeroImpactNodes.Value && (!impactValue.IsAlmost(0.0))) continue;
    137         else if (NodeImpactThreshold.Value < impactValue) continue;
     147        if (PruneOnlyZeroImpactNodes) {
     148          if (!impactValue.IsAlmost(0.0)) continue;
     149        } else if (NodeImpactThreshold < impactValue) {
     150          continue;
     151        }
    138152
    139         var constantNode = new ConstantTreeNode(new Constant()) { Value = replacementValue };
     153        var constantNode = (ConstantTreeNode)node.Grammar.GetSymbol("Constant").CreateTreeNode();
     154        constantNode.Value = replacementValue;
     155
    140156        ReplaceWithConstant(node, constantNode);
    141157        i += node.GetLength() - 1; // skip subtrees under the node that was folded
     
    152168      return base.Apply();
    153169    }
     170
    154171    private static void ReplaceWithConstant(ISymbolicExpressionTreeNode original, ISymbolicExpressionTreeNode replacement) {
    155172      var parent = original.Parent;
     
    158175      parent.InsertSubtree(i, replacement);
    159176    }
    160     protected abstract ISymbolicDataAnalysisModel CreateModel();
    161     protected abstract double Evaluate(IDataAnalysisModel model);
    162177  }
    163178}
Note: See TracChangeset for help on using the changeset viewer.