Free cookie consent management tool by TermsFeed Policy Generator

source: branches/2988_ModelsOfModels2/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Analyzers/TerminalNodesFrequencyAnalyzer.cs @ 17002

Last change on this file since 17002 was 17002, checked in by msemenki, 5 years ago

#2988:
Class HelpFuction get new static functions that are used in different Map’s classes and possible in other classes.
Branch was adapted to Hive.
New version of class structure for Maps:

  1. 3 new variants of maps (RankMap, SuccessMap and ZeroMap) are added.
  2. BaseMap class was simplified, some class members were deleted and other were transported to child class, because some of them are not used in all kinds of maps.
  3. Functions between base class and child class were divided in other way.
  4. Mutation operators were adapted to work with new class structure. Now mutation make less work for ModelNodes than previously.
  5. ModelNode and Model symbols were simplified. They should not take into account a map type.
  6. Models frequency analyzers were adapted for new variants of maps.
  7. EMMAlgorithm class was adapted to new maps
File size: 7.8 KB
Line 
1#region License Information
2/* HeuristicLab
3 * Copyright (C) 2002-2019 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
4 *
5 * This file is part of HeuristicLab.
6 *
7 * HeuristicLab is free software: you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation, either version 3 of the License, or
10 * (at your option) any later version.
11 *
12 * HeuristicLab is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
19 */
20#endregion
21
22using HEAL.Attic;
23using HeuristicLab.Analysis;
24using HeuristicLab.Common;
25using HeuristicLab.Core;
26using HeuristicLab.Data;
27using HeuristicLab.Encodings.SymbolicExpressionTreeEncoding;
28using HeuristicLab.Optimization;
29using HeuristicLab.Parameters;
30using System;
31using System.Collections.Generic;
32using System.Linq;
33
34namespace HeuristicLab.Problems.DataAnalysis.Symbolic {
35  /// <summary>
36  /// Calculates the accumulated frequencies of variable-symbols over all trees in the population.
37  /// </summary>
38  [Item("TerminalNodesFrequencyAnalyzer", "Calculates the accumulated frequencies of Terminal Nodes over all trees in the population.")]
39  [StorableType("638ECFFA-B441-4099-AB5F-DFCA1FE41154")]
40  public sealed class TerminalNodesFrequencyAnalyzer : SymbolicDataAnalysisAnalyzer {
41    private const string TerminalNodesFrequencyParameterName = "TerminalNodesFrequency";
42    private const string AggregateTerminalNodesParameterName = "AggregateTerminalNodes";
43
44    #region parameter properties
45    public ILookupParameter<DataTable> TerminalNodesFrequencyParameter {
46      get { return (ILookupParameter<DataTable>)Parameters[TerminalNodesFrequencyParameterName]; }
47    }
48    public IValueLookupParameter<BoolValue> AggregateTerminalNodesParameter {
49      get { return (IValueLookupParameter<BoolValue>)Parameters[AggregateTerminalNodesParameterName]; }
50    }
51    #endregion
52    #region properties
53    public BoolValue AggregateTerminalNodes {
54      get { return AggregateTerminalNodesParameter.ActualValue; }
55      set { AggregateTerminalNodesParameter.Value = value; }
56    }
57    public DataTable TerminalNodesFrequency {
58      get { return TerminalNodesFrequencyParameter.ActualValue; }
59      set { TerminalNodesFrequencyParameter.ActualValue = value; }
60    }
61
62    #endregion
63    [StorableConstructor]
64    private TerminalNodesFrequencyAnalyzer(StorableConstructorFlag _) : base(_) { }
65    private TerminalNodesFrequencyAnalyzer(TerminalNodesFrequencyAnalyzer original, Cloner cloner)
66      : base(original, cloner) {
67    }
68    public TerminalNodesFrequencyAnalyzer()
69      : base() {
70      Parameters.Add(new LookupParameter<DataTable>(TerminalNodesFrequencyParameterName, "The relative Terminal Nodes reference frequencies aggregated over all trees in the population."));
71      Parameters.Add(new ValueLookupParameter<BoolValue>(AggregateTerminalNodesParameterName, "Switch that determines whether all references to factor Terminal Nodes should be aggregated regardless of the value. Turn off to analyze all factor variable references with different values separately.", new BoolValue(true)));
72    }
73
74    [StorableHook(HookType.AfterDeserialization)]
75    private void AfterDeserialization() {
76      // BackwardsCompatibility3.3
77      #region Backwards compatible code, remove with 3.4
78      if (!Parameters.ContainsKey(AggregateTerminalNodesParameterName)) {
79        Parameters.Add(new ValueLookupParameter<BoolValue>(AggregateTerminalNodesParameterName, "Switch that determines whether all references to factor Terminal Nodes should be aggregated regardless of the value. Turn off to analyze all factor Terminal Nodes references with different values separately.", new BoolValue(true)));
80      }
81      #endregion
82    }
83
84    public override IDeepCloneable Clone(Cloner cloner) {
85      return new TerminalNodesFrequencyAnalyzer(this, cloner);
86    }
87
88    public override IOperation Apply() {
89      ItemArray<ISymbolicExpressionTree> expressions = SymbolicExpressionTreeParameter.ActualValue;
90      ResultCollection results = ResultCollection;
91      DataTable datatable;
92      if (TerminalNodesFrequencyParameter.ActualValue == null) {
93        datatable = new DataTable("Terminal Nodes frequencies", "Relative frequency of Terminal Nodes references aggregated over the whole population.");
94        datatable.VisualProperties.XAxisTitle = "Generation";
95        datatable.VisualProperties.YAxisTitle = "Relative Model Frequency";
96        TerminalNodesFrequencyParameter.ActualValue = datatable;
97        results.Add(new Result("Terminal Nodes frequencies", "Relative frequency of Terminal Nodes references aggregated over the whole population.", datatable));
98      }
99
100      datatable = TerminalNodesFrequencyParameter.ActualValue;
101      // all rows must have the same number of values so we can just take the first
102      int numberOfValues = datatable.Rows.Select(r => r.Values.Count).DefaultIfEmpty().First();
103      foreach (var pair in CalculateTerminalNodesFrequency(expressions).OrderByDescending(x => x.Value)) {
104        //var pair in CalculateModelFrequency(expressions).OrderByDescending(x => x.Value).Take(10)
105        if (!datatable.Rows.ContainsKey(pair.Key)) {
106          // initialize a new row for the variable and pad with zeros
107          DataRow row = new DataRow(pair.Key, "", Enumerable.Repeat(0.0, numberOfValues));
108          row.VisualProperties.StartIndexZero = true;
109          datatable.Rows.Add(row);
110        }
111        datatable.Rows[pair.Key].Values.Add(Math.Round(pair.Value, 3));
112      }
113
114      // add a zero for each data row that was not modified in the previous loop
115      foreach (var row in datatable.Rows.Where(r => r.Values.Count != numberOfValues + 1))
116        row.Values.Add(0.0);
117
118      return base.Apply();
119    }
120
121    public static IEnumerable<KeyValuePair<string, double>> CalculateTerminalNodesFrequency(IEnumerable<ISymbolicExpressionTree> trees) {
122      var terminalNodesFrequency = trees
123          .SelectMany(t => GetTerminalNodesReferences(t))
124          .GroupBy(pair => pair.Key, pair => pair.Value)
125          .ToDictionary(g => g.Key, g => (double)g.Sum());
126
127      double totalNumberOfSymbols = terminalNodesFrequency.Values.Sum();
128
129      foreach (var pair in terminalNodesFrequency.OrderBy(p => p.Key, new NaturalStringComparer()))
130        yield return new KeyValuePair<string, double>(pair.Key, pair.Value / totalNumberOfSymbols);
131    }
132
133    private static IEnumerable<KeyValuePair<string, int>> GetTerminalNodesReferences(ISymbolicExpressionTree tree) {
134      Dictionary<string, int> references = new Dictionary<string, int>();
135      foreach (var treeNode in tree.IterateNodesPrefix().OfType<VariableTreeNode>()) {
136        string referenceId = "Variable ";
137        if (references.ContainsKey(referenceId)) {
138          references[referenceId]++;
139        } else {
140          references[referenceId] = 1;
141        }
142      }
143      foreach (var treeNode in tree.IterateNodesPrefix().OfType<TreeModelTreeNode>()) {
144        string referenceId = "Model ";
145        if (references.ContainsKey(referenceId)) {
146          references[referenceId]++;
147        } else {
148          references[referenceId] = 1;
149        }
150      }
151      foreach (var treeNode in tree.IterateNodesPrefix().OfType<ConstantTreeNode>()) {
152        string referenceId = "Constant";
153        if (references.ContainsKey(referenceId)) {
154          references[referenceId]++;
155        } else {
156          references[referenceId] = 1;
157        }
158      }
159      return references;
160    }
161  }
162}
Note: See TracBrowser for help on using the repository browser.