Changeset 16461
- Timestamp:
- 12/28/18 15:44:31 (6 years ago)
- Location:
- branches/2974_Constants_Optimization
- Files:
-
- 7 added
- 5 edited
Legend:
- Unmodified
- Added
- Removed
-
branches/2974_Constants_Optimization/ConstantsOptimization.sln
r16456 r16461 15 15 EndProject 16 16 Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "HeuristicLab.Problems.DataAnalysis.Symbolic-3.4", "HeuristicLab.Problems.DataAnalysis.Symbolic\3.4\HeuristicLab.Problems.DataAnalysis.Symbolic-3.4.csproj", "{3D28463F-EC96-4D82-AFEE-38BE91A0CA00}" 17 EndProject 18 Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "UnitTests", "UnitTests\UnitTests.csproj", "{9617D7C7-90FB-41BB-A9B2-6DAC68E15197}" 17 19 EndProject 18 20 Global … … 50 52 {3D28463F-EC96-4D82-AFEE-38BE91A0CA00}.Release|x86.ActiveCfg = Release|x86 51 53 {3D28463F-EC96-4D82-AFEE-38BE91A0CA00}.Release|x86.Build.0 = Release|x86 54 {9617D7C7-90FB-41BB-A9B2-6DAC68E15197}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 55 {9617D7C7-90FB-41BB-A9B2-6DAC68E15197}.Debug|Any CPU.Build.0 = Debug|Any CPU 56 {9617D7C7-90FB-41BB-A9B2-6DAC68E15197}.Debug|x64.ActiveCfg = Debug|Any CPU 57 {9617D7C7-90FB-41BB-A9B2-6DAC68E15197}.Debug|x64.Build.0 = Debug|Any CPU 58 {9617D7C7-90FB-41BB-A9B2-6DAC68E15197}.Debug|x86.ActiveCfg = Debug|Any CPU 59 {9617D7C7-90FB-41BB-A9B2-6DAC68E15197}.Debug|x86.Build.0 = Debug|Any CPU 60 {9617D7C7-90FB-41BB-A9B2-6DAC68E15197}.Release|Any CPU.ActiveCfg = Release|Any CPU 61 {9617D7C7-90FB-41BB-A9B2-6DAC68E15197}.Release|Any CPU.Build.0 = Release|Any CPU 62 {9617D7C7-90FB-41BB-A9B2-6DAC68E15197}.Release|x64.ActiveCfg = Release|Any CPU 63 {9617D7C7-90FB-41BB-A9B2-6DAC68E15197}.Release|x64.Build.0 = Release|Any CPU 64 {9617D7C7-90FB-41BB-A9B2-6DAC68E15197}.Release|x86.ActiveCfg = Release|Any CPU 65 {9617D7C7-90FB-41BB-A9B2-6DAC68E15197}.Release|x86.Build.0 = Release|Any CPU 52 66 EndGlobalSection 53 67 GlobalSection(SolutionProperties) = preSolution -
branches/2974_Constants_Optimization/HeuristicLab.Problems.DataAnalysis.Symbolic.Regression/3.4/HeuristicLab.Problems.DataAnalysis.Symbolic.Regression-3.4.csproj
r16460 r16461 102 102 <HintPath>..\..\..\..\trunk\bin\ALGLIB-3.7.0.dll</HintPath> 103 103 <Private>False</Private> 104 </Reference> 105 <Reference Include="AutoDiff-1.0, Version=1.0.0.14388, Culture=neutral, PublicKeyToken=ba48961d6f65dcec, processorArchitecture=MSIL"> 106 <SpecificVersion>False</SpecificVersion> 107 <HintPath>..\..\..\..\trunk\bin\AutoDiff-1.0.dll</HintPath> 104 108 </Reference> 105 109 <Reference Include="HeuristicLab.Analysis-3.3"> -
branches/2974_Constants_Optimization/HeuristicLab.Problems.DataAnalysis.Symbolic.Regression/3.4/SingleObjective/Evaluators/ConstantsOptimizationEvaluator.cs
r16459 r16461 131 131 } 132 132 133 134 133 private static readonly object locker = new object(); 135 134 public override IOperation InstrumentedApply() { … … 189 188 } 190 189 190 [ThreadStatic] 191 private static double[,] x = null; 192 [ThreadStatic] 193 private static IDataset ds = null; 194 [ThreadStatic] 195 private static Dictionary<DataForVariable, AutoDiff.Variable> parameters; 196 191 197 public static double OptimizeConstants(ISymbolicDataAnalysisExpressionTreeInterpreter interpreter, 192 198 ISymbolicExpressionTree tree, IRegressionProblemData problemData, IEnumerable<int> rows, bool applyLinearScaling, … … 195 201 bool updateConstantsInTree = true, Action<double[], double, object> iterationCallback = null, EvaluationsCounter counter = null) { 196 202 203 if (ds == null || ds != problemData.Dataset) { 204 ds = problemData.Dataset; 205 parameters = ConstantsOptimization.Util.ExtractParameters(problemData.Dataset); 206 x = ConstantsOptimization.Util.ExtractData(ds, parameters.Keys, rows); 207 208 } 209 double[] y = ds.GetDoubleValues(problemData.TargetVariable, rows).ToArray(); 210 197 211 198 212 // numeric constants in the tree become variables for constant opt … … 201 215 // variable name, variable value (for factor vars) and lag as a DataForVariable object. 202 216 // A dictionary is used to find parameters 203 double[] initialConstants;204 var parameters = new List<TreeToAutoDiffTermConverter.DataForVariable>();205 206 217 TreeToAutoDiffTermConverter.ParametricFunction func; 207 218 TreeToAutoDiffTermConverter.ParametricFunctionGradient func_grad; 208 if (!TreeToAutoDiffTermConverter.TryConvertToAutoDiff(tree, updateVariableWeights, applyLinearScaling, out parameters, out initialConstants, out func, out func_grad)) 219 220 if (!TreeToAutoDiffTermConverter.TryConvertToAutoDiff(tree, updateVariableWeights, applyLinearScaling, parameters, out func, out func_grad)) 209 221 throw new NotSupportedException("Could not optimize constants of symbolic expression tree due to not supported symbols used in the tree."); 210 222 if (parameters.Count == 0) return 0.0; // gkronber: constant expressions always have a R² of 0.0 211 //var parameterEntries = parameters.ToArray(); // order of entries must be the same for x 223 224 var initialConstants = ConstantsOptimization.Util.ExtractConstants(tree); 212 225 213 226 //extract inital constants … … 231 244 int retVal; 232 245 233 IDataset ds = problemData.Dataset; 234 var x = ConstantsOptimization.Util.ExtractData(ds, parameters, rows); 235 double[] y = ds.GetDoubleValues(problemData.TargetVariable, rows).ToArray(); 246 236 247 int n = x.GetLength(0); 237 248 int m = x.GetLength(1); … … 263 274 var tmp = new double[c.Length - 2]; 264 275 Array.Copy(c, 2, tmp, 0, tmp.Length); 265 UpdateConstants(tree, tmp, updateVariableWeights);266 } else UpdateConstants(tree, c, updateVariableWeights);276 ConstantsOptimization.Util.UpdateConstants(tree, tmp); 277 } else ConstantsOptimization.Util.UpdateConstants(tree, c); 267 278 } 268 279 var quality = SymbolicRegressionSingleObjectivePearsonRSquaredEvaluator.Calculate(interpreter, tree, lowerEstimationLimit, upperEstimationLimit, problemData, rows, applyLinearScaling); 269 280 270 if (!updateConstantsInTree) UpdateConstants(tree, initialConstants, updateVariableWeights); 281 if (!updateConstantsInTree) 282 ConstantsOptimization.Util.UpdateConstants(tree, initialConstants); 271 283 272 284 if (originalQuality - quality > 0.001 || double.IsNaN(quality)) { 273 UpdateConstants(tree, initialConstants, updateVariableWeights);285 ConstantsOptimization.Util.UpdateConstants(tree, initialConstants); 274 286 return originalQuality; 275 287 } 276 288 return quality; 277 }278 279 private static void UpdateConstants(ISymbolicExpressionTree tree, double[] constants, bool updateVariableWeights) {280 int i = 0;281 foreach (var node in tree.Root.IterateNodesPrefix().OfType<SymbolicExpressionTreeTerminalNode>()) {282 ConstantTreeNode constantTreeNode = node as ConstantTreeNode;283 VariableTreeNodeBase variableTreeNodeBase = node as VariableTreeNodeBase;284 FactorVariableTreeNode factorVarTreeNode = node as FactorVariableTreeNode;285 if (constantTreeNode != null)286 constantTreeNode.Value = constants[i++];287 else if (updateVariableWeights && variableTreeNodeBase != null)288 variableTreeNodeBase.Weight = constants[i++];289 else if (factorVarTreeNode != null) {290 for (int j = 0; j < factorVarTreeNode.Weights.Length; j++)291 factorVarTreeNode.Weights[j] = constants[i++];292 }293 }294 289 } 295 290 -
branches/2974_Constants_Optimization/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Constants Optimization/Util.cs
r16459 r16461 37 37 foreach (var variable in variables) { 38 38 if (dataset.VariableHasType<double>(variable.variableName)) { 39 x[row, col] = dataset.GetDoubleValue(variable.variableName, r +variable.lag);39 x[row, col] = dataset.GetDoubleValue(variable.variableName, r + variable.lag); 40 40 } else if (dataset.VariableHasType<string>(variable.variableName)) { 41 41 x[row, col] = dataset.GetStringValue(variable.variableName, r) == variable.variableValue ? 1 : 0; … … 50 50 public static Dictionary<DataForVariable, AutoDiff.Variable> ExtractParameters(IDataset dataset) { 51 51 var parameters = new Dictionary<DataForVariable, AutoDiff.Variable>(); 52 foreach (var doubleVariable in dataset.DoubleVariables) {52 foreach (var doubleVariable in dataset.DoubleVariables) { 53 53 var data = new DataForVariable(doubleVariable, string.Empty, 0); 54 54 var param = new AutoDiff.Variable(); 55 parameters.Add(data, param);55 parameters.Add(data, param); 56 56 } 57 57 58 foreach (var stringVariable in dataset.StringVariables) {59 foreach (var stringValue in dataset.GetStringValues(stringVariable).Distinct()) {60 var data = new DataForVariable(stringVariable, stringVa riable, 0);58 foreach (var stringVariable in dataset.StringVariables) { 59 foreach (var stringValue in dataset.GetStringValues(stringVariable).Distinct()) { 60 var data = new DataForVariable(stringVariable, stringValue, 0); 61 61 var param = new AutoDiff.Variable(); 62 62 parameters.Add(data, param); … … 64 64 } 65 65 return parameters; 66 } 67 68 public static double[] ExtractConstants(ISymbolicExpressionTree tree) { 69 var constants = new List<double>(); 70 foreach (var node in tree.IterateNodesPrefix().OfType<SymbolicExpressionTreeTerminalNode>()) { 71 ConstantTreeNode constantTreeNode = node as ConstantTreeNode; 72 VariableTreeNodeBase variableTreeNodeBase = node as VariableTreeNodeBase; 73 FactorVariableTreeNode factorVarTreeNode = node as FactorVariableTreeNode; 74 if (constantTreeNode != null) 75 constants.Add(constantTreeNode.Value); 76 else if (variableTreeNodeBase != null) 77 constants.Add(variableTreeNodeBase.Weight); 78 else if (factorVarTreeNode != null) { 79 for (int j = 0; j < factorVarTreeNode.Weights.Length; j++) 80 constants.Add(factorVarTreeNode.Weights[j]); 81 } 82 } 83 return constants.ToArray(); 66 84 } 67 85 -
branches/2974_Constants_Optimization/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Converters/TreeToAutoDiffTermConverter.cs
r16458 r16461 131 131 } 132 132 133 public static bool TryConvertToAutoDiff(ISymbolicExpressionTree tree, bool makeVariableWeightsVariable, bool addLinearScalingTerms, Dictionary<DataForVariable, AutoDiff.Variable> parameters, 134 out ParametricFunction func, 135 out ParametricFunctionGradient func_grad 136 ) { 137 138 // use a transformator object which holds the state (variable list, parameter list, ...) for recursive transformation of the tree 139 var transformator = new TreeToAutoDiffTermConverter(makeVariableWeightsVariable, parameters); 140 AutoDiff.Term term; 141 try { 142 term = transformator.ConvertToAutoDiff(tree.Root.GetSubtree(0)); 143 144 if (addLinearScalingTerms) { 145 // scaling variables α, β are given at the beginning of the parameter vector 146 var alpha = new AutoDiff.Variable(); 147 var beta = new AutoDiff.Variable(); 148 transformator.variables.Insert(0, alpha); 149 transformator.variables.Insert(0, beta); 150 151 term = term * alpha + beta; 152 } 153 154 var compiledTerm = term.Compile(transformator.variables.ToArray(), parameters.Select(kvp => kvp.Value).ToArray()); 155 156 157 func = (vars, @params) => compiledTerm.Evaluate(vars, @params); 158 func_grad = (vars, @params) => compiledTerm.Differentiate(vars, @params); 159 return true; 160 } catch (ConversionException) { 161 func = null; 162 func_grad = null; 163 } 164 return false; 165 } 166 133 167 // state for recursive transformation of trees 134 168 private readonly List<double> initialConstants; … … 137 171 private readonly bool makeVariableWeightsVariable; 138 172 139 private TreeToAutoDiffTermConverter(bool makeVariableWeightsVariable ) {173 private TreeToAutoDiffTermConverter(bool makeVariableWeightsVariable, Dictionary<DataForVariable, AutoDiff.Variable> parameters = null) { 140 174 this.makeVariableWeightsVariable = makeVariableWeightsVariable; 141 175 this.initialConstants = new List<double>(); 142 this.parameters = new Dictionary<DataForVariable, AutoDiff.Variable>(); 176 if (parameters == null) 177 this.parameters = new Dictionary<DataForVariable, AutoDiff.Variable>(); 178 else 179 this.parameters = parameters; 143 180 this.variables = new List<AutoDiff.Variable>(); 144 181 }
Note: See TracChangeset
for help on using the changeset viewer.