Free cookie consent management tool by TermsFeed Policy Generator

source: branches/3136_Structural_GP/HeuristicLab.Problems.DataAnalysis.Symbolic.Regression/3.4/SingleObjective/StructuredSymbolicRegressionSingleObjectiveProblem.cs @ 18066

Last change on this file since 18066 was 18066, checked in by dpiringe, 3 years ago

#3136

  • added a simple way of evaluation (using r2 evaluator)
  • added a simple analyzing logic for "Best Tree"
  • added a connection to SubFunction in SubFunctionTreeNode
File size: 7.4 KB
Line 
1using System;
2using System.Collections.Generic;
3using System.Linq;
4using System.Text;
5using System.Threading.Tasks;
6using HeuristicLab.Core;
7using HeuristicLab.Optimization;
8using HEAL.Attic;
9using HeuristicLab.Common;
10using HeuristicLab.Problems.Instances;
11using HeuristicLab.Parameters;
12using HeuristicLab.Data;
13using HeuristicLab.Encodings.SymbolicExpressionTreeEncoding;
14
15namespace HeuristicLab.Problems.DataAnalysis.Symbolic.Regression {
16  [StorableType("7464E84B-65CC-440A-91F0-9FA920D730F9")]
17  [Item(Name = "Structured Symbolic Regression Single Objective Problem (single-objective)", Description = "A problem with a structural definition and unfixed subfunctions.")]
18  [Creatable(CreatableAttribute.Categories.GeneticProgrammingProblems, Priority = 150)]
19  public class StructuredSymbolicRegressionSingleObjectiveProblem : SingleObjectiveBasicProblem<MultiEncoding>, IRegressionProblem, IProblemInstanceConsumer<RegressionProblemData> {
20
21    #region Constants
22    private const string ProblemDataParameterName = "ProblemData";
23    private const string StructureDefinitionParameterName = "Structure Definition";
24    private const string GrammarParameterName = "Grammar";
25    private const string StructureTemplateParameterName = "Structure Template";
26    #endregion
27
28    #region Parameter
29    public IValueParameter<IRegressionProblemData> ProblemDataParameter => (IValueParameter<IRegressionProblemData>)Parameters[ProblemDataParameterName];
30    public IFixedValueParameter<StringValue> StructureDefinitionParameter => (IFixedValueParameter<StringValue>)Parameters[StructureDefinitionParameterName];
31    public IFixedValueParameter<StructureTemplate> StructureTemplateParameter => (IFixedValueParameter<StructureTemplate>)Parameters[StructureTemplateParameterName];
32    public IValueParameter<ISymbolicDataAnalysisGrammar> GrammarParameter => (IValueParameter<ISymbolicDataAnalysisGrammar>)Parameters[GrammarParameterName];
33    #endregion
34
35    #region Properties
36    public IRegressionProblemData ProblemData {
37      get => ProblemDataParameter.Value;
38      set {
39        ProblemDataParameter.Value = value;
40        ProblemDataChanged?.Invoke(this, EventArgs.Empty);
41      }
42    }
43
44    public string StructureDefinition {
45      get => StructureDefinitionParameter.Value.Value;
46      set => StructureDefinitionParameter.Value.Value = value;
47    }
48
49    public StructureTemplate StructureTemplate {
50      get => StructureTemplateParameter.Value;
51    }
52
53    public ISymbolicDataAnalysisGrammar Grammar {
54      get => GrammarParameter.Value;
55      set => GrammarParameter.Value = value;
56    }
57
58    IParameter IDataAnalysisProblem.ProblemDataParameter => ProblemDataParameter;
59    IDataAnalysisProblemData IDataAnalysisProblem.ProblemData => ProblemData;
60
61    public override bool Maximization => true;
62    #endregion
63
64    #region EventHandlers
65    public event EventHandler ProblemDataChanged;
66    #endregion
67
68    #region Constructors & Cloning
69    public StructuredSymbolicRegressionSingleObjectiveProblem() {
70      var problemData = new ShapeConstrainedRegressionProblemData();
71      var grammar = new LinearScalingGrammar();
72      var varSym = (Variable)grammar.GetSymbol("Variable");
73      varSym.AllVariableNames = problemData.InputVariables.Select(x => x.Value);
74      varSym.VariableNames = problemData.InputVariables.Select(x => x.Value);
75      varSym.Enabled = true;
76
77      var structureTemplate = new StructureTemplate();
78      structureTemplate.Changed += OnTemplateChanged;
79
80      Parameters.Add(new ValueParameter<IRegressionProblemData>(ProblemDataParameterName, problemData));
81      Parameters.Add(new FixedValueParameter<StructureTemplate>(StructureTemplateParameterName, structureTemplate));
82      Parameters.Add(new ValueParameter<ISymbolicDataAnalysisGrammar>(GrammarParameterName, grammar));
83
84      structureTemplate.Template = "f(x)*f(y)+5";
85    }
86
87    public StructuredSymbolicRegressionSingleObjectiveProblem(StructuredSymbolicRegressionSingleObjectiveProblem original, Cloner cloner) { }
88
89    [StorableConstructor]
90    protected StructuredSymbolicRegressionSingleObjectiveProblem(StorableConstructorFlag _) : base(_) { }
91    #endregion
92
93    #region Cloning
94    public override IDeepCloneable Clone(Cloner cloner) =>
95      new StructuredSymbolicRegressionSingleObjectiveProblem(this, cloner);
96    #endregion
97
98    private void OnTemplateChanged(object sender, EventArgs args) {
99      foreach (var e in Encoding.Encodings.ToArray())
100        Encoding.Remove(e);
101
102      foreach (var sf in StructureTemplate.SubFunctions.Values) {
103        Encoding.Add(new SymbolicExpressionTreeEncoding(sf.Name, sf.Grammar, sf.MaximumSymbolicExpressionTreeLength, sf.MaximumSymbolicExpressionTreeDepth));
104      }
105    }
106
107    public override void Analyze(Individual[] individuals, double[] qualities, ResultCollection results, IRandom random) {
108      base.Analyze(individuals, qualities, results, random);
109
110      int bestIdx = 0;
111      double bestQuality = Maximization ? double.MinValue : double.MaxValue;
112      for(int idx = 0; idx < qualities.Length; ++idx) {
113        if((Maximization && qualities[idx] > bestQuality) ||
114          (!Maximization && qualities[idx] < bestQuality)) {
115          bestQuality = qualities[idx];
116          bestIdx = idx;
117        }
118      }
119
120      if (results.TryGetValue("Best Tree", out IResult result))
121        result.Value = BuildTree(individuals[bestIdx]);
122      else
123        results.Add(new Result("Best Tree", BuildTree(individuals[bestIdx])));
124
125      /*
126      if (results.TryGetValue("Tree", out IResult result)) {
127        var list = result.Value as ItemList<ISymbolicExpressionTree>;
128        list.Clear();
129        list.AddRange(individuals.Select(x => (BuildTree(x))));
130      } else
131        results.Add(new Result("Tree", new ItemList<ISymbolicExpressionTree>(individuals.Select(x => (BuildTree(x))))));
132      */
133    }
134
135    public override double Evaluate(Individual individual, IRandom random) {
136      var tree = BuildTree(individual);
137      var interpreter = new SymbolicDataAnalysisExpressionTreeInterpreter();
138      var estimationInterval = ProblemData.VariableRanges.GetInterval(ProblemData.TargetVariable);
139      var quality = SymbolicRegressionSingleObjectivePearsonRSquaredEvaluator.Calculate(
140        interpreter, tree,
141        estimationInterval.LowerBound, estimationInterval.UpperBound,
142        ProblemData, ProblemData.TrainingIndices, false);
143     
144      return quality;
145    }
146
147    private ISymbolicExpressionTree BuildTree(Individual individual) {
148      var templateTree = (ISymbolicExpressionTree)StructureTemplate.Tree.Clone();
149
150      // build main tree
151      foreach (var n in templateTree.IterateNodesPrefix()) {
152        if (n.Symbol is SubFunctionSymbol) {
153          var subFunctionTreeNode = n as SubFunctionTreeNode;
154          var subFunctionTree = individual.SymbolicExpressionTree(subFunctionTreeNode.SubFunction.Name);
155          var parent = n.Parent;
156
157          // remove SubFunctionTreeNode
158          parent.RemoveSubtree(parent.IndexOfSubtree(subFunctionTreeNode));
159
160          // add new tree
161          var subTree = subFunctionTree.Root.GetSubtree(0)  // Start
162                                            .GetSubtree(0); // Offset
163          parent.AddSubtree(subTree);
164        }
165      }
166      return templateTree;
167    }
168
169    public void Load(RegressionProblemData data) {
170      ProblemData = data;
171    }
172  }
173}
Note: See TracBrowser for help on using the repository browser.