Changeset 18197
- Timestamp:
- 01/14/22 12:06:18 (3 years ago)
- Location:
- branches/3136_Structural_GP
- Files:
-
- 3 edited
Legend:
- Unmodified
- Added
- Removed
-
branches/3136_Structural_GP/HeuristicLab.Problems.DataAnalysis.Symbolic.Regression/3.4/ParameterOptimization.cs
r18192 r18197 27 27 namespace HeuristicLab.Problems.DataAnalysis.Symbolic.Regression { 28 28 public static class ParameterOptimization { 29 public static double OptimizeTreeParameters(IRegressionProblemData problemData, ISymbolicExpressionTree tree, 30 int maxIterations = 10, bool updateParametersInTree = true, bool updateVariableWeights = true,29 public static double OptimizeTreeParameters(IRegressionProblemData problemData, ISymbolicExpressionTree tree, int maxIterations = 10, 30 bool updateParametersInTree = true, bool updateVariableWeights = true, IEnumerable<ISymbolicExpressionTreeNode> excludeNodes = null, 31 31 double lowerEstimationLimit = double.MinValue, double upperEstimationLimit = double.MaxValue, 32 32 IEnumerable<int> rows = null, ISymbolicDataAnalysisExpressionTreeInterpreter interpreter = null, … … 35 35 if (rows == null) rows = problemData.TrainingIndices; 36 36 if (interpreter == null) interpreter = new SymbolicDataAnalysisExpressionTreeBatchInterpreter(); 37 if (excludeNodes == null) excludeNodes = Enumerable.Empty<ISymbolicExpressionTreeNode>(); 37 38 38 39 // Numeric parameters in the tree become variables for parameter optimization. … … 46 47 TreeToAutoDiffTermConverter.ParametricFunction func; 47 48 TreeToAutoDiffTermConverter.ParametricFunctionGradient func_grad; 48 if (!TreeToAutoDiffTermConverter.TryConvertToAutoDiff(tree, updateVariableWeights, addLinearScalingTerms: false, out parameters, out initialParameters, out func, out func_grad)) 49 if (!TreeToAutoDiffTermConverter.TryConvertToAutoDiff(tree, 50 updateVariableWeights, addLinearScalingTerms: false, excludeNodes, 51 out parameters, out initialParameters, out func, out func_grad)) 49 52 throw new NotSupportedException("Could not optimize parameters of symbolic expression tree due to not supported symbols used in the tree."); 50 53 var parameterEntries = parameters.ToArray(); // order of entries must be the same for x … … 112 115 // request was submitted. 113 116 if (rep.terminationtype > 0) { 114 UpdateParameters(tree, c, updateVariableWeights );117 UpdateParameters(tree, c, updateVariableWeights, excludeNodes); 115 118 } 116 119 var quality = SymbolicRegressionSingleObjectiveMeanSquaredErrorEvaluator.Calculate( … … 119 122 lowerEstimationLimit, upperEstimationLimit); 120 123 121 if (!updateParametersInTree) UpdateParameters(tree, initialParameters, updateVariableWeights );124 if (!updateParametersInTree) UpdateParameters(tree, initialParameters, updateVariableWeights, excludeNodes); 122 125 123 126 if (originalQuality < quality || double.IsNaN(quality)) { 124 UpdateParameters(tree, initialParameters, updateVariableWeights );127 UpdateParameters(tree, initialParameters, updateVariableWeights, excludeNodes); 125 128 return originalQuality; 126 129 } … … 128 131 } 129 132 130 private static void UpdateParameters(ISymbolicExpressionTree tree, double[] parameters, bool updateVariableWeights) { 133 private static void UpdateParameters(ISymbolicExpressionTree tree, double[] parameters, 134 bool updateVariableWeights, IEnumerable<ISymbolicExpressionTreeNode> excludedNodes) { 131 135 int i = 0; 132 foreach (var node in tree.Root.IterateNodesPrefix().OfType<SymbolicExpressionTreeTerminalNode>() ) {136 foreach (var node in tree.Root.IterateNodesPrefix().OfType<SymbolicExpressionTreeTerminalNode>().Except(excludedNodes)) { 133 137 NumberTreeNode numberTreeNode = node as NumberTreeNode; 134 138 VariableTreeNodeBase variableTreeNodeBase = node as VariableTreeNodeBase; … … 140 144 } else if (updateVariableWeights && variableTreeNodeBase != null) 141 145 variableTreeNodeBase.Weight = parameters[i++]; 142 else if ( factorVarTreeNode != null) {146 else if (updateVariableWeights && factorVarTreeNode != null) { 143 147 for (int j = 0; j < factorVarTreeNode.Weights.Length; j++) 144 148 factorVarTreeNode.Weights[j] = parameters[i++]; -
branches/3136_Structural_GP/HeuristicLab.Problems.DataAnalysis.Symbolic.Regression/3.4/SingleObjective/StructuredSymbolicRegressionSingleObjectiveProblem.cs
r18194 r18197 21 21 22 22 using System; 23 using System.Collections.Generic; 23 24 using System.Linq; 24 25 using HEAL.Attic; … … 279 280 throw new ArgumentException("No structure template defined!"); 280 281 281 var tree = BuildTreeFromIndividual(templateTree, individual, updateNumericParameters: StructureTemplate.ContainsNumericParameters);282 var tree = BuildTreeFromIndividual(templateTree, individual, containsNumericParameters: StructureTemplate.ContainsNumericParameters); 282 283 individual[SymbolicExpressionTreeName] = tree; 283 284 284 285 if (OptimizeParameters) { 285 ParameterOptimization.OptimizeTreeParameters(ProblemData, tree, interpreter: Interpreter); 286 var excludeNodes = GetTemplateTreeNodes(tree.Root).OfType<IVariableTreeNode>(); 287 ParameterOptimization.OptimizeTreeParameters(ProblemData, tree, interpreter: Interpreter, excludeNodes: excludeNodes); 286 288 } else if (ApplyLinearScaling) { 287 289 LinearScaling.AdjustLinearScalingParams(ProblemData, tree, Interpreter); 288 290 } 289 291 290 UpdateIndividualFromTree(tree, individual, updateNumericParameters: StructureTemplate.ContainsNumericParameters);292 UpdateIndividualFromTree(tree, individual, containsNumericParameters: StructureTemplate.ContainsNumericParameters); 291 293 292 294 //calculate NMSE … … 317 319 } 318 320 319 private static ISymbolicExpressionTree BuildTreeFromIndividual(ISymbolicExpressionTree template, Individual individual, bool updateNumericParameters) { 321 private static IEnumerable<ISymbolicExpressionTreeNode> GetTemplateTreeNodes(ISymbolicExpressionTreeNode rootNode) { 322 yield return rootNode; 323 foreach (var node in rootNode.Subtrees) { 324 if (node is SubFunctionTreeNode) { 325 yield return node; 326 continue; 327 } 328 329 foreach (var subNode in GetTemplateTreeNodes(node)) 330 yield return subNode; 331 } 332 } 333 334 private static ISymbolicExpressionTree BuildTreeFromIndividual(ISymbolicExpressionTree template, Individual individual, bool containsNumericParameters) { 320 335 var resolvedTree = (ISymbolicExpressionTree)template.Clone(); 321 336 322 337 //set numeric parameter values 323 if ( updateNumericParameters) {338 if (containsNumericParameters) { 324 339 var realVector = individual.RealVector(NumericParametersEncoding); 325 340 var numberTreeNodes = resolvedTree.IterateNodesPrefix().OfType<NumberTreeNode>().ToArray(); … … 345 360 } 346 361 347 private static void UpdateIndividualFromTree(ISymbolicExpressionTree tree, Individual individual, bool updateNumericParameters) {362 private static void UpdateIndividualFromTree(ISymbolicExpressionTree tree, Individual individual, bool containsNumericParameters) { 348 363 var clonedTree = (ISymbolicExpressionTree)tree.Clone(); 349 364 … … 357 372 var rootNode = (SymbolicExpressionTreeTopLevelNode)new ProgramRootSymbol().CreateTreeNode(); 358 373 rootNode.SetGrammar(grammar); 359 360 374 var startNode = (SymbolicExpressionTreeTopLevelNode)new StartSymbol().CreateTreeNode(); 361 375 startNode.SetGrammar(grammar); … … 368 382 369 383 //set numeric parameter values 370 if ( updateNumericParameters) {384 if (containsNumericParameters) { 371 385 var realVector = individual.RealVector(NumericParametersEncoding); 372 386 var numberTreeNodes = clonedTree.IterateNodesPrefix().OfType<NumberTreeNode>().ToArray(); -
branches/3136_Structural_GP/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Converters/TreeToAutoDiffTermConverter.cs
r18146 r18197 106 106 out ParametricFunctionGradient func_grad) { 107 107 108 return TryConvertToAutoDiff(tree, makeVariableWeightsVariable, addLinearScalingTerms, Enumerable.Empty<ISymbolicExpressionTreeNode>(), 109 out parameters, out initialParamValues, out func, out func_grad); 110 } 111 112 public static bool TryConvertToAutoDiff(ISymbolicExpressionTree tree, bool makeVariableWeightsVariable, bool addLinearScalingTerms, IEnumerable<ISymbolicExpressionTreeNode> excludedNodes, 113 out List<DataForVariable> parameters, out double[] initialParamValues, 114 out ParametricFunction func, 115 out ParametricFunctionGradient func_grad) { 116 108 117 // use a transformator object which holds the state (variable list, parameter list, ...) for recursive transformation of the tree 109 var transformator = new TreeToAutoDiffTermConverter(makeVariableWeightsVariable, addLinearScalingTerms );118 var transformator = new TreeToAutoDiffTermConverter(makeVariableWeightsVariable, addLinearScalingTerms, excludedNodes); 110 119 AutoDiff.Term term; 111 120 try { … … 134 143 private readonly bool makeVariableWeightsVariable; 135 144 private readonly bool addLinearScalingTerms; 136 137 private TreeToAutoDiffTermConverter(bool makeVariableWeightsVariable, bool addLinearScalingTerms) { 145 private readonly HashSet<ISymbolicExpressionTreeNode> excludedNodes; 146 147 private TreeToAutoDiffTermConverter(bool makeVariableWeightsVariable, bool addLinearScalingTerms, IEnumerable<ISymbolicExpressionTreeNode> excludedNodes) { 138 148 this.makeVariableWeightsVariable = makeVariableWeightsVariable; 139 149 this.addLinearScalingTerms = addLinearScalingTerms; 150 this.excludedNodes = new HashSet<ISymbolicExpressionTreeNode>(excludedNodes); 151 140 152 this.initialParamValues = new List<double>(); 141 153 this.parameters = new Dictionary<DataForVariable, AutoDiff.Variable>(); … … 161 173 var par = FindOrCreateParameter(parameters, varNode.VariableName, varValue); 162 174 163 if (makeVariableWeightsVariable ) {175 if (makeVariableWeightsVariable && !excludedNodes.Contains(node)) { 164 176 initialParamValues.Add(varNode.Weight); 165 177 var w = new AutoDiff.Variable(); … … 176 188 var par = FindOrCreateParameter(parameters, factorVarNode.VariableName, variableValue); 177 189 178 initialParamValues.Add(factorVarNode.GetValue(variableValue)); 179 var wVar = new AutoDiff.Variable(); 180 variables.Add(wVar); 181 182 products.Add(AutoDiff.TermBuilder.Product(wVar, par)); 190 if (makeVariableWeightsVariable && !excludedNodes.Contains(node)) { 191 initialParamValues.Add(factorVarNode.GetValue(variableValue)); 192 var wVar = new AutoDiff.Variable(); 193 variables.Add(wVar); 194 195 products.Add(AutoDiff.TermBuilder.Product(wVar, par)); 196 } else { 197 var weight = factorVarNode.GetValue(variableValue); 198 products.Add(weight * par); 199 } 200 183 201 } 184 202 return AutoDiff.TermBuilder.Sum(products); … … 188 206 var par = FindOrCreateParameter(parameters, varNode.VariableName, string.Empty, varNode.Lag); 189 207 190 if (makeVariableWeightsVariable ) {208 if (makeVariableWeightsVariable && !excludedNodes.Contains(node)) { 191 209 initialParamValues.Add(varNode.Weight); 192 210 var w = new AutoDiff.Variable();
Note: See TracChangeset
for help on using the changeset viewer.