Free cookie consent management tool by TermsFeed Policy Generator

source: trunk/sources/HeuristicLab.GP.StructureIdentification/3.3/LinearScalingPredictorBuilder.cs @ 2722

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

Added a special predictor builder for linear scaling tree evaluation and changed default GP engines to use linear scaling evaluators. #823.

File size: 7.1 KB
Line 
1#region License Information
2/* HeuristicLab
3 * Copyright (C) 2002-2008 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.Text;
26using HeuristicLab.Core;
27using HeuristicLab.Data;
28using HeuristicLab.GP.Interfaces;
29using HeuristicLab.Modeling;
30using HeuristicLab.DataAnalysis;
31using HeuristicLab.Common;
32namespace HeuristicLab.GP.StructureIdentification {
33  public class LinearScalingPredictorBuilder : OperatorBase {
34    public LinearScalingPredictorBuilder()
35      : base() {
36      AddVariableInfo(new VariableInfo("FunctionTree", "The function tree", typeof(IGeneticProgrammingModel), VariableKind.In));
37      AddVariableInfo(new VariableInfo("PunishmentFactor", "The punishment factor limits the estimated values to a certain range", typeof(DoubleData), VariableKind.In));
38      AddVariableInfo(new VariableInfo("Dataset", "The dataset", typeof(Dataset), VariableKind.In));
39      AddVariableInfo(new VariableInfo("TrainingSamplesStart", "Start index of training set", typeof(DoubleData), VariableKind.In));
40      AddVariableInfo(new VariableInfo("TrainingSamplesEnd", "End index of training set", typeof(DoubleData), VariableKind.In));
41      AddVariableInfo(new VariableInfo("TargetVariable", "Name of the target variable", typeof(StringData), VariableKind.In));
42      AddVariableInfo(new VariableInfo("Predictor", "The predictor combines the function tree and the evaluator and can be used to generate estimated values", typeof(IPredictor), VariableKind.New));
43    }
44
45    public override string Description {
46      get { return "Extracts the function tree scales the output of the tree and combines the scaled tree with a HL3TreeEvaluator to a predictor for the model analyzer."; }
47    }
48
49    public override IOperation Apply(IScope scope) {
50      IGeneticProgrammingModel model = GetVariableValue<IGeneticProgrammingModel>("FunctionTree", scope, true);
51      double punishmentFactor = GetVariableValue<DoubleData>("PunishmentFactor", scope, true).Data;
52      Dataset dataset = GetVariableValue<Dataset>("Dataset", scope, true);
53      int start = GetVariableValue<IntData>("TrainingSamplesStart", scope, true).Data;
54      int end = GetVariableValue<IntData>("TrainingSamplesEnd", scope, true).Data;
55      string targetVariable = GetVariableValue<StringData>("TargetVariable", scope, true).Data;
56      IPredictor predictor = CreatePredictor(model, punishmentFactor, dataset, targetVariable, start, end);
57      scope.AddVariable(new HeuristicLab.Core.Variable(scope.TranslateName("Predictor"), predictor));
58      return null;
59    }
60
61    public static IPredictor CreatePredictor(IGeneticProgrammingModel model, double punishmentFactor,
62  Dataset dataset, string targetVariable, int start, int end) {
63      return CreatePredictor(model, punishmentFactor, dataset, dataset.GetVariableIndex(targetVariable), start, end);
64    }
65
66
67    public static IPredictor CreatePredictor(IGeneticProgrammingModel model, double punishmentFactor,
68      Dataset dataset, int targetVariable, int start, int end) {
69
70      var evaluator = new HL3TreeEvaluator();
71      // evaluate for all rows
72      evaluator.PrepareForEvaluation(dataset, model.FunctionTree);
73      var result = from row in Enumerable.Range(start, end - start)
74                   let y = evaluator.Evaluate(row)
75                   let y_ = dataset.GetValue(row, targetVariable)
76                   select new { Row = row, Estimation = y, Target = y_ };
77
78      // calculate alpha and beta on the subset of rows with valid values
79      var filteredResult = result.Where(x => IsValidValue(x.Target) && IsValidValue(x.Estimation));
80      var target = filteredResult.Select(x => x.Target);
81      var estimation = filteredResult.Select(x => x.Estimation);
82      double a, b;
83      if (filteredResult.Count() > 2) {
84        double tMean = target.Sum() / target.Count();
85        double xMean = estimation.Sum() / estimation.Count();
86        double sumXT = 0;
87        double sumXX = 0;
88        foreach (var r in result) {
89          double x = r.Estimation;
90          double t = r.Target;
91          sumXT += (x - xMean) * (t - tMean);
92          sumXX += (x - xMean) * (x - xMean);
93        }
94        b = sumXT / sumXX;
95        a = tMean - b * xMean;
96      } else {
97        b = 1.0;
98        a = 0.0;
99      }
100      double mean = dataset.GetMean(targetVariable, start, end);
101      double range = dataset.GetRange(targetVariable, start, end);
102      double minEstimatedValue = mean - punishmentFactor * range;
103      double maxEstimatedValue = mean + punishmentFactor * range;
104      evaluator.LowerEvaluationLimit = minEstimatedValue;
105      evaluator.UpperEvaluationLimit = maxEstimatedValue;
106      var resultModel = new GeneticProgrammingModel(MakeSum(MakeProduct(model.FunctionTree, b), a));
107      return new Predictor(evaluator, resultModel, minEstimatedValue, maxEstimatedValue);
108    }
109
110    private static bool IsValidValue(double d) {
111      return !double.IsInfinity(d) && !double.IsNaN(d);
112    }
113
114
115    private static IFunctionTree MakeSum(IFunctionTree tree, double x) {
116      if (x.IsAlmost(0.0)) return tree;
117      var sum = (new Addition()).GetTreeNode();
118      sum.AddSubTree(tree);
119      sum.AddSubTree(MakeConstant(x));
120      return sum;
121    }
122
123    private static IFunctionTree MakeProduct(IFunctionTree tree, double a) {
124      if (a.IsAlmost(1.0)) return tree;
125      var prod = (new Multiplication()).GetTreeNode();
126      prod.AddSubTree(tree);
127      prod.AddSubTree(MakeConstant(a));
128      return prod;
129    }
130
131    private static IFunctionTree MakeConstant(double x) {
132      var constX = (ConstantFunctionTree)(new Constant()).GetTreeNode();
133      constX.Value = x;
134      return constX;
135    }
136
137    private static void CalculateScalingParameters(IEnumerable<double> xs, IEnumerable<double> ys, out double k, out double d) {
138      if (xs.Count() != ys.Count()) throw new ArgumentException();
139      double xMean = xs.Sum() / xs.Count();
140      double yMean = ys.Sum() / ys.Count();
141
142      var yEnumerator = ys.GetEnumerator();
143      var xEnumerator = xs.GetEnumerator();
144
145      double sumXY = 0.0;
146      double sumXX = 0.0;
147      while (xEnumerator.MoveNext() && yEnumerator.MoveNext()) {
148        sumXY += (xEnumerator.Current - xMean) * (yEnumerator.Current - yMean);
149        sumXX += (xEnumerator.Current - xMean) * (xEnumerator.Current - xMean);
150      }
151
152      k = sumXY / sumXX;
153      d = yMean - k * xMean;
154    }
155  }
156}
Note: See TracBrowser for help on using the repository browser.