Free cookie consent management tool by TermsFeed Policy Generator

Ignore:
Timestamp:
07/12/15 11:23:06 (9 years ago)
Author:
gkronber
Message:

#2359, #2398: merged r12189,r12358,r12359,r12361,r12461,r12674,r12720,r12744 from trunk to stable

Location:
stable
Files:
5 edited

Legend:

Unmodified
Added
Removed
  • stable

  • stable/HeuristicLab.Problems.DataAnalysis.Symbolic.Regression

  • stable/HeuristicLab.Problems.DataAnalysis.Symbolic.Regression/3.4/SymbolicRegressionPruningAnalyzer.cs

    r12009 r12745  
    2424using HeuristicLab.Common;
    2525using HeuristicLab.Core;
     26using HeuristicLab.Data;
    2627using HeuristicLab.Parameters;
    2728using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
     
    3132  [StorableClass]
    3233  public sealed class SymbolicRegressionPruningAnalyzer : SymbolicDataAnalysisSingleObjectivePruningAnalyzer {
    33     private const string ImpactValuesCalculatorParameterName = "ImpactValuesCalculator";
    3434    private const string PruningOperatorParameterName = "PruningOperator";
    35     private SymbolicRegressionPruningAnalyzer(SymbolicRegressionPruningAnalyzer original, Cloner cloner)
    36       : base(original, cloner) {
     35    public IValueParameter<SymbolicRegressionPruningOperator> PruningOperatorParameter {
     36      get { return (IValueParameter<SymbolicRegressionPruningOperator>)Parameters[PruningOperatorParameterName]; }
    3737    }
    38     public override IDeepCloneable Clone(Cloner cloner) {
    39       return new SymbolicRegressionPruningAnalyzer(this, cloner);
     38
     39    protected override SymbolicDataAnalysisExpressionPruningOperator PruningOperator {
     40      get { return PruningOperatorParameter.Value; }
    4041    }
     42
     43    private SymbolicRegressionPruningAnalyzer(SymbolicRegressionPruningAnalyzer original, Cloner cloner) : base(original, cloner) { }
     44    public override IDeepCloneable Clone(Cloner cloner) { return new SymbolicRegressionPruningAnalyzer(this, cloner); }
    4145
    4246    [StorableConstructor]
     
    4448
    4549    public SymbolicRegressionPruningAnalyzer() {
    46       Parameters.Add(new ValueParameter<SymbolicDataAnalysisSolutionImpactValuesCalculator>(ImpactValuesCalculatorParameterName, "The impact values calculator", new SymbolicRegressionSolutionImpactValuesCalculator()));
    47       Parameters.Add(new ValueParameter<SymbolicDataAnalysisExpressionPruningOperator>(PruningOperatorParameterName, "The operator used to prune trees", new SymbolicRegressionPruningOperator()));
     50      Parameters.Add(new ValueParameter<SymbolicRegressionPruningOperator>(PruningOperatorParameterName, "The operator used to prune trees", new SymbolicRegressionPruningOperator(new SymbolicRegressionSolutionImpactValuesCalculator())));
     51    }
     52
     53    [StorableHook(HookType.AfterDeserialization)]
     54    private void AfterDeserialization() {
     55      // BackwardsCompatibility3.3
     56
     57      #region Backwards compatible code, remove with 3.4
     58      if (Parameters.ContainsKey(PruningOperatorParameterName)) {
     59        var oldParam = Parameters[PruningOperatorParameterName] as ValueParameter<SymbolicDataAnalysisExpressionPruningOperator>;
     60        if (oldParam != null) {
     61          Parameters.Remove(oldParam);
     62          Parameters.Add(new ValueParameter<SymbolicRegressionPruningOperator>(PruningOperatorParameterName, "The operator used to prune trees", new SymbolicRegressionPruningOperator(new SymbolicRegressionSolutionImpactValuesCalculator())));
     63        }
     64      } else {
     65        // not yet contained
     66        Parameters.Add(new ValueParameter<SymbolicRegressionPruningOperator>(PruningOperatorParameterName, "The operator used to prune trees", new SymbolicRegressionPruningOperator(new SymbolicRegressionSolutionImpactValuesCalculator())));
     67      }
     68
     69
     70      if (Parameters.ContainsKey("PruneOnlyZeroImpactNodes")) {
     71        PruningOperator.PruneOnlyZeroImpactNodes = ((IFixedValueParameter<BoolValue>)Parameters["PruneOnlyZeroImpactNodes"]).Value.Value;
     72        Parameters.Remove(Parameters["PruneOnlyZeroImpactNodes"]);
     73      }
     74      if (Parameters.ContainsKey("ImpactThreshold")) {
     75        PruningOperator.NodeImpactThreshold = ((IFixedValueParameter<DoubleValue>)Parameters["ImpactThreshold"]).Value.Value;
     76        Parameters.Remove(Parameters["ImpactThreshold"]);
     77      }
     78      if (Parameters.ContainsKey("ImpactValuesCalculator")) {
     79        PruningOperator.ImpactValuesCalculator = ((ValueParameter<SymbolicDataAnalysisSolutionImpactValuesCalculator>)Parameters["ImpactValuesCalculator"]).Value;
     80        Parameters.Remove(Parameters["ImpactValuesCalculator"]);
     81      }
     82
     83      #endregion
    4884    }
    4985  }
  • stable/HeuristicLab.Problems.DataAnalysis.Symbolic.Regression/3.4/SymbolicRegressionPruningOperator.cs

    r12669 r12745  
    2222#endregion
    2323
     24using System.Collections.Generic;
    2425using System.Linq;
    2526using HeuristicLab.Common;
    2627using HeuristicLab.Core;
     28using HeuristicLab.Encodings.SymbolicExpressionTreeEncoding;
    2729using HeuristicLab.Parameters;
    2830using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
     
    3234  [Item("SymbolicRegressionPruningOperator", "An operator which prunes symbolic regression trees.")]
    3335  public class SymbolicRegressionPruningOperator : SymbolicDataAnalysisExpressionPruningOperator {
    34     private const string ImpactValuesCalculatorParameterName = "ImpactValuesCalculator";
     36    private const string EvaluatorParameterName = "Evaluator";
     37
     38    #region parameter properties
     39    public ILookupParameter<ISymbolicRegressionSingleObjectiveEvaluator> EvaluatorParameter {
     40      get { return (ILookupParameter<ISymbolicRegressionSingleObjectiveEvaluator>)Parameters[EvaluatorParameterName]; }
     41    }
     42    #endregion
    3543
    3644    protected SymbolicRegressionPruningOperator(SymbolicRegressionPruningOperator original, Cloner cloner)
     
    4452    protected SymbolicRegressionPruningOperator(bool deserializing) : base(deserializing) { }
    4553
    46     public SymbolicRegressionPruningOperator() {
    47       var impactValuesCalculator = new SymbolicRegressionSolutionImpactValuesCalculator();
    48       Parameters.Add(new ValueParameter<ISymbolicDataAnalysisSolutionImpactValuesCalculator>(ImpactValuesCalculatorParameterName, "The impact values calculator to be used for figuring out the node impacts.", impactValuesCalculator));
     54    public SymbolicRegressionPruningOperator(ISymbolicDataAnalysisSolutionImpactValuesCalculator impactValuesCalculator)
     55      : base(impactValuesCalculator) {
     56      Parameters.Add(new LookupParameter<ISymbolicRegressionSingleObjectiveEvaluator>(EvaluatorParameterName));
    4957    }
    5058
    51     protected override ISymbolicDataAnalysisModel CreateModel() {
    52       return new SymbolicRegressionModel(SymbolicExpressionTree, Interpreter, EstimationLimits.Lower, EstimationLimits.Upper);
     59    [StorableHook(HookType.AfterDeserialization)]
     60    private void AfterDeserialization() {
     61      // BackwardsCompatibility3.3
     62      #region Backwards compatible code, remove with 3.4
     63      base.ImpactValuesCalculator = new SymbolicRegressionSolutionImpactValuesCalculator();
     64      if (!Parameters.ContainsKey(EvaluatorParameterName)) {
     65        Parameters.Add(new LookupParameter<ISymbolicRegressionSingleObjectiveEvaluator>(EvaluatorParameterName));
     66      }
     67      #endregion
     68    }
     69
     70    protected override ISymbolicDataAnalysisModel CreateModel(ISymbolicExpressionTree tree, ISymbolicDataAnalysisExpressionTreeInterpreter interpreter, IDataAnalysisProblemData problemData, DoubleLimit estimationLimits) {
     71      return new SymbolicRegressionModel(tree, interpreter, estimationLimits.Lower, estimationLimits.Upper);
    5372    }
    5473
    5574    protected override double Evaluate(IDataAnalysisModel model) {
    56       var regressionModel = (IRegressionModel)model;
    57       var regressionProblemData = (IRegressionProblemData)ProblemData;
    58       var trainingIndices = Enumerable.Range(FitnessCalculationPartition.Start, FitnessCalculationPartition.Size);
    59       var estimatedValues = regressionModel.GetEstimatedValues(ProblemData.Dataset, trainingIndices); // also bounds the values
    60       var targetValues = ProblemData.Dataset.GetDoubleValues(regressionProblemData.TargetVariable, trainingIndices);
    61       OnlineCalculatorError errorState;
    62       var quality = OnlinePearsonsRCalculator.Calculate(targetValues, estimatedValues, out errorState);
    63       if (errorState != OnlineCalculatorError.None) return double.NaN;
    64       return quality*quality;
     75      var regressionModel = (ISymbolicRegressionModel)model;
     76      var regressionProblemData = (IRegressionProblemData)ProblemDataParameter.ActualValue;
     77      var evaluator = EvaluatorParameter.ActualValue;
     78      var fitnessEvaluationPartition = FitnessCalculationPartitionParameter.ActualValue;
     79      var rows = Enumerable.Range(fitnessEvaluationPartition.Start, fitnessEvaluationPartition.Size);
     80      return evaluator.Evaluate(this.ExecutionContext, regressionModel.SymbolicExpressionTree, regressionProblemData, rows);
     81    }
     82
     83    public static ISymbolicExpressionTree Prune(ISymbolicExpressionTree tree, SymbolicRegressionSolutionImpactValuesCalculator impactValuesCalculator, ISymbolicDataAnalysisExpressionTreeInterpreter interpreter, IRegressionProblemData problemData, DoubleLimit estimationLimits, IEnumerable<int> rows, double nodeImpactThreshold = 0.0, bool pruneOnlyZeroImpactNodes = false) {
     84      var clonedTree = (ISymbolicExpressionTree)tree.Clone();
     85      var model = new SymbolicRegressionModel(clonedTree, interpreter, estimationLimits.Lower, estimationLimits.Upper);
     86      var nodes = clonedTree.Root.GetSubtree(0).GetSubtree(0).IterateNodesPrefix().ToList(); // skip the nodes corresponding to the ProgramRootSymbol and the StartSymbol
     87
     88      double qualityForImpactsCalculation = double.NaN; // pass a NaN value initially so the impact calculator will calculate the quality
     89
     90      for (int i = 0; i < nodes.Count; ++i) {
     91        var node = nodes[i];
     92        if (node is ConstantTreeNode) continue;
     93
     94        double impactValue, replacementValue;
     95        double newQualityForImpactsCalculation;
     96        impactValuesCalculator.CalculateImpactAndReplacementValues(model, node, problemData, rows, out impactValue, out replacementValue, out newQualityForImpactsCalculation, qualityForImpactsCalculation);
     97
     98        if (pruneOnlyZeroImpactNodes && !impactValue.IsAlmost(0.0)) continue;
     99        if (!pruneOnlyZeroImpactNodes && impactValue > nodeImpactThreshold) continue;
     100
     101        var constantNode = (ConstantTreeNode)node.Grammar.GetSymbol("Constant").CreateTreeNode();
     102        constantNode.Value = replacementValue;
     103
     104        ReplaceWithConstant(node, constantNode);
     105        i += node.GetLength() - 1; // skip subtrees under the node that was folded
     106
     107        qualityForImpactsCalculation = newQualityForImpactsCalculation;
     108      }
     109      return model.SymbolicExpressionTree;
    65110    }
    66111  }
  • stable/HeuristicLab.Problems.DataAnalysis.Symbolic.Regression/3.4/SymbolicRegressionSolutionImpactValuesCalculator.cs

    r12669 r12745  
    4848    }
    4949
    50     public override double CalculateImpactValue(ISymbolicDataAnalysisModel model, ISymbolicExpressionTreeNode node, IDataAnalysisProblemData problemData, IEnumerable<int> rows, double originalQuality = double.NaN) {
    51       double impactValue, replacementValue;
    52       CalculateImpactAndReplacementValues(model, node, problemData, rows, out impactValue, out replacementValue, originalQuality);
     50    public override double CalculateImpactValue(ISymbolicDataAnalysisModel model, ISymbolicExpressionTreeNode node, IDataAnalysisProblemData problemData, IEnumerable<int> rows, double qualityForImpactsCalculation = double.NaN) {
     51      double impactValue, replacementValue, newQualityForImpactsCalculation;
     52      CalculateImpactAndReplacementValues(model, node, problemData, rows, out impactValue, out replacementValue, out newQualityForImpactsCalculation, qualityForImpactsCalculation);
    5353      return impactValue;
    5454    }
    5555
    5656    public override void CalculateImpactAndReplacementValues(ISymbolicDataAnalysisModel model, ISymbolicExpressionTreeNode node,
    57       IDataAnalysisProblemData problemData, IEnumerable<int> rows, out double impactValue, out double replacementValue,
    58       double originalQuality = Double.NaN) {
     57      IDataAnalysisProblemData problemData, IEnumerable<int> rows, out double impactValue, out double replacementValue, out double newQualityForImpactsCalculation,
     58      double qualityForImpactsCalculation = Double.NaN) {
    5959      var regressionModel = (ISymbolicRegressionModel)model;
    6060      var regressionProblemData = (IRegressionProblemData)problemData;
     
    6464
    6565      OnlineCalculatorError errorState;
    66       if (double.IsNaN(originalQuality)) {
    67         var originalValues = regressionModel.GetEstimatedValues(dataset, rows);
    68         originalQuality = OnlinePearsonsRCalculator.Calculate(targetValues, originalValues, out errorState);
    69         if (errorState != OnlineCalculatorError.None) originalQuality = 0.0;
    70       }
     66      if (double.IsNaN(qualityForImpactsCalculation))
     67        qualityForImpactsCalculation = CalculateQualityForImpacts(regressionModel, regressionProblemData, rows);
    7168
    7269      replacementValue = CalculateReplacementValue(regressionModel, node, regressionProblemData, rows);
     
    8380
    8481      var estimatedValues = tempModel.GetEstimatedValues(dataset, rows);
    85       double newQuality = OnlinePearsonsRCalculator.Calculate(targetValues, estimatedValues, out errorState);
    86       if (errorState != OnlineCalculatorError.None) newQuality = 0.0;
     82      double r = OnlinePearsonsRCalculator.Calculate(targetValues, estimatedValues, out errorState);
     83      if (errorState != OnlineCalculatorError.None) r = 0.0;
     84      newQualityForImpactsCalculation = r * r;
    8785
    88       impactValue = (originalQuality*originalQuality) - (newQuality*newQuality);
     86      impactValue = qualityForImpactsCalculation - newQualityForImpactsCalculation;
     87    }
     88
     89    public static double CalculateQualityForImpacts(ISymbolicRegressionModel model, IRegressionProblemData problemData, IEnumerable<int> rows) {
     90      var estimatedValues = model.GetEstimatedValues(problemData.Dataset, rows); // also bounds the values
     91      var targetValues = problemData.Dataset.GetDoubleValues(problemData.TargetVariable, rows);
     92      OnlineCalculatorError errorState;
     93      var r = OnlinePearsonsRCalculator.Calculate(targetValues, estimatedValues, out errorState);
     94      var quality = r * r;
     95      if (errorState != OnlineCalculatorError.None) return double.NaN;
     96      return quality;
    8997    }
    9098  }
Note: See TracChangeset for help on using the changeset viewer.