#region License Information /* HeuristicLab * Copyright (C) 2002-2008 Heuristic and Evolutionary Algorithms Laboratory (HEAL) * * This file is part of HeuristicLab. * * HeuristicLab is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * HeuristicLab is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with HeuristicLab. If not, see . */ #endregion using System; using System.Collections.Generic; using System.Linq; using System.Text; using HeuristicLab.Core; namespace HeuristicLab.Modeling { public abstract class ModelingResultCalculators { private enum DatasetPart { Training, Validation, Test }; private static readonly Dictionary> ClassificationModelingResults; private static readonly Dictionary> RegressionModelingResults; private static readonly Dictionary> TimeSeriesPrognosisModelingResults; private static readonly Dictionary ClassificationModelingResultEvaluators; private static readonly Dictionary RegressionModelingResultEvaluators; private static readonly Dictionary TimeSeriesPrognosisModelingResultEvaluators; private static readonly Dictionary> regressionResults = new Dictionary>() { { typeof(SimpleMSEEvaluator), new ModelingResult[] { ModelingResult.TrainingMeanSquaredError, ModelingResult.ValidationMeanSquaredError, ModelingResult.TestMeanSquaredError }}, { typeof(SimpleNMSEEvaluator), new ModelingResult[] { ModelingResult.TrainingNormalizedMeanSquaredError, ModelingResult.ValidationNormalizedMeanSquaredError, ModelingResult.TestNormalizedMeanSquaredError } }, { typeof(SimpleR2Evaluator), new ModelingResult[] { ModelingResult.TrainingCoefficientOfDetermination, ModelingResult.ValidationCoefficientOfDetermination, ModelingResult.TestCoefficientOfDetermination } }, { typeof(SimplePearsonCorrelationCoefficientEvaluator), new ModelingResult[] { ModelingResult.TrainingPearsonCorrelationCoefficient, ModelingResult.TrainingPearsonsCorrelationCoefficient, ModelingResult.ValidationPearsonCorrelationCoefficient, ModelingResult.TestPearsonCorrelationCoefficient } }, { typeof(SimpleStableCorrelationCoefficientEvaluator), new ModelingResult[] { ModelingResult.TrainingStablePearsonCorrelationCoefficient, ModelingResult.TrainingStablePearsonsCorrelationCoefficient, ModelingResult.ValidationStablePearsonCorrelationCoefficient, ModelingResult.TestStablePearsonCorrelationCoefficient } }, { typeof(SimpleSpearmansRankCorrelationCoefficientEvaluator), new ModelingResult[] { ModelingResult.TrainingSpearmansRankCorrelationCoefficient, ModelingResult.ValidationSpearmansRankCorrelationCoefficient, ModelingResult.TestSpearmansRankCorrelationCoefficient } }, { typeof(SimpleVarianceAccountedForEvaluator), new ModelingResult[] { ModelingResult.TrainingVarianceAccountedFor, ModelingResult.ValidationVarianceAccountedFor, ModelingResult.TestVarianceAccountedFor } }, { typeof(SimpleMeanAbsolutePercentageErrorEvaluator), new ModelingResult[] { ModelingResult.TrainingMeanAbsolutePercentageError, ModelingResult.ValidationMeanAbsolutePercentageError, ModelingResult.TestMeanAbsolutePercentageError } }, { typeof(SimpleMeanAbsolutePercentageOfRangeErrorEvaluator), new ModelingResult[] { ModelingResult.TrainingMeanAbsolutePercentageOfRangeError, ModelingResult.ValidationMeanAbsolutePercentageOfRangeError, ModelingResult.TestMeanAbsolutePercentageOfRangeError } } }; private static readonly Dictionary> timeSeriesResults = new Dictionary>() { { typeof(SimpleTheilInequalityCoefficientEvaluator), new ModelingResult[] { ModelingResult.TrainingTheilInequality, ModelingResult.ValidationTheilInequality, ModelingResult.TestTheilInequality } }, { typeof(SimpleDirectionalSymmetryEvaluator), new ModelingResult[] { ModelingResult.TrainingDirectionalSymmetry, ModelingResult.ValidationDirectionalSymmetry, ModelingResult.TestDirectionalSymmetry } }, { typeof(SimpleWeightedDirectionalSymmetryEvaluator), new ModelingResult[] { ModelingResult.TrainingWeightedDirectionalSymmetry, ModelingResult.ValidationWeightedDirectionalSymmetry, ModelingResult.TestWeightedDirectionalSymmetry } } }; private static readonly Dictionary> classificationResults = new Dictionary>() { { typeof(SimpleAccuracyEvaluator), new ModelingResult[] { ModelingResult.TrainingAccuracy, ModelingResult.ValidationAccuracy, ModelingResult.TestAccuracy } } }; static ModelingResultCalculators() { RegressionModelingResults = new Dictionary>(); ClassificationModelingResults = new Dictionary>(); TimeSeriesPrognosisModelingResults = new Dictionary>(); //Mean squared errors RegressionModelingResults[ModelingResult.TrainingMeanSquaredError] = SimpleMSEEvaluator.Calculate; RegressionModelingResults[ModelingResult.ValidationMeanSquaredError] = SimpleMSEEvaluator.Calculate; RegressionModelingResults[ModelingResult.TestMeanSquaredError] = SimpleMSEEvaluator.Calculate; //Normalized mean squared errors RegressionModelingResults[ModelingResult.TrainingNormalizedMeanSquaredError] = SimpleNMSEEvaluator.Calculate; RegressionModelingResults[ModelingResult.ValidationNormalizedMeanSquaredError] = SimpleNMSEEvaluator.Calculate; RegressionModelingResults[ModelingResult.TestNormalizedMeanSquaredError] = SimpleNMSEEvaluator.Calculate; //Mean absolute percentage error RegressionModelingResults[ModelingResult.TrainingMeanAbsolutePercentageError] = SimpleMeanAbsolutePercentageErrorEvaluator.Calculate; RegressionModelingResults[ModelingResult.ValidationMeanAbsolutePercentageError] = SimpleMeanAbsolutePercentageErrorEvaluator.Calculate; RegressionModelingResults[ModelingResult.TestMeanAbsolutePercentageError] = SimpleMeanAbsolutePercentageErrorEvaluator.Calculate; //Mean absolute percentage of range error RegressionModelingResults[ModelingResult.TrainingMeanAbsolutePercentageOfRangeError] = SimpleMeanAbsolutePercentageOfRangeErrorEvaluator.Calculate; RegressionModelingResults[ModelingResult.ValidationMeanAbsolutePercentageOfRangeError] = SimpleMeanAbsolutePercentageOfRangeErrorEvaluator.Calculate; RegressionModelingResults[ModelingResult.TestMeanAbsolutePercentageOfRangeError] = SimpleMeanAbsolutePercentageOfRangeErrorEvaluator.Calculate; //Coefficient of determination RegressionModelingResults[ModelingResult.TrainingCoefficientOfDetermination] = SimpleR2Evaluator.Calculate; RegressionModelingResults[ModelingResult.ValidationCoefficientOfDetermination] = SimpleR2Evaluator.Calculate; RegressionModelingResults[ModelingResult.TestCoefficientOfDetermination] = SimpleR2Evaluator.Calculate; //Pearson Correlation Coefficient RegressionModelingResults[ModelingResult.TrainingPearsonCorrelationCoefficient] = SimplePearsonCorrelationCoefficientEvaluator.Calculate; RegressionModelingResults[ModelingResult.TrainingPearsonsCorrelationCoefficient] = SimplePearsonCorrelationCoefficientEvaluator.Calculate; RegressionModelingResults[ModelingResult.ValidationPearsonCorrelationCoefficient] = SimplePearsonCorrelationCoefficientEvaluator.Calculate; RegressionModelingResults[ModelingResult.TestPearsonCorrelationCoefficient] = SimplePearsonCorrelationCoefficientEvaluator.Calculate; //Stable Pearson Correlation Coefficient RegressionModelingResults[ModelingResult.TrainingStablePearsonCorrelationCoefficient] = SimpleStableCorrelationCoefficientEvaluator.Calculate; RegressionModelingResults[ModelingResult.TrainingStablePearsonsCorrelationCoefficient] = SimpleStableCorrelationCoefficientEvaluator.Calculate; RegressionModelingResults[ModelingResult.ValidationStablePearsonCorrelationCoefficient] = SimpleStableCorrelationCoefficientEvaluator.Calculate; RegressionModelingResults[ModelingResult.TestStablePearsonCorrelationCoefficient] = SimpleStableCorrelationCoefficientEvaluator.Calculate; //Spearman's rank correlation coefficient RegressionModelingResults[ModelingResult.TrainingSpearmansRankCorrelationCoefficient] = SimpleSpearmansRankCorrelationCoefficientEvaluator.Calculate; RegressionModelingResults[ModelingResult.ValidationSpearmansRankCorrelationCoefficient] = SimpleSpearmansRankCorrelationCoefficientEvaluator.Calculate; RegressionModelingResults[ModelingResult.TestSpearmansRankCorrelationCoefficient] = SimpleSpearmansRankCorrelationCoefficientEvaluator.Calculate; //Variance accounted for RegressionModelingResults[ModelingResult.TrainingVarianceAccountedFor] = SimpleVarianceAccountedForEvaluator.Calculate; RegressionModelingResults[ModelingResult.ValidationVarianceAccountedFor] = SimpleVarianceAccountedForEvaluator.Calculate; RegressionModelingResults[ModelingResult.TestVarianceAccountedFor] = SimpleVarianceAccountedForEvaluator.Calculate; //Accuracy ClassificationModelingResults[ModelingResult.TrainingAccuracy] = SimpleAccuracyEvaluator.Calculate; ClassificationModelingResults[ModelingResult.ValidationAccuracy] = SimpleAccuracyEvaluator.Calculate; ClassificationModelingResults[ModelingResult.TestAccuracy] = SimpleAccuracyEvaluator.Calculate; //Theil inequality TimeSeriesPrognosisModelingResults[ModelingResult.TrainingTheilInequality] = SimpleTheilInequalityCoefficientEvaluator.Calculate; TimeSeriesPrognosisModelingResults[ModelingResult.ValidationTheilInequality] = SimpleTheilInequalityCoefficientEvaluator.Calculate; TimeSeriesPrognosisModelingResults[ModelingResult.TestTheilInequality] = SimpleTheilInequalityCoefficientEvaluator.Calculate; //Directional symmetry TimeSeriesPrognosisModelingResults[ModelingResult.TrainingDirectionalSymmetry] = SimpleDirectionalSymmetryEvaluator.Calculate; TimeSeriesPrognosisModelingResults[ModelingResult.ValidationDirectionalSymmetry] = SimpleDirectionalSymmetryEvaluator.Calculate; TimeSeriesPrognosisModelingResults[ModelingResult.TestDirectionalSymmetry] = SimpleDirectionalSymmetryEvaluator.Calculate; //Weighted directional symmetry TimeSeriesPrognosisModelingResults[ModelingResult.TrainingWeightedDirectionalSymmetry] = SimpleWeightedDirectionalSymmetryEvaluator.Calculate; TimeSeriesPrognosisModelingResults[ModelingResult.ValidationWeightedDirectionalSymmetry] = SimpleWeightedDirectionalSymmetryEvaluator.Calculate; TimeSeriesPrognosisModelingResults[ModelingResult.TestWeightedDirectionalSymmetry] = SimpleWeightedDirectionalSymmetryEvaluator.Calculate; #region result evaluators RegressionModelingResultEvaluators = new Dictionary(); foreach (Type evaluatorT in regressionResults.Keys) { foreach (ModelingResult r in regressionResults[evaluatorT]) { RegressionModelingResultEvaluators[r] = CreateEvaluator(evaluatorT, r); } } timeSeriesResults = CombineDictionaries(regressionResults, timeSeriesResults); TimeSeriesPrognosisModelingResultEvaluators = new Dictionary(); foreach (Type evaluatorT in timeSeriesResults.Keys) { foreach (ModelingResult r in timeSeriesResults[evaluatorT]) { TimeSeriesPrognosisModelingResultEvaluators[r] = CreateEvaluator(evaluatorT, r); } } classificationResults = CombineDictionaries(regressionResults, classificationResults); ClassificationModelingResultEvaluators = new Dictionary(); foreach (Type evaluatorT in classificationResults.Keys) { foreach (ModelingResult r in classificationResults[evaluatorT]) { ClassificationModelingResultEvaluators[r] = CreateEvaluator(evaluatorT, r); } } #endregion } public static Dictionary> GetModelingResult(ModelType modelType) { switch (modelType) { case ModelType.Regression: return CombineDictionaries(RegressionModelingResults, new Dictionary>()); case ModelType.Classification: return CombineDictionaries(RegressionModelingResults, ClassificationModelingResults); case ModelType.TimeSeriesPrognosis: return CombineDictionaries(RegressionModelingResults, TimeSeriesPrognosisModelingResults); default: throw new ArgumentException("Modeling result mapping for ModelType " + modelType + " not defined."); } } public static Func GetModelingResultCalculator(ModelingResult modelingResult) { if (RegressionModelingResults.ContainsKey(modelingResult)) return RegressionModelingResults[modelingResult]; else if (ClassificationModelingResults.ContainsKey(modelingResult)) return ClassificationModelingResults[modelingResult]; else if (TimeSeriesPrognosisModelingResults.ContainsKey(modelingResult)) return TimeSeriesPrognosisModelingResults[modelingResult]; else throw new ArgumentException("Calculator for modeling result " + modelingResult + " not defined."); } public static IOperator CreateModelingResultEvaluator(ModelingResult modelingResult) { IOperator opTemplate = null; if (RegressionModelingResultEvaluators.ContainsKey(modelingResult)) opTemplate = RegressionModelingResultEvaluators[modelingResult]; else if (ClassificationModelingResultEvaluators.ContainsKey(modelingResult)) opTemplate = ClassificationModelingResultEvaluators[modelingResult]; else if (TimeSeriesPrognosisModelingResultEvaluators.ContainsKey(modelingResult)) opTemplate = TimeSeriesPrognosisModelingResultEvaluators[modelingResult]; else throw new ArgumentException("Evaluator for modeling result " + modelingResult + " not defined."); return (IOperator)opTemplate.Clone(); } private static IOperator CreateEvaluator(Type evaluatorType, ModelingResult result) { SimpleEvaluatorBase evaluator = (SimpleEvaluatorBase)Activator.CreateInstance(evaluatorType); evaluator.GetVariableInfo("Values").ActualName = GetDatasetPart(result) + "Values"; evaluator.GetVariableInfo(evaluator.OutputVariableName).ActualName = result.ToString(); return evaluator; } private static DatasetPart GetDatasetPart(ModelingResult result) { if (result.ToString().StartsWith("Training")) return DatasetPart.Training; else if (result.ToString().StartsWith("Validation")) return DatasetPart.Validation; else if (result.ToString().StartsWith("Test")) return DatasetPart.Test; else throw new ArgumentException("Can't determine dataset part of modeling result " + result + "."); } private static Dictionary CombineDictionaries( Dictionary x, Dictionary y) { Dictionary result = new Dictionary(x); return x.Union(y).ToDictionary, T1, T2>(p => p.Key, p => p.Value); } } }