Free cookie consent management tool by TermsFeed Policy Generator

Ignore:
Timestamp:
04/21/10 15:21:34 (14 years ago)
Author:
gkronber
Message:

Refactored symbolic expression tree encoding and problem classes for symbolic regression. #937 , #938

Location:
trunk/sources/HeuristicLab.Problems.DataAnalysis.Regression/3.3/Symbolic
Files:
6 edited

Legend:

Unmodified
Added
Removed
  • trunk/sources/HeuristicLab.Problems.DataAnalysis.Regression/3.3/Symbolic/BestValidationSymbolicRegressionSolutionVisualizer.cs

    r3452 r3462  
    3939  [StorableClass]
    4040  public sealed class BestValidationSymbolicRegressionSolutionVisualizer : SingleSuccessorOperator, ISingleObjectiveSolutionsVisualizer, ISolutionsVisualizer {
    41     private const string EvaluatorParameterName = "Evaluator";
     41    private const string SymbolicExpressionTreeInterpreterParameterName = "SymbolicExpressionTreeInterpreter";
    4242    private const string SymbolicRegressionModelParameterName = "SymbolicRegressionModel";
    4343    private const string DataAnalysisProblemDataParameterName = "DataAnalysisProblemData";
     
    4949
    5050    #region parameter properties
    51     public ILookupParameter<ISymbolicRegressionEvaluator> EvaluatorParameter {
    52       get { return (ILookupParameter<ISymbolicRegressionEvaluator>)Parameters[EvaluatorParameterName]; }
     51    public ILookupParameter<ISymbolicExpressionTreeInterpreter> SymbolicExpressionTreeInterpreterParameter {
     52      get { return (ILookupParameter<ISymbolicExpressionTreeInterpreter>)Parameters[SymbolicExpressionTreeInterpreterParameterName]; }
    5353    }
    5454    public IValueLookupParameter<IntValue> ValidationSamplesStartParameter {
     
    8282
    8383    #region properties
    84     public ISymbolicRegressionEvaluator Evaluator {
    85       get { return EvaluatorParameter.ActualValue; }
     84    public ISymbolicExpressionTreeInterpreter SymbolicExpressionTreeInterpreter {
     85      get { return SymbolicExpressionTreeInterpreterParameter.ActualValue; }
    8686    }
    8787    public IntValue ValidationSamplesStart {
     
    9898      Parameters.Add(new SubScopesLookupParameter<DoubleValue>(QualityParameterName, "The quality of the symbolic regression solutions."));
    9999      Parameters.Add(new LookupParameter<DataAnalysisProblemData>(DataAnalysisProblemDataParameterName, "The symbolic regression problme data on which the best solution should be evaluated."));
     100      Parameters.Add(new LookupParameter<ISymbolicExpressionTreeInterpreter>(SymbolicExpressionTreeInterpreterParameterName, "The interpreter that should be used to calculate the output values of symbolic expression trees."));
    100101      Parameters.Add(new ValueLookupParameter<IntValue>(ValidationSamplesStartParameterName, "The start index of the validation partition (part of the training partition)."));
    101102      Parameters.Add(new ValueLookupParameter<IntValue>(ValidationSamplesEndParameterName, "The end index of the validation partition (part of the training partition)."));
     
    113114
    114115      var currentBestExpression = (from expression in expressions
    115                                    let validationQuality = SymbolicRegressionMeanSquaredErrorEvaluator.Calculate(expression, problemData.Dataset, problemData.TargetVariable.Value, validationSamplesStart, validationSamplesEnd)
     116                                   let validationQuality =
     117                                     SymbolicRegressionMeanSquaredErrorEvaluator.Calculate(
     118                                       SymbolicExpressionTreeInterpreter, expression,
     119                                       problemData.Dataset, problemData.TargetVariable.Value,
     120                                       validationSamplesStart, validationSamplesEnd)
    116121                                   select new { Expression = expression, ValidationQuality = validationQuality })
    117122                                   .OrderBy(x => x.ValidationQuality)
     
    121126      if (bestOfRunSolution == null) {
    122127        // no best of run solution yet -> make a solution from the currentBestExpression
    123         UpdateBestOfRunSolution(problemData, currentBestExpression.Expression);
     128        UpdateBestOfRunSolution(problemData, currentBestExpression.Expression, SymbolicExpressionTreeInterpreter);
    124129      } else {
    125130        // compare quality of current best with best of run solution
     
    127132        var bestOfRunValidationQuality = SimpleMSEEvaluator.Calculate(validationValues, estimatedValidationValues);
    128133        if (bestOfRunValidationQuality > currentBestExpression.ValidationQuality) {
    129           UpdateBestOfRunSolution(problemData, currentBestExpression.Expression);
     134          UpdateBestOfRunSolution(problemData, currentBestExpression.Expression, SymbolicExpressionTreeInterpreter);
    130135        }
    131136      }
     
    135140    }
    136141
    137     private void UpdateBestOfRunSolution(DataAnalysisProblemData problemData, SymbolicExpressionTree tree) {
    138       var newBestSolution = CreateDataAnalysisSolution(problemData, tree);
    139       BestValidationSolutionParameter.ActualValue = newBestSolution;
     142    private void UpdateBestOfRunSolution(DataAnalysisProblemData problemData, SymbolicExpressionTree tree, ISymbolicExpressionTreeInterpreter interpreter) {
     143      var newBestSolution = CreateDataAnalysisSolution(problemData, tree, interpreter);
     144      if (BestValidationSolutionParameter.ActualValue == null)
     145        BestValidationSolutionParameter.ActualValue = newBestSolution;
     146      else
     147        // only update model
     148        BestValidationSolutionParameter.ActualValue.Model = newBestSolution.Model;
    140149
    141150      var trainingValues = problemData.Dataset.GetVariableValues(problemData.TargetVariable.Value, problemData.TrainingSamplesStart.Value, problemData.TrainingSamplesEnd.Value);
     
    160169    }
    161170
    162     private SymbolicRegressionModel CreateModel(DataAnalysisProblemData problemData, SymbolicExpressionTree expression) {
    163       return new SymbolicRegressionModel(expression, problemData.InputVariables.Select(x => x.Value));
    164     }
    165 
    166     private SymbolicRegressionSolution CreateDataAnalysisSolution(DataAnalysisProblemData problemData, SymbolicExpressionTree expression) {
    167       return new SymbolicRegressionSolution(problemData, CreateModel(problemData, expression));
     171    private SymbolicRegressionSolution CreateDataAnalysisSolution(DataAnalysisProblemData problemData, SymbolicExpressionTree expression, ISymbolicExpressionTreeInterpreter interpreter) {
     172      var model = new SymbolicRegressionModel(interpreter, expression, problemData.InputVariables.Select(s => s.Value));
     173      return new SymbolicRegressionSolution(problemData, model);
    168174    }
    169175  }
  • trunk/sources/HeuristicLab.Problems.DataAnalysis.Regression/3.3/Symbolic/SymbolicRegressionEvaluator.cs

    r3452 r3462  
    3434using HeuristicLab.Problems.DataAnalysis;
    3535using HeuristicLab.Operators;
     36using HeuristicLab.Problems.DataAnalysis.Symbolic;
    3637
    3738namespace HeuristicLab.Problems.DataAnalysis.Regression.Symbolic {
     
    4041  public abstract class SymbolicRegressionEvaluator : SingleSuccessorOperator, ISymbolicRegressionEvaluator {
    4142    private const string QualityParameterName = "Quality";
     43    private const string SymbolicExpressionTreeInterpreterParameterName = "SymbolicExpressionTreeInterpreter";
    4244    private const string FunctionTreeParameterName = "FunctionTree";
    4345    private const string RegressionProblemDataParameterName = "RegressionProblemData";
     
    4951    public ILookupParameter<DoubleValue> QualityParameter {
    5052      get { return (ILookupParameter<DoubleValue>)Parameters[QualityParameterName]; }
     53    }
     54
     55    public ILookupParameter<ISymbolicExpressionTreeInterpreter> SymbolicExpressionTreeInterpreterParameter {
     56      get { return (ILookupParameter<ISymbolicExpressionTreeInterpreter>)Parameters[SymbolicExpressionTreeInterpreterParameterName]; }
    5157    }
    5258
     
    7278    #endregion
    7379    #region properties
     80    public ISymbolicExpressionTreeInterpreter SymbolicExpressionTreeInterpreter {
     81      get { return SymbolicExpressionTreeInterpreterParameter.ActualValue; }
     82    }
    7483    public SymbolicExpressionTree SymbolicExpressionTree {
    7584      get { return SymbolicExpressionTreeParameter.ActualValue; }
     
    8998      : base() {
    9099      Parameters.Add(new LookupParameter<DoubleValue>(QualityParameterName, "The quality of the evaluated symbolic regression solution."));
     100      Parameters.Add(new LookupParameter<ISymbolicExpressionTreeInterpreter>(SymbolicExpressionTreeInterpreterParameterName, "The interpreter that should be used to calculate the output values of the symbolic expression tree."));
    91101      Parameters.Add(new LookupParameter<SymbolicExpressionTree>(FunctionTreeParameterName, "The symbolic regression solution encoded as a symbolic expression tree."));
    92102      Parameters.Add(new LookupParameter<DataAnalysisProblemData>(RegressionProblemDataParameterName, "The problem data on which the symbolic regression solution should be evaluated."));
     
    98108    public override IOperation Apply() {
    99109      DoubleValue numberOfEvaluatedNodes = NumberOfEvaluatedNodesParameter.ActualValue;
    100       QualityParameter.ActualValue = new DoubleValue(Evaluate(SymbolicExpressionTree, RegressionProblemData.Dataset,
     110      QualityParameter.ActualValue = new DoubleValue(Evaluate(SymbolicExpressionTreeInterpreter, SymbolicExpressionTree, RegressionProblemData.Dataset,
    101111        RegressionProblemData.TargetVariable, SamplesStart, SamplesEnd, numberOfEvaluatedNodes));
    102112      return null;
    103113    }
    104114
    105     protected abstract double Evaluate(SymbolicExpressionTree solution, Dataset dataset, StringValue targetVariable, IntValue samplesStart, IntValue samplesEnd, DoubleValue numberOfEvaluatedNodes);
     115    protected abstract double Evaluate(ISymbolicExpressionTreeInterpreter interpreter,
     116      SymbolicExpressionTree solution,
     117      Dataset dataset,
     118      StringValue targetVariable,
     119      IntValue samplesStart, IntValue samplesEnd,
     120      DoubleValue numberOfEvaluatedNodes);
    106121  }
    107122}
  • trunk/sources/HeuristicLab.Problems.DataAnalysis.Regression/3.3/Symbolic/SymbolicRegressionMeanSquaredErrorEvaluator.cs

    r3374 r3462  
    4141  [StorableClass]
    4242  public class SymbolicRegressionMeanSquaredErrorEvaluator : SymbolicRegressionEvaluator {
    43     protected override double Evaluate(SymbolicExpressionTree solution, Dataset dataset, StringValue targetVariable, IntValue samplesStart, IntValue samplesEnd, DoubleValue numberOfEvaluatedNodes) {
    44       double mse = Calculate(solution, dataset, targetVariable.Value, samplesStart.Value, samplesEnd.Value);
     43    protected override double Evaluate(ISymbolicExpressionTreeInterpreter interpreter, SymbolicExpressionTree solution, Dataset dataset, StringValue targetVariable, IntValue samplesStart, IntValue samplesEnd, DoubleValue numberOfEvaluatedNodes) {
     44      double mse = Calculate(interpreter, solution, dataset, targetVariable.Value, samplesStart.Value, samplesEnd.Value);
    4545      numberOfEvaluatedNodes.Value += solution.Size * (samplesEnd.Value - samplesStart.Value);
    4646      return mse;
    4747    }
    4848
    49     public static double Calculate(SymbolicExpressionTree solution, Dataset dataset, string targetVariable, int start, int end) {
    50       SimpleArithmeticExpressionEvaluator evaluator = new SimpleArithmeticExpressionEvaluator();
     49    public static double Calculate(ISymbolicExpressionTreeInterpreter interpreter, SymbolicExpressionTree solution, Dataset dataset, string targetVariable, int start, int end) {
    5150      int targetVariableIndex = dataset.GetVariableIndex(targetVariable);
    52       var estimatedValues = evaluator.EstimatedValues(solution, dataset, Enumerable.Range(start, end - start));
     51      var estimatedValues = interpreter.GetSymbolicExpressionTreeValues(solution, dataset, Enumerable.Range(start, end - start));
    5352      var originalValues = from row in Enumerable.Range(start, end - start) select dataset[row, targetVariableIndex];
    5453      return SimpleMSEEvaluator.Calculate(originalValues, estimatedValues);
  • trunk/sources/HeuristicLab.Problems.DataAnalysis.Regression/3.3/Symbolic/SymbolicRegressionModel.cs

    r3442 r3462  
    3838namespace HeuristicLab.Problems.DataAnalysis.Regression.Symbolic {
    3939  [StorableClass]
    40   public class SymbolicRegressionModel : DeepCloneable, IModel {
     40  [Item("SymbolicRegressionModel", "A symbolic regression model represents an entity that provides estimated values based on input values.")]
     41  public class SymbolicRegressionModel : Item {
    4142    [Storable]
    4243    private SymbolicExpressionTree tree;
     
    4546    }
    4647    [Storable]
    47     private SimpleArithmeticExpressionEvaluator evaluator;
    48     public SimpleArithmeticExpressionEvaluator Evaluator {
    49       get { return evaluator; }
     48    private ISymbolicExpressionTreeInterpreter interpreter;
     49    public ISymbolicExpressionTreeInterpreter Interpreter {
     50      get { return interpreter; }
    5051    }
    51     private Dataset emptyDataset;
    52     private IEnumerable<int> firstRow = new int[] { 0 };
     52    [Storable]
     53    private List<string> inputVariables;
     54    public IEnumerable<string> InputVariables {
     55      get { return inputVariables.AsEnumerable(); }
     56    }
    5357
    5458    public SymbolicRegressionModel() : base() { } // for cloning
    5559
    56     public SymbolicRegressionModel(SymbolicExpressionTree tree, IEnumerable<string> inputVariables)
     60    public SymbolicRegressionModel(ISymbolicExpressionTreeInterpreter interpreter, SymbolicExpressionTree tree, IEnumerable<string> inputVariables)
    5761      : base() {
    5862      this.tree = tree;
    59       this.evaluator = new SimpleArithmeticExpressionEvaluator();
    60       emptyDataset = new Dataset(inputVariables, new double[1, inputVariables.Count()]);
     63      this.interpreter = interpreter;
     64      this.inputVariables = inputVariables.ToList();
    6165    }
    6266
    63     #region IModel Members
    64 
    65     public double GetValue(double[] xs) {
    66       if (xs.Length != emptyDataset.Columns) throw new ArgumentException("Length of input vector doesn't match model");
    67       for (int i = 0; i < xs.Length; i++) {
    68         emptyDataset[0, i] = xs[i];
    69       }
    70       return evaluator.EstimatedValues(tree, emptyDataset, firstRow).First();
     67    public IEnumerable<double> GetEstimatedValues(Dataset dataset, int start, int end) {
     68      return interpreter.GetSymbolicExpressionTreeValues(tree, dataset, Enumerable.Range(start, end - start));
    7169    }
    7270
    73     #endregion
     71    public override IDeepCloneable Clone(Cloner cloner) {
     72      var clone = (SymbolicRegressionModel)base.Clone(cloner);
     73      clone.tree = (SymbolicExpressionTree)tree.Clone(cloner);
     74      clone.interpreter = (ISymbolicExpressionTreeInterpreter)interpreter.Clone(cloner);
     75      clone.inputVariables = new List<string>(inputVariables);
     76      return clone;
     77    }
    7478  }
    7579}
  • trunk/sources/HeuristicLab.Problems.DataAnalysis.Regression/3.3/Symbolic/SymbolicRegressionProblem.cs

    r3452 r3462  
    3434using HeuristicLab.Problems.DataAnalysis.Regression;
    3535using HeuristicLab.Problems.DataAnalysis.Symbolic;
     36using HeuristicLab.Encodings.SymbolicExpressionTreeEncoding.ArchitectureAlteringOperators;
     37using HeuristicLab.Encodings.SymbolicExpressionTreeEncoding.Manipulators;
     38using HeuristicLab.Encodings.SymbolicExpressionTreeEncoding.Crossovers;
     39using HeuristicLab.Encodings.SymbolicExpressionTreeEncoding.Creators;
    3640
    3741namespace HeuristicLab.Problems.DataAnalysis.Regression.Symbolic {
     
    144148      var globalGrammar = new GlobalSymbolicExpressionGrammar(grammar);
    145149      var visualizer = new BestValidationSymbolicRegressionSolutionVisualizer();
     150      var interpreter = new SimpleArithmeticExpressionInterpreter();
    146151      Parameters.Add(new ValueParameter<BoolValue>("Maximization", "Set to false as the error of the regression model should be minimized.", new BoolValue(false)));
    147152      Parameters.Add(new ValueParameter<SymbolicExpressionTreeCreator>("SolutionCreator", "The operator which should be used to create new symbolic regression solutions.", creator));
     153      Parameters.Add(new ValueParameter<ISymbolicExpressionTreeInterpreter>("SymbolicExpressionTreeInterpreter", "The interpreter that should be used to evaluate the symbolic expression tree.", interpreter));
    148154      Parameters.Add(new ValueParameter<ISymbolicRegressionEvaluator>("Evaluator", "The operator which should be used to evaluate symbolic regression solutions.", evaluator));
    149155      Parameters.Add(new OptionalValueParameter<DoubleValue>("BestKnownQuality", "The minimal error value that reached by symbolic regression solutions for the problem."));
  • trunk/sources/HeuristicLab.Problems.DataAnalysis.Regression/3.3/Symbolic/SymbolicRegressionSolution.cs

    r3442 r3462  
    3636  [StorableClass]
    3737  public sealed class SymbolicRegressionSolution : DataAnalysisSolution {
    38     public new SymbolicRegressionModel Model {
    39       get { return (SymbolicRegressionModel)base.Model; }
    40       set { base.Model = value; }
     38    private SymbolicRegressionModel model;
     39    public SymbolicRegressionModel Model {
     40      get { return model; }
     41      set {
     42        if (model != value) {
     43          if (value == null) throw new ArgumentNullException();
     44          model = value;
     45          OnModelChanged(EventArgs.Empty);
     46        }
     47      }
    4148    }
    4249
    4350    public SymbolicRegressionSolution() : base() { }
    4451    public SymbolicRegressionSolution(DataAnalysisProblemData problemData, SymbolicRegressionModel model)
    45       : base(problemData, model) {
     52      : base(problemData) {
     53      this.model = model;
     54      RecalculateEstimatedValues();
     55    }
     56
     57    public event EventHandler ModelChanged;
     58    private void OnModelChanged(EventArgs e) {
     59      RecalculateEstimatedValues();
     60      var listeners = ModelChanged;
     61      if (listeners != null)
     62        listeners(this, e);
     63    }
     64
     65    protected override void OnProblemDataChanged(EventArgs e) {
     66      RecalculateEstimatedValues();
     67    }
     68
     69    private void RecalculateEstimatedValues() {
     70      estimatedValues = model.GetEstimatedValues(ProblemData.Dataset, 0, ProblemData.Dataset.Rows).ToList();
     71      OnEstimatedValuesChanged(EventArgs.Empty);
     72    }
     73
     74    private List<double> estimatedValues;
     75    public override IEnumerable<double> EstimatedValues {
     76      get {
     77        return estimatedValues.AsEnumerable();
     78      }
     79    }
     80
     81    public override IEnumerable<double> EstimatedTrainingValues {
     82      get {
     83        int start = ProblemData.TrainingSamplesStart.Value;
     84        int n = ProblemData.TrainingSamplesEnd.Value - start;
     85        return estimatedValues.Skip(start).Take(n).ToList();
     86      }
     87    }
     88
     89    public override IEnumerable<double> EstimatedTestValues {
     90      get {
     91        int start = ProblemData.TestSamplesStart.Value;
     92        int n = ProblemData.TestSamplesEnd.Value - start;
     93        return estimatedValues.Skip(start).Take(n).ToList();
     94      }
    4695    }
    4796  }
Note: See TracChangeset for help on using the changeset viewer.