Free cookie consent management tool by TermsFeed Policy Generator

Ignore:
Timestamp:
11/19/15 11:59:51 (8 years ago)
Author:
gkronber
Message:

#1967: partial merge of r13160 from trunk to stable

Location:
stable/HeuristicLab.Algorithms.DataAnalysis
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • stable/HeuristicLab.Algorithms.DataAnalysis

  • stable/HeuristicLab.Algorithms.DataAnalysis/3.4/GaussianProcess/GaussianProcessCovarianceOptimizationProblem.cs

    r13286 r13287  
    2626using HeuristicLab.Data;
    2727using HeuristicLab.Encodings.SymbolicExpressionTreeEncoding;
     28using HeuristicLab.Optimization;
    2829using HeuristicLab.Parameters;
    2930using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
     
    233234    }
    234235
    235     public void ObjectiveFunction(double[] x, ref double func, double[] grad, object obj) {
     236    public override void Analyze(ISymbolicExpressionTree[] trees, double[] qualities, ResultCollection results, IRandom random) {
     237      if (!results.ContainsKey("Best Solution Quality")) {
     238        results.Add(new Result("Best Solution Quality", typeof(DoubleValue)));
     239      }
     240      if (!results.ContainsKey("Best Tree")) {
     241        results.Add(new Result("Best Tree", typeof(ISymbolicExpressionTree)));
     242      }
     243      if (!results.ContainsKey("Best Solution")) {
     244        results.Add(new Result("Best Solution", typeof(GaussianProcessRegressionSolution)));
     245      }
     246
     247      var bestQuality = qualities.Max();
     248
     249      if (results["Best Solution Quality"].Value == null || bestQuality > ((DoubleValue)results["Best Solution Quality"].Value).Value) {
     250        var bestIdx = Array.IndexOf(qualities, bestQuality);
     251        var bestClone = (ISymbolicExpressionTree)trees[bestIdx].Clone();
     252        results["Best Tree"].Value = bestClone;
     253        results["Best Solution Quality"].Value = new DoubleValue(bestQuality);
     254        results["Best Solution"].Value = CreateSolution(bestClone, random);
     255      }
     256    }
     257
     258    private IItem CreateSolution(ISymbolicExpressionTree tree, IRandom random) {
     259      // again tune the hyper-parameters.
     260      // this is suboptimal because 1) more effort and 2) we cannot be sure to find the same local optimum
     261      var meanFunction = new MeanConst();
     262      var problemData = ProblemData;
     263      var ds = problemData.Dataset;
     264      var targetVariable = problemData.TargetVariable;
     265      var allowedInputVariables = problemData.AllowedInputVariables.ToArray();
     266      var nVars = allowedInputVariables.Length;
     267      var trainingRows = problemData.TrainingIndices.ToArray();
     268      var bestObjValue = new double[1] { double.MinValue };
     269
     270      // use the same covariance function for each restart
     271      var covarianceFunction = TreeToCovarianceFunction(tree);
     272      // data that is necessary for the objective function
     273      var data = Tuple.Create(ds, targetVariable, allowedInputVariables, trainingRows, (IMeanFunction)meanFunction, covarianceFunction, bestObjValue);
     274
     275      // allocate hyperparameters
     276      var hyperParameters = new double[meanFunction.GetNumberOfParameters(nVars) + covarianceFunction.GetNumberOfParameters(nVars) + 1]; // mean + cov + noise
     277
     278      // initialize hyperparameters
     279      hyperParameters[0] = ds.GetDoubleValues(targetVariable).Average(); // mean const
     280
     281      for (int i = 0; i < covarianceFunction.GetNumberOfParameters(nVars); i++) {
     282        hyperParameters[1 + i] = random.NextDouble() * 2.0 - 1.0;
     283      }
     284      hyperParameters[hyperParameters.Length - 1] = 1.0; // s² = exp(2), TODO: other inits better?
     285
     286      // use alglib.bfgs for hyper-parameter optimization ...
     287      double epsg = 0;
     288      double epsf = 0.00001;
     289      double epsx = 0;
     290      double stpmax = 1;
     291      int maxits = ConstantOptIterations;
     292      alglib.mincgstate state;
     293      alglib.mincgreport rep;
     294
     295      alglib.mincgcreate(hyperParameters, out state);
     296      alglib.mincgsetcond(state, epsg, epsf, epsx, maxits);
     297      alglib.mincgsetstpmax(state, stpmax);
     298      alglib.mincgoptimize(state, ObjectiveFunction, null, data);
     299
     300      alglib.mincgresults(state, out hyperParameters, out rep);
     301
     302      if (rep.terminationtype >= 0) {
     303
     304        var model = new GaussianProcessModel(ds, targetVariable, allowedInputVariables, trainingRows, hyperParameters, meanFunction, covarianceFunction);
     305        return model.CreateRegressionSolution(ProblemData);
     306      } else return null;
     307    }
     308
     309    private void ObjectiveFunction(double[] x, ref double func, double[] grad, object obj) {
    236310      // we want to optimize the model likelihood by changing the hyperparameters and also return the gradient for each hyperparameter
    237311      var data = (Tuple<IDataset, string, string[], int[], IMeanFunction, ICovarianceFunction, double[]>)obj;
     
    252326        var gradients = model.HyperparameterGradients;
    253327        Array.Copy(gradients, grad, gradients.Length);
    254       } catch (Exception) {
     328      } catch (ArgumentException) {
    255329        // building the GaussianProcessModel might fail, in this case we return the worst possible objective value
    256330        func = 1.0E+300;
Note: See TracChangeset for help on using the changeset viewer.