Free cookie consent management tool by TermsFeed Policy Generator

source: branches/GBT/HeuristicLab.Algorithms.DataAnalysis/3.4/GradientBoostedTrees/GradientBoostedTreesAlgorithm.cs @ 12373

Last change on this file since 12373 was 12373, checked in by gkronber, 9 years ago

#2261: added hidden alg.-parameter to disable solution-creation (this is useful for cross-validation)

File size: 11.0 KB
Line 
1#region License Information
2/* HeuristicLab
3 * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
4 * and the BEACON Center for the Study of Evolution in Action.
5 *
6 * This file is part of HeuristicLab.
7 *
8 * HeuristicLab is free software: you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation, either version 3 of the License, or
11 * (at your option) any later version.
12 *
13 * HeuristicLab is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
20 */
21#endregion
22
23using System;
24using System.Collections.Generic;
25using System.ComponentModel;
26using System.Diagnostics.Contracts;
27using System.Linq;
28using System.Threading;
29using GradientBoostedTrees;
30using HeuristicLab.Analysis;
31using HeuristicLab.Common;
32using HeuristicLab.Core;
33using HeuristicLab.Data;
34using HeuristicLab.Optimization;
35using HeuristicLab.Parameters;
36using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
37using HeuristicLab.PluginInfrastructure;
38using HeuristicLab.Problems.DataAnalysis;
39using HeuristicLab.Random;
40
41namespace HeuristicLab.Algorithms.DataAnalysis {
42  [Item("Gradient Boosted Trees", "")]
43  [StorableClass]
44  [Creatable("Algorithms")]
45  public class GradientBoostedTreesAlgorithm : BasicAlgorithm {
46    public override Type ProblemType {
47      get { return typeof(IRegressionProblem); }
48    }
49    public new IRegressionProblem Problem {
50      get { return (IRegressionProblem)base.Problem; }
51      set { base.Problem = value; }
52    }
53
54    #region ParameterNames
55    private const string IterationsParameterName = "Iterations";
56    private const string MaxDepthParameterName = "Maximum Tree Depth";
57    private const string NuParameterName = "Nu";
58    private const string RParameterName = "R";
59    private const string MParameterName = "M";
60    private const string SeedParameterName = "Seed";
61    private const string SetSeedRandomlyParameterName = "SetSeedRandomly";
62    private const string LossFunctionParameterName = "LossFunction";
63    private const string UpdateIntervalParameterName = "UpdateInterval";
64    private const string CreateSolutionParameterName = "CreateSolution";
65    #endregion
66
67    #region ParameterProperties
68    public IFixedValueParameter<IntValue> IterationsParameter {
69      get { return (IFixedValueParameter<IntValue>)Parameters[IterationsParameterName]; }
70    }
71    public IFixedValueParameter<IntValue> MaxDepthParameter {
72      get { return (IFixedValueParameter<IntValue>)Parameters[MaxDepthParameterName]; }
73    }
74    public IFixedValueParameter<DoubleValue> NuParameter {
75      get { return (IFixedValueParameter<DoubleValue>)Parameters[NuParameterName]; }
76    }
77    public IFixedValueParameter<DoubleValue> RParameter {
78      get { return (IFixedValueParameter<DoubleValue>)Parameters[RParameterName]; }
79    }
80    public IFixedValueParameter<DoubleValue> MParameter {
81      get { return (IFixedValueParameter<DoubleValue>)Parameters[MParameterName]; }
82    }
83    public IFixedValueParameter<IntValue> SeedParameter {
84      get { return (IFixedValueParameter<IntValue>)Parameters[SeedParameterName]; }
85    }
86    public FixedValueParameter<BoolValue> SetSeedRandomlyParameter {
87      get { return (FixedValueParameter<BoolValue>)Parameters[SetSeedRandomlyParameterName]; }
88    }
89    public IConstrainedValueParameter<StringValue> LossFunctionParameter {
90      get { return (IConstrainedValueParameter<StringValue>)Parameters[LossFunctionParameterName]; }
91    }
92    public IFixedValueParameter<IntValue> UpdateIntervalParameter {
93      get { return (IFixedValueParameter<IntValue>)Parameters[UpdateIntervalParameterName]; }
94    }
95    public IFixedValueParameter<BoolValue> CreateSolutionParameter {
96      get { return (IFixedValueParameter<BoolValue>)Parameters[CreateSolutionParameterName]; }
97    }
98    #endregion
99
100    #region Properties
101    public int Iterations {
102      get { return IterationsParameter.Value.Value; }
103      set { IterationsParameter.Value.Value = value; }
104    }
105    public int Seed {
106      get { return SeedParameter.Value.Value; }
107      set { SeedParameter.Value.Value = value; }
108    }
109    public bool SetSeedRandomly {
110      get { return SetSeedRandomlyParameter.Value.Value; }
111      set { SetSeedRandomlyParameter.Value.Value = value; }
112    }
113    public int MaxDepth {
114      get { return MaxDepthParameter.Value.Value; }
115      set { MaxDepthParameter.Value.Value = value; }
116    }
117    public double Nu {
118      get { return NuParameter.Value.Value; }
119      set { NuParameter.Value.Value = value; }
120    }
121    public double R {
122      get { return RParameter.Value.Value; }
123      set { RParameter.Value.Value = value; }
124    }
125    public double M {
126      get { return MParameter.Value.Value; }
127      set { MParameter.Value.Value = value; }
128    }
129    public bool CreateSolution {
130      get { return CreateSolutionParameter.Value.Value; }
131      set { CreateSolutionParameter.Value.Value = value; }
132    }
133    #endregion
134
135    #region ResultsProperties
136    private double ResultsBestQuality {
137      get { return ((DoubleValue)Results["Best Quality"].Value).Value; }
138      set { ((DoubleValue)Results["Best Quality"].Value).Value = value; }
139    }
140    private DataTable ResultsQualities {
141      get { return ((DataTable)Results["Qualities"].Value); }
142    }
143    #endregion
144
145    [StorableConstructor]
146    protected GradientBoostedTreesAlgorithm(bool deserializing) : base(deserializing) { }
147
148    protected GradientBoostedTreesAlgorithm(GradientBoostedTreesAlgorithm original, Cloner cloner)
149      : base(original, cloner) {
150    }
151
152    public override IDeepCloneable Clone(Cloner cloner) {
153      return new GradientBoostedTreesAlgorithm(this, cloner);
154    }
155
156    public GradientBoostedTreesAlgorithm() {
157      Problem = new RegressionProblem(); // default problem
158
159      Parameters.Add(new FixedValueParameter<IntValue>(IterationsParameterName, "Number of iterations (set as high as possible, adjust in combination with nu, when increasing iterations also decrease nu)", new IntValue(1000)));
160      Parameters.Add(new FixedValueParameter<IntValue>(SeedParameterName, "The random seed used to initialize the new pseudo random number generator.", new IntValue(0)));
161      Parameters.Add(new FixedValueParameter<BoolValue>(SetSeedRandomlyParameterName, "True if the random seed should be set to a random value, otherwise false.", new BoolValue(true)));
162      Parameters.Add(new FixedValueParameter<IntValue>(MaxDepthParameterName, "Maximal depth of the tree learned in each step (prefer smaller depths if possible)", new IntValue(5)));
163      Parameters.Add(new FixedValueParameter<DoubleValue>(RParameterName, "Ratio of training rows selected randomly in each step (0 < R <= 1)", new DoubleValue(0.5)));
164      Parameters.Add(new FixedValueParameter<DoubleValue>(MParameterName, "Ratio of variables selected randomly in each step (0 < M <= 1)", new DoubleValue(0.5)));
165      Parameters.Add(new FixedValueParameter<DoubleValue>(NuParameterName, "Learning rate nu (step size for the gradient update, should be small 0 < nu < 0.1)", new DoubleValue(0.002)));
166      Parameters.Add(new FixedValueParameter<IntValue>(UpdateIntervalParameterName, "", new IntValue(100)));
167      Parameters[UpdateIntervalParameterName].Hidden = true;
168      Parameters.Add(new FixedValueParameter<BoolValue>(CreateSolutionParameterName, "Flag that indicates if a solution should be produced at the end of the run", new BoolValue(true)));
169      Parameters[CreateSolutionParameterName].Hidden = true;
170
171      var lossFunctionNames = ApplicationManager.Manager.GetInstances<ILossFunction>().Select(l => new StringValue(l.ToString()).AsReadOnly());
172      var defaultLossFunction = lossFunctionNames.First(l => l.Value.Contains("Squared")); // squared error loss is the default
173      Parameters.Add(new ConstrainedValueParameter<StringValue>(LossFunctionParameterName, "The loss function", new ItemSet<StringValue>(lossFunctionNames), defaultLossFunction));
174    }
175
176
177    protected override void Run(CancellationToken cancellationToken) {
178      // Set up the algorithm
179      if (SetSeedRandomly) Seed = new System.Random().Next();
180      // random.Reset(Seed);
181
182      // Set up the results display
183      var iterations = new IntValue(0);
184      Results.Add(new Result("Iterations", iterations));
185
186      var table = new DataTable("Qualities");
187      table.Rows.Add(new DataRow("Loss (train)"));
188      table.Rows.Add(new DataRow("Loss (test)"));
189      Results.Add(new Result("Qualities", table));
190      var curLoss = new DoubleValue();
191      Results.Add(new Result("Loss (train)", curLoss));
192
193      // init
194      var problemData = Problem.ProblemData;
195      var lossFunction = ApplicationManager.Manager.GetInstances<ILossFunction>().Single(l => l.ToString() == LossFunctionParameter.Value.Value);
196      var state = GradientBoostedTreesAlgorithmStatic.CreateGbmState(problemData, lossFunction, (uint)Seed, MaxDepth, R, M, Nu);
197
198      var updateInterval = UpdateIntervalParameter.Value.Value;
199      // Loop until iteration limit reached or canceled.
200      for (int i = 0; i < Iterations; i++) {
201        cancellationToken.ThrowIfCancellationRequested();
202
203        GradientBoostedTreesAlgorithmStatic.MakeStep(state);
204
205        // iteration results
206        if (i % updateInterval == 0) {
207          curLoss.Value = state.GetTrainLoss();
208          table.Rows["Loss (train)"].Values.Add(curLoss.Value);
209          table.Rows["Loss (test)"].Values.Add(state.GetTestLoss());
210          iterations.Value = i;
211        }
212      }
213
214      // final results
215      iterations.Value = Iterations;
216      curLoss.Value = state.GetTrainLoss();
217      table.Rows["Loss (train)"].Values.Add(curLoss.Value);
218      table.Rows["Loss (test)"].Values.Add(state.GetTestLoss());
219
220      // produce variable relevance
221      // update variable impacts matrix
222      var orderedImpacts = state.GetVariableRelevance().Select(t => new { name = t.Key, impact = t.Value }).ToList();
223
224      var impacts = new DoubleMatrix();
225      var matrix = impacts as IStringConvertibleMatrix;
226      matrix.Rows = orderedImpacts.Count;
227      matrix.RowNames = orderedImpacts.Select(x => x.name);
228      matrix.Columns = 1;
229      matrix.ColumnNames = new string[] { "Relative variable relevance" };
230
231      int rowIdx = 0;
232      foreach (var p in orderedImpacts) {
233        matrix.SetValue(string.Format("{0:N2}", p.impact), rowIdx++, 0);
234      }
235
236      Results.Add(new Result("Variable relevance", impacts));
237      Results.Add(new Result("Loss (test)", new DoubleValue(state.GetTestLoss())));
238
239      // produce solution
240      if (CreateSolution)
241        Results.Add(new Result("Solution", new RegressionSolution(state.GetModel(), (IRegressionProblemData)problemData.Clone())));
242    }
243  }
244}
Note: See TracBrowser for help on using the repository browser.