Free cookie consent management tool by TermsFeed Policy Generator

Ignore:
Timestamp:
08/06/18 16:54:14 (6 years ago)
Author:
bburlacu
Message:

#2886: Refactor RSquaredEvaluator as a standalone ParameterizedNamedItem which is a parameter of the algorithm. Implement BestSolutionAnalyzer analyzer for quality statistics. Add license headers where missing.

File:
1 moved

Legend:

Unmodified
Added
Removed
  • branches/2886_SymRegGrammarEnumeration/HeuristicLab.Algorithms.DataAnalysis.SymRegGrammarEnumeration/GrammarEnumeration/RSquaredEvaluator.cs

    r16052 r16053  
    1 using System;
    2 using System.Diagnostics;
    3 using HeuristicLab.Analysis;
     1#region License Information
     2/* HeuristicLab
     3 * Copyright (C) 2002-2018 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
    422using HeuristicLab.Common;
    523using HeuristicLab.Core;
    624using HeuristicLab.Data;
    725using HeuristicLab.Encodings.SymbolicExpressionTreeEncoding;
     26using HeuristicLab.Parameters;
    827using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
    928using HeuristicLab.Problems.DataAnalysis;
     
    1433  [Item("RSquaredEvaluator", "")]
    1534  [StorableClass]
    16   public class RSquaredEvaluator : Item, IGrammarEnumerationAnalyzer {
    17     public static readonly string BestTrainingQualityResultName = "Best R² (Training)";
    18     public static readonly string BestTestQualityResultName = "Best R² (Test)";
    19     public static readonly string BestTrainingModelResultName = "Best model (Training)";
    20     public static readonly string BestTrainingSolutionResultName = "Best solution (Training)";
    21     public static readonly string BestComplexityResultName = "Best solution complexity";
    22     public static readonly string BestSolutions = "Best solutions";
     35  public class RSquaredEvaluator : ParameterizedNamedItem, IGrammarEnumerationEvaluator {
     36    private readonly string OptimizeConstantsParameterName = "Optimize Constants";
     37    private readonly string ApplyLinearScalingParameterName = "Apply Linear Scaling";
     38    private readonly string ConstantOptimizationIterationsParameterName = "Constant Optimization Iterations";
     39
     40    #region parameter properties
     41    public IFixedValueParameter<BoolValue> OptimizeConstantsParameter {
     42      get { return (IFixedValueParameter<BoolValue>)Parameters[OptimizeConstantsParameterName]; }
     43    }
     44
     45    public IFixedValueParameter<BoolValue> ApplyLinearScalingParameter {
     46      get { return (IFixedValueParameter<BoolValue>)Parameters[ApplyLinearScalingParameterName]; }
     47    }
     48
     49    public IFixedValueParameter<IntValue> ConstantOptimizationIterationsParameter {
     50      get { return (IFixedValueParameter<IntValue>)Parameters[ConstantOptimizationIterationsParameterName]; }
     51    }
     52
     53    public bool OptimizeConstants {
     54      get { return OptimizeConstantsParameter.Value.Value; }
     55      set { OptimizeConstantsParameter.Value.Value = value; }
     56    }
     57
     58    public bool ApplyLinearScaling {
     59      get { return ApplyLinearScalingParameter.Value.Value; }
     60      set { ApplyLinearScalingParameter.Value.Value = value; }
     61    }
     62
     63    public int ConstantOptimizationIterations {
     64      get { return ConstantOptimizationIterationsParameter.Value.Value; }
     65      set { ConstantOptimizationIterationsParameter.Value.Value = value; }
     66    }
     67    #endregion
    2368
    2469    private static readonly ISymbolicDataAnalysisExpressionTreeInterpreter expressionTreeLinearInterpreter = new SymbolicDataAnalysisExpressionTreeLinearInterpreter();
    2570
    26     public RSquaredEvaluator() { }
     71    public RSquaredEvaluator() {
     72      Parameters.Add(new FixedValueParameter<BoolValue>(OptimizeConstantsParameterName, "Run constant optimization in sentence evaluation.", new BoolValue(false)));
     73      Parameters.Add(new FixedValueParameter<BoolValue>(ApplyLinearScalingParameterName, "Apply linear scaling on the tree model during evaluation.", new BoolValue(false)));
     74      Parameters.Add(new FixedValueParameter<IntValue>(ConstantOptimizationIterationsParameterName, new IntValue(10)));
     75    }
    2776
    2877    [StorableConstructor]
     
    3685    }
    3786
    38     public void Register(GrammarEnumerationAlgorithm algorithm) {
    39       algorithm.Started += OnStarted;
    40       algorithm.Stopped += OnStopped;
    41       algorithm.DistinctSentenceGenerated += AlgorithmOnDistinctSentenceGenerated;
     87    public double Evaluate(IRegressionProblemData problemData, Grammar grammar, SymbolList sentence) {
     88      var tree = grammar.ParseSymbolicExpressionTree(sentence);
     89      return Evaluate(problemData, tree, OptimizeConstants, ConstantOptimizationIterations, ApplyLinearScaling);
    4290    }
    4391
    44     public void Deregister(GrammarEnumerationAlgorithm algorithm) {
    45       algorithm.Started -= OnStarted;
    46       algorithm.Stopped -= OnStopped;
    47       algorithm.DistinctSentenceGenerated -= AlgorithmOnDistinctSentenceGenerated;
     92    public double Evaluate(IRegressionProblemData problemData, ISymbolicExpressionTree tree) {
     93      return Evaluate(problemData, tree, OptimizeConstants, ConstantOptimizationIterations, ApplyLinearScaling);
    4894    }
    4995
    50     private void AlgorithmOnDistinctSentenceGenerated(object sender, PhraseAddedEventArgs phraseAddedEventArgs) {
    51       GrammarEnumerationAlgorithm algorithm = (GrammarEnumerationAlgorithm)sender;
    52       EvaluateSentence(algorithm, phraseAddedEventArgs.NewPhrase, algorithm.OptimizeConstants, algorithm.ConstantOptimizationIterations);
    53     }
    54 
    55     private void OnStarted(object sender, EventArgs eventArgs) {
    56       GrammarEnumerationAlgorithm algorithm = (GrammarEnumerationAlgorithm)sender;
    57 
    58       algorithm.BestTrainingSentence = null;
    59     }
    60 
    61     private void OnStopped(object sender, EventArgs eventArgs) { }
    62 
    63     private T GetValue<T>(IItem value) where T : struct {
    64       var v = value as ValueTypeValue<T>;
    65       if (v == null)
    66         throw new ArgumentException(string.Format("Item is not of type {0}", typeof(ValueTypeValue<T>)));
    67       return v.Value;
    68     }
    69 
    70     private void EvaluateSentence(GrammarEnumerationAlgorithm algorithm, SymbolList sentence, bool optimizeConstants, int maxIterations) {
    71       var results = algorithm.Results;
    72       var grammar = algorithm.Grammar;
    73       var problemData = algorithm.Problem.ProblemData;
    74 
    75       SymbolicExpressionTree tree = algorithm.Grammar.ParseSymbolicExpressionTree(sentence);
    76       Debug.Assert(SymbolicRegressionConstantOptimizationEvaluator.CanOptimizeConstants(tree));
    77 
    78       double r2 = Evaluate(problemData, tree, optimizeConstants, maxIterations);
    79       double bestR2 = results.ContainsKey(BestTrainingQualityResultName) ? GetValue<double>(results[BestTrainingQualityResultName].Value) : 0.0;
    80       if (r2 < bestR2)
    81         return;
    82 
    83       var bestComplexity = results.ContainsKey(BestComplexityResultName) ? GetValue<int>(results[BestComplexityResultName].Value) : int.MaxValue;
    84       var complexity = sentence.Complexity;
    85 
    86       if (algorithm.BestTrainingSentence == null || r2 > bestR2 || (r2.IsAlmost(bestR2) && complexity < bestComplexity)) {
    87         algorithm.BestTrainingSentence = sentence;
    88 
    89         var model = new SymbolicRegressionModel(problemData.TargetVariable, tree, expressionTreeLinearInterpreter);
    90         model.Scale(problemData);
    91         var bestSolution = model.CreateRegressionSolution(problemData);
    92 
    93         results.AddOrUpdateResult(BestTrainingQualityResultName, new DoubleValue(bestSolution.TrainingRSquared));
    94         results.AddOrUpdateResult(BestTestQualityResultName, new DoubleValue(bestSolution.TestRSquared));
    95         results.AddOrUpdateResult(BestTrainingModelResultName, bestSolution.Model);
    96         results.AddOrUpdateResult(BestTrainingSolutionResultName, bestSolution);
    97         results.AddOrUpdateResult(BestComplexityResultName, new IntValue(complexity));
    98 
    99         // record best sentence quality & length
    100         DataTable dt;
    101         if (!results.ContainsKey(BestSolutions)) {
    102           var names = new[] { "Quality", "Relative Length", "Complexity", "Timestamp" };
    103           dt = new DataTable();
    104           foreach (var name in names) {
    105             dt.Rows.Add(new DataRow(name) { VisualProperties = { StartIndexZero = true } });
    106           }
    107           results.AddOrUpdateResult(BestSolutions, dt);
    108         }
    109         dt = (DataTable)results[BestSolutions].Value;
    110         dt.Rows["Quality"].Values.Add(r2);
    111         dt.Rows["Relative Length"].Values.Add((double)sentence.Count);
    112         dt.Rows["Complexity"].Values.Add(complexity);
    113         dt.Rows["Timestamp"].Values.Add(algorithm.ExecutionTime.TotalMilliseconds / 1000d);
    114       }
    115     }
    116 
    117     public static double Evaluate(IRegressionProblemData problemData, SymbolicExpressionTree tree, bool optimizeConstants = true, int maxIterations = 10) {
     96    public static double Evaluate(IRegressionProblemData problemData, ISymbolicExpressionTree tree, bool optimizeConstants = true, int maxIterations = 10, bool applyLinearScaling = false) {
    11897      double r2;
    11998
     
    125104          problemData,
    126105          problemData.TrainingIndices,
    127           applyLinearScaling: true,
     106          applyLinearScaling: applyLinearScaling,
    128107          maxIterations: maxIterations,
    129108          updateVariableWeights: false,
     
    143122          problemData,
    144123          problemData.TrainingIndices,
    145           applyLinearScaling: true);
     124          applyLinearScaling: applyLinearScaling);
    146125      }
    147126      return double.IsNaN(r2) ? 0.0 : r2;
Note: See TracChangeset for help on using the changeset viewer.