Free cookie consent management tool by TermsFeed Policy Generator

Ignore:
Timestamp:
08/09/12 16:32:44 (12 years ago)
Author:
gkronber
Message:

#1902 improved GPR implementation

Location:
trunk/sources/HeuristicLab.Algorithms.DataAnalysis/3.4
Files:
10 edited

Legend:

Unmodified
Added
Removed
  • trunk/sources/HeuristicLab.Algorithms.DataAnalysis/3.4/GaussianProcess/CovariancePeriodic.cs

    r8455 r8463  
    102102    }
    103103
    104 
    105     public double[] GetDiagonalCovariances() {
    106       if (x != xt) throw new InvalidOperationException();
    107       int rows = x.GetLength(0);
    108       var cov = new double[rows];
    109       for (int i = 0; i < rows; i++) {
    110         double k = Math.Sqrt(Util.SqrDist(Util.GetRow(x, i), Util.GetRow(xt, i)));
    111         k = Math.PI * k / p;
    112         k = Math.Sin(k) / l;
    113         k = k * k;
    114         cov[i] = sf2 * Math.Exp(-2.0 * k);
    115       }
    116       return cov;
    117     }
    118 
    119104    public double GetGradient(int i, int j, int k) {
    120105      double v = Math.PI * sd[i, j] / p;
  • trunk/sources/HeuristicLab.Algorithms.DataAnalysis/3.4/GaussianProcess/CovarianceProd.cs

    r8455 r8463  
    2020#endregion
    2121
     22using System;
     23using System.Collections.Generic;
    2224using System.Linq;
    2325using HeuristicLab.Common;
     
    4850      this.factors = cloner.Clone(original.factors);
    4951      this.numberOfVariables = original.numberOfVariables;
     52      AttachEventHandlers();
    5053    }
    5154
     
    5356      : base() {
    5457      this.factors = new ItemList<ICovarianceFunction>();
     58      AttachEventHandlers();
     59    }
     60
     61    private void AttachEventHandlers() {
     62      this.factors.CollectionReset += (sender, args) => ClearCache();
     63      this.factors.ItemsAdded += (sender, args) => ClearCache();
     64      this.factors.ItemsRemoved += (sender, args) => ClearCache();
     65      this.factors.ItemsReplaced += (sender, args) => ClearCache();
     66      this.factors.ItemsMoved += (sender, args) => ClearCache();
    5567    }
    5668
     
    8698    }
    8799
     100    private Dictionary<int, Tuple<int, int>> cachedParameterMap;
    88101    public double GetGradient(int i, int j, int k) {
    89       // map from parameter index to factor
    90       var vi = factors.Select((f, idx) => Enumerable.Repeat(idx, f.GetNumberOfParameters(numberOfVariables))).SelectMany(x => x).ToArray();
     102      if (cachedParameterMap == null) {
     103        CalculateParameterMap();
     104      }
     105      int ti = cachedParameterMap[k].Item1;
     106      k = cachedParameterMap[k].Item2;
    91107      double res = 1.0;
    92       int jj = Enumerable.Range(0, k).Count(e => vi[e] == vi[k]);
    93108      for (int ii = 0; ii < factors.Count; ii++) {
    94109        var f = factors[ii];
    95         if (ii == vi[k]) {
    96           res *= f.GetGradient(i, j, jj);
     110        if (ii == ti) {
     111          res *= f.GetGradient(i, j, k);
    97112        } else {
    98113          res *= f.GetCovariance(i, j);
     
    101116      return res;
    102117    }
     118
     119    private void ClearCache() {
     120      cachedParameterMap = null;
     121    }
     122
     123    private void CalculateParameterMap() {
     124      cachedParameterMap = new Dictionary<int, Tuple<int, int>>();
     125      int k = 0;
     126      for (int ti = 0; ti < factors.Count; ti++) {
     127        for (int ti_k = 0; ti_k < factors[ti].GetNumberOfParameters(numberOfVariables); ti_k++) {
     128          cachedParameterMap[k++] = Tuple.Create(ti, ti_k);
     129        }
     130      }
     131    }
    103132  }
    104133}
  • trunk/sources/HeuristicLab.Algorithms.DataAnalysis/3.4/GaussianProcess/CovarianceSEiso.cs

    r8455 r8463  
    114114      int cols = xt.GetLength(0);
    115115      sd = new double[rows, cols];
     116      double lInv = 1.0 / l;
    116117      if (symmetric) {
    117118        for (int i = 0; i < rows; i++) {
    118119          for (int j = i; j < rows; j++) {
    119             sd[i, j] = Util.SqrDist(Util.GetRow(x, i).Select(e => e / l), Util.GetRow(xt, j).Select(e => e / l));
     120            sd[i, j] = Util.SqrDist(Util.GetRow(x, i).Select(e => e * lInv), Util.GetRow(xt, j).Select(e => e * lInv));
    120121            sd[j, i] = sd[i, j];
    121122          }
     
    124125        for (int i = 0; i < rows; i++) {
    125126          for (int j = 0; j < cols; j++) {
    126             sd[i, j] = Util.SqrDist(Util.GetRow(x, i).Select(e => e / l), Util.GetRow(xt, j).Select(e => e / l));
     127            sd[i, j] = Util.SqrDist(Util.GetRow(x, i).Select(e => e * lInv), Util.GetRow(xt, j).Select(e => e * lInv));
    127128          }
    128129        }
  • trunk/sources/HeuristicLab.Algorithms.DataAnalysis/3.4/GaussianProcess/CovarianceSum.cs

    r8455 r8463  
    2020#endregion
    2121
     22using System;
     23using System.Collections.Generic;
    2224using System.Linq;
    2325using HeuristicLab.Common;
     
    4850      this.terms = cloner.Clone(original.terms);
    4951      this.numberOfVariables = original.numberOfVariables;
     52      AttachEventHandlers();
    5053    }
    5154
     
    5356      : base() {
    5457      this.terms = new ItemList<ICovarianceFunction>();
     58      AttachEventHandlers();
     59    }
     60
     61    private void AttachEventHandlers() {
     62      this.terms.CollectionReset += (sender, args) => ClearCache();
     63      this.terms.ItemsAdded += (sender, args) => ClearCache();
     64      this.terms.ItemsRemoved += (sender, args) => ClearCache();
     65      this.terms.ItemsReplaced += (sender, args) => ClearCache();
     66      this.terms.ItemsMoved += (sender, args) => ClearCache();
    5567    }
    5668
     
    8698    }
    8799
     100    private Dictionary<int, Tuple<int, int>> cachedParameterMap;
    88101    public double GetGradient(int i, int j, int k) {
    89       int ii = 0;
    90       while (k > terms[ii].GetNumberOfParameters(numberOfVariables)) {
    91         k -= terms[ii].GetNumberOfParameters(numberOfVariables);
     102      if (cachedParameterMap == null) {
     103        CalculateParameterMap();
    92104      }
    93       return terms[ii].GetGradient(i, j, k);
     105      int ti = cachedParameterMap[k].Item1;
     106      k = cachedParameterMap[k].Item2;
     107      return terms[ti].GetGradient(i, j, k);
     108    }
     109    private void ClearCache() {
     110      cachedParameterMap = null;
     111    }
     112
     113    private void CalculateParameterMap() {
     114      cachedParameterMap = new Dictionary<int, Tuple<int, int>>();
     115      int k = 0;
     116      for (int ti = 0; ti < terms.Count; ti++) {
     117        for (int ti_k = 0; ti_k < terms[ti].GetNumberOfParameters(numberOfVariables); ti_k++) {
     118          cachedParameterMap[k++] = Tuple.Create(ti, ti_k);
     119        }
     120      }
    94121    }
    95122  }
  • trunk/sources/HeuristicLab.Algorithms.DataAnalysis/3.4/GaussianProcess/GaussianProcessHyperparameterInitializer.cs

    r8419 r8463  
    9191      var rand = RandomParameter.ActualValue;
    9292      for (int i = 0; i < r.Length; i++)
    93         r[i] = rand.NextDouble() * 4 - 2;
     93        r[i] = rand.NextDouble() * 2 - 1;
    9494
    9595      HyperparameterParameter.ActualValue = r;
  • trunk/sources/HeuristicLab.Algorithms.DataAnalysis/3.4/GaussianProcess/GaussianProcessModel.cs

    r8455 r8463  
    7373    private double[,] x;
    7474    [Storable]
    75     private Scaling scaling;
     75    private Scaling inputScaling;
     76    [Storable]
     77    private Scaling targetScaling;
    7678
    7779
     
    8284      this.meanFunction = cloner.Clone(original.meanFunction);
    8385      this.covarianceFunction = cloner.Clone(original.covarianceFunction);
    84       this.scaling = cloner.Clone(original.scaling);
     86      this.inputScaling = cloner.Clone(original.inputScaling);
     87      this.targetScaling = cloner.Clone(original.targetScaling);
    8588      this.negativeLogLikelihood = original.negativeLogLikelihood;
    8689      this.targetVariable = original.targetVariable;
     
    118121
    119122    private void CalculateModel(Dataset ds, IEnumerable<int> rows) {
    120       scaling = new Scaling(ds, allowedInputVariables, rows);
    121       x = AlglibUtil.PrepareAndScaleInputMatrix(ds, allowedInputVariables, rows, scaling);
    122 
    123       var y = ds.GetDoubleValues(targetVariable, rows).ToArray();
     123      inputScaling = new Scaling(ds, allowedInputVariables, rows);
     124      x = AlglibUtil.PrepareAndScaleInputMatrix(ds, allowedInputVariables, rows, inputScaling);
     125
     126
     127      targetScaling = new Scaling(ds, new string[] { targetVariable }, rows);
     128      var y = targetScaling.GetScaledValues(ds, targetVariable, rows);
    124129
    125130      int n = x.GetLength(0);
     
    162167      int n = x.GetLength(0);
    163168      int nAllowedVariables = x.GetLength(1);
    164       double[,] q = new double[n, n];
    165       double[,] eye = new double[n, n];
    166       for (int i = 0; i < n; i++) eye[i, i] = 1.0;
    167169
    168170      int info;
    169       alglib.densesolverreport denseSolveRep;
    170 
    171       alglib.spdmatrixcholeskysolvem(l, n, false, eye, n, out info, out denseSolveRep, out q);
    172       // double[,] a2 = outerProd(alpha, alpha);
     171      alglib.matinvreport matInvRep;
     172
     173      alglib.spdmatrixcholeskyinverse(ref l, n, false, out info, out matInvRep);
     174      if (info != 1) throw new ArgumentException("Can't invert matrix to calculate gradients.");
    173175      for (int i = 0; i < n; i++) {
    174         for (int j = 0; j < n; j++)
    175           q[i, j] = q[i, j] / sqrSigmaNoise - alpha[i] * alpha[j]; // a2[i, j];
    176       }
    177 
    178       double noiseGradient = sqrSigmaNoise * Enumerable.Range(0, n).Select(i => q[i, i]).Sum();
     176        for (int j = 0; j <= i; j++)
     177          l[i, j] = l[i, j] / sqrSigmaNoise - alpha[i] * alpha[j];
     178      }
     179
     180      double noiseGradient = sqrSigmaNoise * Enumerable.Range(0, n).Select(i => l[i, i]).Sum();
    179181
    180182      double[] meanGradients = new double[meanFunction.GetNumberOfParameters(nAllowedVariables)];
     
    187189      if (covGradients.Length > 0) {
    188190        for (int i = 0; i < n; i++) {
    189           for (int j = 0; j < n; j++) {
    190             for (int k = 0; k < covGradients.Length; k++) {
    191               covGradients[k] += q[i, j] * covarianceFunction.GetGradient(i, j, k);
     191          for (int k = 0; k < covGradients.Length; k++) {
     192            for (int j = 0; j < i; j++) {
     193              covGradients[k] += l[i, j] * covarianceFunction.GetGradient(i, j, k);
    192194            }
     195            covGradients[k] += 0.5 * l[i, i] * covarianceFunction.GetGradient(i, i, k);
    193196          }
    194197        }
    195         covGradients = covGradients.Select(g => g / 2.0).ToArray();
    196198      }
    197199
     
    219221
    220222    private IEnumerable<double> GetEstimatedValuesHelper(Dataset dataset, IEnumerable<int> rows) {
    221       var newX = AlglibUtil.PrepareAndScaleInputMatrix(dataset, allowedInputVariables, rows, scaling);
     223      var newX = AlglibUtil.PrepareAndScaleInputMatrix(dataset, allowedInputVariables, rows, inputScaling);
    222224      int newN = newX.GetLength(0);
    223225      int n = x.GetLength(0);
     
    251253      // alglib.rmatrixsolvem(l, n, sWKs, newN, true, out info, out denseSolveRep, out v);
    252254
    253 
    254       for (int i = 0; i < newN; i++) {
    255         // predMean[i] = ms[i] + prod(GetRow(Ks, i), alpha);
    256         yield return ms[i] + Util.ScalarProd(Util.GetRow(Ks, i), alpha);
    257         // var sumV2 = prod(GetCol(v, i), GetCol(v, i));
    258         // predVar[i] = kss[i] - sumV2;
    259       }
     255      double targetScaleMin, targetScaleMax;
     256      targetScaling.GetScalingParameters(targetVariable, out targetScaleMin, out targetScaleMax);
     257      return Enumerable.Range(0, newN)
     258        .Select(i => ms[i] + Util.ScalarProd(Util.GetRow(Ks, i), alpha))
     259        .Select(m => m * (targetScaleMax - targetScaleMin) + targetScaleMin);
     260      //for (int i = 0; i < newN; i++) {
     261      //  // predMean[i] = ms[i] + prod(GetRow(Ks, i), alpha);
     262      //  // var sumV2 = prod(GetCol(v, i), GetCol(v, i));
     263      //  // predVar[i] = kss[i] - sumV2;
     264      //}
    260265
    261266    }
  • trunk/sources/HeuristicLab.Algorithms.DataAnalysis/3.4/GaussianProcess/GaussianProcessRegressionSolutionCreator.cs

    r8416 r8463  
    7575
    7676    public override IOperation Apply() {
    77       var m = ModelParameter.ActualValue;
    78       var data = ProblemDataParameter.ActualValue;
     77      var m = (IGaussianProcessModel)ModelParameter.ActualValue.Clone();
     78      var data = (IRegressionProblemData)ProblemDataParameter.ActualValue.Clone();
    7979      var s = new GaussianProcessRegressionSolution(m, data);
    8080
  • trunk/sources/HeuristicLab.Algorithms.DataAnalysis/3.4/GaussianProcess/MeanProd.cs

    r8439 r8463  
    8282    public double[] GetGradients(int k, double[,] x) {
    8383      double[] res = Enumerable.Repeat(1.0, x.GetLength(0)).ToArray();
    84       foreach (var f in factors) {
    85         var numParam = f.GetNumberOfParameters(numberOfVariables);
    86         if (k >= 0 && k < numParam) {
     84      // find index of factor for the given k
     85      int j = 0;
     86      while (k >= factors[j].GetNumberOfParameters(numberOfVariables)) {
     87        k -= factors[j].GetNumberOfParameters(numberOfVariables);
     88        j++;
     89      }
     90      for (int i = 0; i < factors.Count; i++) {
     91        var f = factors[i];
     92        if (i == j) {
    8793          // multiply gradient
    8894          var g = f.GetGradients(k, x);
    89           for (int i = 0; i < res.Length; i++) res[i] *= g[i];
    90           k -= numParam;
     95          for (int ii = 0; ii < res.Length; ii++) res[ii] *= g[ii];
    9196        } else {
    9297          // multiply mean
    9398          var m = f.GetMean(x);
    94           for (int i = 0; i < res.Length; i++) res[i] *= m[i];
    95           k -= numParam;
     99          for (int ii = 0; ii < res.Length; ii++) res[ii] *= m[ii];
    96100        }
    97101      }
  • trunk/sources/HeuristicLab.Algorithms.DataAnalysis/3.4/GaussianProcess/Util.cs

    r8401 r8463  
    2020#endregion
    2121
    22 using System;
    2322using System.Collections.Generic;
    2423using System.Linq;
     
    3231    public static double SqrDist(double x, double y) {
    3332      double d = x - y;
    34       return Math.Max(d * d, 0.0);
     33      return d * d;
    3534    }
    3635
    3736    public static double SqrDist(IEnumerable<double> x, IEnumerable<double> y) {
    38       return x.Zip(y, SqrDist).Sum();
     37      return x.Zip(y, (a, b) => (a - b) * (a - b)).Sum();
    3938    }
    4039
  • trunk/sources/HeuristicLab.Algorithms.DataAnalysis/3.4/Linear/Scaling.cs

    r8416 r8463  
    5959      return ds.GetDoubleValues(variable, rows).Select(x => (x - min) / (max - min));
    6060    }
     61
     62    public void GetScalingParameters(string variable, out double min, out double max) {
     63      min = scalingParameters[variable].Item1;
     64      max = scalingParameters[variable].Item2;
     65    }
    6166  }
    6267}
Note: See TracChangeset for help on using the changeset viewer.