Free cookie consent management tool by TermsFeed Policy Generator

source: trunk/sources/HeuristicLab.Problems.DataAnalysis.Regression/3.3/Symbolic/SymbolicRegressionProblem.cs @ 3545

Last change on this file since 3545 was 3545, checked in by gkronber, 14 years ago

Fixed bugs in wiring of data analysis and symbolic regression problems. #938 (Data types and operators for regression problems)

File size: 21.2 KB
Line 
1#region License Information
2/* HeuristicLab
3 * Copyright (C) 2002-2010 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
22using System;
23using System.Collections.Generic;
24using System.Linq;
25using System.Drawing;
26using HeuristicLab.Common;
27using HeuristicLab.Core;
28using HeuristicLab.Data;
29using HeuristicLab.Optimization;
30using HeuristicLab.Parameters;
31using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
32using HeuristicLab.PluginInfrastructure;
33using HeuristicLab.Encodings.SymbolicExpressionTreeEncoding;
34using HeuristicLab.Problems.DataAnalysis.Regression;
35using HeuristicLab.Problems.DataAnalysis.Symbolic;
36using HeuristicLab.Encodings.SymbolicExpressionTreeEncoding.ArchitectureManipulators;
37using HeuristicLab.Encodings.SymbolicExpressionTreeEncoding.Manipulators;
38using HeuristicLab.Encodings.SymbolicExpressionTreeEncoding.Crossovers;
39using HeuristicLab.Encodings.SymbolicExpressionTreeEncoding.Creators;
40using HeuristicLab.Encodings.SymbolicExpressionTreeEncoding.Interfaces;
41
42namespace HeuristicLab.Problems.DataAnalysis.Regression.Symbolic {
43  [Item("Symbolic Regression Problem", "Represents a symbolic regression problem.")]
44  [Creatable("Problems")]
45  [StorableClass]
46  public class SymbolicRegressionProblem : DataAnalysisProblem, ISingleObjectiveProblem {
47
48    #region Parameter Properties
49    public ValueParameter<BoolValue> MaximizationParameter {
50      get { return (ValueParameter<BoolValue>)Parameters["Maximization"]; }
51    }
52    IParameter ISingleObjectiveProblem.MaximizationParameter {
53      get { return MaximizationParameter; }
54    }
55    public ValueParameter<SymbolicExpressionTreeCreator> SolutionCreatorParameter {
56      get { return (ValueParameter<SymbolicExpressionTreeCreator>)Parameters["SolutionCreator"]; }
57    }
58    IParameter IProblem.SolutionCreatorParameter {
59      get { return SolutionCreatorParameter; }
60    }
61    public ValueParameter<DoubleValue> LowerEstimationLimitParameter {
62      get { return (ValueParameter<DoubleValue>)Parameters["LowerEstimationLimit"]; }
63    }
64    public ValueParameter<DoubleValue> UpperEstimationLimitParameter {
65      get { return (ValueParameter<DoubleValue>)Parameters["UpperEstimationLimit"]; }
66    }
67    public ValueParameter<ISymbolicExpressionTreeInterpreter> SymbolicExpressionTreeInterpreterParameter {
68      get { return (ValueParameter<ISymbolicExpressionTreeInterpreter>)Parameters["SymbolicExpressionTreeInterpreter"]; }
69    }
70    public ValueParameter<ISymbolicRegressionEvaluator> EvaluatorParameter {
71      get { return (ValueParameter<ISymbolicRegressionEvaluator>)Parameters["Evaluator"]; }
72    }
73    IParameter IProblem.EvaluatorParameter {
74      get { return EvaluatorParameter; }
75    }
76    public ValueParameter<ISymbolicExpressionGrammar> FunctionTreeGrammarParameter {
77      get { return (ValueParameter<ISymbolicExpressionGrammar>)Parameters["FunctionTreeGrammar"]; }
78    }
79    public ValueParameter<IntValue> MaxExpressionLengthParameter {
80      get { return (ValueParameter<IntValue>)Parameters["MaxExpressionLength"]; }
81    }
82    public ValueParameter<IntValue> MaxExpressionDepthParameter {
83      get { return (ValueParameter<IntValue>)Parameters["MaxExpressionDepth"]; }
84    }
85    public ValueParameter<IntValue> MaxFunctionDefiningBranchesParameter {
86      get { return (ValueParameter<IntValue>)Parameters["MaxFunctionDefiningBranches"]; }
87    }
88    public ValueParameter<IntValue> MaxFunctionArgumentsParameter {
89      get { return (ValueParameter<IntValue>)Parameters["MaxFunctionArguments"]; }
90    }
91    public OptionalValueParameter<ISingleObjectiveSolutionsVisualizer> VisualizerParameter {
92      get { return (OptionalValueParameter<ISingleObjectiveSolutionsVisualizer>)Parameters["Visualizer"]; }
93    }
94    IParameter IProblem.VisualizerParameter {
95      get { return VisualizerParameter; }
96    }
97    public OptionalValueParameter<DoubleValue> BestKnownQualityParameter {
98      get { return (OptionalValueParameter<DoubleValue>)Parameters["BestKnownQuality"]; }
99    }
100    IParameter ISingleObjectiveProblem.BestKnownQualityParameter {
101      get { return BestKnownQualityParameter; }
102    }
103    #endregion
104
105    #region Properties
106    public IntValue MaxExpressionLength {
107      get { return MaxExpressionLengthParameter.Value; }
108      set { MaxExpressionLengthParameter.Value = value; }
109    }
110    public IntValue MaxExpressionDepth {
111      get { return MaxExpressionDepthParameter.Value; }
112      set { MaxExpressionDepthParameter.Value = value; }
113    }
114    public IntValue MaxFunctionDefiningBranches {
115      get { return MaxFunctionDefiningBranchesParameter.Value; }
116      set { MaxFunctionDefiningBranchesParameter.Value = value; }
117    }
118    public IntValue MaxFunctionArguments {
119      get { return MaxFunctionArgumentsParameter.Value; }
120      set { MaxFunctionArgumentsParameter.Value = value; }
121    }
122    public SymbolicExpressionTreeCreator SolutionCreator {
123      get { return SolutionCreatorParameter.Value; }
124      set { SolutionCreatorParameter.Value = value; }
125    }
126    ISolutionCreator IProblem.SolutionCreator {
127      get { return SolutionCreatorParameter.Value; }
128    }
129    public ISymbolicExpressionTreeInterpreter SymbolicExpressionTreeInterpreter {
130      get { return SymbolicExpressionTreeInterpreterParameter.Value; }
131      set { SymbolicExpressionTreeInterpreterParameter.Value = value; }
132    }
133    public DoubleValue LowerEstimationLimit {
134      get { return LowerEstimationLimitParameter.Value; }
135      set { LowerEstimationLimitParameter.Value = value; }
136    }
137    public DoubleValue UpperEstimationLimit {
138      get { return UpperEstimationLimitParameter.Value; }
139      set { UpperEstimationLimitParameter.Value = value; }
140    }
141
142    public ISymbolicRegressionEvaluator Evaluator {
143      get { return EvaluatorParameter.Value; }
144      set { EvaluatorParameter.Value = value; }
145    }
146    ISingleObjectiveEvaluator ISingleObjectiveProblem.Evaluator {
147      get { return EvaluatorParameter.Value; }
148    }
149    IEvaluator IProblem.Evaluator {
150      get { return EvaluatorParameter.Value; }
151    }
152    public ISymbolicExpressionGrammar FunctionTreeGrammar {
153      get { return (ISymbolicExpressionGrammar)FunctionTreeGrammarParameter.Value; }
154    }
155    public ISingleObjectiveSolutionsVisualizer Visualizer {
156      get { return VisualizerParameter.Value; }
157      set { VisualizerParameter.Value = value; }
158    }
159    ISolutionsVisualizer IProblem.Visualizer {
160      get { return VisualizerParameter.Value; }
161    }
162    public DoubleValue BestKnownQuality {
163      get { return BestKnownQualityParameter.Value; }
164    }
165    private List<ISymbolicExpressionTreeOperator> operators;
166    public IEnumerable<IOperator> Operators {
167      get { return operators.Cast<IOperator>(); }
168    }
169    public DoubleValue PunishmentFactor {
170      get { return new DoubleValue(10.0); }
171    }
172    public IntValue TrainingSamplesStart {
173      get { return new IntValue(DataAnalysisProblemData.TrainingSamplesStart.Value); }
174    }
175    public IntValue TrainingSamplesEnd {
176      get {
177        return new IntValue((DataAnalysisProblemData.TrainingSamplesStart.Value +
178          DataAnalysisProblemData.TrainingSamplesEnd.Value) / 2);
179      }
180    }
181    public IntValue ValidationSamplesStart {
182      get { return TrainingSamplesEnd; }
183    }
184    public IntValue ValidationSamplesEnd {
185      get { return new IntValue(DataAnalysisProblemData.TrainingSamplesEnd.Value); }
186    }
187    #endregion
188
189    public SymbolicRegressionProblem()
190      : base() {
191      SymbolicExpressionTreeCreator creator = new ProbabilisticTreeCreator();
192      var evaluator = new SymbolicRegressionScaledMeanSquaredErrorEvaluator();
193      var grammar = new ArithmeticExpressionGrammar();
194      var globalGrammar = new GlobalSymbolicExpressionGrammar(grammar);
195      var visualizer = new BestValidationSymbolicRegressionSolutionVisualizer();
196      var interpreter = new SimpleArithmeticExpressionInterpreter();
197      Parameters.Add(new ValueParameter<BoolValue>("Maximization", "Set to false as the error of the regression model should be minimized.", (BoolValue)new BoolValue(false).AsReadOnly()));
198      Parameters.Add(new ValueParameter<SymbolicExpressionTreeCreator>("SolutionCreator", "The operator which should be used to create new symbolic regression solutions.", creator));
199      Parameters.Add(new ValueParameter<ISymbolicExpressionTreeInterpreter>("SymbolicExpressionTreeInterpreter", "The interpreter that should be used to evaluate the symbolic expression tree.", interpreter));
200      Parameters.Add(new ValueParameter<ISymbolicRegressionEvaluator>("Evaluator", "The operator which should be used to evaluate symbolic regression solutions.", evaluator));
201      Parameters.Add(new ValueParameter<DoubleValue>("LowerEstimationLimit", "The lower limit for the estimated value that can be returned by the symbolic regression model.", new DoubleValue(double.NegativeInfinity)));
202      Parameters.Add(new ValueParameter<DoubleValue>("UpperEstimationLimit", "The upper limit for the estimated value that can be returned by the symbolic regression model.", new DoubleValue(double.PositiveInfinity)));
203      Parameters.Add(new OptionalValueParameter<DoubleValue>("BestKnownQuality", "The minimal error value that reached by symbolic regression solutions for the problem."));
204      Parameters.Add(new ValueParameter<ISymbolicExpressionGrammar>("FunctionTreeGrammar", "The grammar that should be used for symbolic regression models.", globalGrammar));
205      Parameters.Add(new ValueParameter<IntValue>("MaxExpressionLength", "Maximal length of the symbolic expression.", new IntValue(100)));
206      Parameters.Add(new ValueParameter<IntValue>("MaxExpressionDepth", "Maximal depth of the symbolic expression.", new IntValue(10)));
207      Parameters.Add(new ValueParameter<IntValue>("MaxFunctionDefiningBranches", "Maximal number of automatically defined functions.", (IntValue)new IntValue(0).AsReadOnly()));
208      Parameters.Add(new ValueParameter<IntValue>("MaxFunctionArguments", "Maximal number of arguments of automatically defined functions.", (IntValue)new IntValue(0).AsReadOnly()));
209      Parameters.Add(new ValueParameter<ISingleObjectiveSolutionsVisualizer>("Visualizer", "The operator which should be used to visualize symbolic regression solutions.", visualizer));
210
211      creator.SymbolicExpressionTreeParameter.ActualName = "SymbolicRegressionModel";
212      evaluator.QualityParameter.ActualName = "TrainingMeanSquaredError";
213
214      ParameterizeSolutionCreator();
215      ParameterizeEvaluator();
216      ParameterizeVisualizer();
217
218      UpdateGrammar();
219      UpdateEstimationLimits();
220      Initialize();
221    }
222
223    [StorableConstructor]
224    private SymbolicRegressionProblem(bool deserializing) : base() { }
225
226    [StorableHook(HookType.AfterDeserialization)]
227    private void AfterDeserializationHook() {
228      Initialize();
229    }
230
231    public override IDeepCloneable Clone(Cloner cloner) {
232      SymbolicRegressionProblem clone = (SymbolicRegressionProblem)base.Clone(cloner);
233      clone.Initialize();
234      return clone;
235    }
236
237    private void RegisterParameterValueEvents() {
238      MaxFunctionArgumentsParameter.ValueChanged += new EventHandler(ArchitectureParameter_ValueChanged);
239      MaxFunctionDefiningBranchesParameter.ValueChanged += new EventHandler(ArchitectureParameter_ValueChanged);
240      SolutionCreatorParameter.ValueChanged += new EventHandler(SolutionCreatorParameter_ValueChanged);
241      EvaluatorParameter.ValueChanged += new EventHandler(EvaluatorParameter_ValueChanged);
242      VisualizerParameter.ValueChanged += new EventHandler(VisualizerParameter_ValueChanged);
243    }
244
245    private void RegisterParameterEvents() {
246      MaxFunctionArgumentsParameter.Value.ValueChanged += new EventHandler(ArchitectureParameter_ValueChanged);
247      MaxFunctionDefiningBranchesParameter.Value.ValueChanged += new EventHandler(ArchitectureParameter_ValueChanged);
248      SolutionCreator.SymbolicExpressionTreeParameter.ActualNameChanged += new EventHandler(SolutionCreator_SymbolicExpressionTreeParameter_ActualNameChanged);
249      Evaluator.QualityParameter.ActualNameChanged += new EventHandler(Evaluator_QualityParameter_ActualNameChanged);
250    }
251
252    #region event handling
253    protected override void OnDataAnalysisProblemChanged(EventArgs e) {
254      base.OnDataAnalysisProblemChanged(e);
255      // paritions could be changed
256      ParameterizeEvaluator();
257      ParameterizeVisualizer();
258      // input variables could have been changed
259      UpdateGrammar();
260      // estimation limits have to be recalculated
261      UpdateEstimationLimits();
262    }
263    protected virtual void OnArchitectureParameterChanged(EventArgs e) {
264      var globalGrammar = FunctionTreeGrammar as GlobalSymbolicExpressionGrammar;
265      if (globalGrammar != null) {
266        globalGrammar.MaxFunctionArguments = MaxFunctionArguments.Value;
267        globalGrammar.MaxFunctionDefinitions = MaxFunctionDefiningBranches.Value;
268      }
269    }
270    protected virtual void OnGrammarChanged(EventArgs e) { }
271    protected virtual void OnOperatorsChanged(EventArgs e) { RaiseOperatorsChanged(e); }
272    protected virtual void OnSolutionCreatorChanged(EventArgs e) {
273      SolutionCreator.SymbolicExpressionTreeParameter.ActualNameChanged += new EventHandler(SolutionCreator_SymbolicExpressionTreeParameter_ActualNameChanged);
274      ParameterizeSolutionCreator();
275      OnSolutionParameterNameChanged(e);
276      RaiseSolutionCreatorChanged(e);
277    }
278
279    protected virtual void OnSolutionParameterNameChanged(EventArgs e) {
280      ParameterizeEvaluator();
281      ParameterizeVisualizer();
282      ParameterizeOperators();
283    }
284
285    protected virtual void OnEvaluatorChanged(EventArgs e) {
286      Evaluator.QualityParameter.ActualNameChanged += new EventHandler(Evaluator_QualityParameter_ActualNameChanged);
287      ParameterizeEvaluator();
288      ParameterizeVisualizer();
289      RaiseEvaluatorChanged(e);
290    }
291    protected virtual void OnQualityParameterNameChanged(EventArgs e) {
292      ParameterizeVisualizer();
293    }
294    protected virtual void OnVisualizerChanged(EventArgs e) {
295      ParameterizeVisualizer();
296      RaiseVisualizerChanged(e);
297    }
298    #endregion
299
300    #region event handlers
301    private void SolutionCreatorParameter_ValueChanged(object sender, EventArgs e) {
302      OnSolutionCreatorChanged(e);
303    }
304    private void SolutionCreator_SymbolicExpressionTreeParameter_ActualNameChanged(object sender, EventArgs e) {
305      OnSolutionParameterNameChanged(e);
306    }
307    private void EvaluatorParameter_ValueChanged(object sender, EventArgs e) {
308      OnEvaluatorChanged(e);
309    }
310    private void VisualizerParameter_ValueChanged(object sender, EventArgs e) {
311      OnVisualizerChanged(e);
312    }
313    private void ArchitectureParameter_ValueChanged(object sender, EventArgs e) {
314      OnArchitectureParameterChanged(e);
315    }
316    private void Evaluator_QualityParameter_ActualNameChanged(object sender, EventArgs e) {
317      OnQualityParameterNameChanged(e);
318    }
319    #endregion
320
321    #region events
322    public event EventHandler SolutionCreatorChanged;
323    private void RaiseSolutionCreatorChanged(EventArgs e) {
324      var changed = SolutionCreatorChanged;
325      if (changed != null)
326        changed(this, e);
327    }
328    public event EventHandler EvaluatorChanged;
329    private void RaiseEvaluatorChanged(EventArgs e) {
330      var changed = EvaluatorChanged;
331      if (changed != null)
332        changed(this, e);
333    }
334    public event EventHandler VisualizerChanged;
335    private void RaiseVisualizerChanged(EventArgs e) {
336      var changed = VisualizerChanged;
337      if (changed != null)
338        changed(this, e);
339    }
340
341    public event EventHandler OperatorsChanged;
342    private void RaiseOperatorsChanged(EventArgs e) {
343      var changed = OperatorsChanged;
344      if (changed != null)
345        changed(this, e);
346    }
347    #endregion
348
349    #region Helpers
350    private void Initialize() {
351      InitializeOperators();
352      RegisterParameterEvents();
353      RegisterParameterValueEvents();
354    }
355
356    private void UpdateGrammar() {
357      foreach (var varSymbol in FunctionTreeGrammar.Symbols.OfType<HeuristicLab.Problems.DataAnalysis.Symbolic.Symbols.Variable>()) {
358        varSymbol.VariableNames = DataAnalysisProblemData.InputVariables.Select(x => x.Value);
359      }
360    }
361
362    private void UpdateEstimationLimits() {
363      if (TrainingSamplesStart.Value < TrainingSamplesEnd.Value &&
364        DataAnalysisProblemData.Dataset.VariableNames.Contains(DataAnalysisProblemData.TargetVariable.Value)) {
365        var targetValues = DataAnalysisProblemData.Dataset.GetVariableValues(DataAnalysisProblemData.TargetVariable.Value, TrainingSamplesStart.Value, TrainingSamplesEnd.Value);
366        var mean = targetValues.Average();
367        var range = targetValues.Max() - targetValues.Min();
368        UpperEstimationLimit = new DoubleValue(mean + PunishmentFactor.Value * range);
369        LowerEstimationLimit = new DoubleValue(mean - PunishmentFactor.Value * range);
370      }
371    }
372
373    private void InitializeOperators() {
374      operators = new List<ISymbolicExpressionTreeOperator>();
375      operators.AddRange(ApplicationManager.Manager.GetInstances<ISymbolicExpressionTreeOperator>());
376      ParameterizeOperators();
377    }
378
379    private void ParameterizeSolutionCreator() {
380      SolutionCreator.SymbolicExpressionGrammarParameter.ActualName = FunctionTreeGrammarParameter.Name;
381      SolutionCreator.MaxTreeHeightParameter.ActualName = MaxExpressionDepthParameter.Name;
382      SolutionCreator.MaxTreeSizeParameter.ActualName = MaxExpressionLengthParameter.Name;
383      SolutionCreator.MaxFunctionArgumentsParameter.ActualName = MaxFunctionArgumentsParameter.Name;
384      SolutionCreator.MaxFunctionDefinitionsParameter.ActualName = MaxFunctionDefiningBranchesParameter.Name;
385    }
386
387    private void ParameterizeEvaluator() {
388      Evaluator.SymbolicExpressionTreeParameter.ActualName = SolutionCreator.SymbolicExpressionTreeParameter.ActualName;
389      Evaluator.RegressionProblemDataParameter.ActualName = DataAnalysisProblemDataParameter.Name;
390      Evaluator.SamplesStartParameter.Value = TrainingSamplesStart;
391      Evaluator.SamplesEndParameter.Value = TrainingSamplesEnd;
392    }
393
394    private void ParameterizeVisualizer() {
395      var solutionVisualizer = Visualizer as BestValidationSymbolicRegressionSolutionVisualizer;
396      if (solutionVisualizer != null) {
397        solutionVisualizer.SymbolicExpressionTreeParameter.ActualName = SolutionCreator.SymbolicExpressionTreeParameter.ActualName;
398        solutionVisualizer.DataAnalysisProblemDataParameter.ActualName = DataAnalysisProblemDataParameter.Name;
399        solutionVisualizer.UpperEstimationLimitParameter.ActualName = UpperEstimationLimitParameter.Name;
400        solutionVisualizer.LowerEstimationLimitParameter.ActualName = LowerEstimationLimitParameter.Name;
401        solutionVisualizer.QualityParameter.ActualName = Evaluator.QualityParameter.Name;
402        solutionVisualizer.SymbolicExpressionTreeInterpreterParameter.ActualName = SymbolicExpressionTreeInterpreterParameter.Name;
403        solutionVisualizer.ValidationSamplesStartParameter.Value = ValidationSamplesStart;
404        solutionVisualizer.ValidationSamplesEndParameter.Value = ValidationSamplesEnd;
405      }
406    }
407
408    private void ParameterizeOperators() {
409      foreach (ISymbolicExpressionTreeOperator op in Operators.OfType<ISymbolicExpressionTreeOperator>()) {
410        op.MaxTreeHeightParameter.ActualName = MaxExpressionDepthParameter.Name;
411        op.MaxTreeSizeParameter.ActualName = MaxExpressionLengthParameter.Name;
412        op.SymbolicExpressionGrammarParameter.ActualName = FunctionTreeGrammarParameter.Name;
413      }
414      foreach (ISymbolicExpressionTreeCrossover op in Operators.OfType<ISymbolicExpressionTreeCrossover>()) {
415        op.ParentsParameter.ActualName = SolutionCreator.SymbolicExpressionTreeParameter.ActualName;
416        op.ChildParameter.ActualName = SolutionCreator.SymbolicExpressionTreeParameter.ActualName;
417      }
418      foreach (ISymbolicExpressionTreeManipulator op in Operators.OfType<ISymbolicExpressionTreeManipulator>()) {
419        op.SymbolicExpressionTreeParameter.ActualName = SolutionCreator.SymbolicExpressionTreeParameter.ActualName;
420      }
421      foreach (ISymbolicExpressionTreeArchitectureManipulator op in Operators.OfType<ISymbolicExpressionTreeArchitectureManipulator>()) {
422        op.MaxFunctionArgumentsParameter.ActualName = MaxFunctionArgumentsParameter.Name;
423        op.MaxFunctionDefinitionsParameter.ActualName = MaxFunctionDefiningBranchesParameter.Name;
424      }
425    }
426    #endregion
427  }
428}
Note: See TracBrowser for help on using the repository browser.