Free cookie consent management tool by TermsFeed Policy Generator

source: trunk/sources/HeuristicLab.Problems.DataAnalysis.Classification/3.3/Symbolic/SymbolicClassificationProblem.cs @ 5273

Last change on this file since 5273 was 5273, checked in by gkronber, 13 years ago

Added calculation of R², MSE and rel. Error for training best classification solution. Fixed calculation of accuracy. Fixed namespace and name of TrainingBestSymbolicClassificationSolutionAnalyzer. #1369

File size: 18.6 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 HeuristicLab.Common;
26using HeuristicLab.Core;
27using HeuristicLab.Data;
28using HeuristicLab.Encodings.SymbolicExpressionTreeEncoding;
29using HeuristicLab.Encodings.SymbolicExpressionTreeEncoding.Analyzers;
30using HeuristicLab.Encodings.SymbolicExpressionTreeEncoding.Creators;
31using HeuristicLab.Encodings.SymbolicExpressionTreeEncoding.Interfaces;
32using HeuristicLab.Encodings.SymbolicExpressionTreeEncoding.Symbols;
33using HeuristicLab.Parameters;
34using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
35using HeuristicLab.PluginInfrastructure;
36using HeuristicLab.Problems.DataAnalysis.Regression.Symbolic.Analyzers;
37using HeuristicLab.Problems.DataAnalysis.Symbolic;
38using HeuristicLab.Problems.DataAnalysis.Symbolic.Symbols;
39using HeuristicLab.Problems.DataAnalysis.Classification.Symbolic.Analyzers;
40
41namespace HeuristicLab.Problems.DataAnalysis.Classification {
42  [Item("Classification Problem", "Represents a classfication problem.")]
43  [StorableClass]
44  [Creatable("Problems")]
45  public sealed class SymbolicClassificationProblem : SingleObjectiveClassificationProblem<ISymbolicClassificationEvaluator, ISymbolicExpressionTreeCreator>, IStorableContent {
46    private const string SymbolicExpressionTreeInterpreterParameterName = "SymbolicExpressionTreeInterpreter";
47    private const string FunctionTreeGrammarParameterName = "FunctionTreeGrammar";
48    private const string MaxExpressionLengthParameterName = "MaxExpressionLength";
49    private const string MaxExpressionDepthParameterName = "MaxExpressionDepth";
50    private const string UpperEstimationLimitParameterName = "UpperEstimationLimit";
51    private const string LowerEstimationLimitParameterName = "LowerEstimationLimit";
52    private const string MaxFunctionDefiningBranchensParameterName = "MaxFunctionDefiningBranches";
53    private const string MaxFunctionArgumentsParameterName = "MaxFunctionArguments";
54
55    #region properties
56    public string Filename { get; set; }
57
58    public ISymbolicExpressionTreeInterpreter SymbolicExpressionTreeInterpreter {
59      get { return SymbolicExpressionTreeInterpreterParameter.Value; }
60      private set { SymbolicExpressionTreeInterpreterParameter.Value = value; }
61    }
62    public IValueParameter<ISymbolicExpressionTreeInterpreter> SymbolicExpressionTreeInterpreterParameter {
63      get { return (IValueParameter<ISymbolicExpressionTreeInterpreter>)Parameters[SymbolicExpressionTreeInterpreterParameterName]; }
64    }
65
66    public ISymbolicExpressionGrammar FunctionTreeGrammar {
67      get { return (ISymbolicExpressionGrammar)FunctionTreeGrammarParameter.Value; }
68      private set { FunctionTreeGrammarParameter.Value = value; }
69    }
70    public IValueParameter<ISymbolicExpressionGrammar> FunctionTreeGrammarParameter {
71      get { return (IValueParameter<ISymbolicExpressionGrammar>)Parameters[FunctionTreeGrammarParameterName]; }
72    }
73
74    public IntValue MaxExpressionLength {
75      get { return MaxExpressionLengthParameter.Value; }
76      private set { MaxExpressionLengthParameter.Value = value; }
77    }
78    public IValueParameter<IntValue> MaxExpressionLengthParameter {
79      get { return (IValueParameter<IntValue>)Parameters[MaxExpressionLengthParameterName]; }
80    }
81
82    public IntValue MaxExpressionDepth {
83      get { return MaxExpressionDepthParameter.Value; }
84      private set { MaxExpressionDepthParameter.Value = value; }
85    }
86    public ValueParameter<IntValue> MaxExpressionDepthParameter {
87      get { return (ValueParameter<IntValue>)Parameters[MaxExpressionDepthParameterName]; }
88    }
89
90    public DoubleValue UpperEstimationLimit {
91      get { return UpperEstimationLimitParameter.Value; }
92      private set { UpperEstimationLimitParameter.Value = value; }
93    }
94    public IValueParameter<DoubleValue> UpperEstimationLimitParameter {
95      get { return (IValueParameter<DoubleValue>)Parameters[UpperEstimationLimitParameterName]; }
96    }
97
98    public DoubleValue LowerEstimationLimit {
99      get { return LowerEstimationLimitParameter.Value; }
100      private set { LowerEstimationLimitParameter.Value = value; }
101    }
102    public IValueParameter<DoubleValue> LowerEstimationLimitParameter {
103      get { return (IValueParameter<DoubleValue>)Parameters[LowerEstimationLimitParameterName]; }
104    }
105
106    public IntValue MaxFunctionDefiningBranches {
107      get { return MaxFunctionDefiningBranchesParameter.Value; }
108      private set { MaxFunctionDefiningBranchesParameter.Value = value; }
109    }
110    public IValueParameter<IntValue> MaxFunctionDefiningBranchesParameter {
111      get { return (IValueParameter<IntValue>)Parameters[MaxFunctionDefiningBranchensParameterName]; }
112    }
113
114    public IntValue MaxFunctionArguments {
115      get { return MaxFunctionArgumentsParameter.Value; }
116      private set { MaxFunctionArgumentsParameter.Value = value; }
117    }
118    public IValueParameter<IntValue> MaxFunctionArgumentsParameter {
119      get { return (IValueParameter<IntValue>)Parameters[MaxFunctionArgumentsParameterName]; }
120    }
121
122    public DoubleValue PunishmentFactor {
123      get { return new DoubleValue(10.0); }
124    }
125    public IntValue TrainingSamplesStart { get { return new IntValue(ClassificationProblemData.TrainingSamplesStart.Value); } }
126    public IntValue TrainingSamplesEnd {
127      get { return new IntValue((ClassificationProblemData.TrainingSamplesStart.Value + ClassificationProblemData.TrainingSamplesEnd.Value) / 2); }
128    }
129    public IntValue ValidationSamplesStart { get { return TrainingSamplesEnd; } }
130    public IntValue ValidationSamplesEnd { get { return new IntValue(ClassificationProblemData.TrainingSamplesEnd.Value); } }
131    public IntValue TestSamplesStart { get { return ClassificationProblemData.TestSamplesStart; } }
132    public IntValue TestSamplesEnd { get { return ClassificationProblemData.TestSamplesEnd; } }
133    #endregion
134
135    [StorableConstructor]
136    private SymbolicClassificationProblem(bool deserializing) : base(deserializing) { }
137    private SymbolicClassificationProblem(SymbolicClassificationProblem original, Cloner cloner)
138      : base(original, cloner) {
139      RegisterParameterEvents();
140    }
141
142    public SymbolicClassificationProblem()
143      : base() {
144      Parameters.Add(new ValueParameter<ISymbolicExpressionTreeInterpreter>(SymbolicExpressionTreeInterpreterParameterName, "The interpreter that should be used to evaluate the symbolic expression tree."));
145      Parameters.Add(new ValueParameter<ISymbolicExpressionGrammar>(FunctionTreeGrammarParameterName, "The grammar that should be used for symbolic regression models."));
146      Parameters.Add(new ValueParameter<IntValue>(MaxExpressionLengthParameterName, "Maximal length of the symbolic expression."));
147      Parameters.Add(new ValueParameter<IntValue>(MaxExpressionDepthParameterName, "Maximal depth of the symbolic expression."));
148      Parameters.Add(new ValueParameter<DoubleValue>(UpperEstimationLimitParameterName, "The upper limit for the estimated value that can be returned by the symbolic regression model."));
149      Parameters.Add(new ValueParameter<DoubleValue>(LowerEstimationLimitParameterName, "The lower limit for the estimated value that can be returned by the symbolic regression model."));
150      Parameters.Add(new ValueParameter<IntValue>(MaxFunctionDefiningBranchensParameterName, "Maximal number of automatically defined functions."));
151      Parameters.Add(new ValueParameter<IntValue>(MaxFunctionArgumentsParameterName, "Maximal number of arguments of automatically defined functions."));
152
153      SolutionCreator = new ProbabilisticTreeCreator();
154      Evaluator = new SymbolicClassifacitionMeanSquaredErrorEvaluator();
155      ParameterizeSolutionCreator();
156      Maximization = new BoolValue(false);
157      FunctionTreeGrammar = new GlobalSymbolicExpressionGrammar(new FullFunctionalExpressionGrammar());
158      SymbolicExpressionTreeInterpreter = new SimpleArithmeticExpressionInterpreter();
159      MaxExpressionLength = new IntValue(100);
160      MaxExpressionDepth = new IntValue(10);
161      MaxFunctionDefiningBranches = new IntValue(0);
162      MaxFunctionArguments = new IntValue(0);
163
164      InitializeOperators();
165      RegisterParameterEvents();
166
167      UpdateEstimationLimits();
168      ParameterizeEvaluator();
169      ParameterizeSolutionCreator();
170      ParameterizeGrammar();
171      ParameterizeOperators();
172      ParameterizeAnalyzers();
173    }
174
175    public override IDeepCloneable Clone(Cloner cloner) {
176      return new SymbolicClassificationProblem(this, cloner);
177    }
178
179    private void RegisterParameterEvents() {
180      SolutionCreator.SymbolicExpressionTreeParameter.ActualNameChanged += new EventHandler(SolutionCreator_SymbolicExpressionTreeParameter_ActualNameChanged);
181      FunctionTreeGrammarParameter.ValueChanged += new EventHandler(FunctionTreeGrammarParameter_ValueChanged);
182
183      MaxFunctionArgumentsParameter.ValueChanged += new EventHandler(ArchitectureParameter_ValueChanged);
184      MaxFunctionDefiningBranchesParameter.ValueChanged += new EventHandler(ArchitectureParameter_ValueChanged);
185      MaxFunctionArgumentsParameter.Value.ValueChanged += new EventHandler(ArchitectureParameterValue_ValueChanged);
186      MaxFunctionDefiningBranchesParameter.Value.ValueChanged += new EventHandler(ArchitectureParameterValue_ValueChanged);
187    }
188
189    protected override void OnEvaluatorChanged() {
190      ParameterizeEvaluator();
191      ParameterizeAnalyzers();
192      base.OnEvaluatorChanged();
193    }
194
195    protected override void OnSolutionCreatorChanged() {
196      ParameterizeSolutionCreator();
197      SolutionCreator.SymbolicExpressionTreeParameter.ActualNameChanged += new EventHandler(SolutionCreator_SymbolicExpressionTreeParameter_ActualNameChanged);
198      base.OnSolutionCreatorChanged();
199    }
200    private void SolutionCreator_SymbolicExpressionTreeParameter_ActualNameChanged(object sender, System.EventArgs e) {
201      ParameterizeEvaluator();
202      ParameterizeOperators();
203      ParameterizeAnalyzers();
204    }
205
206    protected override void OnClassificationProblemDataChanged() {
207      ParameterizeAnalyzers();
208      ParameterizeGrammar();
209      ParameterizeEvaluator();
210      UpdateEstimationLimits();
211      base.OnClassificationProblemDataChanged();
212    }
213
214    private void FunctionTreeGrammarParameter_ValueChanged(object sender, System.EventArgs e) {
215      if (!(FunctionTreeGrammar is GlobalSymbolicExpressionGrammar))
216        FunctionTreeGrammar = new GlobalSymbolicExpressionGrammar(FunctionTreeGrammar);
217      OnGrammarChanged();
218    }
219    private void OnGrammarChanged() {
220      ParameterizeGrammar();
221    }
222
223    private void ArchitectureParameter_ValueChanged(object sender, EventArgs e) {
224      MaxFunctionArgumentsParameter.Value.ValueChanged += new EventHandler(ArchitectureParameterValue_ValueChanged);
225      MaxFunctionDefiningBranchesParameter.Value.ValueChanged += new EventHandler(ArchitectureParameterValue_ValueChanged);
226      OnArchitectureParameterChanged();
227    }
228    private void ArchitectureParameterValue_ValueChanged(object sender, EventArgs e) {
229      OnArchitectureParameterChanged();
230    }
231    private void OnArchitectureParameterChanged() {
232      ParameterizeGrammar();
233    }
234
235    private void InitializeOperators() {
236      Operators.AddRange(ApplicationManager.Manager.GetInstances<ISymbolicExpressionTreeOperator>().OfType<IOperator>());
237      Operators.Add(new MinAverageMaxSymbolicExpressionTreeSizeAnalyzer());
238      Operators.Add(new SymbolicRegressionVariableFrequencyAnalyzer());
239      Operators.Add(new ValidationBestSymbolicClassificationSolutionAnalyzer());
240      Operators.Add(new TrainingBestSymbolicClassificationSolutionAnalyzer());
241    }
242
243    #region operator parameterization
244    private void UpdateEstimationLimits() {
245      if (TrainingSamplesStart.Value < TrainingSamplesEnd.Value &&
246        ClassificationProblemData.Dataset.VariableNames.Contains(ClassificationProblemData.TargetVariable.Value)) {
247        var targetValues = ClassificationProblemData.Dataset.GetVariableValues(ClassificationProblemData.TargetVariable.Value, TrainingSamplesStart.Value, TrainingSamplesEnd.Value);
248        var mean = targetValues.Average();
249        var range = targetValues.Max() - targetValues.Min();
250        UpperEstimationLimit = new DoubleValue(mean + PunishmentFactor.Value * range);
251        LowerEstimationLimit = new DoubleValue(mean - PunishmentFactor.Value * range);
252      }
253    }
254
255    private void ParameterizeEvaluator() {
256      if (Evaluator != null) {
257        Evaluator.SymbolicExpressionTreeParameter.ActualName = SolutionCreator.SymbolicExpressionTreeParameter.ActualName;
258        Evaluator.RegressionProblemDataParameter.ActualName = ClassificationProblemDataParameter.Name;
259        Evaluator.SamplesStartParameter.Value = TrainingSamplesStart;
260        Evaluator.SamplesEndParameter.Value = TrainingSamplesEnd;
261      }
262    }
263
264    private void ParameterizeGrammar() {
265      List<LaggedVariable> laggedSymbols = FunctionTreeGrammar.Symbols.OfType<LaggedVariable>().ToList();
266      foreach (Symbol symbol in laggedSymbols)
267        FunctionTreeGrammar.RemoveSymbol(symbol);
268      foreach (var varSymbol in FunctionTreeGrammar.Symbols.OfType<HeuristicLab.Problems.DataAnalysis.Symbolic.Symbols.Variable>()) {
269        varSymbol.VariableNames = ClassificationProblemData.InputVariables.CheckedItems.Select(x => x.Value.Value);
270      }
271      var globalGrammar = FunctionTreeGrammar as GlobalSymbolicExpressionGrammar;
272      if (globalGrammar != null) {
273        globalGrammar.MaxFunctionArguments = MaxFunctionArguments.Value;
274        globalGrammar.MaxFunctionDefinitions = MaxFunctionDefiningBranches.Value;
275      }
276    }
277
278    private void ParameterizeSolutionCreator() {
279      SolutionCreator.SymbolicExpressionGrammarParameter.ActualName = FunctionTreeGrammarParameter.Name;
280      SolutionCreator.MaxTreeHeightParameter.ActualName = MaxExpressionDepthParameter.Name;
281      SolutionCreator.MaxTreeSizeParameter.ActualName = MaxExpressionLengthParameter.Name;
282      SolutionCreator.MaxFunctionArgumentsParameter.ActualName = MaxFunctionArgumentsParameter.Name;
283      SolutionCreator.MaxFunctionDefinitionsParameter.ActualName = MaxFunctionDefiningBranchesParameter.Name;
284    }
285
286    private void ParameterizeOperators() {
287      foreach (ISymbolicExpressionTreeOperator op in Operators.OfType<ISymbolicExpressionTreeOperator>()) {
288        op.MaxTreeHeightParameter.ActualName = MaxExpressionDepthParameter.Name;
289        op.MaxTreeSizeParameter.ActualName = MaxExpressionLengthParameter.Name;
290        op.SymbolicExpressionGrammarParameter.ActualName = FunctionTreeGrammarParameter.Name;
291      }
292      foreach (ISymbolicExpressionTreeCrossover op in Operators.OfType<ISymbolicExpressionTreeCrossover>()) {
293        op.ParentsParameter.ActualName = SolutionCreator.SymbolicExpressionTreeParameter.ActualName;
294        op.ChildParameter.ActualName = SolutionCreator.SymbolicExpressionTreeParameter.ActualName;
295      }
296      foreach (ISymbolicExpressionTreeManipulator op in Operators.OfType<ISymbolicExpressionTreeManipulator>()) {
297        op.SymbolicExpressionTreeParameter.ActualName = SolutionCreator.SymbolicExpressionTreeParameter.ActualName;
298      }
299      foreach (ISymbolicExpressionTreeArchitectureManipulator op in Operators.OfType<ISymbolicExpressionTreeArchitectureManipulator>()) {
300        op.MaxFunctionArgumentsParameter.ActualName = MaxFunctionArgumentsParameter.Name;
301        op.MaxFunctionDefinitionsParameter.ActualName = MaxFunctionDefiningBranchesParameter.Name;
302      }
303    }
304
305    private void ParameterizeAnalyzers() {
306      foreach (ISymbolicRegressionAnalyzer analyzer in Operators.OfType<ISymbolicRegressionAnalyzer>()) {
307        analyzer.SymbolicExpressionTreeParameter.ActualName = SolutionCreator.SymbolicExpressionTreeParameter.ActualName;
308        var bestValidationSolutionAnalyzer = analyzer as ValidationBestSymbolicClassificationSolutionAnalyzer;
309        if (bestValidationSolutionAnalyzer != null) {
310          bestValidationSolutionAnalyzer.ClassificationProblemDataParameter.ActualName = ClassificationProblemDataParameter.Name;
311          bestValidationSolutionAnalyzer.UpperEstimationLimitParameter.ActualName = UpperEstimationLimitParameter.Name;
312          bestValidationSolutionAnalyzer.LowerEstimationLimitParameter.ActualName = LowerEstimationLimitParameter.Name;
313          bestValidationSolutionAnalyzer.SymbolicExpressionTreeInterpreterParameter.ActualName = SymbolicExpressionTreeInterpreterParameter.Name;
314          bestValidationSolutionAnalyzer.SymbolicExpressionTreeParameter.ActualName = SolutionCreator.SymbolicExpressionTreeParameter.ActualName;
315          bestValidationSolutionAnalyzer.ValidationSamplesStartParameter.Value = ValidationSamplesStart;
316          bestValidationSolutionAnalyzer.ValidationSamplesEndParameter.Value = ValidationSamplesEnd;
317        }
318        var bestTrainingSolutionAnalyzer = analyzer as TrainingBestSymbolicClassificationSolutionAnalyzer;
319        if (bestTrainingSolutionAnalyzer != null) {
320          bestTrainingSolutionAnalyzer.ProblemDataParameter.ActualName = ClassificationProblemDataParameter.Name;
321          bestTrainingSolutionAnalyzer.UpperEstimationLimitParameter.ActualName = UpperEstimationLimitParameter.Name;
322          bestTrainingSolutionAnalyzer.LowerEstimationLimitParameter.ActualName = LowerEstimationLimitParameter.Name;
323          bestTrainingSolutionAnalyzer.SymbolicExpressionTreeInterpreterParameter.ActualName = SymbolicExpressionTreeInterpreterParameter.Name;
324          bestTrainingSolutionAnalyzer.SymbolicExpressionTreeParameter.ActualName = SolutionCreator.SymbolicExpressionTreeParameter.ActualName;
325        }
326        var varFreqAnalyzer = analyzer as SymbolicRegressionVariableFrequencyAnalyzer;
327        if (varFreqAnalyzer != null) {
328          varFreqAnalyzer.ProblemDataParameter.ActualName = ClassificationProblemDataParameter.Name;
329        }
330      }
331    }
332    #endregion
333  }
334}
Note: See TracBrowser for help on using the repository browser.