private double ComputeEI(double bestVal, double[] forestStatistics, bool isMetricMaximizing) { double empMean = forestStatistics[0]; double empStdDev = forestStatistics[1]; double centered = empMean - bestVal; if (!isMetricMaximizing) { centered *= -1; } if (empStdDev == 0) { return(centered); } double ztrans = centered / empStdDev; return(centered * SweeperProbabilityUtils.StdNormalCdf(ztrans) + empStdDev * SweeperProbabilityUtils.StdNormalPdf(ztrans)); }
/// <summary> /// Goes through forest to extract the set of leaf values associated with filtering each configuration. /// </summary> /// <param name="forest">Trained forest predictor, used for filtering configs.</param> /// <param name="configs">Parameter configurations.</param> /// <returns>2D array where rows correspond to configurations, and columns to the predicted leaf values.</returns> private double[][] GetForestRegressionLeafValues(FastForestRegressionModelParameters forest, ParameterSet[] configs) { List <double[]> datasetLeafValues = new List <double[]>(); foreach (ParameterSet config in configs) { List <double> leafValues = new List <double>(); for (var treeId = 0; treeId < forest.TrainedTreeEnsemble.Trees.Count; treeId++) { Float[] transformedParams = SweeperProbabilityUtils.ParameterSetAsFloatArray(_sweepParameters, config, true); VBuffer <Float> features = new VBuffer <Float>(transformedParams.Length, transformedParams); var leafId = GetLeaf(forest, treeId, features); var leafValue = GetLeafValue(forest, treeId, leafId); leafValues.Add(leafValue); } datasetLeafValues.Add(leafValues.ToArray()); } return(datasetLeafValues.ToArray()); }
private FastForestRegressionModelParameters FitModel(IEnumerable <IRunResult> previousRuns) { Single[] targets = new Single[previousRuns.Count()]; Single[][] features = new Single[previousRuns.Count()][]; int i = 0; foreach (RunResult r in previousRuns) { features[i] = SweeperProbabilityUtils.ParameterSetAsFloatArray(_sweepParameters, r.ParameterSet, true); targets[i] = (Float)r.MetricValue; i++; } ArrayDataViewBuilder dvBuilder = new ArrayDataViewBuilder(_context); dvBuilder.AddColumn(DefaultColumnNames.Label, NumberDataViewType.Single, targets); dvBuilder.AddColumn(DefaultColumnNames.Features, NumberDataViewType.Single, features); IDataView data = dvBuilder.GetDataView(); Runtime.Contracts.Assert(data.GetRowCount() == targets.Length, "This data view will have as many rows as there have been evaluations"); // Set relevant random forest arguments. // Train random forest. var trainer = _context.Regression.Trainers.FastForest(new FastForestRegressionTrainer.Options() { FeatureFraction = _args.SplitRatio, NumberOfTrees = _args.NumOfTrees, MinimumExampleCountPerLeaf = _args.NMinForSplit }); var predictor = trainer.Fit(data).Model; // Return random forest predictor. return(predictor); }
/// <summary> /// Computes a single-mutation neighborhood (one parameter at a time) for a given configuration. For /// numeric parameters, samples K mutations (i.e., creates K neighbors based on that parameter). /// </summary> /// <param name="parent">Starting configuration.</param> /// <returns>A set of configurations that each differ from parent in exactly one parameter.</returns> private ParameterSet[] GetOneMutationNeighborhood(ParameterSet parent) { List <ParameterSet> neighbors = new List <ParameterSet>(); SweeperProbabilityUtils spu = new SweeperProbabilityUtils(); for (int i = 0; i < _sweepParameters.Length; i++) { // This allows us to query possible values of this parameter. IValueGenerator sweepParam = _sweepParameters[i]; // This holds the actual value for this parameter, chosen in this parameter set. IParameterValue pset = parent[sweepParam.Name]; Runtime.Contracts.Assert(pset != null); DiscreteValueGenerator parameterDiscrete = sweepParam as DiscreteValueGenerator; if (parameterDiscrete != null) { // Create one neighbor for every discrete parameter. Float[] neighbor = SweeperProbabilityUtils.ParameterSetAsFloatArray(_sweepParameters, parent, false); int hotIndex = -1; for (int j = 0; j < parameterDiscrete.Count; j++) { if (parameterDiscrete[j].Equals(pset)) { hotIndex = j; break; } } Runtime.Contracts.Assert(hotIndex >= 0); Random r = new Random(); int randomIndex = r.Next(0, parameterDiscrete.Count - 1); randomIndex += randomIndex >= hotIndex ? 1 : 0; neighbor[i] = randomIndex; neighbors.Add(SweeperProbabilityUtils.FloatArrayAsParameterSet(_sweepParameters, neighbor, false)); } else { INumericValueGenerator parameterNumeric = sweepParam as INumericValueGenerator; Runtime.Contracts.Assert(parameterNumeric != null, "SMAC sweeper can only sweep over discrete and numeric parameters"); // Create k neighbors (typically 4) for every numerical parameter. for (int j = 0; j < _args.NumNeighborsForNumericalParams; j++) { Float[] neigh = SweeperProbabilityUtils.ParameterSetAsFloatArray(_sweepParameters, parent, false); double newVal = spu.NormalRVs(1, neigh[i], 0.2)[0]; while (newVal <= 0.0 || newVal >= 1.0) { newVal = spu.NormalRVs(1, neigh[i], 0.2)[0]; } neigh[i] = (Float)newVal; ParameterSet neighbor = SweeperProbabilityUtils.FloatArrayAsParameterSet(_sweepParameters, neigh, false); neighbors.Add(neighbor); } } } return(neighbors.ToArray()); }