Changeset 14310 for branches/HeuristicLab.Problems.GeneticProgramming.BloodGlucosePrediction/Interpreter.cs
- Timestamp:
- 09/27/16 16:30:54 (8 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
branches/HeuristicLab.Problems.GeneticProgramming.BloodGlucosePrediction/Interpreter.cs
r13870 r14310 2 2 using System.Collections; 3 3 using System.Collections.Generic; 4 using System.Collections.ObjectModel; 4 5 using System.Collections.Specialized; 5 6 using System.Drawing.Design; 6 7 using System.Linq; 8 using HeuristicLab.Common; 7 9 using HeuristicLab.Encodings.SymbolicExpressionTreeEncoding; 8 10 using HeuristicLab.Problems.DataAnalysis; … … 15 17 public double[] realIns; 16 18 public double[] realCh; 17 public double[] predGluc;19 public Dictionary<ISymbolicExpressionTreeNode, double[]> precalculatedValues; 18 20 } 19 21 … … 25 27 realIns = dataset.GetDoubleValues("Insuline", rows).ToArray(), 26 28 realCh = dataset.GetDoubleValues("CH", rows).ToArray(), 29 precalculatedValues = CreatePrecalculatedValues(model, dataset) 27 30 }; 28 data.predGluc = new double[data.realGluc.Length];29 Array.Copy(data.realGluc, data.predGluc, data.predGluc.Length);30 for (int k = 0; k < data.predGluc.Length; k++) {31 var predictions = new double[targetGluc.Length]; 32 var rowsEnumerator = rows.GetEnumerator(); 33 for (int k = 0; k < predictions.Length; k++, rowsEnumerator.MoveNext()) { 31 34 if (double.IsNaN(targetGluc[k])) { 32 data.predGluc[k] = double.NaN;35 predictions[k] = double.NaN; 33 36 } else { 34 var rawPred = InterpretRec(model, data, k); 35 data.predGluc[k] = Math.Max(0, Math.Min(400, rawPred)); // limit output values of the model to 0 ... 400 36 } 37 } 38 return data.predGluc; 37 var rawPred = InterpretRec(model, data, rowsEnumerator.Current); 38 predictions[k] = rawPred; 39 } 40 } 41 return predictions; 42 } 43 44 private static Dictionary<ISymbolicExpressionTreeNode, double[]> CreatePrecalculatedValues(ISymbolicExpressionTreeNode root, IDataset dataset) { 45 var dict = new Dictionary<ISymbolicExpressionTreeNode, double[]>(); 46 // here we integrate ins or ch inputs over the whole day to generate smoothed ins/ch values with the same number of rows 47 // the integrated values are reset to zero whenever a new evluation period starts 48 foreach (var node in root.IterateNodesPrefix()) { 49 var curvedInsNode = node as CurvedInsVariableTreeNode; 50 var curvedChNode = node as CurvedChVariableTreeNode; 51 if (curvedInsNode != null) { 52 dict.Add(curvedInsNode, Integrate(curvedInsNode, dataset)); 53 } else if (curvedChNode != null) { 54 dict.Add(curvedChNode, Integrate(curvedChNode, dataset)); 55 } 56 } 57 return dict; 58 } 59 60 private static double[] Integrate(CurvedInsVariableTreeNode node, IDataset dataset) { 61 // d Q1 / dt = ins(t) - alpha * Q1(t) 62 // d Q2 / dt = alpha * (Q1(t) - Q2(t)) 63 // S = Q1(t) + Q2(t) 64 var alpha = node.Alpha; 65 66 var ins = dataset.GetReadOnlyDoubleValues("Insuline"); 67 var time = dataset.GetReadOnlyDoubleValues("HourMin").ToArray(); 68 69 // TODO reset for new time intervals 70 71 double q1, q2, q1_prev, q2_prev; 72 // starting values: zeros 73 q1 = q2 = q1_prev = q2_prev = 0; 74 double[] s = new double[dataset.Rows]; 75 76 for (int t = 1; t < dataset.Rows; t++) { 77 if (IsStartOfNewPeriod(time, t)) { 78 q1 = q2 = q1_prev = q2_prev = 0; 79 } 80 q1 = q1_prev + ins[t] - alpha * q1_prev; 81 q2 = q2_prev + alpha * (q1_prev - q2_prev); 82 s[t] = q1 + q2; 83 q1_prev = q1; 84 q2_prev = q2; 85 86 } 87 return s; 88 } 89 90 private static bool IsStartOfNewPeriod(double[] time, int t) { 91 return t == 0 || 92 (time[t].IsAlmost(2005) && !time[t - 1].IsAlmost(2000)); 93 } 94 95 96 private static double[] Integrate(CurvedChVariableTreeNode node, IDataset dataset) { 97 // d Q1 / dt = ins(t) - alpha * Q1(t) 98 // d Q2 / dt = alpha * (Q1(t) - Q2(t)) 99 // S = Q1(t) + Q2(t) 100 var alpha = node.Alpha; 101 102 var ch = dataset.GetReadOnlyDoubleValues("CH"); 103 var time = dataset.GetReadOnlyDoubleValues("HourMin").ToArray(); 104 105 // TODO reset for new time intervals 106 107 double q1, q2, q1_prev, q2_prev; 108 // starting values: zeros 109 q1 = q2 = q1_prev = q2_prev = 0; 110 double[] s = new double[dataset.Rows]; 111 112 for (int t = 1; t < dataset.Rows; t++) { 113 if (IsStartOfNewPeriod(time, t)) { 114 q1 = q2 = q1_prev = q2_prev = 0; 115 } 116 q1 = q1_prev + ch[t] - alpha * q1_prev; 117 q2 = q2_prev + alpha * (q1_prev - q2_prev); 118 s[t] = q1 + q2; 119 q1_prev = q1; 120 q2_prev = q2; 121 122 } 123 return s; 39 124 } 40 125 … … 102 187 } 103 188 } else if (node.Symbol is PredictedGlucoseVariableSymbol) { 104 var n = (PredictedGlucoseVariableTreeNode)node; 105 return n.Weight * data.predGluc[k + n.RowOffset]; 189 throw new NotSupportedException(); 106 190 } else if (node.Symbol is RealGlucoseVariableSymbol) { 107 191 var n = (RealGlucoseVariableTreeNode)node; 108 return n.Weight * data.realGluc[k + n.RowOffset]; 192 if (k + n.RowOffset < 0 || k + n.RowOffset >= data.realGluc.Length) return double.NaN; 193 return data.realGluc[k + n.RowOffset]; 109 194 } else if (node.Symbol is CurvedChVariableSymbol) { 110 var n = (CurvedChVariableTreeNode)node; 111 double prevVal; 112 int prevValDistance; 113 GetPrevDataAndDistance(data.realCh, k, out prevVal, out prevValDistance, maxDistance: 48); 114 return n.Weight * prevVal * Beta(prevValDistance / 48.0, n.Alpha, n.Beta); 195 return data.precalculatedValues[node][k]; 115 196 } else if (node.Symbol is RealInsulineVariableSymbol) { 116 var n = (RealInsulineVariableTreeNode)node; 117 return n.Weight * data.realIns[k + n.RowOffset]; 197 throw new NotSupportedException(); 118 198 } else if (node.Symbol is CurvedInsVariableSymbol) { 119 var n = (CurvedInsVariableTreeNode)node; 120 double maxVal; 121 int maxValDistance; 122 var sum = GetSumOfValues(48, k, data.realIns); 123 124 GetMaxValueAndDistance(data.realIns, k, out maxVal, out maxValDistance, maxDistance: 48); 125 return n.Weight * (sum - maxVal) * maxVal * Beta(maxValDistance / 48.0, n.Alpha, n.Beta); 199 return data.precalculatedValues[node][k]; 126 200 } else if (node.Symbol is Constant) { 127 201 var n = (ConstantTreeNode)node; … … 135 209 return 1.0 / alglib.beta(alpha, beta) * Math.Pow(x, alpha - 1) * Math.Pow(1 - x, beta - 1); 136 210 } 137 138 private static void GetPrevDataAndDistance(double[] vals, int k, out double val, out int dist, int maxDistance = 48, double threshold = 0.0) {139 // look backward from the current idx k and find the first value above the threshold140 for (int i = k; i >= 0 && i >= (k - maxDistance); i--) {141 if (vals[i] > threshold) {142 val = vals[i];143 dist = k - i;144 return;145 }146 }147 val = 0;148 dist = maxDistance;149 }150 151 private static double GetSumOfValues(int windowSize, int k, double[] vals) {152 var sum = 0.0;153 for (int i = k; i >= 0 && i >= k - windowSize; i--)154 sum += vals[i];155 return sum;156 }157 158 private static void GetMaxValueAndDistance(double[] vals, int k, out double maxVal, out int dist, int maxDistance = 48) {159 // look backward from the current idx k and find the max value and it's distance160 maxVal = vals[k];161 dist = 0;162 for (int i = k; i >= 0 && i >= (k - maxDistance); i--) {163 if (vals[i] > maxVal) {164 maxVal = vals[i];165 dist = k - i;166 }167 }168 }169 211 } 170 212 }
Note: See TracChangeset
for help on using the changeset viewer.