Free cookie consent management tool by TermsFeed Policy Generator

source: branches/RBFRegression/HeuristicLab.Algorithms.DataAnalysis/3.4/KernelRidgeRegression/KernelRidgeRegression.cs @ 14905

Last change on this file since 14905 was 14888, checked in by gkronber, 8 years ago

#2699: re-added calculation of leave one out cv estimate

File size: 6.4 KB
Line 
1#region License Information
2/* HeuristicLab
3 * Copyright (C) 2002-2016 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.Linq;
24using System.Threading;
25using HeuristicLab.Common;
26using HeuristicLab.Core;
27using HeuristicLab.Data;
28using HeuristicLab.Optimization;
29using HeuristicLab.Parameters;
30using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
31using HeuristicLab.Problems.DataAnalysis;
32
33namespace HeuristicLab.Algorithms.DataAnalysis.KernelRidgeRegression {
34  [Item("Kernel Ridge Regression", "Kernelized ridge regression e.g. for radial basis function (RBF) regression.")]
35  [Creatable(CreatableAttribute.Categories.DataAnalysisRegression, Priority = 100)]
36  [StorableClass]
37  public sealed class KernelRidgeRegression : BasicAlgorithm {
38    private const string SolutionResultName = "Kernel ridge regression solution";
39
40    public override bool SupportsPause {
41      get { return false; }
42    }
43    public override Type ProblemType {
44      get { return typeof(IRegressionProblem); }
45    }
46    public new IRegressionProblem Problem {
47      get { return (IRegressionProblem)base.Problem; }
48      set { base.Problem = value; }
49    }
50
51    #region parameter names
52    private const string KernelParameterName = "Kernel";
53    private const string ScaleInputVariablesParameterName = "ScaleInputVariables";
54    private const string LambdaParameterName = "LogLambda";
55    private const string BetaParameterName = "Beta";
56    #endregion
57
58    #region parameter properties
59    public ValueParameter<IKernel> KernelParameter {
60      get { return (ValueParameter<IKernel>)Parameters[KernelParameterName]; }
61    }
62
63    public IFixedValueParameter<BoolValue> ScaleInputVariablesParameter {
64      get { return (IFixedValueParameter<BoolValue>)Parameters[ScaleInputVariablesParameterName]; }
65    }
66
67    public IFixedValueParameter<DoubleValue> LogLambdaParameter {
68      get { return (IFixedValueParameter<DoubleValue>)Parameters[LambdaParameterName]; }
69    }
70
71    public IFixedValueParameter<DoubleValue> BetaParameter {
72      get { return (IFixedValueParameter<DoubleValue>)Parameters[BetaParameterName]; }
73    }
74    #endregion
75
76    #region properties
77    public IKernel Kernel {
78      get { return KernelParameter.Value; }
79    }
80
81    public bool ScaleInputVariables {
82      get { return ScaleInputVariablesParameter.Value.Value; }
83      set { ScaleInputVariablesParameter.Value.Value = value; }
84    }
85
86    public double LogLambda {
87      get { return LogLambdaParameter.Value.Value; }
88      set { LogLambdaParameter.Value.Value = value; }
89    }
90
91    public double Beta {
92      get { return BetaParameter.Value.Value; }
93      set { BetaParameter.Value.Value = value; }
94    }
95    #endregion
96
97    [StorableConstructor]
98    private KernelRidgeRegression(bool deserializing) : base(deserializing) { }
99    private KernelRidgeRegression(KernelRidgeRegression original, Cloner cloner)
100      : base(original, cloner) {
101    }
102    public KernelRidgeRegression() {
103      Problem = new RegressionProblem();
104      Parameters.Add(new ValueParameter<IKernel>(KernelParameterName, "The kernel", new GaussianKernel()));
105      Parameters.Add(new FixedValueParameter<BoolValue>(ScaleInputVariablesParameterName, "Set to true if the input variables should be scaled to the interval [0..1]", new BoolValue(true)));
106      Parameters.Add(new FixedValueParameter<DoubleValue>(LambdaParameterName, "The log10-transformed weight for the regularization term lambda [-inf..+inf]. Small values produce more complex models, large values produce models with larger errors. Set to very small value (e.g. -1.0e15) for almost exact approximation", new DoubleValue(-2)));
107      Parameters.Add(new FixedValueParameter<DoubleValue>(BetaParameterName, "The beta parameter for the kernel", new DoubleValue(2)));
108    }
109    [StorableHook(HookType.AfterDeserialization)]
110    private void AfterDeserialization() { }
111
112    public override IDeepCloneable Clone(Cloner cloner) {
113      return new KernelRidgeRegression(this, cloner);
114    }
115
116    protected override void Run(CancellationToken cancellationToken) {
117      double rmsError, looCvRMSE;
118      var kernel = Kernel;
119      kernel.Beta = Beta;
120      var solution = CreateRadialBasisRegressionSolution(Problem.ProblemData, kernel, Math.Pow(10, LogLambda), ScaleInputVariables, out rmsError, out looCvRMSE);
121      Results.Add(new Result(SolutionResultName, "The kernel ridge regression solution.", solution));
122      Results.Add(new Result("RMSE (test)", "The root mean squared error of the solution on the test set.", new DoubleValue(rmsError)));
123      Results.Add(new Result("RMSE (LOO-CV)", "The leave-one-out-cross-validation root mean squared error", new DoubleValue(looCvRMSE)));
124    }
125
126    public static IRegressionSolution CreateRadialBasisRegressionSolution(IRegressionProblemData problemData, ICovarianceFunction kernel, double lambda, bool scaleInputs, out double rmsError, out double looCvRMSE) {
127      var model = new KernelRidgeRegressionModel(problemData.Dataset, problemData.TargetVariable, problemData.AllowedInputVariables, problemData.TrainingIndices, scaleInputs, kernel, lambda);
128      rmsError = double.NaN;
129      if (problemData.TestIndices.Any()) {
130        rmsError = Math.Sqrt(model.GetEstimatedValues(problemData.Dataset, problemData.TestIndices)
131          .Zip(problemData.TargetVariableTestValues, (a, b) => (a - b) * (a - b))
132          .Average());
133      }
134      var solution = model.CreateRegressionSolution((IRegressionProblemData)problemData.Clone());
135      solution.Model.Name = "Kernel ridge regression model";
136      solution.Name = SolutionResultName;
137      looCvRMSE = model.LooCvRMSE;
138      return solution;
139    }
140  }
141}
Note: See TracBrowser for help on using the repository browser.