Free cookie consent management tool by TermsFeed Policy Generator

Ignore:
Timestamp:
03/09/16 12:05:50 (9 years ago)
Author:
mkommend
Message:

#2584: Added parameter in constant optimization that determines whether variable weights should be modified.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/sources/HeuristicLab.Problems.DataAnalysis.Symbolic.Regression/3.4/SingleObjective/Evaluators/SymbolicRegressionConstantOptimizationEvaluator.cs

    r13300 r13670  
    4040    private const string ConstantOptimizationRowsPercentageParameterName = "ConstantOptimizationRowsPercentage";
    4141    private const string UpdateConstantsInTreeParameterName = "UpdateConstantsInSymbolicExpressionTree";
     42    private const string UpdateVariableWeightsParameterName = "Update Variable Weights";
    4243
    4344    public IFixedValueParameter<IntValue> ConstantOptimizationIterationsParameter {
     
    5657      get { return (IFixedValueParameter<BoolValue>)Parameters[UpdateConstantsInTreeParameterName]; }
    5758    }
     59    public IFixedValueParameter<BoolValue> UpdateVariableWeightsParameter {
     60      get { return (IFixedValueParameter<BoolValue>)Parameters[UpdateVariableWeightsParameterName]; }
     61    }
     62
    5863
    5964    public IntValue ConstantOptimizationIterations {
     
    7277      get { return UpdateConstantsInTreeParameter.Value.Value; }
    7378      set { UpdateConstantsInTreeParameter.Value.Value = value; }
     79    }
     80
     81    public bool UpdateVariableWeights {
     82      get { return UpdateVariableWeightsParameter.Value.Value; }
     83      set { UpdateVariableWeightsParameter.Value.Value = value; }
    7484    }
    7585
     
    90100      Parameters.Add(new FixedValueParameter<PercentValue>(ConstantOptimizationRowsPercentageParameterName, "Determines the percentage of the rows which should be used for constant optimization", new PercentValue(1), true));
    91101      Parameters.Add(new FixedValueParameter<BoolValue>(UpdateConstantsInTreeParameterName, "Determines if the constants in the tree should be overwritten by the optimized constants.", new BoolValue(true)));
     102      Parameters.Add(new FixedValueParameter<BoolValue>(UpdateVariableWeightsParameterName, "Determines if the variable weights in the tree should be  optimized.", new BoolValue(true)));
    92103    }
    93104
     
    100111      if (!Parameters.ContainsKey(UpdateConstantsInTreeParameterName))
    101112        Parameters.Add(new FixedValueParameter<BoolValue>(UpdateConstantsInTreeParameterName, "Determines if the constants in the tree should be overwritten by the optimized constants.", new BoolValue(true)));
     113      if (!Parameters.ContainsKey(UpdateVariableWeightsParameterName))
     114        Parameters.Add(new FixedValueParameter<BoolValue>(UpdateVariableWeightsParameterName, "Determines if the variable weights in the tree should be  optimized.", new BoolValue(true)));
    102115    }
    103116
     
    108121        IEnumerable<int> constantOptimizationRows = GenerateRowsToEvaluate(ConstantOptimizationRowsPercentage.Value);
    109122        quality = OptimizeConstants(SymbolicDataAnalysisTreeInterpreterParameter.ActualValue, solution, ProblemDataParameter.ActualValue,
    110            constantOptimizationRows, ApplyLinearScalingParameter.ActualValue.Value, ConstantOptimizationIterations.Value,
    111            EstimationLimitsParameter.ActualValue.Upper, EstimationLimitsParameter.ActualValue.Lower, UpdateConstantsInTree);
     123           constantOptimizationRows, ApplyLinearScalingParameter.ActualValue.Value, ConstantOptimizationIterations.Value, updateVariableWeights: UpdateVariableWeights, lowerEstimationLimit: EstimationLimitsParameter.ActualValue.Lower, upperEstimationLimit: EstimationLimitsParameter.ActualValue.Upper, updateConstantsInTree: UpdateConstantsInTree);
    112124
    113125        if (ConstantOptimizationRowsPercentage.Value != RelativeNumberOfEvaluatedSamplesParameter.ActualValue.Value) {
     
    164176
    165177
    166     // TODO: swap positions of lowerEstimationLimit and upperEstimationLimit parameters
    167     public static double OptimizeConstants(ISymbolicDataAnalysisExpressionTreeInterpreter interpreter, ISymbolicExpressionTree tree, IRegressionProblemData problemData,
    168       IEnumerable<int> rows, bool applyLinearScaling, int maxIterations, double upperEstimationLimit = double.MaxValue, double lowerEstimationLimit = double.MinValue, bool updateConstantsInTree = true) {
     178    public static double OptimizeConstants(ISymbolicDataAnalysisExpressionTreeInterpreter interpreter, ISymbolicExpressionTree tree, IRegressionProblemData problemData, IEnumerable<int> rows, bool applyLinearScaling, int maxIterations, bool updateVariableWeights = true, double lowerEstimationLimit = double.MinValue, double upperEstimationLimit = double.MaxValue, bool updateConstantsInTree = true) {
    169179
    170180      List<AutoDiff.Variable> variables = new List<AutoDiff.Variable>();
     
    173183
    174184      AutoDiff.Term func;
    175       if (!TryTransformToAutoDiff(tree.Root.GetSubtree(0), variables, parameters, variableNames, out func))
     185      if (!TryTransformToAutoDiff(tree.Root.GetSubtree(0), variables, parameters, variableNames, updateVariableWeights, out func))
    176186        throw new NotSupportedException("Could not optimize constants of symbolic expression tree due to not supported symbols used in the tree.");
    177187      if (variableNames.Count == 0) return 0.0;
    178188
    179       AutoDiff.IParametricCompiledTerm compiledFunc = AutoDiff.TermUtils.Compile(func, variables.ToArray(), parameters.ToArray());
    180 
    181       List<SymbolicExpressionTreeTerminalNode> terminalNodes = tree.Root.IterateNodesPrefix().OfType<SymbolicExpressionTreeTerminalNode>().ToList();
     189      AutoDiff.IParametricCompiledTerm compiledFunc = func.Compile(variables.ToArray(), parameters.ToArray());
     190
     191      List<SymbolicExpressionTreeTerminalNode> terminalNodes = null;
     192      if (updateVariableWeights)
     193        terminalNodes = tree.Root.IterateNodesPrefix().OfType<SymbolicExpressionTreeTerminalNode>().ToList();
     194      else
     195        terminalNodes = new List<SymbolicExpressionTreeTerminalNode>(tree.Root.IterateNodesPrefix().OfType<ConstantTreeNode>());
     196
     197      //extract inital constants
    182198      double[] c = new double[variables.Count];
    183 
    184199      {
    185200        c[0] = 0.0;
    186201        c[1] = 1.0;
    187         //extract inital constants
    188202        int i = 2;
    189203        foreach (var node in terminalNodes) {
     
    192206          if (constantTreeNode != null)
    193207            c[i++] = constantTreeNode.Value;
    194           else if (variableTreeNode != null)
     208          else if (updateVariableWeights && variableTreeNode != null)
    195209            c[i++] = variableTreeNode.Weight;
    196210        }
     
    235249
    236250      //info == -7  => constant optimization failed due to wrong gradient
    237       if (info != -7) UpdateConstants(tree, c.Skip(2).ToArray());
     251      if (info != -7) UpdateConstants(tree, c.Skip(2).ToArray(), updateVariableWeights);
    238252      var quality = SymbolicRegressionSingleObjectivePearsonRSquaredEvaluator.Calculate(interpreter, tree, lowerEstimationLimit, upperEstimationLimit, problemData, rows, applyLinearScaling);
    239253
    240       if (!updateConstantsInTree) UpdateConstants(tree, originalConstants.Skip(2).ToArray());
     254      if (!updateConstantsInTree) UpdateConstants(tree, originalConstants.Skip(2).ToArray(), updateVariableWeights);
    241255      if (originalQuality - quality > 0.001 || double.IsNaN(quality)) {
    242         UpdateConstants(tree, originalConstants.Skip(2).ToArray());
     256        UpdateConstants(tree, originalConstants.Skip(2).ToArray(), updateVariableWeights);
    243257        return originalQuality;
    244258      }
     
    246260    }
    247261
    248     private static void UpdateConstants(ISymbolicExpressionTree tree, double[] constants) {
     262    private static void UpdateConstants(ISymbolicExpressionTree tree, double[] constants, bool updateVariableWeights) {
    249263      int i = 0;
    250264      foreach (var node in tree.Root.IterateNodesPrefix().OfType<SymbolicExpressionTreeTerminalNode>()) {
     
    253267        if (constantTreeNode != null)
    254268          constantTreeNode.Value = constants[i++];
    255         else if (variableTreeNode != null)
     269        else if (updateVariableWeights && variableTreeNode != null)
    256270          variableTreeNode.Weight = constants[i++];
    257271      }
     
    272286    }
    273287
    274     private static bool TryTransformToAutoDiff(ISymbolicExpressionTreeNode node, List<AutoDiff.Variable> variables, List<AutoDiff.Variable> parameters, List<string> variableNames, out AutoDiff.Term term) {
     288    private static bool TryTransformToAutoDiff(ISymbolicExpressionTreeNode node, List<AutoDiff.Variable> variables, List<AutoDiff.Variable> parameters, List<string> variableNames, bool updateVariableWeights, out AutoDiff.Term term) {
    275289      if (node.Symbol is Constant) {
    276290        var var = new AutoDiff.Variable();
     
    284298        parameters.Add(par);
    285299        variableNames.Add(varNode.VariableName);
    286         var w = new AutoDiff.Variable();
    287         variables.Add(w);
    288         term = AutoDiff.TermBuilder.Product(w, par);
     300
     301        if (updateVariableWeights) {
     302          var w = new AutoDiff.Variable();
     303          variables.Add(w);
     304          term = AutoDiff.TermBuilder.Product(w, par);
     305        } else {
     306          term = par;
     307        }
    289308        return true;
    290309      }
     
    293312        foreach (var subTree in node.Subtrees) {
    294313          AutoDiff.Term t;
    295           if (!TryTransformToAutoDiff(subTree, variables, parameters, variableNames, out t)) {
     314          if (!TryTransformToAutoDiff(subTree, variables, parameters, variableNames, updateVariableWeights, out t)) {
    296315            term = null;
    297316            return false;
     
    306325        for (int i = 0; i < node.SubtreeCount; i++) {
    307326          AutoDiff.Term t;
    308           if (!TryTransformToAutoDiff(node.GetSubtree(i), variables, parameters, variableNames, out t)) {
     327          if (!TryTransformToAutoDiff(node.GetSubtree(i), variables, parameters, variableNames, updateVariableWeights, out t)) {
    309328            term = null;
    310329            return false;
     
    318337      if (node.Symbol is Multiplication) {
    319338        AutoDiff.Term a, b;
    320         if (!TryTransformToAutoDiff(node.GetSubtree(0), variables, parameters, variableNames, out a) ||
    321           !TryTransformToAutoDiff(node.GetSubtree(1), variables, parameters, variableNames, out b)) {
     339        if (!TryTransformToAutoDiff(node.GetSubtree(0), variables, parameters, variableNames, updateVariableWeights, out a) ||
     340          !TryTransformToAutoDiff(node.GetSubtree(1), variables, parameters, variableNames, updateVariableWeights, out b)) {
    322341          term = null;
    323342          return false;
     
    326345          foreach (var subTree in node.Subtrees.Skip(2)) {
    327346            AutoDiff.Term f;
    328             if (!TryTransformToAutoDiff(subTree, variables, parameters, variableNames, out f)) {
     347            if (!TryTransformToAutoDiff(subTree, variables, parameters, variableNames, updateVariableWeights, out f)) {
    329348              term = null;
    330349              return false;
     
    339358        // only works for at least two subtrees
    340359        AutoDiff.Term a, b;
    341         if (!TryTransformToAutoDiff(node.GetSubtree(0), variables, parameters, variableNames, out a) ||
    342           !TryTransformToAutoDiff(node.GetSubtree(1), variables, parameters, variableNames, out b)) {
     360        if (!TryTransformToAutoDiff(node.GetSubtree(0), variables, parameters, variableNames, updateVariableWeights, out a) ||
     361          !TryTransformToAutoDiff(node.GetSubtree(1), variables, parameters, variableNames, updateVariableWeights, out b)) {
    343362          term = null;
    344363          return false;
     
    347366          foreach (var subTree in node.Subtrees.Skip(2)) {
    348367            AutoDiff.Term f;
    349             if (!TryTransformToAutoDiff(subTree, variables, parameters, variableNames, out f)) {
     368            if (!TryTransformToAutoDiff(subTree, variables, parameters, variableNames, updateVariableWeights, out f)) {
    350369              term = null;
    351370              return false;
     
    359378      if (node.Symbol is Logarithm) {
    360379        AutoDiff.Term t;
    361         if (!TryTransformToAutoDiff(node.GetSubtree(0), variables, parameters, variableNames, out t)) {
     380        if (!TryTransformToAutoDiff(node.GetSubtree(0), variables, parameters, variableNames, updateVariableWeights, out t)) {
    362381          term = null;
    363382          return false;
     
    369388      if (node.Symbol is Exponential) {
    370389        AutoDiff.Term t;
    371         if (!TryTransformToAutoDiff(node.GetSubtree(0), variables, parameters, variableNames, out t)) {
     390        if (!TryTransformToAutoDiff(node.GetSubtree(0), variables, parameters, variableNames, updateVariableWeights, out t)) {
    372391          term = null;
    373392          return false;
     
    379398      if (node.Symbol is Square) {
    380399        AutoDiff.Term t;
    381         if (!TryTransformToAutoDiff(node.GetSubtree(0), variables, parameters, variableNames, out t)) {
     400        if (!TryTransformToAutoDiff(node.GetSubtree(0), variables, parameters, variableNames, updateVariableWeights, out t)) {
    382401          term = null;
    383402          return false;
     
    388407      } if (node.Symbol is SquareRoot) {
    389408        AutoDiff.Term t;
    390         if (!TryTransformToAutoDiff(node.GetSubtree(0), variables, parameters, variableNames, out t)) {
     409        if (!TryTransformToAutoDiff(node.GetSubtree(0), variables, parameters, variableNames, updateVariableWeights, out t)) {
    391410          term = null;
    392411          return false;
     
    397416      } if (node.Symbol is Sine) {
    398417        AutoDiff.Term t;
    399         if (!TryTransformToAutoDiff(node.GetSubtree(0), variables, parameters, variableNames, out t)) {
     418        if (!TryTransformToAutoDiff(node.GetSubtree(0), variables, parameters, variableNames, updateVariableWeights, out t)) {
    400419          term = null;
    401420          return false;
     
    406425      } if (node.Symbol is Cosine) {
    407426        AutoDiff.Term t;
    408         if (!TryTransformToAutoDiff(node.GetSubtree(0), variables, parameters, variableNames, out t)) {
     427        if (!TryTransformToAutoDiff(node.GetSubtree(0), variables, parameters, variableNames, updateVariableWeights, out t)) {
    409428          term = null;
    410429          return false;
     
    415434      } if (node.Symbol is Tangent) {
    416435        AutoDiff.Term t;
    417         if (!TryTransformToAutoDiff(node.GetSubtree(0), variables, parameters, variableNames, out t)) {
     436        if (!TryTransformToAutoDiff(node.GetSubtree(0), variables, parameters, variableNames, updateVariableWeights, out t)) {
    418437          term = null;
    419438          return false;
     
    424443      } if (node.Symbol is Erf) {
    425444        AutoDiff.Term t;
    426         if (!TryTransformToAutoDiff(node.GetSubtree(0), variables, parameters, variableNames, out t)) {
     445        if (!TryTransformToAutoDiff(node.GetSubtree(0), variables, parameters, variableNames, updateVariableWeights, out t)) {
    427446          term = null;
    428447          return false;
     
    433452      } if (node.Symbol is Norm) {
    434453        AutoDiff.Term t;
    435         if (!TryTransformToAutoDiff(node.GetSubtree(0), variables, parameters, variableNames, out t)) {
     454        if (!TryTransformToAutoDiff(node.GetSubtree(0), variables, parameters, variableNames, updateVariableWeights, out t)) {
    436455          term = null;
    437456          return false;
     
    447466        variables.Add(alpha);
    448467        AutoDiff.Term branchTerm;
    449         if (TryTransformToAutoDiff(node.GetSubtree(0), variables, parameters, variableNames, out branchTerm)) {
     468        if (TryTransformToAutoDiff(node.GetSubtree(0), variables, parameters, variableNames, updateVariableWeights, out branchTerm)) {
    450469          term = branchTerm * alpha + beta;
    451470          return true;
Note: See TracChangeset for help on using the changeset viewer.