Changeset 14888


Ignore:
Timestamp:
04/25/17 09:42:18 (2 years ago)
Author:
gkronber
Message:

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

Location:
branches/RBFRegression/HeuristicLab.Algorithms.DataAnalysis/3.4/KernelRidgeRegression
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • branches/RBFRegression/HeuristicLab.Algorithms.DataAnalysis/3.4/KernelRidgeRegression/KernelRidgeRegression.cs

    r14887 r14888  
    115115
    116116    protected override void Run(CancellationToken cancellationToken) {
    117       double rmsError;
     117      double rmsError, looCvRMSE;
    118118      var kernel = Kernel;
    119119      kernel.Beta = Beta;
    120       var solution = CreateRadialBasisRegressionSolution(Problem.ProblemData, kernel, Math.Pow(10, LogLambda), ScaleInputVariables, out rmsError);
     120      var solution = CreateRadialBasisRegressionSolution(Problem.ProblemData, kernel, Math.Pow(10, LogLambda), ScaleInputVariables, out rmsError, out looCvRMSE);
    121121      Results.Add(new Result(SolutionResultName, "The kernel ridge regression solution.", solution));
    122122      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)));
    123124    }
    124125
    125     public static IRegressionSolution CreateRadialBasisRegressionSolution(IRegressionProblemData problemData, ICovarianceFunction kernel, double lambda, bool scaleInputs, out double rmsError) {
     126    public static IRegressionSolution CreateRadialBasisRegressionSolution(IRegressionProblemData problemData, ICovarianceFunction kernel, double lambda, bool scaleInputs, out double rmsError, out double looCvRMSE) {
    126127      var model = new KernelRidgeRegressionModel(problemData.Dataset, problemData.TargetVariable, problemData.AllowedInputVariables, problemData.TrainingIndices, scaleInputs, kernel, lambda);
    127128      rmsError = double.NaN;
     
    134135      solution.Model.Name = "Kernel ridge regression model";
    135136      solution.Name = SolutionResultName;
     137      looCvRMSE = model.LooCvRMSE;
    136138      return solution;
    137139    }
  • branches/RBFRegression/HeuristicLab.Algorithms.DataAnalysis/3.4/KernelRidgeRegression/KernelRidgeRegressionModel.cs

    r14887 r14888  
    2121
    2222using System;
    23 using System.Collections.Generic;   
     23using System.Collections.Generic;
    2424using System.Linq;
    2525using HeuristicLab.Common;
     
    4242    }
    4343
     44
     45    [Storable]
     46    public double LooCvRMSE { get; private set; }
     47
    4448    [Storable]
    4549    private readonly double[] alpha;
     
    5862
    5963    [Storable]
    60     private readonly double yOffset; // implementation works for zero-mean target variables
     64    private readonly double yOffset; // implementation works for zero-mean, unit-variance target variables
    6165
    6266    [Storable]
     
    7377      scaling = original.scaling;
    7478      lambda = original.lambda;
     79      LooCvRMSE = original.LooCvRMSE;
    7580
    7681      yOffset = original.yOffset;
     
    104109        }
    105110        int info;
     111        int n = trainX.GetLength(0);
    106112        alglib.densesolverreport denseSolveRep;
    107         var gram = BuildGramMatrix(trainX, lambda); 
    108         int n = trainX.GetLength(0);
     113        var gram = BuildGramMatrix(trainX, lambda);
     114        var l = new double[n, n]; Array.Copy(gram, l, l.Length);
    109115
    110116        // cholesky decomposition
    111         var res = alglib.trfac.spdmatrixcholesky(ref gram, n, false);
    112         if(res == false) throw new ArgumentException("Could not decompose matrix. Is it quadratic symmetric positive definite?");
    113 
    114         alglib.spdmatrixcholeskysolve(gram, n, false, y, out info, out denseSolveRep, out alpha);
     117        var res = alglib.trfac.spdmatrixcholesky(ref l, n, false);
     118        if (res == false) throw new ArgumentException("Could not decompose matrix. Is it quadratic symmetric positive definite?");
     119
     120        alglib.spdmatrixcholeskysolve(l, n, false, y, out info, out denseSolveRep, out alpha);
    115121        if (info != 1) throw new ArgumentException("Could not create model.");
     122
     123
     124        {
     125          // for LOO-CV we need to build the inverse of the gram matrix
     126          alglib.matinvreport rep;
     127          var invG = l;   // rename
     128          alglib.spdmatrixcholeskyinverse(ref invG, n, false, out info, out rep);         
     129          if (info != 1) throw new ArgumentException("Could not invert Gram matrix.");
     130          var ssqLooError = 0.0;
     131          for (int i = 0; i < n; i++) {
     132            var pred_i = Util.ScalarProd(Util.GetRow(gram, i).ToArray(), alpha);
     133            var looPred_i = pred_i - alpha[i] / invG[i, i];
     134            var error = (y[i] - looPred_i) / yScale;
     135            ssqLooError += error * error;
     136          }
     137          LooCvRMSE = Math.Sqrt(ssqLooError / n);
     138        }
    116139      } catch (alglib.alglibexception ae) {
    117140        // wrap exception so that calling code doesn't have to know about alglib implementation
     
    151174      for (var i = 0; i < n; i++) {
    152175        for (var j = i; j < n; j++) {
    153           gram[j, i] = cov.Covariance(data, i, j); // symmetric matrix --> fill only lower triangle
     176          gram[i, j] = gram[j, i] = cov.Covariance(data, i, j); // symmetric matrix
    154177        }
    155178        gram[i, i] += lambda;
Note: See TracChangeset for help on using the changeset viewer.