protected static void CalculateWithScaling(IEnumerable <double> targetValues, IEnumerable <double> estimatedValues, double lowerEstimationLimit, double upperEstimationLimit, IOnlineCalculator calculator, int maxRows) { if (cache == null || cache.Length < maxRows) { cache = new double[maxRows]; } // calculate linear scaling int i = 0; var linearScalingCalculator = new OnlineLinearScalingParameterCalculator(); var targetValuesEnumerator = targetValues.GetEnumerator(); var estimatedValuesEnumerator = estimatedValues.GetEnumerator(); while (targetValuesEnumerator.MoveNext() & estimatedValuesEnumerator.MoveNext()) { double target = targetValuesEnumerator.Current; double estimated = estimatedValuesEnumerator.Current; cache[i] = estimated; if (!double.IsNaN(estimated) && !double.IsInfinity(estimated)) { linearScalingCalculator.Add(estimated, target); } i++; } if (linearScalingCalculator.ErrorState == OnlineCalculatorError.None && (targetValuesEnumerator.MoveNext() || estimatedValuesEnumerator.MoveNext())) { throw new ArgumentException("Number of elements in target and estimated values enumeration do not match."); } double alpha = linearScalingCalculator.Alpha; double beta = linearScalingCalculator.Beta; if (linearScalingCalculator.ErrorState != OnlineCalculatorError.None) { alpha = 0.0; beta = 1.0; } //calculate the quality by using the passed online calculator targetValuesEnumerator = targetValues.GetEnumerator(); var scaledBoundedEstimatedValuesEnumerator = Enumerable.Range(0, i).Select(x => cache[x] * beta + alpha) .LimitToRange(lowerEstimationLimit, upperEstimationLimit).GetEnumerator(); while (targetValuesEnumerator.MoveNext() & scaledBoundedEstimatedValuesEnumerator.MoveNext()) { calculator.Add(targetValuesEnumerator.Current, scaledBoundedEstimatedValuesEnumerator.Current); } }
protected override IEnumerable <IRegressionSolution> CreateBaselineSolutions() { foreach (var sol in base.CreateBaselineSolutions()) { yield return(sol); } IEnumerable <double> trainingStartValues = ProblemData.Dataset.GetDoubleValues(ProblemData.TargetVariable, ProblemData.TrainingIndices.Select(r => r - 1).Where(r => r > 0)).ToList(); //AR1 model double alpha, beta; OnlineCalculatorError errorState; OnlineLinearScalingParameterCalculator.Calculate(ProblemData.Dataset.GetDoubleValues(ProblemData.TargetVariable, ProblemData.TrainingIndices.Where(x => x > 0)), trainingStartValues, out alpha, out beta, out errorState); var ar1Solution = new TimeSeriesPrognosisAutoRegressiveModel(ProblemData.TargetVariable, new double[] { beta }, alpha).CreateTimeSeriesPrognosisSolution(ProblemData); ar1Solution.Name = "AR(1)"; yield return(ar1Solution); }
protected void Scale(IDataAnalysisProblemData problemData, string targetVariable) { var dataset = problemData.Dataset; var rows = problemData.TrainingIndices; var estimatedValues = Interpreter.GetSymbolicExpressionTreeValues(SymbolicExpressionTree, dataset, rows); var targetValues = dataset.GetDoubleValues(targetVariable, rows); var linearScalingCalculator = new OnlineLinearScalingParameterCalculator(); var targetValuesEnumerator = targetValues.GetEnumerator(); var estimatedValuesEnumerator = estimatedValues.GetEnumerator(); while (targetValuesEnumerator.MoveNext() & estimatedValuesEnumerator.MoveNext()) { double target = targetValuesEnumerator.Current; double estimated = estimatedValuesEnumerator.Current; if (!double.IsNaN(estimated) && !double.IsInfinity(estimated)) linearScalingCalculator.Add(estimated, target); } if (linearScalingCalculator.ErrorState == OnlineCalculatorError.None && (targetValuesEnumerator.MoveNext() || estimatedValuesEnumerator.MoveNext())) throw new ArgumentException("Number of elements in target and estimated values enumeration do not match."); double alpha = linearScalingCalculator.Alpha; double beta = linearScalingCalculator.Beta; if (linearScalingCalculator.ErrorState != OnlineCalculatorError.None) return; ConstantTreeNode alphaTreeNode = null; ConstantTreeNode betaTreeNode = null; // check if model has been scaled previously by analyzing the structure of the tree var startNode = SymbolicExpressionTree.Root.GetSubtree(0); if (startNode.GetSubtree(0).Symbol is Addition) { var addNode = startNode.GetSubtree(0); if (addNode.SubtreeCount == 2 && addNode.GetSubtree(0).Symbol is Multiplication && addNode.GetSubtree(1).Symbol is Constant) { alphaTreeNode = addNode.GetSubtree(1) as ConstantTreeNode; var mulNode = addNode.GetSubtree(0); if (mulNode.SubtreeCount == 2 && mulNode.GetSubtree(1).Symbol is Constant) { betaTreeNode = mulNode.GetSubtree(1) as ConstantTreeNode; } } } // if tree structure matches the structure necessary for linear scaling then reuse the existing tree nodes if (alphaTreeNode != null && betaTreeNode != null) { betaTreeNode.Value *= beta; alphaTreeNode.Value *= beta; alphaTreeNode.Value += alpha; } else { var mainBranch = startNode.GetSubtree(0); startNode.RemoveSubtree(0); var scaledMainBranch = MakeSum(MakeProduct(mainBranch, beta), alpha); startNode.AddSubtree(scaledMainBranch); } }
protected void Scale(IDataAnalysisProblemData problemData, string targetVariable) { var dataset = problemData.Dataset; var rows = problemData.TrainingIndices; var estimatedValues = Interpreter.GetSymbolicExpressionTreeValues(SymbolicExpressionTree, dataset, rows); var targetValues = dataset.GetDoubleValues(targetVariable, rows); var linearScalingCalculator = new OnlineLinearScalingParameterCalculator(); var targetValuesEnumerator = targetValues.GetEnumerator(); var estimatedValuesEnumerator = estimatedValues.GetEnumerator(); while (targetValuesEnumerator.MoveNext() & estimatedValuesEnumerator.MoveNext()) { double target = targetValuesEnumerator.Current; double estimated = estimatedValuesEnumerator.Current; if (!double.IsNaN(estimated) && !double.IsInfinity(estimated)) { linearScalingCalculator.Add(estimated, target); } } if (linearScalingCalculator.ErrorState == OnlineCalculatorError.None && (targetValuesEnumerator.MoveNext() || estimatedValuesEnumerator.MoveNext())) { throw new ArgumentException("Number of elements in target and estimated values enumeration do not match."); } double alpha = linearScalingCalculator.Alpha; double beta = linearScalingCalculator.Beta; if (linearScalingCalculator.ErrorState != OnlineCalculatorError.None) { return; } ConstantTreeNode alphaTreeNode = null; ConstantTreeNode betaTreeNode = null; // check if model has been scaled previously by analyzing the structure of the tree var startNode = SymbolicExpressionTree.Root.GetSubtree(0); if (startNode.GetSubtree(0).Symbol is Addition) { var addNode = startNode.GetSubtree(0); if (addNode.SubtreeCount == 2 && addNode.GetSubtree(0).Symbol is Multiplication && addNode.GetSubtree(1).Symbol is Constant) { alphaTreeNode = addNode.GetSubtree(1) as ConstantTreeNode; var mulNode = addNode.GetSubtree(0); if (mulNode.SubtreeCount == 2 && mulNode.GetSubtree(1).Symbol is Constant) { betaTreeNode = mulNode.GetSubtree(1) as ConstantTreeNode; } } } // if tree structure matches the structure necessary for linear scaling then reuse the existing tree nodes if (alphaTreeNode != null && betaTreeNode != null) { betaTreeNode.Value *= beta; alphaTreeNode.Value *= beta; alphaTreeNode.Value += alpha; } else { var mainBranch = startNode.GetSubtree(0); startNode.RemoveSubtree(0); var scaledMainBranch = MakeSum(MakeProduct(mainBranch, beta), alpha); startNode.AddSubtree(scaledMainBranch); } }