Free cookie consent management tool by TermsFeed Policy Generator

source: trunk/sources/HeuristicLab.CEDMA.Core/3.3/Results.cs @ 2138

Last change on this file since 2138 was 2137, checked in by gkronber, 15 years ago

Improved loading speed of CEDMA results by:

  • Limit number of models to the best 10% for each target variable
  • Cache sqlite rdf store to memory on first query

#286 (Variable-usage diagrams for the CEDMA frontend)

File size: 9.8 KB
Line 
1#region License Information
2/* HeuristicLab
3 * Copyright (C) 2002-2008 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 System;
23using System.Collections.Generic;
24using System.Linq;
25using System.Text;
26using HeuristicLab.Core;
27using System.Collections;
28using HeuristicLab.CEDMA.DB.Interfaces;
29using System.Xml;
30using System.Runtime.Serialization;
31using System.IO;
32using HeuristicLab.PluginInfrastructure;
33using HeuristicLab.Data;
34using HeuristicLab.DataAnalysis;
35using System.Drawing;
36
37namespace HeuristicLab.CEDMA.Core {
38  public class Results : ItemBase {
39    private const int PAGE_SIZE = 1000;
40    private string[] categoricalVariables = null;
41    public string[] CategoricalVariables {
42      get {
43        if (categoricalVariables == null) {
44          LoadModelAttributes();
45        }
46        return categoricalVariables;
47      }
48    }
49
50    private string[] ordinalVariables = null;
51    public string[] OrdinalVariables {
52      get {
53        if (ordinalVariables == null) {
54          LoadModelAttributes();
55        }
56        return ordinalVariables;
57      }
58    }
59
60    private string[] multiDimensionalOrdinalVariables = new string[] { "VariableImpacts: EvaluationImpact", "VariableImpacts: QualityImpact" };
61    public string[] MultiDimensionalOrdinalVariables {
62      get { return multiDimensionalOrdinalVariables; }
63    }
64
65    private string[] multiDimensionalCategoricalVariables = new string[] { "VariableImpacts: InputVariableName" };
66    public string[] MultiDimensionalCategoricalVariables {
67      get { return multiDimensionalCategoricalVariables; }
68    }
69
70    private IStore store;
71    public IStore Store {
72      get { return store; }
73      set {
74        store = value;
75      }
76    }
77
78    private Dictionary<string, Dictionary<object, double>> categoricalValueIndices = new Dictionary<string, Dictionary<object, double>>();
79
80    public Results(IStore store) {
81      this.store = store;
82    }
83
84    private List<ResultsEntry> entries = null;
85    private bool cached = false;
86    public IEnumerable<ResultsEntry> GetEntries() {
87      if (!cached)
88        return SelectRows();
89      return entries.AsEnumerable();
90    }
91
92    long nStatements;
93    DateTime start, stop;
94    private IEnumerable<ResultsEntry> SelectRows() {
95      start = DateTime.Now;
96      nStatements = 0;
97      int page = 0;
98      int resultsReturned = 0;
99      entries = new List<ResultsEntry>();
100      if (store == null) return entries;
101      do {
102        var allModels = store.Query(
103          "?Model <" + Ontology.InstanceOf + "> <" + Ontology.TypeModel + "> ." +
104          "?Model <" + Ontology.TargetVariable + "> ?TargetVariable ." +
105          "?Model <" + Ontology.TestMeanSquaredError + "> ?TestMSE .",
106          0, 3000)
107          .Select(modelBinding => new {
108            Model = ((Entity)modelBinding.Get("Model")).Uri,
109            TestMSE = (double)((Literal)modelBinding.Get("TestMSE")).Value,
110            TargetVariable = (string)((Literal)modelBinding.Get("TargetVariable")).Value
111          })
112          .Distinct()
113          .GroupBy(m => m.TargetVariable)
114          .Select(grouping => grouping.OrderBy(m => m.TestMSE));
115        foreach (var targetVariableBindings in allModels) {
116          resultsReturned = targetVariableBindings.Count();
117          nStatements += resultsReturned;
118          int nModels = Math.Max(10, resultsReturned * 10 / 100);
119          foreach (var modelBindings in targetVariableBindings.Take(nModels)) {
120            ResultsEntry entry = new ResultsEntry();
121            entry.Uri = modelBindings.Model;
122            entries.Add(entry);
123            SetModelAttributes(entry, modelBindings.Model);
124            entry.Set("VariableImpacts", SelectVariableImpacts(modelBindings.Model));
125          }
126        }
127        page++;
128      } while (resultsReturned == PAGE_SIZE);
129      stop = DateTime.Now;
130      FireChanged();
131      cached = true;
132      return entries;
133    }
134
135    private void SetModelAttributes(ResultsEntry entry, string modelUri) {
136      var modelBindings = store.Query(
137        "<" + modelUri + "> ?Attribute ?Value .",
138        0, PAGE_SIZE);
139      nStatements += modelBindings.Count();
140      foreach (var binding in modelBindings) {
141        if (binding.Get("Value") is Literal) {
142          string name = ((Entity)binding.Get("Attribute")).Uri.Replace(Ontology.CedmaNameSpace, "");
143          if (entry.Get(name) == null) {
144            object value = ((Literal)binding.Get("Value")).Value;
145            entry.Set(name, value);
146          }
147        }
148      }
149    }
150
151    private IEnumerable<ResultsEntry> SelectVariableImpacts(string modelUri) {
152      var inputVariableNameBindings = store.Query(
153          "<" + modelUri + "> <" + Ontology.HasInputVariable + "> ?InputVariable ." +
154          "?InputVariable <" + Ontology.Name + "> ?InputName .",
155          0, PAGE_SIZE);
156
157      var qualityImpactBindings = store.Query(
158          "<" + modelUri + "> <" + Ontology.HasInputVariable + "> ?InputVariable ." +
159          "?InputVariable <" + Ontology.QualityImpact + "> ?QualityImpact .",
160          0, PAGE_SIZE);
161
162      var evaluationImpactBindings = store.Query(
163           "<" + modelUri + "> <" + Ontology.HasInputVariable + "> ?InputVariable ." +
164           "?InputVariable <" + Ontology.EvaluationImpact + "> ?EvaluationImpact .",
165           0, PAGE_SIZE);
166      Dictionary<object, ResultsEntry> inputVariableAttributes = new Dictionary<object, ResultsEntry>();
167      nStatements += inputVariableNameBindings.Count();
168      nStatements += qualityImpactBindings.Count();
169      nStatements += evaluationImpactBindings.Count();
170
171      foreach (var inputVariableNameBinding in inputVariableNameBindings) {
172        object inputVariable = inputVariableNameBinding.Get("InputVariable");
173        object name = ((Literal)inputVariableNameBinding.Get("InputName")).Value;
174        if (!inputVariableAttributes.ContainsKey(inputVariable)) {
175          inputVariableAttributes[inputVariable] = new ResultsEntry();
176          inputVariableAttributes[inputVariable].Set("InputVariableName", name);
177        }
178      }
179
180      foreach (var qualityImpactBinding in qualityImpactBindings) {
181        double qualityImpact = (double)((Literal)qualityImpactBinding.Get("QualityImpact")).Value;
182        object inputVariable = qualityImpactBinding.Get("InputVariable");
183        if (!IsAlmost(qualityImpact, 1.0)) {
184          if (inputVariableAttributes[inputVariable].Get("QualityImpact") == null)
185            inputVariableAttributes[inputVariable].Set("QualityImpact", qualityImpact);
186        } else inputVariableAttributes.Remove(inputVariable);
187      }
188
189      foreach (var evaluationImpactBinding in evaluationImpactBindings) {
190        double evaluationImpact = (double)((Literal)evaluationImpactBinding.Get("EvaluationImpact")).Value;
191        object inputVariable = evaluationImpactBinding.Get("InputVariable");
192        if (!IsAlmost(evaluationImpact, 0.0)) {
193          if (inputVariableAttributes.ContainsKey(inputVariable) && inputVariableAttributes[inputVariable].Get("EvaluationImpact") == null)
194            inputVariableAttributes[inputVariable].Set("EvaluationImpact", evaluationImpact);
195        } else inputVariableAttributes.Remove(inputVariable);
196      }
197
198      return inputVariableAttributes.Values;
199    }
200
201    private bool IsAlmost(double x, double y) {
202      return Math.Abs(x - y) < 1.0E-12;
203    }
204
205    internal IEnumerable<string> SelectModelAttributes() {
206      return CategoricalVariables.Concat(OrdinalVariables);
207    }
208
209    private void LoadModelAttributes() {
210      this.ordinalVariables =
211        store
212          .Query(
213            "?ModelAttribute <" + Ontology.InstanceOf + "> <" + Ontology.TypeModelAttribute + "> ." + Environment.NewLine +
214            "?ModelAttribute <" + Ontology.InstanceOf + "> <" + Ontology.TypeOrdinalAttribute + "> .", 0, 100)
215          .Select(s => ((Entity)s.Get("ModelAttribute")).Uri.Replace(Ontology.CedmaNameSpace, ""))
216          .Distinct()
217          .ToArray();
218      this.categoricalVariables =
219        store
220          .Query(
221            "?ModelAttribute <" + Ontology.InstanceOf + "> <" + Ontology.TypeModelAttribute + "> ." + Environment.NewLine +
222            "?ModelAttribute <" + Ontology.InstanceOf + "> <" + Ontology.TypeCategoricalAttribute + "> .", 0, 100)
223          .Select(s => ((Entity)s.Get("ModelAttribute")).Uri.Replace(Ontology.CedmaNameSpace, ""))
224          .Distinct()
225          .ToArray();
226    }
227
228    public double IndexOfCategoricalValue(string variable, object value) {
229      if (value == null) return double.NaN;
230      Dictionary<object, double> valueToIndexMap;
231      if (categoricalValueIndices.ContainsKey(variable)) {
232        valueToIndexMap = categoricalValueIndices[variable];
233      } else {
234        valueToIndexMap = new Dictionary<object, double>();
235        categoricalValueIndices[variable] = valueToIndexMap;
236      }
237      if (!valueToIndexMap.ContainsKey(value)) {
238        if (valueToIndexMap.Values.Count == 0) valueToIndexMap[value] = 1.0;
239        else valueToIndexMap[value] = 1.0 + valueToIndexMap.Values.Max();
240      }
241      return valueToIndexMap[value];
242    }
243  }
244}
Note: See TracBrowser for help on using the repository browser.