Free cookie consent management tool by TermsFeed Policy Generator

Ignore:
Timestamp:
08/09/16 15:18:32 (8 years ago)
Author:
gkronber
Message:

#2650: added support for factor variables to target variation view together with Philipp

Location:
branches/symbreg-factors-2650/HeuristicLab.Problems.DataAnalysis.Views/3.4
Files:
3 added
4 edited

Legend:

Unmodified
Added
Removed
  • branches/symbreg-factors-2650/HeuristicLab.Problems.DataAnalysis.Views/3.4/Controls/DensityChart.cs

    r14099 r14248  
    3030    }
    3131
     32    public void UpdateChart(IList<string> data, double minimumHeight = 0.1) {
     33      if (data == null || !data.Any())
     34        return;
     35      UpdateChartWithBuckets(CalculateBuckets(data));
     36    }
     37
     38
    3239    public void UpdateChart(IList<double> data, double min, double max, int numBuckets, double minimumHeight = 0.1) {
    3340      if (data == null || numBuckets < 0 || min > max || max < min)
    3441        return;
    3542
    36       var buckets = CalculateBuckets(data, numBuckets, min, max);
     43      UpdateChartWithBuckets(CalculateBuckets(data, numBuckets, min, max));
     44    }
    3745
     46
     47    private void UpdateChartWithBuckets(double[] buckets) {
    3848      // set minimum height of all non-zero buckets on 10% of maximum
    3949      double minHeight = buckets.Max() * 0.1;
     
    6979      return buckets;
    7080    }
     81    private double[] CalculateBuckets(IList<string> data) {
     82      return data.GroupBy(val => val).OrderBy(g => g.Key).Select(g => (double)g.Count()).Concat(new double[] { 0.0 }).ToArray();
     83    }
    7184  }
    7285}
  • branches/symbreg-factors-2650/HeuristicLab.Problems.DataAnalysis.Views/3.4/Controls/GradientChart.cs

    r14158 r14248  
    2121
    2222using System;
     23using System.Collections;
    2324using System.Collections.Generic;
    2425using System.Drawing;
     
    3435
    3536namespace HeuristicLab.Problems.DataAnalysis.Views {
    36   public partial class GradientChart : UserControl {
     37  public partial class GradientChart : UserControl, IGradientChart {
    3738    private ModifiableDataset sharedFixedVariables; // used for syncronising variable values between charts
    3839    private ModifiableDataset internalDataset; // holds the x values for each point drawn
     
    319320        if (updateOnFinish)
    320321          Update();
    321       }
    322       catch (OperationCanceledException) { }
    323       catch (AggregateException ae) {
     322      } catch (OperationCanceledException) { } catch (AggregateException ae) {
    324323        if (!ae.InnerExceptions.Any(e => e is OperationCanceledException))
    325324          throw;
     
    347346      try {
    348347        chart.ChartAreas[0].RecalculateAxesScale();
    349       }
    350       catch (InvalidOperationException) {
     348      } catch (InvalidOperationException) {
    351349        // Can occur if eg. axis min == axis max
    352350      }
     
    381379        xvalues.Add(xmin + i * step);
    382380
    383       var variables = sharedFixedVariables.DoubleVariables.ToList();
    384       internalDataset = new ModifiableDataset(variables,
    385         variables.Select(x => x == FreeVariable
    386           ? xvalues
    387           : Enumerable.Repeat(sharedFixedVariables.GetDoubleValue(x, 0), xvalues.Count).ToList()
    388         )
    389       );
     381      if (sharedFixedVariables == null)
     382        return;
     383
     384      var variables = sharedFixedVariables.VariableNames.ToList();
     385      var values = new List<IList>();
     386      foreach (var varName in variables) {
     387        if (varName == FreeVariable) {
     388          values.Add(xvalues);
     389        } else if (sharedFixedVariables.VariableHasType<double>(varName)) {
     390          values.Add(Enumerable.Repeat(sharedFixedVariables.GetDoubleValue(varName, 0), xvalues.Count).ToList());
     391        } else if (sharedFixedVariables.VariableHasType<string>(varName)) {
     392          values.Add(Enumerable.Repeat(sharedFixedVariables.GetStringValue(varName, 0), xvalues.Count).ToList());
     393        }
     394      }
     395
     396      internalDataset = new ModifiableDataset(variables, values);
    390397    }
    391398
     
    552559
    553560    private static bool SolutionsCompatible(IEnumerable<IRegressionSolution> solutions) {
    554       foreach (var solution1 in solutions) {
    555         var variables1 = solution1.ProblemData.Dataset.DoubleVariables;
    556         foreach (var solution2 in solutions) {
    557           if (solution1 == solution2)
    558             continue;
    559           var variables2 = solution2.ProblemData.Dataset.DoubleVariables;
    560           if (!variables1.All(variables2.Contains))
    561             return false;
     561      var refSolution = solutions.First();
     562      var refSolVars = refSolution.ProblemData.Dataset.VariableNames;
     563      foreach (var solution in solutions.Skip(1)) {
     564        var variables1 = solution.ProblemData.Dataset.VariableNames;
     565        if (!variables1.All(refSolVars.Contains))
     566          return false;
     567
     568        foreach (var factorVar in variables1.Where(solution.ProblemData.Dataset.VariableHasType<string>)) {
     569          var distinctVals = refSolution.ProblemData.Dataset.GetStringValues(factorVar).Distinct();
     570          if (solution.ProblemData.Dataset.GetStringValues(factorVar).Any(val => !distinctVals.Contains(val))) return false;
    562571        }
    563572      }
     
    608617    private void sharedFixedVariables_ItemChanged(object o, EventArgs<int, int> e) {
    609618      if (o != sharedFixedVariables) return;
    610       var variables = sharedFixedVariables.DoubleVariables.ToList();
     619      var variables = sharedFixedVariables.VariableNames.ToList();
    611620      var rowIndex = e.Value;
    612621      var columnIndex = e.Value2;
     
    614623      var variableName = variables[columnIndex];
    615624      if (variableName == FreeVariable) return;
    616       var v = sharedFixedVariables.GetDoubleValue(variableName, rowIndex);
    617       var values = new List<double>(Enumerable.Repeat(v, DrawingSteps));
    618       internalDataset.ReplaceVariable(variableName, values);
     625      if (internalDataset.VariableHasType<double>(variableName)) {
     626        var v = sharedFixedVariables.GetDoubleValue(variableName, rowIndex);
     627        var values = new List<double>(Enumerable.Repeat(v, internalDataset.Rows));
     628        internalDataset.ReplaceVariable(variableName, values);
     629      } else if (internalDataset.VariableHasType<string>(variableName)) {
     630        var v = sharedFixedVariables.GetStringValue(variableName, rowIndex);
     631        var values = new List<String>(Enumerable.Repeat(v, internalDataset.Rows));
     632        internalDataset.ReplaceVariable(variableName, values);
     633      } else {
     634        // unsupported type
     635        throw new NotSupportedException();
     636      }
    619637    }
    620638
     
    635653      UpdateCursor();
    636654    }
    637     void UpdateCursor() {
     655    private void UpdateCursor() {
    638656      var x = VerticalLineAnnotation.X;
    639657      sharedFixedVariables.SetVariableValue(x, FreeVariable, 0);
  • branches/symbreg-factors-2650/HeuristicLab.Problems.DataAnalysis.Views/3.4/HeuristicLab.Problems.DataAnalysis.Views-3.4.csproj

    r14125 r14248  
    132132      <DependentUpon>DensityTrackbar.cs</DependentUpon>
    133133    </Compile>
     134    <Compile Include="Controls\FactorGradientChart.cs">
     135      <SubType>UserControl</SubType>
     136    </Compile>
     137    <Compile Include="Controls\FactorGradientChart.Designer.cs">
     138      <DependentUpon>FactorGradientChart.cs</DependentUpon>
     139    </Compile>
    134140    <Compile Include="FeatureCorrelation\TimeframeFeatureCorrelationCalculator.cs" />
    135141    <Compile Include="FeatureCorrelation\AbstractFeatureCorrelationCalculator.cs" />
     
    207213      <DependentUpon>GradientChartConfigurationDialog.cs</DependentUpon>
    208214    </Compile>
     215    <Compile Include="Interfaces\IGradientChart.cs" />
    209216    <Compile Include="Interfaces\IDataPreprocessorStarter.cs" />
    210217    <Compile Include="MenuItems\ShrinkDataAnalysisRunsMenuItem.cs" />
  • branches/symbreg-factors-2650/HeuristicLab.Problems.DataAnalysis.Views/3.4/Regression/RegressionSolutionTargetResponseGradientView.cs

    r14158 r14248  
    2121
    2222using System;
     23using System.Collections;
    2324using System.Collections.Generic;
    2425using System.Drawing;
     
    3435  [Content(typeof(IRegressionSolution))]
    3536  public partial class RegressionSolutionTargetResponseGradientView : DataAnalysisSolutionEvaluationView {
    36     private readonly Dictionary<string, GradientChart> gradientCharts;
     37    private readonly Dictionary<string, IGradientChart> gradientCharts;
    3738    private readonly Dictionary<string, DensityChart> densityCharts;
    3839    private readonly Dictionary<string, Panel> groupingPanels;
     
    4748      }
    4849    }
    49     private IEnumerable<GradientChart> VisibleGradientCharts {
     50    private IEnumerable<IGradientChart> VisibleGradientCharts {
    5051      get { return VisibleVariables.Select(v => gradientCharts[v]); }
    5152    }
     
    5960    public RegressionSolutionTargetResponseGradientView() {
    6061      InitializeComponent();
    61       gradientCharts = new Dictionary<string, GradientChart>();
     62      gradientCharts = new Dictionary<string, IGradientChart>();
    6263      densityCharts = new Dictionary<string, DensityChart>();
    6364      groupingPanels = new Dictionary<string, Panel>();
     
    112113      // create dataset
    113114      var allowedInputVariables = Content.ProblemData.AllowedInputVariables;
    114       var variableValues = allowedInputVariables.Select(x => new List<double> { problemData.Dataset.GetDoubleValues(x, problemData.TrainingIndices).Median() });
    115       var sharedFixedVariables = new ModifiableDataset(allowedInputVariables, variableValues);
     115      var doubleVariables = allowedInputVariables.Where(problemData.Dataset.VariableHasType<double>);
     116      var doubleVariableValues = (IEnumerable<IList>)doubleVariables.Select(x => new List<double> { problemData.Dataset.GetDoubleValues(x, problemData.TrainingIndices).Median() });
     117
     118      var factorVariables = allowedInputVariables.Where(problemData.Dataset.VariableHasType<string>);
     119      var factorVariableValues = (IEnumerable<IList>)factorVariables.Select(x => new List<string> {
     120        problemData.Dataset.GetStringValues(x, problemData.TrainingIndices)
     121        .GroupBy(val => val).OrderByDescending(g => g.Count()).First().Key // most frequent value
     122      });
     123
     124      var sharedFixedVariables = new ModifiableDataset(doubleVariables.Concat(factorVariables), doubleVariableValues.Concat(factorVariableValues));
     125
    116126
    117127      // create controls
     
    119129      densityCharts.Clear();
    120130      groupingPanels.Clear();
    121       foreach (var variableName in allowedInputVariables) {
     131      foreach (var variableName in doubleVariables) {
    122132        var gradientChart = CreateGradientChart(variableName, sharedFixedVariables);
    123133        gradientCharts.Add(variableName, gradientChart);
     
    147157        // Initially, the inner plot areas are not initialized for hidden charts (scollpanel, ...)
    148158        // This event handler listens for the paint event once (where everything is already initialized) to do some manual layouting.
    149         gradientChart.ChartPostPaint += OnGradientChartOnChartPostPaint;
     159        gradientChart.ChartPostPaint += OnGradientChartPostPaint;
    150160
    151161        var panel = new Panel() {
     
    159169        groupingPanels.Add(variableName, panel);
    160170      }
    161 
     171      foreach (var variableName in factorVariables) {
     172        var gradientChart = CreateFactorGradientChart(variableName, sharedFixedVariables);
     173        gradientCharts.Add(variableName, gradientChart);
     174
     175        var densityChart = new DensityChart() {
     176          Anchor = AnchorStyles.Left | AnchorStyles.Top | AnchorStyles.Right,
     177          Margin = Padding.Empty,
     178          Height = 12,
     179          Visible = false,
     180          Top = (int)(gradientChart.Height * 0.1),
     181        };
     182        densityCharts.Add(variableName, densityChart);
     183        gradientChart.ZoomChanged += (o, e) => {
     184          var gradient = (FactorGradientChart)o;
     185          var density = densityCharts[gradient.FreeVariable];
     186          density.Visible = densityComboBox.SelectedIndex != 0 && !gradient.IsZoomed;
     187          if (density.Visible)
     188            UpdateDensityChart(density, gradient.FreeVariable);
     189        };
     190        gradientChart.SizeChanged += (o, e) => {
     191          var gradient = (FactorGradientChart)o;
     192          var density = densityCharts[gradient.FreeVariable];
     193          density.Top = (int)(gradient.Height * 0.1);
     194        };
     195
     196        // Initially, the inner plot areas are not initialized for hidden charts (scollpanel, ...)
     197        // This event handler listens for the paint event once (where everything is already initialized) to do some manual layouting.
     198        gradientChart.ChartPostPaint += OnFactorGradientChartPostPaint;
     199
     200        var panel = new Panel() {
     201          Dock = DockStyle.Fill,
     202          Margin = Padding.Empty,
     203          BackColor = Color.White
     204        };
     205
     206        panel.Controls.Add(densityChart);
     207        panel.Controls.Add(gradientChart);
     208        groupingPanels.Add(variableName, panel);
     209      }
    162210      // update variable list
    163211      variableListView.ItemChecked -= variableListView_ItemChecked;
     
    173221    }
    174222
    175     private void OnGradientChartOnChartPostPaint(object o, EventArgs e) {
     223    private void OnGradientChartPostPaint(object o, EventArgs e) {
    176224      var gradient = (GradientChart)o;
    177225      var density = densityCharts[gradient.FreeVariable];
     
    186234      // removed after succesful layouting due to performance reasons
    187235      if (gcPlotPosition.Width != 0)
    188         gradient.ChartPostPaint -= OnGradientChartOnChartPostPaint;
     236        gradient.ChartPostPaint -= OnGradientChartPostPaint;
     237    }
     238
     239    private void OnFactorGradientChartPostPaint(object o, EventArgs e) {
     240      var gradient = (FactorGradientChart)o;
     241      var density = densityCharts[gradient.FreeVariable];
     242
     243      density.Width = gradient.Width;
     244
     245      var gcPlotPosition = gradient.InnerPlotPosition;
     246      density.Left = (int)(gcPlotPosition.X / 100.0 * gradient.Width);
     247      density.Width = (int)(gcPlotPosition.Width / 100.0 * gradient.Width);
     248      gradient.UpdateTitlePosition();
     249
     250      // removed after succesful layouting due to performance reasons
     251      if (gcPlotPosition.Width != 0)
     252        gradient.ChartPostPaint -= OnFactorGradientChartPostPaint;
    189253    }
    190254
     
    192256      foreach (var variable in VisibleVariables) {
    193257        var gradientChart = gradientCharts[variable];
    194         await gradientChart.RecalculateAsync();
     258        await gradientChart.RecalculateAsync(false, false);
    195259      }
    196260      gradientChartTableLayout.SuspendLayout();
     
    201265      gradientChartTableLayout.Refresh();
    202266      foreach (var variable in VisibleVariables) {
    203         var densityChart = densityCharts[variable];
    204         UpdateDensityChart(densityChart, variable);
     267        DensityChart densityChart;
     268        if (densityCharts.TryGetValue(variable, out densityChart)) {
     269          UpdateDensityChart(densityChart, variable);
     270        }
    205271      }
    206272    }
     
    215281      };
    216282      gradientChart.VariableValueChanged += async (o, e) => {
    217         var recalculations = VisibleGradientCharts.Except(new[] { (GradientChart)o }).Select(async chart => {
    218           await chart.RecalculateAsync(updateOnFinish: false, resetYAxis: false);
    219         }).ToList();
     283        var recalculations = VisibleGradientCharts
     284          .Except(new[] { (IGradientChart)o })
     285          .Select(async chart => {
     286            await chart.RecalculateAsync(updateOnFinish: false, resetYAxis: false);
     287          }).ToList();
    220288        await Task.WhenAll(recalculations);
    221289
     
    228296      return gradientChart;
    229297    }
    230 
     298    private FactorGradientChart CreateFactorGradientChart(string variableName, ModifiableDataset sharedFixedVariables) {
     299      var gradientChart = new FactorGradientChart {
     300        Dock = DockStyle.Fill,
     301        Margin = Padding.Empty,
     302        ShowLegend = false,
     303        ShowCursor = true,
     304        YAxisTicks = 5,
     305      };
     306      gradientChart.VariableValueChanged += async (o, e) => {
     307        var recalculations = VisibleGradientCharts
     308          .Except(new[] { (FactorGradientChart)o })
     309          .Select(async chart => {
     310            await chart.RecalculateAsync(updateOnFinish: false, resetYAxis: false);
     311          }).ToList();
     312        await Task.WhenAll(recalculations);
     313
     314        if (recalculations.All(t => t.IsCompleted))
     315          SetupYAxis();
     316      };
     317      var variableValues = Content.ProblemData.Dataset.GetStringValues(variableName).Distinct().OrderBy(n => n).ToList();
     318      gradientChart.Configure(new[] { Content }, sharedFixedVariables, variableName, variableValues);
     319      gradientChart.SolutionAdded += gradientChart_SolutionAdded;
     320      gradientChart.SolutionRemoved += gradientChart_SolutionRemoved;
     321      return gradientChart;
     322    }
    231323    private void SetupYAxis() {
    232324      double axisMin, axisMax;
     
    319411      if (item.Checked) {
    320412        tl.Controls.Add(chartsPanel);
    321         await gradientChart.RecalculateAsync();
     413        await gradientChart.RecalculateAsync(false, false);
    322414      } else {
    323415        tl.Controls.Remove(chartsPanel);
     
    383475        indices = GetDensityIndices(densityComboBox.SelectedIndex).ToList();
    384476      }
    385       var data = Content.ProblemData.Dataset.GetDoubleValues(variable, indices).ToList();
    386       var gradientChart = gradientCharts[variable];
    387       var min = gradientChart.FixedXAxisMin;
    388       var max = gradientChart.FixedXAxisMax;
    389       var buckets = gradientChart.DrawingSteps;
    390       if (min.HasValue && max.HasValue) {
    391         densityChart.UpdateChart(data, min.Value, max.Value, buckets);
    392         densityChart.Width = gradientChart.Width;
    393 
    394         var gcPlotPosition = gradientChart.InnerPlotPosition;
    395         densityChart.Left = (int)(gcPlotPosition.X / 100.0 * gradientChart.Width);
    396         densityChart.Width = (int)(gcPlotPosition.Width / 100.0 * gradientChart.Width);
    397 
    398         densityChart.Visible = true;
    399       }
    400 
    401       gradientChart.UpdateTitlePosition();
     477      if (Content.ProblemData.Dataset.VariableHasType<double>(variable)) {
     478        var data = Content.ProblemData.Dataset.GetDoubleValues(variable, indices).ToList();
     479        var gradientChart = gradientCharts[variable] as GradientChart;
     480        if (gradientChart != null) {
     481          var min = gradientChart.FixedXAxisMin;
     482          var max = gradientChart.FixedXAxisMax;
     483          var buckets = gradientChart.DrawingSteps;
     484          if (min.HasValue && max.HasValue) {
     485            densityChart.UpdateChart(data, min.Value, max.Value, buckets);
     486            densityChart.Width = gradientChart.Width;
     487
     488            var gcPlotPosition = gradientChart.InnerPlotPosition;
     489            densityChart.Left = (int)(gcPlotPosition.X / 100.0 * gradientChart.Width);
     490            densityChart.Width = (int)(gcPlotPosition.Width / 100.0 * gradientChart.Width);
     491
     492            densityChart.Visible = true;
     493          }
     494          gradientChart.UpdateTitlePosition();
     495        }
     496      } else if (Content.ProblemData.Dataset.VariableHasType<string>(variable)) {
     497        var data = Content.ProblemData.Dataset.GetStringValues(variable).ToList();
     498        var gradientChart = gradientCharts[variable] as FactorGradientChart;
     499        if (gradientChart != null) {
     500          densityChart.UpdateChart(data);
     501          densityChart.Width = gradientChart.Width;
     502
     503          var gcPlotPosition = gradientChart.InnerPlotPosition;
     504          densityChart.Left = (int)(gcPlotPosition.X / 100.0 * gradientChart.Width);
     505          densityChart.Width = (int)(gcPlotPosition.Width / 100.0 * gradientChart.Width);
     506
     507          densityChart.Visible = true;
     508
     509          gradientChart.UpdateTitlePosition();
     510        }
     511      }
    402512    }
    403513
     
    422532        var densityChart = densityCharts[variable];
    423533        // recalculate and refresh
    424         await gradientChart.RecalculateAsync();
     534        await gradientChart.RecalculateAsync(false, false);
    425535        gradientChart.Refresh();
    426536        UpdateDensityChart(densityChart, variable);
Note: See TracChangeset for help on using the changeset viewer.