Free cookie consent management tool by TermsFeed Policy Generator

Ignore:
Timestamp:
10/05/16 15:34:15 (8 years ago)
Author:
bburlacu
Message:

#2679: Refactor problems (rename to goal seeking, simplify code, simplify interface, remove unused methods)

File:
1 edited

Legend:

Unmodified
Added
Removed
  • branches/HeuristicLab.GoalSeekingProblem/HeuristicLab.GoalSeekingProblem/3.4/MultiObjectiveGoalSeekingProblem.cs

    r14321 r14324  
    3434using HeuristicLab.Problems.DataAnalysis;
    3535
    36 namespace HeuristicLab.ProcessParameterOptimization {
    37   [Item("Process parameter optimization problem (multi-objective)", "Represents a single objective optimization problem which uses configurable regression models to evaluate targets from a given dataset.")]
     36namespace HeuristicLab.GoalSeeking {
     37  [Item("Goal seeking problem (multi-objective)", "Represents a single objective optimization problem which uses configurable regression models to evaluate targets from a given dataset.")]
    3838  [Creatable("Problems")]
    3939  [StorableClass]
     
    5656    public IValueParameter<IRegressionProblemData> ProblemDataParameter {
    5757      get { return (IValueParameter<IRegressionProblemData>)Parameters[ProblemDataParameterName]; }
    58     }
    59     public IValueParameter<IDataset> ModifiableDatasetParameter {
    60       get { return (IValueParameter<IDataset>)Parameters[ModifiableDatasetParameterName]; }
    6158    }
    6259    public IValueParameter<CheckedItemList<StringValue>> ControllableParametersParameter {
     
    129126
    130127    #region targets
    131     public IEnumerable<string> ActiveTargets {
    132       get { return TargetList.CheckedItems.Select(x => x.Value.Value); }
    133     }
    134 
    135     public IEnumerable<string> Targets {
    136       get { return TargetList.Select(x => x.Value); }
    137     }
    138 
    139128    public ICheckedItemList<StringValue> TargetList {
    140129      get { return TargetsParameter.Value; }
    141130      set { TargetsParameter.Value = (CheckedItemList<StringValue>)value; }
    142131    }
     132    // convenience method
     133    private IEnumerable<string> ActiveTargets {
     134      get { return TargetList.CheckedItems.Select(x => x.Value.Value); }
     135    }
    143136    #endregion
    144137
    145138    #region parameters
    146     public IEnumerable<string> ActiveParameters {
    147       get { return ControllableParameters.CheckedItems.Select(x => x.Value.Value); }
    148     }
    149 
    150139    public ICheckedItemList<StringValue> ControllableParameters {
    151140      get { return ControllableParametersParameter.Value; }
    152141      set { ControllableParametersParameter.Value = (CheckedItemList<StringValue>)value; }
    153142    }
    154 
     143    // convenience method
     144    private IEnumerable<string> ActiveParameters {
     145      get { return ControllableParameters.CheckedItems.Select(x => x.Value.Value); }
     146    }
    155147    public DoubleMatrix ControllableParameterBounds {
    156148      get { return ControllableParameterBoundsParameter.Value; }
     
    162154    #region IProcessParameterOptimizationProblem methods
    163155    #region models
    164     public double GetVariableValue(string variableName) {
    165       return dataset.GetDoubleValue(variableName, 0);
    166     }
    167 
    168     public void SetVariableValue(string variableName, double variableValue) {
    169       dataset.SetVariableValue(variableValue, variableName, 0); // will throw if the variable is not present in the dataset
    170     }
    171 
    172     public double[] GetEstimatedGoalValues(IEnumerable<double> parameters, bool round = false) {
     156    public IEnumerable<double> GetEstimatedGoalValues(IEnumerable<double> parameterValues, bool round = false) {
    173157      var ds = (ModifiableDataset)dataset.Clone();
    174       var estimatedValues = new double[ActiveTargets.Count()];
    175       var e1 = parameters.GetEnumerator();
    176       var e2 = ActiveParameters.GetEnumerator();
    177       while (e1.MoveNext() && e2.MoveNext())
    178         ds.SetVariableValue(e1.Current, e2.Current, 0);
     158      foreach (var parameter in ActiveParameters.Zip(parameterValues, (p, v) => new { Name = p, Value = v })) {
     159        ds.SetVariableValue(parameter.Value, parameter.Name, 0);
     160      }
    179161      var rows = new[] { 0 }; // actually just one row
    180       int i = 0;
    181       var models = ModelCollection.ToList();
    182       foreach (var target in TargetList.CheckedItems) {
    183         var average = 0d;
    184         var count = 0;
    185         var targetName = target.Value.Value;
    186         foreach (var model in models) {
    187           if (targetName != model.TargetVariable)
    188             continue;
    189           average += model.GetEstimatedValues(ds, rows).Single();
    190           count++;
    191         }
    192         var estimatedValue = average / count;
    193         if (round) {
    194           var accuracy = GetTargetStepSize(targetName);
    195           estimatedValues[i] = RoundToNearestStepMultiple(estimatedValue, accuracy);
    196         } else {
    197           estimatedValues[i] = estimatedValue;
    198         }
    199         ++i;
    200       }
     162
     163      var estimatedValues =
     164        round ? ActiveTargets.Select(t => RoundToNearestStepMultiple(GetModels(t).Average(m => m.GetEstimatedValues(ds, rows).Single()), GetTargetStepSize(t)))
     165              : ActiveTargets.Select(t => GetModels(t).Average(m => m.GetEstimatedValues(ds, rows).Single()));
    201166      return estimatedValues;
    202167    }
     
    245210
    246211    public double GetTargetGoal(string target) {
    247       if (!Targets.Contains(target))
     212      if (!IsValidTarget(target))
    248213        throw new ArgumentException(string.Format("The target variable name \"{0}\" does not exist in the dataset.", target));
    249214      int i = TargetGoals.RowNames.TakeWhile(x => x != target).Count();
     
    252217
    253218    public void SetTargetGoal(string target, double goal) {
    254       if (!Targets.Contains(target))
     219      if (!IsValidTarget(target))
    255220        throw new ArgumentException(string.Format("The target variable name \"{0}\" does not exist in the dataset.", target));
    256221      int i = TargetGoals.RowNames.TakeWhile(x => x != target).Count();
     
    260225
    261226    public double GetTargetWeight(string target) {
    262       if (!Targets.Contains(target))
     227      if (!IsValidTarget(target))
    263228        throw new ArgumentException(string.Format("The target variable name \"{0}\" does not exist in the dataset.", target));
    264229      int i = TargetGoals.RowNames.TakeWhile(x => x != target).Count();
     
    267232
    268233    public void SetTargetWeight(string target, double weight) {
    269       if (!Targets.Contains(target))
     234      if (!IsValidTarget(target))
    270235        throw new ArgumentException(string.Format("The target variable name \"{0}\" does not exist in the dataset.", target));
    271236      int i = TargetGoals.RowNames.TakeWhile(x => x != target).Count();
     
    275240
    276241    public double GetTargetVariance(string target) {
    277       if (!Targets.Contains(target))
     242      if (!IsValidTarget(target))
    278243        throw new ArgumentException(string.Format("The target variable name \"{0}\" does not exist in the dataset.", target));
    279244      int i = TargetGoals.RowNames.TakeWhile(x => x != target).Count();
     
    282247
    283248    public void SetTargetVariance(string target, double variance) {
    284       if (!Targets.Contains(target))
     249      if (!IsValidTarget(target))
    285250        throw new ArgumentException(string.Format("The target variable name \"{0}\" does not exist in the dataset.", target));
    286251      int i = TargetGoals.RowNames.TakeWhile(x => x != target).Count();
     
    290255
    291256    public double GetTargetStepSize(string target) {
    292       if (!Targets.Contains(target))
     257      if (!IsValidTarget(target))
    293258        throw new ArgumentException(string.Format("The target variable name \"{0}\" does not exist in the dataset.", target));
    294259      int i = TargetGoals.RowNames.TakeWhile(x => x != target).Count();
     
    297262
    298263    public void SetTargetStepSize(string target, double stepSize) {
    299       if (!Targets.Contains(target))
     264      if (!IsValidTarget(target))
    300265        throw new ArgumentException(string.Format("The target variable name \"{0}\" does not exist in the dataset.", target));
    301266      int i = TargetGoals.RowNames.TakeWhile(x => x != target).Count();
     
    313278
    314279    #region process parameters
    315     public void SetParameterBounds(string parameterName, double min, double max, double step) {
    316       int i = ControllableParameterBounds.RowNames.TakeWhile(x => x != parameterName).Count();
    317       if (i < ControllableParameterBounds.Rows) {
    318         ControllableParameterBounds[i, 0] = min;
    319         ControllableParameterBounds[i, 1] = max;
    320         ControllableParameterBounds[i, 2] = step;
    321         UpdateEncoding();
    322         OnParametersChanged(this, EventArgs.Empty);
    323       } else {
    324         throw new ArgumentException(string.Format("SetParameterBounds: Invalid parameter name {0}", parameterName));
    325       }
    326 
    327     }
    328 
    329     public double GetParameterStepSize(string parameter) {
    330       int i = ControllableParameterBounds.RowNames.TakeWhile(x => x != parameter).Count();
    331       if (i < ControllableParameterBounds.Rows)
    332         return ControllableParameterBounds[i, 2];
    333       throw new ArgumentException(string.Format("GetParameterStepSize: Invalid parameter name {0}", parameter));
    334     }
    335 
    336     public void SetParameterStepSize(string parameter, double stepSize) {
    337       int i = ControllableParameterBounds.RowNames.TakeWhile(x => x != parameter).Count();
    338       if (i < ControllableParameterBounds.Rows) {
    339         ControllableParameterBounds[i, 2] = stepSize;
    340         OnParametersChanged(this, EventArgs.Empty);
    341       } else {
    342         throw new ArgumentException(string.Format("SetParameterStepSize: Invalid parameter name {0}", parameter));
    343       }
    344     }
    345 
    346 
    347     public bool GetParameterActive(string parameter) {
    348       var item = ControllableParameters.SingleOrDefault(x => x.Value == parameter);
    349       if (item == null)
    350         throw new ArgumentException(string.Format("GetParameterActive: Invalid target name {0}", parameter));
    351       return ControllableParameters.ItemChecked(item);
    352     }
    353 
    354     public void SetParameterActive(string parameter, bool active) {
    355       var item = ControllableParameters.SingleOrDefault(x => x.Value == parameter);
    356       if (item == null)
    357         throw new ArgumentException(string.Format("SetParameterActive: Invalid target name {0}", parameter));
    358       ControllableParameters.SetItemCheckedState(item, active);
    359       OnParametersChanged(this, EventArgs.Empty);
    360     }
    361 
    362280    /// <summary>
    363281    /// Returns the parameter bounds (min and max) and the step size for the specified parameter
     
    376294    }
    377295
     296    public void SetParameterBounds(string parameterName, double min, double max, double step) {
     297      int i = ControllableParameterBounds.RowNames.TakeWhile(x => x != parameterName).Count();
     298      if (i < ControllableParameterBounds.Rows) {
     299        ControllableParameterBounds[i, 0] = min;
     300        ControllableParameterBounds[i, 1] = max;
     301        ControllableParameterBounds[i, 2] = step;
     302        UpdateEncoding();
     303        OnParametersChanged(this, EventArgs.Empty);
     304      } else {
     305        throw new ArgumentException(string.Format("SetParameterBounds: Invalid parameter name {0}", parameterName));
     306      }
     307
     308    }
     309
     310    public double GetParameterStepSize(string parameter) {
     311      int i = ControllableParameterBounds.RowNames.TakeWhile(x => x != parameter).Count();
     312      if (i < ControllableParameterBounds.Rows)
     313        return ControllableParameterBounds[i, 2];
     314      throw new ArgumentException(string.Format("GetParameterStepSize: Invalid parameter name {0}", parameter));
     315    }
     316
     317    public void SetParameterStepSize(string parameter, double stepSize) {
     318      int i = ControllableParameterBounds.RowNames.TakeWhile(x => x != parameter).Count();
     319      if (i < ControllableParameterBounds.Rows) {
     320        ControllableParameterBounds[i, 2] = stepSize;
     321        OnParametersChanged(this, EventArgs.Empty);
     322        return;
     323      }
     324      throw new ArgumentException(string.Format("SetParameterStepSize: Invalid parameter name {0}", parameter));
     325    }
     326
     327    public bool GetParameterActive(string parameter) {
     328      var item = ControllableParameters.SingleOrDefault(x => x.Value == parameter);
     329      if (item == null)
     330        throw new ArgumentException(string.Format("GetParameterActive: Invalid target name {0}", parameter));
     331      return ControllableParameters.ItemChecked(item);
     332    }
     333
     334    public void SetParameterActive(string parameter, bool active) {
     335      var item = ControllableParameters.SingleOrDefault(x => x.Value == parameter);
     336      if (item == null)
     337        throw new ArgumentException(string.Format("SetParameterActive: Invalid target name {0}", parameter));
     338      ControllableParameters.SetItemCheckedState(item, active);
     339      OnParametersChanged(this, EventArgs.Empty);
     340    }
     341
    378342    public void SetControllableParameters(IEnumerable<string> parameterNames) {
    379343      ControllableParameters = new CheckedItemList<StringValue>();
     
    410374    }
    411375    #endregion // process parameters
    412     #endregion // IProcessParameterOprimizationProblem methods
     376    #endregion // IGoalSeekingProblem methods
    413377
    414378    #region data members
     
    431395    private MultiObjectiveGoalSeekingProblem(bool deserializing) : base(deserializing) { }
    432396
    433     private MultiObjectiveGoalSeekingProblem(MultiObjectiveGoalSeekingProblem original, Cloner cloner)
    434       : base(original, cloner) {
     397    private MultiObjectiveGoalSeekingProblem(MultiObjectiveGoalSeekingProblem original, Cloner cloner) : base(original, cloner) {
    435398      this.dataset = cloner.Clone(original.dataset);
    436399      this.problemData = cloner.Clone(original.problemData);
     
    512475        ++i;
    513476      }
    514       i = 0;
    515       var qualities = new double[ActiveTargets.Count()];
    516477      var estimatedValues = GetEstimatedGoalValues(vector, round: true);
    517       // round target estimated values and calculate qualities
    518       foreach (var target in ActiveTargets) {
    519         var estimatedValue = estimatedValues[i];
    520         var goal = GetTargetGoal(target);
    521         var weight = GetTargetWeight(target);
    522         var variance = GetTargetVariance(target);
    523         qualities[i] = weight * Math.Pow(estimatedValue - goal, 2) / variance;
    524         ++i;
    525       }
    526       return qualities;
     478      var qualities = TargetList.CheckedItems.Zip(estimatedValues, (t, v) => new { Name = t.Value.Value, Index = t.Index, EstimatedValue = v })
     479                                .Select(target => {
     480                                  var goal = TargetGoals[target.Index, 0];
     481                                  var weight = TargetGoals[target.Index, 1];
     482                                  var variance = TargetGoals[target.Index, 2];
     483                                  return weight * Math.Pow(target.EstimatedValue - goal, 2) / variance;
     484                                });
     485      return qualities.ToArray();
    527486    }
    528487
     
    561520          continue;
    562521        var vector = individuals[i].RealVector();
    563         var estimatedValues = GetEstimatedGoalValues(vector);
     522        var estimatedValues = GetEstimatedGoalValues(vector).ToList();
    564523        var rowValues = new double[columnNames.Count];
    565524        rowValues[0] = qualitySum;
     
    658617    private void UpdateControllableParameters() {
    659618      if (ProblemData == null) return;
    660       SetControllableParameters(ProblemData.Dataset.DoubleVariables);
     619       if (ProblemData == null) return;
     620      var variablesUsedForPrediction = ModelCollection.Any()
     621        ? ModelCollection.SelectMany(x => x.VariablesUsedForPrediction).Distinct()
     622        : ProblemData.Dataset.DoubleVariables;
     623      SetControllableParameters(variablesUsedForPrediction);
    661624    }
    662625
     
    715678      }
    716679    }
    717     #endregion
    718 
    719     #region util
     680
     681    private bool IsValidTarget(string target) {
     682      return TargetList.Any(x => x.Value == target);
     683    }
    720684    private static double RoundToNearestStepMultiple(double value, double step) {
    721685      return step * (long)Math.Round(value / step);
    722686    }
    723 
     687    private IEnumerable<IRegressionModel> GetModels(string target) {
     688      return ModelCollection.Where(x => x.TargetVariable == target);
     689    }
    724690    private class DoubleEqualityComparer : IEqualityComparer<double> {
    725691      public bool Equals(double x, double y) { return x.IsAlmost(y); }
Note: See TracChangeset for help on using the changeset viewer.