Free cookie consent management tool by TermsFeed Policy Generator

Changeset 18213


Ignore:
Timestamp:
02/08/22 13:06:49 (2 years ago)
Author:
dpiringe
Message:

#3138

  • reimplemented extended constraints with an interface and an implementation, because of project reference troubles
  • moved the extended shape constraints into IShapeConstrainedRegressionProblemData
  • added thresholds for shape constraints -> the error is linear between 0 and 1, error caps at 1 when error >= (intervalbound + thresholdbound)
    • adapted ShapeConstraint and ShapeConstraintsParser to identify and store thresholds
  • adapted IntervalUtil to work with thresholds
  • adapted NMSESingleObjectiveConstraintsEvaluator and ShapeConstraintsAnalyzer to work with extended constraints
  • added a new chart in ShapeConstraintsAnalyzer to show the average constraint violation
Location:
branches/3138_Shape_Constraints_Transformations
Files:
2 added
10 edited

Legend:

Unmodified
Added
Removed
  • branches/3138_Shape_Constraints_Transformations/HeuristicLab.Problems.DataAnalysis.Symbolic.Regression/3.4/HeuristicLab.Problems.DataAnalysis.Symbolic.Regression-3.4.csproj

    r18181 r18213  
    263263      <Private>False</Private>
    264264    </ProjectReference>
     265    <ProjectReference Include="..\..\HeuristicLab.Random\3.3\HeuristicLab.Random-3.3.csproj">
     266      <Project>{F4539FB6-4708-40C9-BE64-0A1390AEA197}</Project>
     267      <Name>HeuristicLab.Random-3.3</Name>
     268    </ProjectReference>
    265269  </ItemGroup>
    266270  <ItemGroup>
  • branches/3138_Shape_Constraints_Transformations/HeuristicLab.Problems.DataAnalysis.Symbolic.Regression/3.4/ShapeConstraintsAnalyzer.cs

    r17958 r18213  
    2020#endregion
    2121
     22using System.Collections;
     23using System.Collections.Generic;
    2224using System.Linq;
    2325using HEAL.Attic;
     
    2830using HeuristicLab.Optimization;
    2931using HeuristicLab.Parameters;
     32using HeuristicLab.Random;
    3033
    3134namespace HeuristicLab.Problems.DataAnalysis.Symbolic.Regression {
     
    3639    private const string ConstraintViolationsParameterName = "ConstraintViolations";
    3740    private const string InfeasibleSolutionsParameterName = "InfeasibleSolutions";
     41    private const string AverageConstraintViolationsParameterName = "AverageConstraintViolations";
     42    private const string SymbolicDataAnalysisTreeInterpreterParameterName = "SymbolicExpressionTreeInterpreter";
    3843
    3944    #region parameter properties
     
    4853      (IResultParameter<DataTable>)Parameters[InfeasibleSolutionsParameterName];
    4954
     55    public IResultParameter<DataTable> AverageConstraintViolationsParameter =>
     56      (IResultParameter<DataTable>)Parameters[AverageConstraintViolationsParameterName];
     57
     58    public ILookupParameter<ISymbolicDataAnalysisExpressionTreeInterpreter> SymbolicDataAnalysisTreeInterpreterParameter =>
     59      (ILookupParameter<ISymbolicDataAnalysisExpressionTreeInterpreter>)Parameters[SymbolicDataAnalysisTreeInterpreterParameterName];
     60   
    5061    #endregion
    5162
    52     #region properties
     63      #region properties
    5364    public IRegressionProblemData RegressionProblemData => RegressionProblemDataParameter.ActualValue;
    5465    public DataTable ConstraintViolations => ConstraintViolationsParameter.ActualValue;
    5566    public DataTable InfeasibleSolutions => InfeasibleSolutionsParameter.ActualValue;
     67    public DataTable AverageConstraintViolations => AverageConstraintViolationsParameter.ActualValue;
    5668    #endregion
    5769
     
    7587      Parameters.Add(new ResultParameter<DataTable>(InfeasibleSolutionsParameterName,
    7688        "The number of infeasible solutions."));
     89      Parameters.Add(new ResultParameter<DataTable>(AverageConstraintViolationsParameterName,
     90        "The average violations of each constraint."));
     91      Parameters.Add(new LookupParameter<ISymbolicDataAnalysisExpressionTreeInterpreter>(SymbolicDataAnalysisTreeInterpreterParameterName,
     92        "The interpreter that should be used to calculate the output values of the symbolic data analysis tree.") { Hidden = true });
     93
    7794
    7895
     
    90107        }
    91108      };
     109
     110      AverageConstraintViolationsParameter.DefaultValue = new DataTable(SymbolicDataAnalysisTreeInterpreterParameterName) {
     111        VisualProperties = {
     112          XAxisTitle = "Generations",
     113          YAxisTitle = "Average Constraint Violations"
     114        }
     115      };
    92116    }
    93117
    94118
    95119    [StorableHook(HookType.AfterDeserialization)]
    96     private void AfterDeserialization() { }
     120    private void AfterDeserialization() {
     121      if (!Parameters.ContainsKey(SymbolicDataAnalysisTreeInterpreterParameterName))
     122        Parameters.Add(new LookupParameter<ISymbolicDataAnalysisExpressionTreeInterpreter>(SymbolicDataAnalysisTreeInterpreterParameterName,
     123          "The interpreter that should be used to calculate the output values of the symbolic data analysis tree.") { Hidden = true });
     124    }
    97125
    98126    public override IOperation Apply() {
    99127      var problemData = (IShapeConstrainedRegressionProblemData)RegressionProblemData;
    100128      var trees = SymbolicExpressionTree.ToArray();
    101 
     129     
    102130      var results = ResultCollection;
    103       var constraints = problemData.ShapeConstraints.EnabledConstraints;
     131      var modelConstraints = problemData.ShapeConstraints.EnabledConstraints;
     132      var extendedConstraints = problemData.CheckedExtendedConstraints;
    104133      var variableRanges = problemData.VariableRanges;
    105134      var constraintViolationsTable = ConstraintViolations;
     135      var averageConstraintViolations = AverageConstraintViolations;
     136      var interpreter = SymbolicDataAnalysisTreeInterpreterParameter.ActualValue;
    106137      var estimator = new IntervalArithBoundsEstimator();
     138     
     139      if (!constraintViolationsTable.Rows.Any()) {
     140        foreach (var constraint in modelConstraints) {
     141          constraintViolationsTable.Rows.Add(new DataRow(constraint.ToString()));
     142          averageConstraintViolations.Rows.Add(new DataRow(constraint.ToString()));
     143        }
    107144
    108       if (!constraintViolationsTable.Rows.Any())
    109         foreach (var constraint in constraints)
    110           constraintViolationsTable.Rows.Add(new DataRow(constraint.ToString()));
     145        foreach (var extendedConstraint in extendedConstraints.SelectMany(x => x.ShapeConstraints.EnabledConstraints)) {
     146          constraintViolationsTable.Rows.Add(new DataRow(extendedConstraint.ToString()));
     147          averageConstraintViolations.Rows.Add(new DataRow(extendedConstraint.ToString()));
     148        }
     149      }
    111150
    112       foreach (var constraint in constraints) {
    113         var numViolations = trees.Count(tree => IntervalUtil.GetConstraintViolation(constraint, estimator, variableRanges, tree) > 0.0);
    114         constraintViolationsTable.Rows[constraint.ToString()].Values.Add(numViolations);
     151      var violationsPerTree = new Dictionary<ISymbolicExpressionTree, int>();
     152      var violationsPerConstraint = new Dictionary<string, IList<double>>();
     153
     154      foreach(var tree in trees) {
     155        var violations = NMSESingleObjectiveConstraintsEvaluator.CalculateShapeConstraintsViolations(problemData, tree, interpreter, estimator, new MersenneTwister());
     156        foreach(var violation in violations) {
     157          var constraint = violation.Item1;
     158          var error = violation.Item2;
     159          if (!violationsPerConstraint.ContainsKey(constraint.ToString()))
     160            violationsPerConstraint.Add(constraint.ToString(), new List<double>());
     161          violationsPerConstraint[constraint.ToString()].Add(error);
     162        }
     163        violationsPerTree.Add(tree, violations.Count(x => x.Item2 > 0));
     164      }
     165
     166      foreach (var constraint in modelConstraints) {
     167        var errors = violationsPerConstraint[constraint.ToString()];
     168        constraintViolationsTable.Rows[constraint.ToString()].Values.Add(errors.Count(x => x > 0));
     169        averageConstraintViolations.Rows[constraint.ToString()].Values.Add(errors.Sum() / errors.Count());
     170      }
     171
     172      foreach (var extendedConstraint in extendedConstraints.SelectMany(x => x.ShapeConstraints.EnabledConstraints)) {
     173        var errors = violationsPerConstraint[extendedConstraint.ToString()];
     174        constraintViolationsTable.Rows[extendedConstraint.ToString()].Values.Add(errors.Count(x => x > 0));
     175        averageConstraintViolations.Rows[extendedConstraint.ToString()].Values.Add(errors.Sum() / errors.Count());
    115176      }
    116177
     
    121182      infeasibleSolutionsDataTable.Rows[InfeasibleSolutionsParameterName]
    122183        .Values
    123         .Add(trees.Count(t => IntervalUtil.GetConstraintViolations(constraints, estimator, variableRanges, t).Any(x => x > 0.0)));
     184        .Add(trees.Count(t => violationsPerTree[t] > 0));
    124185
    125186      return base.Apply();
  • branches/3138_Shape_Constraints_Transformations/HeuristicLab.Problems.DataAnalysis.Symbolic.Regression/3.4/SingleObjective/Evaluators/NMSESingleObjectiveConstraintsEvaluator.cs

    r18181 r18213  
    2121
    2222using System;
     23using System.Collections;
    2324using System.Collections.Generic;
    2425using System.Linq;
     
    2930using HeuristicLab.Encodings.SymbolicExpressionTreeEncoding;
    3031using HeuristicLab.Parameters;
     32using HeuristicLab.Random;
    3133
    3234namespace HeuristicLab.Problems.DataAnalysis.Symbolic.Regression {
     
    4143    private const string BoundsEstimatorParameterName = "BoundsEstimator";
    4244    private const string PenaltyFactorParameterName = "PenaltyFactor";
    43     private const string ExtendedConstraintsParameterName = "ExtendedConstraints";
    4445
    4546
     
    5859      (IFixedValueParameter<DoubleValue>)Parameters[PenaltyFactorParameterName];
    5960
    60     public IFixedValueParameter<IItemList<ExtendedConstraint>> ExtendedConstraintsParameter =>
    61       (IFixedValueParameter<IItemList<ExtendedConstraint>>)Parameters[ExtendedConstraintsParameterName];
    6261
    6362
     
    8685      set => PenaltyFactorParameter.Value.Value = value;
    8786    }
    88 
    89     public IEnumerable<ExtendedConstraint> ExtendedConstraints {
    90       get => ExtendedConstraintsParameter.Value;
    91     }
    92      
    93 
    9487
    9588    public override bool Maximization => false; // NMSE is minimized
     
    116109      Parameters.Add(new FixedValueParameter<DoubleValue>(PenaltyFactorParameterName,
    117110        "Punishment factor for constraint violations for soft constraint handling (fitness = NMSE + penaltyFactor * avg(violations)) (default: 1.0)", new DoubleValue(1.0)));
    118       Parameters.Add(new FixedValueParameter<ItemList<ExtendedConstraint>>(ExtendedConstraintsParameterName, "", new ItemList<ExtendedConstraint>()));
    119111    }
    120112
     
    135127      var estimationLimits = EstimationLimitsParameter.ActualValue;
    136128      var applyLinearScaling = ApplyLinearScalingParameter.ActualValue.Value;
     129      var random = RandomParameter.ActualValue;
    137130
    138131      if (OptimizeParameters) {
     
    175168
    176169      var quality = Calculate(interpreter, tree, estimationLimits.Lower, estimationLimits.Upper, problemData, rows,
    177         BoundsEstimator, UseSoftConstraints, PenalityFactor, ExtendedConstraints);
     170        BoundsEstimator, random, UseSoftConstraints, PenalityFactor);
    178171      QualityParameter.ActualValue = new DoubleValue(quality);
    179172
     
    186179      double lowerEstimationLimit, double upperEstimationLimit,
    187180      IRegressionProblemData problemData, IEnumerable<int> rows,
    188       IBoundsEstimator estimator,
    189       bool useSoftConstraints = false, double penaltyFactor = 1.0,
    190       IEnumerable<ExtendedConstraint> extendedConstraints = null) {
    191 
    192       var estimatedValues = interpreter.GetSymbolicExpressionTreeValues(tree, problemData.Dataset, rows);
     181      IBoundsEstimator estimator, IRandom random,
     182      bool useSoftConstraints = false, double penaltyFactor = 1.0) {
     183
     184      var trainingEstimatedValues = interpreter.GetSymbolicExpressionTreeValues(tree, problemData.Dataset, rows);
    193185      var targetValues = problemData.Dataset.GetDoubleValues(problemData.TargetVariable, rows);
    194       var constraints = Enumerable.Empty<ShapeConstraint>();
     186
     187      var trainingBoundedEstimatedValues = trainingEstimatedValues.LimitToRange(lowerEstimationLimit, upperEstimationLimit);
     188      var nmse = OnlineNormalizedMeanSquaredErrorCalculator.Calculate(targetValues, trainingBoundedEstimatedValues,
     189        out var errorState);
     190
     191      if (errorState != OnlineCalculatorError.None)
     192        return double.MaxValue;
     193
     194      var violations = Enumerable.Empty<double>();
    195195      if (problemData is ShapeConstrainedRegressionProblemData scProbData) {
    196         constraints = scProbData.ShapeConstraints.EnabledConstraints;
    197       }
    198       var intervalCollection = problemData.VariableRanges;
    199 
    200       var boundedEstimatedValues = estimatedValues.LimitToRange(lowerEstimationLimit, upperEstimationLimit);
    201       var nmse = OnlineNormalizedMeanSquaredErrorCalculator.Calculate(targetValues, boundedEstimatedValues,
    202         out var errorState);
    203 
    204       if (errorState != OnlineCalculatorError.None) {
    205         return 1.0;
    206       }
    207 
    208       var constraintViolations = IntervalUtil.GetConstraintViolations(constraints, estimator, intervalCollection, tree);
    209 
    210       if (constraintViolations.Any(x => double.IsNaN(x) || double.IsInfinity(x))) {
    211         return 1.0;
    212       }
     196        violations = CalculateShapeConstraintsViolations(scProbData, tree, interpreter, estimator, random).Select(x => x.Item2);
     197      }
     198
     199      if (violations.Any(x => double.IsNaN(x) || double.IsInfinity(x)))
     200        return double.MaxValue;
    213201
    214202      if (useSoftConstraints) {
     
    216204          throw new ArgumentException("The parameter has to be >= 0.0.", nameof(penaltyFactor));
    217205
    218         var weightedViolationsAvg = constraints
    219           .Zip(constraintViolations, (c, v) => c.Weight * v)
    220           .Average();
    221 
    222         return Math.Min(nmse, 1.0) + penaltyFactor * weightedViolationsAvg;
    223       } else if (constraintViolations.Any(x => x > 0.0)) {
    224         return 1.0;
    225       }
    226 
    227       return nmse;
     206        return nmse + penaltyFactor * violations.Average();
     207      }
     208      return violations.Any(x => x > 0.0) ? 1.0 : nmse;
     209    }
     210
     211    public static IEnumerable<Tuple<ShapeConstraint, double>> CalculateShapeConstraintsViolations(
     212      IShapeConstrainedRegressionProblemData problemData, ISymbolicExpressionTree tree,
     213      ISymbolicDataAnalysisExpressionTreeInterpreter interpreter, IBoundsEstimator estimator,
     214      IRandom random) {
     215      IList<Tuple<ShapeConstraint, double>> violations = new List<Tuple<ShapeConstraint, double>>();
     216     
     217      var baseConstraints = problemData.ShapeConstraints.EnabledConstraints;
     218      var intervalCollection = problemData.VariableRanges;
     219      var extendedShapeConstraints = problemData.CheckedExtendedConstraints;
     220      var allEstimatedValues = interpreter.GetSymbolicExpressionTreeValues(tree, problemData.Dataset, problemData.AllIndices);
     221
     222      foreach (var constraint in baseConstraints)
     223        violations.Add(Tuple.Create(constraint, IntervalUtil.GetConstraintViolation(constraint, estimator, intervalCollection, tree) * constraint.Weight));
     224
     225      IDictionary<string, IList> dict = new Dictionary<string, IList>();
     226      foreach (var varName in problemData.Dataset.VariableNames) {
     227        if (varName != problemData.TargetVariable)
     228          dict.Add(varName, problemData.Dataset.GetDoubleValues(varName).ToList());
     229        else dict.Add(varName, allEstimatedValues.ToList());
     230      }
     231      var tmpDataset = new Dataset(dict.Keys, dict.Values);
     232
     233      foreach (var extendedConstraint in extendedShapeConstraints) {
     234        var enabledConstraints = extendedConstraint.ShapeConstraints.EnabledConstraints;
     235        if (enabledConstraints.Any()) {
     236          var extendedConstraintExprValues = interpreter.GetSymbolicExpressionTreeValues(extendedConstraint.Tree, tmpDataset, problemData.AllIndices);
     237          var extendedConstraintExprInterval = new Interval(extendedConstraintExprValues.Min(), extendedConstraintExprValues.Max());
     238
     239          foreach (var constraint in enabledConstraints) {
     240            if (constraint.Regions.Count > 0) {
     241              // adapt dataset
     242              foreach (var kvp in constraint.Regions.GetReadonlyDictionary()) {
     243                var lb = double.IsNegativeInfinity(kvp.Value.LowerBound) ? double.MinValue : kvp.Value.LowerBound;
     244                var ub = double.IsPositiveInfinity(kvp.Value.UpperBound) ? double.MaxValue : kvp.Value.UpperBound;
     245
     246                var vals = Enumerable.Range(0, dict[kvp.Key].Count - 2)
     247                                     .Select(x => UniformDistributedRandom.NextDouble(random, lb, ub))
     248                                     .ToList();
     249                vals.Add(lb);
     250                vals.Add(ub);
     251                vals.Sort();
     252                dict[kvp.Key] = vals;
     253              }
     254              // calc again with new regions
     255              tmpDataset = new Dataset(dict.Keys, dict.Values);
     256              // calc target again
     257              allEstimatedValues = interpreter.GetSymbolicExpressionTreeValues(tree, tmpDataset, problemData.AllIndices);
     258              dict[problemData.TargetVariable] = allEstimatedValues.ToList();
     259              tmpDataset = new Dataset(dict.Keys, dict.Values);
     260              extendedConstraintExprValues = interpreter.GetSymbolicExpressionTreeValues(extendedConstraint.Tree, tmpDataset, problemData.AllIndices);
     261              extendedConstraintExprInterval = new Interval(extendedConstraintExprValues.Min(), extendedConstraintExprValues.Max());
     262            }
     263            violations.Add(Tuple.Create(constraint, IntervalUtil.GetIntervalError(constraint.Interval, extendedConstraintExprInterval, constraint.Threshold) * constraint.Weight));
     264          }
     265        }
     266      }
     267      return violations;
    228268    }
    229269
     
    234274      EstimationLimitsParameter.ExecutionContext = context;
    235275      ApplyLinearScalingParameter.ExecutionContext = context;
     276      RandomParameter.ExecutionContext = context;
    236277
    237278      var nmse = Calculate(SymbolicDataAnalysisTreeInterpreterParameter.ActualValue, tree,
    238279        EstimationLimitsParameter.ActualValue.Lower, EstimationLimitsParameter.ActualValue.Upper,
    239         problemData, rows, BoundsEstimator, UseSoftConstraints, PenalityFactor, ExtendedConstraints);
     280        problemData, rows, BoundsEstimator, RandomParameter.Value, UseSoftConstraints, PenalityFactor);
    240281
    241282      SymbolicDataAnalysisTreeInterpreterParameter.ExecutionContext = null;
    242283      EstimationLimitsParameter.ExecutionContext = null;
    243284      ApplyLinearScalingParameter.ExecutionContext = null;
     285      RandomParameter.ExecutionContext = null;
    244286
    245287      return nmse;
  • branches/3138_Shape_Constraints_Transformations/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/HeuristicLab.Problems.DataAnalysis.Symbolic-3.4.csproj

    r18180 r18213  
    160160    <Compile Include="Creators\SymbolicDataAnalysisExpressionBalancedTreeCreator.cs" />
    161161    <Compile Include="Crossovers\SymbolicDataAnalysisExpressionDiversityPreservingCrossover.cs" />
     162    <Compile Include="ExtendedConstraint.cs" />
    162163    <Compile Include="Formatters\InfixExpressionFormatter.cs" />
    163164    <Compile Include="Formatters\SymbolicDataAnalysisExpressionPythonFormatter.cs" />
  • branches/3138_Shape_Constraints_Transformations/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/IntervalUtil.cs

    r17906 r18213  
    2828namespace HeuristicLab.Problems.DataAnalysis.Symbolic {
    2929  public static class IntervalUtil {
    30     public static IEnumerable<double> GetConstraintViolations(
    31       IEnumerable<ShapeConstraint> constraints, IBoundsEstimator estimator, IntervalCollection intervalCollection,
    32       ISymbolicExpressionTree solution) {
    33       return constraints.Select(constraint => GetConstraintViolation(constraint, estimator, intervalCollection, solution)).ToList();
    34     }
    35 
    36     public static double GetConstraintViolation(
     30    private static void Prepare(
    3731      ShapeConstraint constraint, IBoundsEstimator estimator, IntervalCollection variableRanges,
    38       ISymbolicExpressionTree tree) {
     32      ISymbolicExpressionTree tree, out ISymbolicExpressionTree preparedTree, out IntervalCollection preparedRanges) {
    3933      var varRanges = variableRanges.GetReadonlyDictionary();
    4034
     
    5549      }
    5650
    57       if (!constraint.IsDerivative) {
    58         return estimator.GetConstraintViolation(tree, regionRanges, constraint);
    59       } else {
     51      if (constraint.IsDerivative) {
    6052        for (var i = 0; i < constraint.NumberOfDerivations; ++i) {
    61           if (!estimator.IsCompatible(tree) || !DerivativeCalculator.IsCompatible(tree)) {
     53          if (!estimator.IsCompatible(tree) || !DerivativeCalculator.IsCompatible(tree))
    6254            throw new ArgumentException("The tree contains an unsupported symbol.");
    63           }
    6455
    6556          tree = DerivativeCalculator.Derive(tree, constraint.Variable);
    6657        }
     58      }
    6759
    68         return estimator.GetConstraintViolation(tree, regionRanges, constraint);
     60      preparedTree = tree;
     61      preparedRanges = regionRanges;
     62    }
     63
     64    public static IEnumerable<double> GetConstraintViolations(
     65      IEnumerable<ShapeConstraint> constraints, IBoundsEstimator estimator, IntervalCollection intervalCollection,
     66      ISymbolicExpressionTree solution) {
     67      return constraints.Select(constraint => GetConstraintViolation(constraint, estimator, intervalCollection, solution)).ToList();
     68    }
     69
     70    public static double GetConstraintViolation(
     71      ShapeConstraint constraint, IBoundsEstimator estimator, IntervalCollection variableRanges,
     72      ISymbolicExpressionTree tree) {
     73
     74      Prepare(constraint, estimator, variableRanges, tree,
     75        out ISymbolicExpressionTree preparedTree, out IntervalCollection preparedRanges);
     76
     77      var bounds = estimator.GetModelBound(preparedTree, preparedRanges);
     78
     79      return GetIntervalError(constraint.Interval, bounds, constraint.Threshold);
     80
     81      //return estimator.GetConstraintViolation(preparedTree, preparedRanges, constraint);
     82    }
     83
     84    public static double GetIntervalError(Interval target, Interval estimation, Interval? threshold = null) {
     85      if(threshold == null)
     86        threshold = new Interval(0, 0);
     87
     88      var error = 0d;
     89      if (!target.Contains(estimation.LowerBound)) {
     90        var lbError = Math.Abs(estimation.LowerBound - target.LowerBound);
     91        error += CalcBoundViolation(lbError, threshold.LowerBound);
    6992      }
     93
     94      if (!target.Contains(estimation.UpperBound)) {
     95        var ubError = Math.Abs(estimation.UpperBound - target.UpperBound);
     96        error += CalcBoundViolation(ubError, threshold.UpperBound);
     97      }
     98
     99      return error == 0 ? 0 : error / 2.0;
     100
     101    }
     102
     103    private static double CalcBoundViolation(double error, double threshold) {
     104      threshold = Math.Abs(threshold);
     105
     106      if (double.IsNaN(error)) return 1.0;
     107      if (double.IsInfinity(error) && !double.IsInfinity(threshold)) return 1.0;
     108      if (double.IsInfinity(threshold)) return 0;
     109      if (error <= 0) return 0;
     110      if (error > threshold) return 1.0;     
     111      if (threshold > 0) return Math.Min(1.0, error / threshold);
     112      return 1.0;
    70113    }
    71114  }
  • branches/3138_Shape_Constraints_Transformations/HeuristicLab.Problems.DataAnalysis/3.4/HeuristicLab.Problems.DataAnalysis-3.4.csproj

    r17960 r18213  
    188188    <Compile Include="Interfaces\Regression\IConfidenceRegressionModel.cs" />
    189189    <Compile Include="Interfaces\Regression\IConfidenceRegressionSolution.cs" />
     190    <Compile Include="Interfaces\Regression\IExtendedConstraint.cs" />
    190191    <Compile Include="Interfaces\Regression\IRegressionEnsembleModel.cs">
    191192      <SubType>Code</SubType>
     
    308309      <Private>False</Private>
    309310    </ProjectReference>
     311    <ProjectReference Include="..\..\HeuristicLab.Encodings.SymbolicExpressionTreeEncoding\3.4\HeuristicLab.Encodings.SymbolicExpressionTreeEncoding-3.4.csproj">
     312      <Project>{06D4A186-9319-48A0-BADE-A2058D462EEA}</Project>
     313      <Name>HeuristicLab.Encodings.SymbolicExpressionTreeEncoding-3.4</Name>
     314    </ProjectReference>
    310315    <ProjectReference Include="..\..\HeuristicLab.Optimization\3.3\HeuristicLab.Optimization-3.3.csproj">
    311316      <Project>{14AB8D24-25BC-400C-A846-4627AA945192}</Project>
  • branches/3138_Shape_Constraints_Transformations/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Regression/ShapeConstrainedRegressionProblemData.cs

    r18180 r18213  
    3434  public class ShapeConstrainedRegressionProblemData : RegressionProblemData, IShapeConstrainedRegressionProblemData {
    3535    protected const string ShapeConstraintsParameterName = "ShapeConstraints";
     36    protected const string ExtendedConstraintsParameterName = "ExtendedConstraints";
    3637
    3738    #region default data
     
    9798      defaultTargetVariable = "y_noise";
    9899      defaultShapeConstraints = new ShapeConstraints {
    99         new ShapeConstraint(new Interval(0, 2), 1.0),
    100         new ShapeConstraint("x", 1, new Interval(0, double.PositiveInfinity), 1.0)
     100        new ShapeConstraint(new Interval(0, 2), 1.0, new Interval(0,0)),
     101        new ShapeConstraint("x", 1, new Interval(0, double.PositiveInfinity), 1.0, new Interval(0,0))
    101102      };
    102103      defaultVariableRanges = defaultDataset.GetVariableRanges();
     
    116117      problemData.Parameters.Add(new FixedValueParameter<IntervalCollection>(VariableRangesParameterName, "", new IntervalCollection()));
    117118      problemData.Parameters.Add(new FixedValueParameter<ShapeConstraints>(ShapeConstraintsParameterName, "", new ShapeConstraints()));
     119      problemData.Parameters.Add(new FixedValueParameter<CheckedItemList<IExtendedConstraint>>(ExtendedConstraintsParameterName, "", new CheckedItemList<IExtendedConstraint>()));
    118120      emptyProblemData = problemData;
    119121    }
     
    122124    public IFixedValueParameter<ShapeConstraints> ShapeConstraintParameter => (IFixedValueParameter<ShapeConstraints>)Parameters[ShapeConstraintsParameterName];
    123125    public ShapeConstraints ShapeConstraints => ShapeConstraintParameter.Value;
     126
     127    public IFixedValueParameter<CheckedItemList<IExtendedConstraint>> ExtendedConstraintsParameter =>
     128      (IFixedValueParameter<CheckedItemList<IExtendedConstraint>>)Parameters[ExtendedConstraintsParameterName];
     129    public CheckedItemList<IExtendedConstraint> ExtendedConstraints => ExtendedConstraintsParameter.Value;
     130    public IEnumerable<IExtendedConstraint> CheckedExtendedConstraints => ExtendedConstraints.CheckedItems.Select(x => x.Value);
    124131
    125132    [StorableConstructor]
     
    132139    [StorableHook(HookType.AfterDeserialization)]
    133140    private void AfterDeserialization() {
     141      if (!Parameters.ContainsKey(ExtendedConstraintsParameterName))
     142        Parameters.Add(new FixedValueParameter<CheckedItemList<IExtendedConstraint>>(ExtendedConstraintsParameterName, "", new CheckedItemList<IExtendedConstraint>()));
     143
    134144      RegisterEventHandlers();
    135145    }
     
    158168      if (sc == null) sc = new ShapeConstraints();
    159169      Parameters.Add(new FixedValueParameter<ShapeConstraints>(ShapeConstraintsParameterName, "Specifies the shape constraints for the regression problem.", (ShapeConstraints)sc.Clone()));
     170      Parameters.Add(new FixedValueParameter<CheckedItemList<IExtendedConstraint>>(ExtendedConstraintsParameterName, "", new CheckedItemList<IExtendedConstraint>()));
    160171      RegisterEventHandlers();
    161172    }
     
    169180      ShapeConstraints.ItemsMoved += ShapeConstraints_Changed;
    170181      ShapeConstraints.ItemsReplaced += ShapeConstraints_Changed;
     182
     183      ExtendedConstraints.CheckedItemsChanged += ShapeConstraints_Changed;
     184      ExtendedConstraints.CollectionReset += ShapeConstraints_Changed;
     185      ExtendedConstraints.ItemsAdded += ShapeConstraints_Changed;
     186      ExtendedConstraints.ItemsRemoved += ShapeConstraints_Changed;
     187      ExtendedConstraints.ItemsMoved += ShapeConstraints_Changed;
     188      ExtendedConstraints.ItemsReplaced += ShapeConstraints_Changed;
    171189    }
    172190
  • branches/3138_Shape_Constraints_Transformations/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Regression/ShapeConstraint.cs

    r17960 r18213  
    106106    }
    107107
     108    [Storable]
     109    private Interval threshold = new Interval(0, 0);
     110    public Interval Threshold {
     111      get => threshold;
     112      set {
     113        if (threshold == value)
     114          return;
     115        threshold = value;
     116        OnToStringChanged();
     117        OnChanged();
     118      }
     119    }
     120
    108121    [StorableConstructor]
    109122    private ShapeConstraint(StorableConstructorFlag _) : base(_) { }
     
    115128
    116129    // without derivation
    117     public ShapeConstraint(Interval interval, double weight)
     130    public ShapeConstraint(Interval interval, double weight, Interval threshold)
    118131      : this(string.Empty, 0,
    119          interval, new IntervalCollection(), weight) { }
    120 
    121     public ShapeConstraint(Interval interval, IntervalCollection regions, double weight)
     132         interval, new IntervalCollection(), weight, threshold) { }
     133
     134    public ShapeConstraint(Interval interval, IntervalCollection regions, double weight, Interval threshold)
    122135      : this(string.Empty, 0,
    123          interval, regions, weight) { }
     136         interval, regions, weight, threshold) { }
    124137
    125138    public ShapeConstraint(string variable, int numberOfDerivations,
    126                               Interval interval, double weight)
     139                              Interval interval, double weight, Interval threshold)
    127140      : this(variable, numberOfDerivations,
    128              interval, new IntervalCollection(), weight) { }
     141             interval, new IntervalCollection(), weight, threshold) { }
    129142
    130143    public ShapeConstraint(string variable, int numberOfDerivations,
    131                               Interval interval, IntervalCollection regions, double weight) {
     144                              Interval interval, IntervalCollection regions, double weight, Interval threshold) {
    132145      Variable = variable;
    133146      NumberOfDerivations = numberOfDerivations;
     
    135148      Regions = regions;
    136149      Weight = weight;
     150      Threshold = threshold;
    137151    }
    138152
     
    148162      Regions = cloner.Clone(original.Regions);
    149163      Weight = original.weight;
     164      Threshold = original.threshold;
    150165    }
    151166
     
    175190      if (!IsDerivative) {
    176191        expression = string.Format($"f in [{write(Interval.LowerBound)} .. {write(Interval.UpperBound)}]");
    177         if (Regions != null) {
    178           foreach (var region in Regions.GetReadonlyDictionary())
    179             expression += $", {region.Key} in [{write(region.Value.LowerBound)} .. {write(region.Value.UpperBound)}]";
     192      } else {
     193        var derivationString = string.Empty;
     194        switch (numberOfDerivations) {
     195          case 1:
     196            derivationString = ""; break;
     197          case 2:
     198            derivationString = "²"; break;
     199          case 3:
     200            derivationString = "³"; break;
    180201        }
    181         if (Weight != 1.0) {
    182           expression += $" weight: {weight}";
    183         }
    184 
    185         return expression;
    186       }
    187 
    188       var derivationString = string.Empty;
    189       switch (numberOfDerivations) {
    190         case 1:
    191           derivationString = ""; break;
    192         case 2:
    193           derivationString = "²"; break;
    194         case 3:
    195           derivationString = "³"; break;
    196       }
    197       expression = string.Format($"∂{derivationString}f/∂{Variable}{derivationString} in [{write(Interval.LowerBound)} .. {write(Interval.UpperBound)}]");
    198       if (Regions != null) {
     202        expression = string.Format($"∂{derivationString}f/∂{Variable}{derivationString} in [{write(Interval.LowerBound)} .. {write(Interval.UpperBound)}]");
     203      }
     204
     205      if (Regions != null)
    199206        foreach (var region in Regions.GetReadonlyDictionary())
    200207          expression += $", {region.Key} in [{write(region.Value.LowerBound)} .. {write(region.Value.UpperBound)}]";
    201       }
    202       if (Weight != 1.0) {
     208
     209      if (Weight != 1.0)
    203210        expression += $" weight: {weight}";
    204       }
     211
     212      if (Threshold.LowerBound != 0 || Threshold.UpperBound != 0)
     213        expression += $" threshold in [{write(Threshold.LowerBound)} .. {write(Threshold.UpperBound)}]";
     214
    205215      return expression;
    206216    }
  • branches/3138_Shape_Constraints_Transformations/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Regression/ShapeConstraintsParser.cs

    r17960 r18213  
    7575    private const string variableRegex = @"(['](?<varName>.*)[']|(?<varName>[^\s²³]+))\s*";
    7676    private const string weightRegex = @"\s*(weight:\s*(?<weight>\S*))?";
     77    private const string thresholdRegex = @"\s*(threshold\s*in\s*(?<threshold> " + intervalRegex + @"))?";
    7778    public static ShapeConstraint ParseFunctionRangeConstraint(string expr) {
    7879      if (!expr.StartsWith("f")) throw new ArgumentException($"Invalid function range constraint {expr} (e.g. f in [1..2])");
     
    8990      // df/d'x' in [0 .. 10] weight: 2.0
    9091      // df / d'x' in [0..10], 'x' in [1 .. 3]
    91       // df / d'x' in [0..10], 'x' in [1 .. 3], y in [10..30] weight: 1.2
     92      // df / d'x' in [0..10], 'x' in [1 .. 3], y in [10..30] weight: 1.2 threshold in [-10 .. 10]
    9293
    9394      var match = Regex.Match(targetConstraint,
     
    99100                      intervalRegex +
    100101                    @")*" +
    101                     weightRegex
     102                    weightRegex +
     103                    thresholdRegex
    102104                    );
    103105
     
    110112        var interval = new Interval(lowerBound, upperBound);
    111113        var weight = 1.0;
     114        var threshold = new Interval(0, 0);
     115        int intervalIdx = 1;
     116        var lowerboundCount = match.Groups["lowerBound"].Captures.Count;
     117        var upperboundCount = match.Groups["upperBound"].Captures.Count;
    112118
    113119        if (match.Groups["weight"].Success && !string.IsNullOrWhiteSpace(match.Groups["weight"].Value))
    114120          weight = ParseAndValidateDouble(match.Groups["weight"].Value);
     121
     122        if (match.Groups["threshold"].Success) {
     123          var thresholdLb = ParseIntervalBounds(match.Groups["lowerBound"].Captures[lowerboundCount - intervalIdx].Value);
     124          var thresholdUb = ParseIntervalBounds(match.Groups["upperBound"].Captures[lowerboundCount - intervalIdx].Value);
     125          intervalIdx++;
     126          threshold = new Interval(thresholdLb, thresholdUb);
     127        }
    115128
    116129        if (match.Groups["varName"].Success) {
     
    127140              throw new ArgumentException($"The constraint {expr} has multiple regions of the same variable.");
    128141          }
    129           return new ShapeConstraint(interval, regions, weight);
     142          return new ShapeConstraint(interval, regions, weight, threshold);
    130143        } else
    131           return new ShapeConstraint(interval, weight);
     144          return new ShapeConstraint(interval, weight, threshold);
    132145      } else
    133146        throw new ArgumentException($"The target constraint {expr} is not valid.");
     
    148161                                  intervalRegex +
    149162                                  @")*" +
    150                                 weightRegex
     163                                weightRegex +
     164                                thresholdRegex
    151165                                );
    152166
     
    172186        var interval = new Interval(lowerBound, upperBound);
    173187        var weight = 1.0;
     188        var threshold = new Interval(0, 0);
     189        int intervalIdx = 1;
     190        var lowerboundCount = match.Groups["lowerBound"].Captures.Count;
     191        var upperboundCount = match.Groups["upperBound"].Captures.Count;
    174192
    175193        if (match.Groups["weight"].Success && !string.IsNullOrWhiteSpace(match.Groups["weight"].Value))
    176194          weight = ParseAndValidateDouble(match.Groups["weight"].Value);
     195
     196        if (match.Groups["threshold"].Success) {
     197          var thresholdLb = ParseIntervalBounds(match.Groups["lowerBound"].Captures[lowerboundCount - intervalIdx].Value);
     198          var thresholdUb = ParseIntervalBounds(match.Groups["upperBound"].Captures[lowerboundCount - intervalIdx].Value);
     199          intervalIdx++;
     200          threshold = new Interval(thresholdLb, thresholdUb);
     201        }
    177202
    178203        if (match.Groups["varName"].Captures.Count > 1) {
     
    189214              throw new ArgumentException($"The constraint {expr} has multiple regions of the same variable.");
    190215          }
    191           return new ShapeConstraint(variable, numberOfDerivation, interval, regions, weight);
     216          return new ShapeConstraint(variable, numberOfDerivation, interval, regions, weight, threshold);
    192217        } else
    193           return new ShapeConstraint(variable, numberOfDerivation, interval, weight);
     218          return new ShapeConstraint(variable, numberOfDerivation, interval, weight, threshold);
    194219      } else
    195220        throw new ArgumentException($"The derivation constraint {expr} is not valid.");
  • branches/3138_Shape_Constraints_Transformations/HeuristicLab.Problems.DataAnalysis/3.4/Interfaces/Regression/IShapeConstrainedRegressionProblemData.cs

    r17960 r18213  
    2020#endregion
    2121
     22using System.Collections.Generic;
    2223using HEAL.Attic;
    2324
     
    2627  public interface IShapeConstrainedRegressionProblemData : IRegressionProblemData {
    2728    ShapeConstraints ShapeConstraints { get; }
     29    IEnumerable<IExtendedConstraint> CheckedExtendedConstraints { get; }
    2830  }
    2931}
Note: See TracChangeset for help on using the changeset viewer.