Index: branches/M5Regression/HeuristicLab.Algorithms.DataAnalysis/3.4/FixedDataAnalysisAlgorithm.cs
===================================================================
--- branches/M5Regression/HeuristicLab.Algorithms.DataAnalysis/3.4/FixedDataAnalysisAlgorithm.cs	(revision 15428)
+++ branches/M5Regression/HeuristicLab.Algorithms.DataAnalysis/3.4/FixedDataAnalysisAlgorithm.cs	(revision 15430)
@@ -21,6 +21,4 @@
 
 using System;
-using System.Linq;
-using System.Threading;
 using HeuristicLab.Common;
 using HeuristicLab.Optimization;
Index: branches/M5Regression/HeuristicLab.Algorithms.DataAnalysis/3.4/GaussianProcess/GaussianProcessClassification.cs
===================================================================
--- branches/M5Regression/HeuristicLab.Algorithms.DataAnalysis/3.4/GaussianProcess/GaussianProcessClassification.cs	(revision 15428)
+++ branches/M5Regression/HeuristicLab.Algorithms.DataAnalysis/3.4/GaussianProcess/GaussianProcessClassification.cs	(revision 15430)
@@ -26,5 +26,4 @@
 using HeuristicLab.Core;
 using HeuristicLab.Data;
-using HeuristicLab.Optimization;
 using HeuristicLab.Parameters;
 using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
Index: branches/M5Regression/HeuristicLab.Algorithms.DataAnalysis/3.4/GaussianProcess/GaussianProcessRegression.cs
===================================================================
--- branches/M5Regression/HeuristicLab.Algorithms.DataAnalysis/3.4/GaussianProcess/GaussianProcessRegression.cs	(revision 15428)
+++ branches/M5Regression/HeuristicLab.Algorithms.DataAnalysis/3.4/GaussianProcess/GaussianProcessRegression.cs	(revision 15430)
@@ -1,3 +1,2 @@
-
 #region License Information
 /* HeuristicLab
@@ -26,5 +25,4 @@
 using HeuristicLab.Core;
 using HeuristicLab.Data;
-using HeuristicLab.Optimization;
 using HeuristicLab.Parameters;
 using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
@@ -42,7 +40,9 @@
     public string Filename { get; set; }
 
-    public override Type ProblemType { get { return typeof(IRegressionProblem); } }
+    public override Type ProblemType {
+      get { return typeof(IRegressionProblem); }
+    }
     public new IRegressionProblem Problem {
-      get { return (IRegressionProblem)base.Problem; }
+      get { return (IRegressionProblem) base.Problem; }
       set { base.Problem = value; }
     }
@@ -54,11 +54,11 @@
     #region parameter properties
     public IConstrainedValueParameter<IGaussianProcessRegressionModelCreator> GaussianProcessModelCreatorParameter {
-      get { return (IConstrainedValueParameter<IGaussianProcessRegressionModelCreator>)Parameters[ModelCreatorParameterName]; }
+      get { return (IConstrainedValueParameter<IGaussianProcessRegressionModelCreator>) Parameters[ModelCreatorParameterName]; }
     }
     public IFixedValueParameter<GaussianProcessRegressionSolutionCreator> GaussianProcessSolutionCreatorParameter {
-      get { return (IFixedValueParameter<GaussianProcessRegressionSolutionCreator>)Parameters[SolutionCreatorParameterName]; }
+      get { return (IFixedValueParameter<GaussianProcessRegressionSolutionCreator>) Parameters[SolutionCreatorParameterName]; }
     }
     public IFixedValueParameter<BoolValue> CreateSolutionParameter {
-      get { return (IFixedValueParameter<BoolValue>)Parameters[CreateSolutionParameterName]; }
+      get { return (IFixedValueParameter<BoolValue>) Parameters[CreateSolutionParameterName]; }
     }
     #endregion
Index: branches/M5Regression/HeuristicLab.Algorithms.DataAnalysis/3.4/GaussianProcess/MeanFunctions/MeanConst.cs
===================================================================
--- branches/M5Regression/HeuristicLab.Algorithms.DataAnalysis/3.4/GaussianProcess/MeanFunctions/MeanConst.cs	(revision 15428)
+++ branches/M5Regression/HeuristicLab.Algorithms.DataAnalysis/3.4/GaussianProcess/MeanFunctions/MeanConst.cs	(revision 15430)
@@ -21,6 +21,4 @@
 
 using System;
-using System.Collections.Generic;
-using System.Linq;
 using HeuristicLab.Common;
 using HeuristicLab.Core;
Index: branches/M5Regression/HeuristicLab.Algorithms.DataAnalysis/3.4/GradientBoostedTrees/LossFunctions/SquaredErrorLoss.cs
===================================================================
--- branches/M5Regression/HeuristicLab.Algorithms.DataAnalysis/3.4/GradientBoostedTrees/LossFunctions/SquaredErrorLoss.cs	(revision 15428)
+++ branches/M5Regression/HeuristicLab.Algorithms.DataAnalysis/3.4/GradientBoostedTrees/LossFunctions/SquaredErrorLoss.cs	(revision 15430)
@@ -23,5 +23,4 @@
 using System;
 using System.Collections.Generic;
-using System.Linq;
 using HeuristicLab.Common;
 using HeuristicLab.Core;
Index: branches/M5Regression/HeuristicLab.Algorithms.DataAnalysis/3.4/HeuristicLab.Algorithms.DataAnalysis-3.4.csproj
===================================================================
--- branches/M5Regression/HeuristicLab.Algorithms.DataAnalysis/3.4/HeuristicLab.Algorithms.DataAnalysis-3.4.csproj	(revision 15428)
+++ branches/M5Regression/HeuristicLab.Algorithms.DataAnalysis/3.4/HeuristicLab.Algorithms.DataAnalysis-3.4.csproj	(revision 15430)
@@ -49,4 +49,5 @@
     <CodeAnalysisRuleSet>AllRules.ruleset</CodeAnalysisRuleSet>
     <Prefer32Bit>false</Prefer32Bit>
+    <LangVersion>5</LangVersion>
   </PropertyGroup>
   <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
@@ -360,4 +361,36 @@
     <Compile Include="Linear\MultinomialLogitModel.cs" />
     <Compile Include="Linear\Scaling.cs" />
+    <Compile Include="M5Regression\Interfaces\IImpurityCalculator.cs" />
+    <Compile Include="M5Regression\Interfaces\IImpurityType.cs" />
+    <Compile Include="M5Regression\Interfaces\IM5MetaModel.cs" />
+    <Compile Include="M5Regression\Interfaces\ILeafType.cs" />
+    <Compile Include="M5Regression\Interfaces\IPruningType.cs" />
+    <Compile Include="M5Regression\LeafTypes\ComplexLeaf.cs" />
+    <Compile Include="M5Regression\LeafTypes\ComponentReductionLinearLeaf.cs" />
+    <Compile Include="M5Regression\LeafTypes\ConstantLeaf.cs" />
+    <Compile Include="M5Regression\LeafTypes\GaussianProcessLeaf.cs" />
+    <Compile Include="M5Regression\LeafTypes\LinearLeaf.cs" />
+    <Compile Include="M5Regression\LeafTypes\LogisticLeaf.cs" />
+    <Compile Include="M5Regression\M5Regression.cs" />
+    <Compile Include="M5Regression\M5Utilities\M5StaticUtilities.cs" />
+    <Compile Include="M5Regression\M5Utilities\M5Analyzer.cs" />
+    <Compile Include="M5Regression\M5Utilities\M5CreationParameters.cs" />
+    <Compile Include="M5Regression\M5Utilities\M5UpdateParameters.cs" />
+    <Compile Include="M5Regression\M5Utilities\SplitInfo.cs" />
+    <Compile Include="M5Regression\MetaModels\ComponentReducedLinearModel.cs" />
+    <Compile Include="M5Regression\MetaModels\M5NodeModel.cs" />
+    <Compile Include="M5Regression\MetaModels\M5RuleModel.cs" />
+    <Compile Include="M5Regression\MetaModels\M5RuleSetModel.cs" />
+    <Compile Include="M5Regression\MetaModels\M5TreeModel.cs" />
+    <Compile Include="M5Regression\MetaModels\DampenedLinearModel.cs" />
+    <Compile Include="M5Regression\MetaModels\PreconstructedLinearModel.cs" />
+    <Compile Include="M5Regression\Pruning\HoldoutLinearPruning.cs" />
+    <Compile Include="M5Regression\Pruning\HoldoutLeafPruning.cs" />
+    <Compile Include="M5Regression\Pruning\M5LinearPruning.cs" />
+    <Compile Include="M5Regression\Pruning\PruningBase.cs" />
+    <Compile Include="M5Regression\Pruning\NoPruning.cs" />
+    <Compile Include="M5Regression\Pruning\M5LeafPruning.cs" />
+    <Compile Include="M5Regression\Spliting\OrderImpurityCalculator.cs" />
+    <Compile Include="M5Regression\Spliting\OrderImpurityType.cs" />
     <Compile Include="Nca\Initialization\INcaInitializer.cs" />
     <Compile Include="Nca\Initialization\LdaInitializer.cs" />
@@ -390,4 +423,6 @@
     <Compile Include="NeuralNetwork\NeuralNetworkRegressionSolution.cs" />
     <Compile Include="NonlinearRegression\NonlinearRegression.cs" />
+    <Compile Include="PCA\PrincipleComponentAnalysis.cs" />
+    <Compile Include="PCA\PrincipleComponentAnalysisStatic.cs" />
     <Compile Include="Plugin.cs" />
     <Compile Include="Properties\AssemblyInfo.cs" />
Index: branches/M5Regression/HeuristicLab.Algorithms.DataAnalysis/3.4/Interfaces/INearestNeighbourClassificationSolution.cs
===================================================================
--- branches/M5Regression/HeuristicLab.Algorithms.DataAnalysis/3.4/Interfaces/INearestNeighbourClassificationSolution.cs	(revision 15428)
+++ branches/M5Regression/HeuristicLab.Algorithms.DataAnalysis/3.4/Interfaces/INearestNeighbourClassificationSolution.cs	(revision 15430)
@@ -20,7 +20,5 @@
 #endregion
 
-using HeuristicLab.Optimization;
 using HeuristicLab.Problems.DataAnalysis;
-using HeuristicLab.Core;
 
 namespace HeuristicLab.Algorithms.DataAnalysis {
Index: branches/M5Regression/HeuristicLab.Algorithms.DataAnalysis/3.4/Interfaces/INearestNeighbourModel.cs
===================================================================
--- branches/M5Regression/HeuristicLab.Algorithms.DataAnalysis/3.4/Interfaces/INearestNeighbourModel.cs	(revision 15428)
+++ branches/M5Regression/HeuristicLab.Algorithms.DataAnalysis/3.4/Interfaces/INearestNeighbourModel.cs	(revision 15430)
@@ -20,8 +20,5 @@
 #endregion
 
-using HeuristicLab.Optimization;
 using HeuristicLab.Problems.DataAnalysis;
-using HeuristicLab.Core;
-using System.Collections.Generic;
 
 namespace HeuristicLab.Algorithms.DataAnalysis {
Index: branches/M5Regression/HeuristicLab.Algorithms.DataAnalysis/3.4/Interfaces/INearestNeighbourRegressionSolution.cs
===================================================================
--- branches/M5Regression/HeuristicLab.Algorithms.DataAnalysis/3.4/Interfaces/INearestNeighbourRegressionSolution.cs	(revision 15428)
+++ branches/M5Regression/HeuristicLab.Algorithms.DataAnalysis/3.4/Interfaces/INearestNeighbourRegressionSolution.cs	(revision 15430)
@@ -20,7 +20,5 @@
 #endregion
 
-using HeuristicLab.Optimization;
 using HeuristicLab.Problems.DataAnalysis;
-using HeuristicLab.Core;
 
 namespace HeuristicLab.Algorithms.DataAnalysis {
Index: branches/M5Regression/HeuristicLab.Algorithms.DataAnalysis/3.4/Interfaces/INeuralNetworkClassificationSolution.cs
===================================================================
--- branches/M5Regression/HeuristicLab.Algorithms.DataAnalysis/3.4/Interfaces/INeuralNetworkClassificationSolution.cs	(revision 15428)
+++ branches/M5Regression/HeuristicLab.Algorithms.DataAnalysis/3.4/Interfaces/INeuralNetworkClassificationSolution.cs	(revision 15430)
@@ -20,7 +20,5 @@
 #endregion
 
-using HeuristicLab.Optimization;
 using HeuristicLab.Problems.DataAnalysis;
-using HeuristicLab.Core;
 
 namespace HeuristicLab.Algorithms.DataAnalysis {
Index: branches/M5Regression/HeuristicLab.Algorithms.DataAnalysis/3.4/Interfaces/INeuralNetworkEnsembleClassificationSolution.cs
===================================================================
--- branches/M5Regression/HeuristicLab.Algorithms.DataAnalysis/3.4/Interfaces/INeuralNetworkEnsembleClassificationSolution.cs	(revision 15428)
+++ branches/M5Regression/HeuristicLab.Algorithms.DataAnalysis/3.4/Interfaces/INeuralNetworkEnsembleClassificationSolution.cs	(revision 15430)
@@ -20,7 +20,5 @@
 #endregion
 
-using HeuristicLab.Optimization;
 using HeuristicLab.Problems.DataAnalysis;
-using HeuristicLab.Core;
 
 namespace HeuristicLab.Algorithms.DataAnalysis {
Index: branches/M5Regression/HeuristicLab.Algorithms.DataAnalysis/3.4/Interfaces/INeuralNetworkEnsembleModel.cs
===================================================================
--- branches/M5Regression/HeuristicLab.Algorithms.DataAnalysis/3.4/Interfaces/INeuralNetworkEnsembleModel.cs	(revision 15428)
+++ branches/M5Regression/HeuristicLab.Algorithms.DataAnalysis/3.4/Interfaces/INeuralNetworkEnsembleModel.cs	(revision 15430)
@@ -20,8 +20,5 @@
 #endregion
 
-using HeuristicLab.Optimization;
 using HeuristicLab.Problems.DataAnalysis;
-using HeuristicLab.Core;
-using System.Collections.Generic;
 
 namespace HeuristicLab.Algorithms.DataAnalysis {
Index: branches/M5Regression/HeuristicLab.Algorithms.DataAnalysis/3.4/Interfaces/INeuralNetworkEnsembleRegressionSolution.cs
===================================================================
--- branches/M5Regression/HeuristicLab.Algorithms.DataAnalysis/3.4/Interfaces/INeuralNetworkEnsembleRegressionSolution.cs	(revision 15428)
+++ branches/M5Regression/HeuristicLab.Algorithms.DataAnalysis/3.4/Interfaces/INeuralNetworkEnsembleRegressionSolution.cs	(revision 15430)
@@ -20,7 +20,5 @@
 #endregion
 
-using HeuristicLab.Optimization;
 using HeuristicLab.Problems.DataAnalysis;
-using HeuristicLab.Core;
 
 namespace HeuristicLab.Algorithms.DataAnalysis {
Index: branches/M5Regression/HeuristicLab.Algorithms.DataAnalysis/3.4/Interfaces/INeuralNetworkModel.cs
===================================================================
--- branches/M5Regression/HeuristicLab.Algorithms.DataAnalysis/3.4/Interfaces/INeuralNetworkModel.cs	(revision 15428)
+++ branches/M5Regression/HeuristicLab.Algorithms.DataAnalysis/3.4/Interfaces/INeuralNetworkModel.cs	(revision 15430)
@@ -20,8 +20,5 @@
 #endregion
 
-using HeuristicLab.Optimization;
 using HeuristicLab.Problems.DataAnalysis;
-using HeuristicLab.Core;
-using System.Collections.Generic;
 
 namespace HeuristicLab.Algorithms.DataAnalysis {
Index: branches/M5Regression/HeuristicLab.Algorithms.DataAnalysis/3.4/Interfaces/INeuralNetworkRegressionSolution.cs
===================================================================
--- branches/M5Regression/HeuristicLab.Algorithms.DataAnalysis/3.4/Interfaces/INeuralNetworkRegressionSolution.cs	(revision 15428)
+++ branches/M5Regression/HeuristicLab.Algorithms.DataAnalysis/3.4/Interfaces/INeuralNetworkRegressionSolution.cs	(revision 15430)
@@ -20,7 +20,5 @@
 #endregion
 
-using HeuristicLab.Optimization;
 using HeuristicLab.Problems.DataAnalysis;
-using HeuristicLab.Core;
 
 namespace HeuristicLab.Algorithms.DataAnalysis {
Index: branches/M5Regression/HeuristicLab.Algorithms.DataAnalysis/3.4/Interfaces/IRandomForestClassificationSolution.cs
===================================================================
--- branches/M5Regression/HeuristicLab.Algorithms.DataAnalysis/3.4/Interfaces/IRandomForestClassificationSolution.cs	(revision 15428)
+++ branches/M5Regression/HeuristicLab.Algorithms.DataAnalysis/3.4/Interfaces/IRandomForestClassificationSolution.cs	(revision 15430)
@@ -20,7 +20,5 @@
 #endregion
 
-using HeuristicLab.Optimization;
 using HeuristicLab.Problems.DataAnalysis;
-using HeuristicLab.Core;
 
 namespace HeuristicLab.Algorithms.DataAnalysis {
Index: branches/M5Regression/HeuristicLab.Algorithms.DataAnalysis/3.4/Interfaces/IRandomForestRegressionSolution.cs
===================================================================
--- branches/M5Regression/HeuristicLab.Algorithms.DataAnalysis/3.4/Interfaces/IRandomForestRegressionSolution.cs	(revision 15428)
+++ branches/M5Regression/HeuristicLab.Algorithms.DataAnalysis/3.4/Interfaces/IRandomForestRegressionSolution.cs	(revision 15430)
@@ -21,5 +21,4 @@
 
 using HeuristicLab.Problems.DataAnalysis;
-using HeuristicLab.Problems.DataAnalysis.Symbolic.Regression;
 
 namespace HeuristicLab.Algorithms.DataAnalysis {
Index: branches/M5Regression/HeuristicLab.Algorithms.DataAnalysis/3.4/Interfaces/ISupportVectorMachineSolution.cs
===================================================================
--- branches/M5Regression/HeuristicLab.Algorithms.DataAnalysis/3.4/Interfaces/ISupportVectorMachineSolution.cs	(revision 15428)
+++ branches/M5Regression/HeuristicLab.Algorithms.DataAnalysis/3.4/Interfaces/ISupportVectorMachineSolution.cs	(revision 15430)
@@ -20,7 +20,5 @@
 #endregion
 
-using HeuristicLab.Optimization;
 using HeuristicLab.Problems.DataAnalysis;
-using HeuristicLab.Core;
 
 namespace HeuristicLab.Algorithms.DataAnalysis {
Index: branches/M5Regression/HeuristicLab.Algorithms.DataAnalysis/3.4/KernelRidgeRegression/KernelRidgeRegression.cs
===================================================================
--- branches/M5Regression/HeuristicLab.Algorithms.DataAnalysis/3.4/KernelRidgeRegression/KernelRidgeRegression.cs	(revision 15428)
+++ branches/M5Regression/HeuristicLab.Algorithms.DataAnalysis/3.4/KernelRidgeRegression/KernelRidgeRegression.cs	(revision 15430)
@@ -36,5 +36,5 @@
   [Creatable(CreatableAttribute.Categories.DataAnalysisRegression, Priority = 100)]
   [StorableClass]
-  public sealed class KernelRidgeRegression : BasicAlgorithm {
+  public sealed class KernelRidgeRegression : BasicAlgorithm, IDataAnalysisAlgorithm<IRegressionProblem> {
     private const string SolutionResultName = "Kernel ridge regression solution";
 
Index: branches/M5Regression/HeuristicLab.Algorithms.DataAnalysis/3.4/M5Regression/Interfaces/IImpurityCalculator.cs
===================================================================
--- branches/M5Regression/HeuristicLab.Algorithms.DataAnalysis/3.4/M5Regression/Interfaces/IImpurityCalculator.cs	(revision 15430)
+++ branches/M5Regression/HeuristicLab.Algorithms.DataAnalysis/3.4/M5Regression/Interfaces/IImpurityCalculator.cs	(revision 15430)
@@ -0,0 +1,30 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2017 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 <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+namespace HeuristicLab.Algorithms.DataAnalysis {
+  public interface IImpurityCalculator {
+    double Impurity { get; }
+    void Increment(double value, IncrementType type);
+  }
+  public enum IncrementType {
+    Left, Right, None
+  }
+}
Index: branches/M5Regression/HeuristicLab.Algorithms.DataAnalysis/3.4/M5Regression/Interfaces/IImpurityType.cs
===================================================================
--- branches/M5Regression/HeuristicLab.Algorithms.DataAnalysis/3.4/M5Regression/Interfaces/IImpurityType.cs	(revision 15430)
+++ branches/M5Regression/HeuristicLab.Algorithms.DataAnalysis/3.4/M5Regression/Interfaces/IImpurityType.cs	(revision 15430)
@@ -0,0 +1,28 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2017 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 <http://www.gnu.org/licenses/>.
+ */
+#endregion
+using System.Collections.Generic;
+using HeuristicLab.Core;
+
+namespace HeuristicLab.Algorithms.DataAnalysis {
+  public interface IImpurityType : IParameterizedNamedItem {
+    IImpurityCalculator GenerateCalculator(int partition, IReadOnlyCollection<double> data);
+  }
+}
Index: branches/M5Regression/HeuristicLab.Algorithms.DataAnalysis/3.4/M5Regression/Interfaces/ILeafType.cs
===================================================================
--- branches/M5Regression/HeuristicLab.Algorithms.DataAnalysis/3.4/M5Regression/Interfaces/ILeafType.cs	(revision 15430)
+++ branches/M5Regression/HeuristicLab.Algorithms.DataAnalysis/3.4/M5Regression/Interfaces/ILeafType.cs	(revision 15430)
@@ -0,0 +1,31 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2017 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 <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System.Threading;
+using HeuristicLab.Core;
+using HeuristicLab.Problems.DataAnalysis;
+
+namespace HeuristicLab.Algorithms.DataAnalysis {
+  public interface ILeafType<out T> : IParameterizedNamedItem where T : IRegressionModel {
+    T BuildModel(IRegressionProblemData pd, IRandom random, CancellationToken cancellation, out int noParameters);
+    int MinLeafSize(IRegressionProblemData pd);
+  }
+}
Index: branches/M5Regression/HeuristicLab.Algorithms.DataAnalysis/3.4/M5Regression/Interfaces/IM5MetaModel.cs
===================================================================
--- branches/M5Regression/HeuristicLab.Algorithms.DataAnalysis/3.4/M5Regression/Interfaces/IM5MetaModel.cs	(revision 15430)
+++ branches/M5Regression/HeuristicLab.Algorithms.DataAnalysis/3.4/M5Regression/Interfaces/IM5MetaModel.cs	(revision 15430)
@@ -0,0 +1,31 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2017 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 <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System.Collections.Generic;
+using System.Threading;
+using HeuristicLab.Problems.DataAnalysis;
+
+namespace HeuristicLab.Algorithms.DataAnalysis {
+  internal interface IM5MetaModel : IRegressionModel {
+    void BuildClassifier(IReadOnlyList<int> trainingRows, IReadOnlyList<int> holdoutRows, M5CreationParameters m5CreationParams, CancellationToken cancellation);
+    void UpdateModel(IReadOnlyList<int> rows, M5UpdateParameters m5UpdateParameters, CancellationToken cancellation);
+  }
+}
Index: branches/M5Regression/HeuristicLab.Algorithms.DataAnalysis/3.4/M5Regression/Interfaces/IPruningType.cs
===================================================================
--- branches/M5Regression/HeuristicLab.Algorithms.DataAnalysis/3.4/M5Regression/Interfaces/IPruningType.cs	(revision 15430)
+++ branches/M5Regression/HeuristicLab.Algorithms.DataAnalysis/3.4/M5Regression/Interfaces/IPruningType.cs	(revision 15430)
@@ -0,0 +1,30 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2017 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 <http://www.gnu.org/licenses/>.
+ */
+#endregion
+using System.Collections.Generic;
+using HeuristicLab.Core;
+using HeuristicLab.Problems.DataAnalysis;
+
+namespace HeuristicLab.Algorithms.DataAnalysis {
+  public interface IPruningType : IParameterizedNamedItem {
+    ILeafType<IRegressionModel> ModelType(ILeafType<IRegressionModel> leafType);
+    void GenerateHoldOutSet(IReadOnlyList<int> allrows, IRandom random, out IReadOnlyList<int> training, out IReadOnlyList<int> holdout);
+  }
+}
Index: branches/M5Regression/HeuristicLab.Algorithms.DataAnalysis/3.4/M5Regression/LeafTypes/ComplexLeaf.cs
===================================================================
--- branches/M5Regression/HeuristicLab.Algorithms.DataAnalysis/3.4/M5Regression/LeafTypes/ComplexLeaf.cs	(revision 15430)
+++ branches/M5Regression/HeuristicLab.Algorithms.DataAnalysis/3.4/M5Regression/LeafTypes/ComplexLeaf.cs	(revision 15430)
@@ -0,0 +1,72 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2017 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 <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System;
+using System.Linq;
+using System.Threading;
+using HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Parameters;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+using HeuristicLab.Problems.DataAnalysis;
+
+namespace HeuristicLab.Algorithms.DataAnalysis {
+  [StorableClass]
+  [Item("ComplexLeaf", "A leaf type that uses an arbitriary RegressionAlgorithm to create leaf models")]
+  public class ComplexLeaf : ParameterizedNamedItem, ILeafType<IRegressionModel> {
+    public const string RegressionParameterName = "Regression";
+    public IValueParameter<IDataAnalysisAlgorithm<IRegressionProblem>> RegressionParameter {
+      get { return Parameters[RegressionParameterName] as IValueParameter<IDataAnalysisAlgorithm<IRegressionProblem>>; }
+    }
+    public IDataAnalysisAlgorithm<IRegressionProblem> Regression {
+      get { return RegressionParameter.Value; }
+    }
+
+    #region Constructors & Cloning
+    [StorableConstructor]
+    private ComplexLeaf(bool deserializing) : base(deserializing) { }
+    private ComplexLeaf(ComplexLeaf original, Cloner cloner) : base(original, cloner) { }
+    public ComplexLeaf() {
+      var regression = new KernelRidgeRegression();
+      Parameters.Add(new ValueParameter<IDataAnalysisAlgorithm<IRegressionProblem>>(RegressionParameterName, "The algorithm creating RegressionModels", regression));
+    }
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new ComplexLeaf(this, cloner);
+    }
+    #endregion
+
+    #region IModelType
+    public IRegressionModel BuildModel(IRegressionProblemData pd, IRandom random, CancellationToken cancellation, out int noParameters) {
+      if (pd.Dataset.Rows < MinLeafSize(pd)) throw new ArgumentException("The number of training instances is too small to create a linear model");
+      noParameters = pd.Dataset.Rows + 1;
+      Regression.Problem = new RegressionProblem {ProblemData = pd};
+      var res = M5StaticUtilities.RunSubAlgorithm(Regression, random.Next(), cancellation);
+      var t = res.Select(x => x.Value).OfType<IRegressionSolution>().FirstOrDefault();
+      if (t == null) throw new ArgumentException("No RegressionSolution was provided by the algorithm");
+      return t.Model;
+    }
+
+    public int MinLeafSize(IRegressionProblemData pd) {
+      return 3;
+    }
+    #endregion
+  }
+}
Index: branches/M5Regression/HeuristicLab.Algorithms.DataAnalysis/3.4/M5Regression/LeafTypes/ComponentReductionLinearLeaf.cs
===================================================================
--- branches/M5Regression/HeuristicLab.Algorithms.DataAnalysis/3.4/M5Regression/LeafTypes/ComponentReductionLinearLeaf.cs	(revision 15430)
+++ branches/M5Regression/HeuristicLab.Algorithms.DataAnalysis/3.4/M5Regression/LeafTypes/ComponentReductionLinearLeaf.cs	(revision 15430)
@@ -0,0 +1,86 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2017 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 <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Threading;
+using HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Data;
+using HeuristicLab.Parameters;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+using HeuristicLab.Problems.DataAnalysis;
+
+namespace HeuristicLab.Algorithms.DataAnalysis {
+  [StorableClass]
+  [Item("ComponentReductionLinearLeaf", "A leaf type that uses principle component analysis to create smaller linear models as leaf models")]
+  public class ComponentReductionLinearLeaf : ParameterizedNamedItem, ILeafType<IConfidenceRegressionModel> {
+    public const string NoComponentsParameterName = "NoComponents";
+    public IFixedValueParameter<IntValue> NoComponentsParameter {
+      get { return Parameters[NoComponentsParameterName] as IFixedValueParameter<IntValue>; }
+    }
+    public int NoComponents {
+      get { return NoComponentsParameter.Value.Value; }
+    }
+
+    #region Constructors & Cloning
+    [StorableConstructor]
+    private ComponentReductionLinearLeaf(bool deserializing) : base(deserializing) { }
+    private ComponentReductionLinearLeaf(ComponentReductionLinearLeaf original, Cloner cloner) : base(original, cloner) { }
+    public ComponentReductionLinearLeaf() {
+      Parameters.Add(new FixedValueParameter<IntValue>(NoComponentsParameterName, "The maximum number of principle components used", new IntValue(10)));
+    }
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new ComponentReductionLinearLeaf(this, cloner);
+    }
+    #endregion
+
+    #region IModelType
+    public IConfidenceRegressionModel BuildModel(IRegressionProblemData pd, IRandom random,
+      CancellationToken cancellation, out int noParameters) {
+      var pca = PrincipleComponentAnalysisStatic.Create(pd.Dataset, pd.TrainingIndices, pd.AllowedInputVariables, true);
+      var pcdata = pca.ProjectProblem(pd);
+      ComponentReducedLinearModel bestModel = null;
+      var bestCvrmse = double.MaxValue;
+      noParameters = 1;
+      for (var i = 1; i <= Math.Min(NoComponents, pd.AllowedInputVariables.Count()); i++) {
+        var pd2 = (IRegressionProblemData) pcdata.Clone();
+        var inputs = new HashSet<string>(pca.Names.Take(i));
+        foreach (var v in pd2.InputVariables.CheckedItems.ToArray())
+          pd2.InputVariables.SetItemCheckedState(v.Value, inputs.Contains(v.Value.Value));
+        double cvRmse;
+        double rmse;
+        var model = PreconstructedLinearModel.CreateConfidenceLinearModel(pd2, out rmse, out cvRmse);
+        if (cvRmse > bestCvrmse) continue;
+        bestModel = new ComponentReducedLinearModel(pd2.TargetVariable, model, pca);
+        noParameters = i + 1;
+        bestCvrmse = cvRmse;
+      }
+      return bestModel;
+    }
+
+    public int MinLeafSize(IRegressionProblemData pd) {
+      return NoComponents + 2;
+    }
+    #endregion
+  }
+}
Index: branches/M5Regression/HeuristicLab.Algorithms.DataAnalysis/3.4/M5Regression/LeafTypes/ConstantLeaf.cs
===================================================================
--- branches/M5Regression/HeuristicLab.Algorithms.DataAnalysis/3.4/M5Regression/LeafTypes/ConstantLeaf.cs	(revision 15430)
+++ branches/M5Regression/HeuristicLab.Algorithms.DataAnalysis/3.4/M5Regression/LeafTypes/ConstantLeaf.cs	(revision 15430)
@@ -0,0 +1,56 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2017 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 <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System;
+using System.Linq;
+using System.Threading;
+using HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+using HeuristicLab.Problems.DataAnalysis;
+
+namespace HeuristicLab.Algorithms.DataAnalysis {
+  [StorableClass]
+  [Item("ConstantLeaf", "A leaf type that uses constant models as leaf models")]
+  public class ConstantLeaf : ParameterizedNamedItem, ILeafType<IRegressionModel> {
+    #region Constructors & Cloning
+    [StorableConstructor]
+    private ConstantLeaf(bool deserializing) : base(deserializing) { }
+    private ConstantLeaf(ConstantLeaf original, Cloner cloner) : base(original, cloner) { }
+    public ConstantLeaf() { }
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new ConstantLeaf(this, cloner);
+    }
+    #endregion
+
+    #region IModelType
+    public IRegressionModel BuildModel(IRegressionProblemData pd, IRandom random, CancellationToken cancellation, out int noParameters) {
+      if (pd.Dataset.Rows < MinLeafSize(pd)) throw new ArgumentException("The number of training instances is too small to create a linear model");
+      noParameters = 1;
+      return new PreconstructedLinearModel(pd.Dataset.GetDoubleValues(pd.TargetVariable).Average(), pd.TargetVariable);
+    }
+
+    public int MinLeafSize(IRegressionProblemData pd) {
+      return 0;
+    }
+    #endregion
+  }
+}
Index: branches/M5Regression/HeuristicLab.Algorithms.DataAnalysis/3.4/M5Regression/LeafTypes/GaussianProcessLeaf.cs
===================================================================
--- branches/M5Regression/HeuristicLab.Algorithms.DataAnalysis/3.4/M5Regression/LeafTypes/GaussianProcessLeaf.cs	(revision 15430)
+++ branches/M5Regression/HeuristicLab.Algorithms.DataAnalysis/3.4/M5Regression/LeafTypes/GaussianProcessLeaf.cs	(revision 15430)
@@ -0,0 +1,105 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2017 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 <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System;
+using System.Linq;
+using System.Threading;
+using HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Data;
+using HeuristicLab.Parameters;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+using HeuristicLab.Problems.DataAnalysis;
+
+namespace HeuristicLab.Algorithms.DataAnalysis {
+  [StorableClass]
+  [Item("GaussianProcessLeaf", "A leaf type that uses gaussian process models as leaf models.")]
+  public class GaussianProcessLeaf : ParameterizedNamedItem, ILeafType<IGaussianProcessModel> {
+    #region ParameterNames
+    public const string TriesParameterName = "Tries";
+    public const string RegressionParameterName = "Regression";
+    #endregion
+
+    #region ParameterProperties
+    public IFixedValueParameter<IntValue> TriesParameter {
+      get { return Parameters[TriesParameterName] as IFixedValueParameter<IntValue>; }
+    }
+    public IFixedValueParameter<GaussianProcessRegression> RegressionParameter {
+      get { return Parameters[RegressionParameterName] as IFixedValueParameter<GaussianProcessRegression>; }
+    }
+    #endregion
+
+    #region Properties
+    public int Tries {
+      get { return TriesParameter.Value.Value; }
+    }
+    public GaussianProcessRegression Regression {
+      get { return RegressionParameter.Value; }
+    }
+    #endregion
+
+    #region Constructors & Cloning
+    [StorableConstructor]
+    private GaussianProcessLeaf(bool deserializing) : base(deserializing) { }
+    private GaussianProcessLeaf(GaussianProcessLeaf original, Cloner cloner) : base(original, cloner) { }
+    public GaussianProcessLeaf() {
+      var gp = new GaussianProcessRegression();
+      gp.CovarianceFunctionParameter.Value = new CovarianceRationalQuadraticIso();
+      gp.MeanFunctionParameter.Value = new MeanLinear();
+
+      Parameters.Add(new FixedValueParameter<IntValue>(TriesParameterName, "Number of repetitions", new IntValue(10)));
+      Parameters.Add(new FixedValueParameter<GaussianProcessRegression>(RegressionParameterName, "The algorithm creating GPmodels", gp));
+    }
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new GaussianProcessLeaf(this, cloner);
+    }
+    #endregion
+
+    #region IModelType
+    public IGaussianProcessModel BuildModel(IRegressionProblemData pd, IRandom random, CancellationToken cancellation, out int noParameters) {
+      if (pd.Dataset.Rows < MinLeafSize(pd)) throw new ArgumentException("The number of training instances is too small to create a linear model");
+      Regression.Problem = new RegressionProblem {ProblemData = pd};
+      var cvscore = double.MaxValue;
+      GaussianProcessRegressionSolution sol = null;
+
+      for (var i = 0; i < Tries; i++) {
+        var res = M5StaticUtilities.RunSubAlgorithm(Regression, random.Next(), cancellation);
+        var t = res.Select(x => x.Value).OfType<GaussianProcessRegressionSolution>().FirstOrDefault();
+        var score = ((DoubleValue) res["Negative log pseudo-likelihood (LOO-CV)"].Value).Value;
+        if (score >= cvscore || t == null || double.IsNaN(t.TrainingRSquared)) continue;
+        cvscore = score;
+        sol = t;
+      }
+
+      if (sol == null) throw new ArgumentException("Could not create Gaussian Process model");
+
+      noParameters = pd.Dataset.Rows + 1
+                     + Regression.CovarianceFunction.GetNumberOfParameters(pd.AllowedInputVariables.Count())
+                     + Regression.MeanFunction.GetNumberOfParameters(pd.AllowedInputVariables.Count());
+      return sol.Model;
+    }
+
+    public int MinLeafSize(IRegressionProblemData pd) {
+      return 3;
+    }
+    #endregion
+  }
+}
Index: branches/M5Regression/HeuristicLab.Algorithms.DataAnalysis/3.4/M5Regression/LeafTypes/LinearLeaf.cs
===================================================================
--- branches/M5Regression/HeuristicLab.Algorithms.DataAnalysis/3.4/M5Regression/LeafTypes/LinearLeaf.cs	(revision 15430)
+++ branches/M5Regression/HeuristicLab.Algorithms.DataAnalysis/3.4/M5Regression/LeafTypes/LinearLeaf.cs	(revision 15430)
@@ -0,0 +1,57 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2017 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 <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System;
+using System.Linq;
+using System.Threading;
+using HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+using HeuristicLab.Problems.DataAnalysis;
+
+namespace HeuristicLab.Algorithms.DataAnalysis {
+  [StorableClass]
+  [Item("LinearLeaf", "A leaf type that uses linear models as leaf models. This is the standard for M5' regression")]
+  public class LinearLeaf : ParameterizedNamedItem, ILeafType<IConfidenceRegressionModel> {
+    #region Constructors & Cloning
+    [StorableConstructor]
+    private LinearLeaf(bool deserializing) : base(deserializing) { }
+    private LinearLeaf(LinearLeaf original, Cloner cloner) : base(original, cloner) { }
+    public LinearLeaf() { }
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new LinearLeaf(this, cloner);
+    }
+    #endregion
+
+    #region IModelType
+    public IConfidenceRegressionModel BuildModel(IRegressionProblemData pd, IRandom random, CancellationToken cancellation, out int noParameters) {
+      if (pd.Dataset.Rows < MinLeafSize(pd)) throw new ArgumentException("The number of training instances is too small to create a linear model");
+      double rmse, cvRmse;
+      noParameters = pd.AllowedInputVariables.Count() + 1;
+      return PreconstructedLinearModel.CreateConfidenceLinearModel(pd, out rmse, out cvRmse);
+    }
+
+    public int MinLeafSize(IRegressionProblemData pd) {
+      return pd.AllowedInputVariables.Count() + 2;
+    }
+    #endregion
+  }
+}
Index: branches/M5Regression/HeuristicLab.Algorithms.DataAnalysis/3.4/M5Regression/LeafTypes/LogisticLeaf.cs
===================================================================
--- branches/M5Regression/HeuristicLab.Algorithms.DataAnalysis/3.4/M5Regression/LeafTypes/LogisticLeaf.cs	(revision 15430)
+++ branches/M5Regression/HeuristicLab.Algorithms.DataAnalysis/3.4/M5Regression/LeafTypes/LogisticLeaf.cs	(revision 15430)
@@ -0,0 +1,69 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2017 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 <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System;
+using System.Linq;
+using System.Threading;
+using HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Data;
+using HeuristicLab.Parameters;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+using HeuristicLab.Problems.DataAnalysis;
+
+namespace HeuristicLab.Algorithms.DataAnalysis {
+  [StorableClass]
+  [Item("LogisticLeaf", "A leaf type that uses linear models with a logistic dampening as leaf models. Dampening reduces prediction values far outside the observed target values.")]
+  public class LogisticLeaf : ParameterizedNamedItem, ILeafType<IConfidenceRegressionModel> {
+    private const string DampeningParameterName = "Dampening";
+    public IFixedValueParameter<DoubleValue> DampeningParameter {
+      get { return Parameters[DampeningParameterName] as IFixedValueParameter<DoubleValue>; }
+    }
+    public double Dampening {
+      get { return DampeningParameter.Value.Value; }
+    }
+
+    #region Constructors & Cloning
+    [StorableConstructor]
+    private LogisticLeaf(bool deserializing) : base(deserializing) { }
+    private LogisticLeaf(LogisticLeaf original, Cloner cloner) : base(original, cloner) { }
+    public LogisticLeaf() {
+      Parameters.Add(new FixedValueParameter<DoubleValue>(DampeningParameterName, "Determines the strenght of the logistic dampening. Must be  > 0.0. Larger numbers make more conservative predictions.", new DoubleValue(1.5)));
+    }
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new LogisticLeaf(this, cloner);
+    }
+    #endregion
+
+    #region IModelType
+    public IConfidenceRegressionModel BuildModel(IRegressionProblemData pd, IRandom random, CancellationToken cancellation, out int noParameters) {
+      if (pd.Dataset.Rows < MinLeafSize(pd)) throw new ArgumentException("The number of training instances is too small to create a linear model");
+      double rmse, cvRmse;
+      noParameters = pd.AllowedInputVariables.Count() + 1;
+      return new DampenedLinearModel(PreconstructedLinearModel.CreateConfidenceLinearModel(pd, out rmse, out cvRmse), pd, Dampening);
+    }
+
+    public int MinLeafSize(IRegressionProblemData pd) {
+      return pd.AllowedInputVariables.Count() + 2;
+    }
+    #endregion
+  }
+}
Index: branches/M5Regression/HeuristicLab.Algorithms.DataAnalysis/3.4/M5Regression/M5Regression.cs
===================================================================
--- branches/M5Regression/HeuristicLab.Algorithms.DataAnalysis/3.4/M5Regression/M5Regression.cs	(revision 15430)
+++ branches/M5Regression/HeuristicLab.Algorithms.DataAnalysis/3.4/M5Regression/M5Regression.cs	(revision 15430)
@@ -0,0 +1,192 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Threading;
+using HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Data;
+using HeuristicLab.Optimization;
+using HeuristicLab.Parameters;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+using HeuristicLab.PluginInfrastructure;
+using HeuristicLab.Problems.DataAnalysis;
+using HeuristicLab.Random;
+
+namespace HeuristicLab.Algorithms.DataAnalysis {
+  [StorableClass]
+  [Creatable(CreatableAttribute.Categories.DataAnalysisRegression, Priority = 95)]
+  [Item("M5RegressionTree", "A M5 regression tree / rule set classifier")]
+  public sealed class M5Regression : FixedDataAnalysisAlgorithm<IRegressionProblem> {
+    #region Parametername
+    private const string GenerateRulesParameterName = "GenerateRules";
+    private const string ImpurityParameterName = "Impurity";
+    private const string MinimalNodeSizeParameterName = "MinimalNodeSize";
+    private const string ModelTypeParameterName = "ModelType";
+    private const string PruningTypeParameterName = "PruningType";
+    private const string SeedParameterName = "Seed";
+    private const string SetSeedRandomlyParameterName = "SetSeedRandomly";
+    #endregion
+
+    #region Parameter properties
+    public IFixedValueParameter<BoolValue> GenerateRulesParameter {
+      get { return Parameters[GenerateRulesParameterName] as IFixedValueParameter<BoolValue>; }
+    }
+    public IConstrainedValueParameter<IImpurityType> ImpurityParameter {
+      get { return Parameters[ImpurityParameterName] as IConstrainedValueParameter<IImpurityType>; }
+    }
+    public IFixedValueParameter<IntValue> MinimalNodeSizeParameter {
+      get { return (IFixedValueParameter<IntValue>) Parameters[MinimalNodeSizeParameterName]; }
+    }
+    public IConstrainedValueParameter<ILeafType<IRegressionModel>> ModelTypeParameter {
+      get { return Parameters[ModelTypeParameterName] as IConstrainedValueParameter<ILeafType<IRegressionModel>>; }
+    }
+    public IConstrainedValueParameter<IPruningType> PruningTypeParameter {
+      get { return Parameters[PruningTypeParameterName] as IConstrainedValueParameter<IPruningType>; }
+    }
+    public IFixedValueParameter<IntValue> SeedParameter {
+      get { return Parameters[SeedParameterName] as IFixedValueParameter<IntValue>; }
+    }
+    public IFixedValueParameter<BoolValue> SetSeedRandomlyParameter {
+      get { return Parameters[SetSeedRandomlyParameterName] as IFixedValueParameter<BoolValue>; }
+    }
+    #endregion
+
+    #region Properties 
+    public bool GenerateRules {
+      get { return GenerateRulesParameter.Value.Value; }
+    }
+    public IImpurityType Impurity {
+      get { return ImpurityParameter.Value; }
+    }
+    public int MinimalNodeSize {
+      get { return MinimalNodeSizeParameter.Value.Value; }
+    }
+    public ILeafType<IRegressionModel> LeafType {
+      get { return ModelTypeParameter.Value; }
+    }
+    public IPruningType PruningType {
+      get { return PruningTypeParameter.Value; }
+    }
+    public int Seed {
+      get { return SeedParameter.Value.Value; }
+    }
+    public bool SetSeedRandomly {
+      get { return SetSeedRandomlyParameter.Value.Value; }
+    }
+    #endregion
+
+    #region Constructors and Cloning
+    [StorableConstructor]
+    private M5Regression(bool deserializing) : base(deserializing) { }
+    private M5Regression(M5Regression original, Cloner cloner) : base(original, cloner) { }
+    public M5Regression() {
+      var modelSet = new ItemSet<ILeafType<IRegressionModel>>(ApplicationManager.Manager.GetInstances<ILeafType<IRegressionModel>>());
+      var pruningSet = new ItemSet<IPruningType>(ApplicationManager.Manager.GetInstances<IPruningType>());
+      var impuritySet = new ItemSet<IImpurityType>(ApplicationManager.Manager.GetInstances<IImpurityType>());
+      Parameters.Add(new FixedValueParameter<BoolValue>(GenerateRulesParameterName, "Whether a set of rules or a decision tree shall be created", new BoolValue(true)));
+      Parameters.Add(new ConstrainedValueParameter<IImpurityType>(ImpurityParameterName, "The type of impurity function used to create node splits", impuritySet, impuritySet.OfType<OrderImpurityType>().First()));
+      Parameters.Add(new FixedValueParameter<IntValue>(MinimalNodeSizeParameterName, "The minimal number of samples in a leaf node", new IntValue(1)));
+      Parameters.Add(new ConstrainedValueParameter<ILeafType<IRegressionModel>>(ModelTypeParameterName, "The type of model used for the nodes", modelSet, modelSet.OfType<LinearLeaf>().First()));
+      Parameters.Add(new ConstrainedValueParameter<IPruningType>(PruningTypeParameterName, "The type of pruning used", pruningSet, pruningSet.OfType<M5LeafPruning>().First()));
+      Parameters.Add(new FixedValueParameter<IntValue>(SeedParameterName, "The random seed used to initialize the new pseudo random number generator.", new IntValue(0)));
+      Parameters.Add(new FixedValueParameter<BoolValue>(SetSeedRandomlyParameterName, "True if the random seed should be set to a random value, otherwise false.", new BoolValue(true)));
+      Problem = new RegressionProblem();
+    }
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new M5Regression(this, cloner);
+    }
+    #endregion
+
+    protected override void Run(CancellationToken cancellationToken) {
+      var random = new MersenneTwister();
+      if (SetSeedRandomly) SeedParameter.Value.Value = new System.Random().Next();
+      random.Reset(Seed);
+      var solution = CreateM5RegressionSolution(Problem.ProblemData, random, LeafType, Impurity, PruningType, cancellationToken, MinimalNodeSize, GenerateRules, Results);
+      AnalyzeSolution(solution);
+    }
+
+    #region Static Interface
+    public static IRegressionSolution CreateM5RegressionSolution(IRegressionProblemData problemData, IRandom random,
+      ILeafType<IRegressionModel> leafType = null, IImpurityType impurityType = null, IPruningType pruningType = null,
+      CancellationToken? cancellationToken = null, int minNumInstances = 4, bool generateRules = false, ResultCollection results = null) {
+      //set default values
+      if (leafType == null) leafType = new LinearLeaf();
+      if (impurityType == null) impurityType = new OrderImpurityType();
+      if (cancellationToken == null) cancellationToken = CancellationToken.None;
+      if (pruningType == null) pruningType = new M5LeafPruning();
+
+
+      var doubleVars = new HashSet<string>(problemData.Dataset.DoubleVariables);
+      var vars = problemData.AllowedInputVariables.Concat(new[] {problemData.TargetVariable}).ToArray();
+      if (vars.Any(v => !doubleVars.Contains(v))) throw new NotSupportedException("M5 regression does not support non-double valued input or output features.");
+
+      var values = vars.Select(v => problemData.Dataset.GetDoubleValues(v, problemData.TrainingIndices).ToArray()).ToArray();
+      if (values.Any(v => v.Any(x => double.IsNaN(x) || double.IsInfinity(x))))
+        throw new NotSupportedException("M5 regression does not support NaN or infinity values in the input dataset.");
+      var trainingData = new Dataset(vars, values);
+      var pd = new RegressionProblemData(trainingData, problemData.AllowedInputVariables, problemData.TargetVariable);
+      pd.TrainingPartition.End = pd.TestPartition.Start = pd.TestPartition.End = pd.Dataset.Rows;
+      pd.TrainingPartition.Start = 0;
+
+      //create & build Model
+      var m5Params = new M5CreationParameters(pruningType, minNumInstances, leafType, pd, random, impurityType, results);
+
+      IReadOnlyList<int> t, h;
+      pruningType.GenerateHoldOutSet(problemData.TrainingIndices.ToArray(), random, out t, out h);
+
+      if (generateRules) {
+        IM5MetaModel model = M5RuleSetModel.CreateRuleModel(problemData.TargetVariable, m5Params);
+        model.BuildClassifier(t, h, m5Params, cancellationToken.Value);
+        return model.CreateRegressionSolution(problemData);
+      }
+      else {
+        IM5MetaModel model = M5TreeModel.CreateTreeModel(problemData.TargetVariable, m5Params);
+        model.BuildClassifier(t, h, m5Params, cancellationToken.Value);
+        return model.CreateRegressionSolution(problemData);
+      }
+    }
+
+    public static void UpdateM5Model(M5TreeModel model, IRegressionProblemData problemData, IRandom random,
+      ILeafType<IRegressionModel> leafType = null, CancellationToken? cancellationToken = null, ResultCollection results = null) {
+      UpdateM5Model(model as IM5MetaModel, problemData, random, leafType, cancellationToken, results);
+    }
+
+    public static void UpdateM5Model(M5RuleSetModel model, IRegressionProblemData problemData, IRandom random,
+      ILeafType<IRegressionModel> leafType = null, CancellationToken? cancellationToken = null, ResultCollection results = null) {
+      UpdateM5Model(model as IM5MetaModel, problemData, random, leafType, cancellationToken, results);
+    }
+
+    private static void UpdateM5Model(IM5MetaModel model, IRegressionProblemData problemData, IRandom random,
+      ILeafType<IRegressionModel> leafType = null, CancellationToken? cancellationToken = null, ResultCollection results = null) {
+      if (cancellationToken == null) cancellationToken = CancellationToken.None;
+      var m5Params = new M5UpdateParameters(leafType, problemData, random, results);
+      model.UpdateModel(problemData.TrainingIndices.ToList(), m5Params, cancellationToken.Value);
+    }
+    #endregion
+
+    #region Helpers
+    private void AnalyzeSolution(IRegressionSolution solution) {
+      Results.Add(new Result("RegressionSolution", (IItem) solution.Clone()));
+
+      Dictionary<string, int> frequencies;
+      if (!GenerateRules) {
+        Results.Add(M5Analyzer.CreateLeafDepthHistogram((M5TreeModel) solution.Model));
+        frequencies = M5Analyzer.GetTreeVariableFrequences((M5TreeModel) solution.Model);
+      }
+      else {
+        Results.Add(M5Analyzer.CreateRulesResult((M5RuleSetModel) solution.Model, Problem.ProblemData, "M5TreeResult", 0, true));
+        frequencies = M5Analyzer.GetRuleVariableFrequences((M5RuleSetModel) solution.Model);
+        Results.Add(M5Analyzer.CreateCoverageDiagram((M5RuleSetModel) solution.Model, Problem.ProblemData));
+      }
+
+      //Variable frequencies
+      var sum = frequencies.Values.Sum();
+      sum = sum == 0 ? 1 : sum;
+      var impactArray = new DoubleArray(frequencies.Select(i => (double) i.Value / sum).ToArray()) {
+        ElementNames = frequencies.Select(i => i.Key)
+      };
+      Results.Add(new Result("Variable Frequences", "relative frequencies of variables in rules and tree nodes", impactArray));
+    }
+    #endregion
+  }
+}
Index: branches/M5Regression/HeuristicLab.Algorithms.DataAnalysis/3.4/M5Regression/M5Utilities/M5Analyzer.cs
===================================================================
--- branches/M5Regression/HeuristicLab.Algorithms.DataAnalysis/3.4/M5Regression/M5Utilities/M5Analyzer.cs	(revision 15430)
+++ branches/M5Regression/HeuristicLab.Algorithms.DataAnalysis/3.4/M5Regression/M5Utilities/M5Analyzer.cs	(revision 15430)
@@ -0,0 +1,163 @@
+#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2017 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 <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System.Collections.Generic;
+using System.Linq;
+using HeuristicLab.Analysis;
+using HeuristicLab.Data;
+using HeuristicLab.Optimization;
+using HeuristicLab.Problems.DataAnalysis;
+
+namespace HeuristicLab.Algorithms.DataAnalysis {
+  internal static class M5Analyzer {
+    private const string LeftResultName = "Left";
+    private const string RightResultName = "Right";
+    private const string ConditionResultName = "Condition";
+    private const string CoverResultName = "Covered Instances";
+    private const string CoverageDiagramResultName = "Coverage";
+    private const string NodeModelResultName = "NodeModel";
+    private const string NodeSizeResultName = "NodeSize";
+    private const string RuleModelResultName = "RuleModel";
+
+    public static Dictionary<string, int> GetRuleVariableFrequences(M5RuleSetModel ruleSetModel) {
+      var res = ruleSetModel.VariablesUsedForPrediction.ToDictionary(x => x, x => 0);
+      foreach (var rule in ruleSetModel.Rules)
+        foreach (var att in rule.SplitAtts)
+          res[att]++;
+      return res;
+    }
+
+    public static Dictionary<string, int> GetTreeVariableFrequences(M5TreeModel treeModel) {
+      var res = treeModel.VariablesUsedForPrediction.ToDictionary(x => x, x => 0);
+      var root = treeModel.Root;
+      foreach (var cur in root.EnumerateNodes().Where(x => !x.IsLeaf))
+        res[cur.SplitAttr]++;
+      return res;
+    }
+
+    public static Result CreateLeafDepthHistogram(M5TreeModel treeModel) {
+      var list = new List<int>();
+      GetLeafDepths(treeModel.Root, 0, list);
+      var row = new DataRow("Depths", "", list.Select(x => (double)x)) {
+        VisualProperties = { ChartType = DataRowVisualProperties.DataRowChartType.Histogram }
+      };
+      var hist = new DataTable("LeafDepths");
+      hist.Rows.Add(row);
+      return new Result(hist.Name, hist);
+    }
+
+    public static Result CreateRulesResult(M5RuleSetModel ruleSetModel, IRegressionProblemData pd, string resultName, int maxDepth, bool displayModels) {
+      var res = new ResultCollection();
+      var i = 0;
+      foreach (var rule in ruleSetModel.Rules)
+        res.Add(new Result("Rule" + i++, CreateRulesResult(rule, pd, maxDepth, displayModels, out pd)));
+      return new Result(resultName, res);
+    }
+
+    public static IResult CreateCoverageDiagram(M5RuleSetModel setModel, IRegressionProblemData problemData) {
+      var res = new DataTable(CoverageDiagramResultName);
+      var training = CountCoverage(setModel, problemData.Dataset, problemData.TrainingIndices);
+      var test = CountCoverage(setModel, problemData.Dataset, problemData.TestIndices);
+      res.Rows.Add(new DataRow("Training", "", training));
+      res.Rows.Add(new DataRow("Test", "", test));
+
+      foreach (var row in res.Rows)
+        row.VisualProperties.ChartType = DataRowVisualProperties.DataRowChartType.Columns;
+      res.VisualProperties.XAxisMaximumFixedValue = training.Count + 1;
+      res.VisualProperties.XAxisMaximumAuto = false;
+      res.VisualProperties.XAxisMinimumFixedValue = 0;
+      res.VisualProperties.XAxisMinimumAuto = false;
+      res.VisualProperties.XAxisTitle = "Rule";
+      res.VisualProperties.YAxisTitle = "Covered Instances";
+
+      return new Result(CoverageDiagramResultName, res);
+    }
+
+    private static void GetLeafDepths(M5NodeModel n, int depth, ICollection<int> res) {
+      if (n == null) return;
+      if (n.Left == null && n.Right == null) res.Add(depth);
+      else {
+        GetLeafDepths(n.Left, depth + 1, res);
+        GetLeafDepths(n.Right, depth + 1, res);
+      }
+    }
+
+    private static ResultCollection CreateRulesResult(M5NodeModel nodeModel, IRegressionProblemData pd, IList<int> rows, int maxDepth, bool displayModels) {
+      var res = new ResultCollection();
+      if (!nodeModel.IsLeaf) {
+        res.Add(new Result(ConditionResultName, new StringValue(nodeModel.SplitAttr + " <= " + nodeModel.SplitValue)));
+        var assignment = pd.Dataset.GetDoubleValues(nodeModel.SplitAttr, rows).Select(x => x <= nodeModel.SplitValue).ToArray();
+        var leftRows = Enumerable.Range(0, assignment.Length).Where(i => assignment[i]).Select(i => rows[i]).ToList();
+        var rightRows = Enumerable.Range(0, assignment.Length).Where(i => !assignment[i]).Select(i => rows[i]).ToList();
+        if (nodeModel.Left != null && maxDepth > 0) res.Add(new Result(LeftResultName, CreateRulesResult(nodeModel.Left, pd, leftRows, maxDepth - 1, displayModels)));
+        if (nodeModel.Right != null && maxDepth > 0) res.Add(new Result(RightResultName, CreateRulesResult(nodeModel.Right, pd, rightRows, maxDepth - 1, displayModels)));
+      }
+      if (nodeModel.NodeModel != null && displayModels) res.Add(new Result(NodeModelResultName, nodeModel.NodeModel.CreateRegressionSolution(pd)));
+      res.Add(new Result(NodeSizeResultName, new IntValue(rows.Count)));
+      return res;
+    }
+
+    private static ResultCollection CreateRulesResult(M5RuleModel m5RuleModel, IRegressionProblemData pd, int maxDepth, bool displayModels, out IRegressionProblemData notCovered) {
+
+      var training = pd.TrainingIndices.Where(x => !m5RuleModel.Covers(pd.Dataset, x)).ToArray();
+      var test = pd.TestIndices.Where(x => !m5RuleModel.Covers(pd.Dataset, x)).ToArray();
+      var data = new Dataset(pd.Dataset.DoubleVariables, pd.Dataset.DoubleVariables.Select(v => pd.Dataset.GetDoubleValues(v, training.Concat(test)).ToArray()));
+      notCovered = new RegressionProblemData(data, pd.AllowedInputVariables, pd.TargetVariable);
+      notCovered.TestPartition.Start = notCovered.TrainingPartition.End = training.Length;
+      notCovered.TestPartition.End = training.Length + test.Length;
+
+      var training2 = pd.TrainingIndices.Where(x => m5RuleModel.Covers(pd.Dataset, x)).ToArray();
+      var test2 = pd.TestIndices.Where(x => m5RuleModel.Covers(pd.Dataset, x)).ToArray();
+      var data2 = new Dataset(pd.Dataset.DoubleVariables, pd.Dataset.DoubleVariables.Select(v => pd.Dataset.GetDoubleValues(v, training2.Concat(test2)).ToArray()));
+      var covered = new RegressionProblemData(data2, pd.AllowedInputVariables, pd.TargetVariable);
+      covered.TestPartition.Start = covered.TrainingPartition.End = training2.Length;
+      covered.TestPartition.End = training2.Length + test2.Length;
+
+      var res = new ResultCollection {
+        new Result(ConditionResultName, new StringValue(m5RuleModel.ToCompactString())),
+        new Result(CoverResultName, new IntValue(pd.TrainingIndices.Count()-training.Length))
+      };
+      if (displayModels) res.Add(new Result(RuleModelResultName, m5RuleModel.CreateRegressionSolution(covered)));
+      return res;
+    }
+
+    private static IEnumerable<double> Cumulate(this IEnumerable<double> values) {
+      double sum = 0.0;
+      foreach (var value in values) {
+        sum += value;
+        yield return sum;
+      }
+    }
+
+    private static IReadOnlyList<double> CountCoverage(M5RuleSetModel setModel, IDataset data, IEnumerable<int> rows) {
+      var rules = setModel.Rules.ToArray();
+      var res = new double[rules.Length];
+      foreach (int row in rows)
+        for (int i = 0; i < rules.Length; i++)
+          if (rules[i].Covers(data, row)) {
+            res[i]++;
+            break;
+          }
+      return res;
+    }
+  }
+}
+
Index: branches/M5Regression/HeuristicLab.Algorithms.DataAnalysis/3.4/M5Regression/M5Utilities/M5CreationParameters.cs
===================================================================
--- branches/M5Regression/HeuristicLab.Algorithms.DataAnalysis/3.4/M5Regression/M5Utilities/M5CreationParameters.cs	(revision 15430)
+++ branches/M5Regression/HeuristicLab.Algorithms.DataAnalysis/3.4/M5Regression/M5Utilities/M5CreationParameters.cs	(revision 15430)
@@ -0,0 +1,84 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2017 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 <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System;
+using System.Collections.Generic;
+using HeuristicLab.Core;
+using HeuristicLab.Optimization;
+using HeuristicLab.Problems.DataAnalysis;
+
+namespace HeuristicLab.Algorithms.DataAnalysis {
+  internal class M5CreationParameters {
+    private readonly IImpurityType Impurity1;
+    private readonly IPruningType Pruningtype1;
+    private readonly ILeafType<IRegressionModel> LeafType1;
+    private readonly int MinLeafSize1;
+    private readonly IRegressionProblemData ProblemData1;
+    private readonly IRandom Random1;
+    private readonly ResultCollection Results1;
+    public IImpurityType Impurity {
+      get { return Impurity1; }
+    }
+    public IPruningType Pruningtype {
+      get { return Pruningtype1; }
+    }
+    public ILeafType<IRegressionModel> LeafType {
+      get { return LeafType1; }
+    }
+    public int MinLeafSize {
+      get { return MinLeafSize1; }
+    }
+    private IRegressionProblemData ProblemData {
+      get { return ProblemData1; }
+    }
+    public IRandom Random {
+      get { return Random1; }
+    }
+    public ResultCollection Results {
+      get { return Results1; }
+    }
+
+    public ILeafType<IRegressionModel> PruningLeaf {
+      get { return Pruningtype.ModelType(LeafType); }
+    }
+    public IEnumerable<string> AllowedInputVariables {
+      get { return ProblemData.AllowedInputVariables; }
+    }
+    public string TargetVariable {
+      get { return ProblemData.TargetVariable; }
+    }
+    public IDataset Data {
+      get { return ProblemData.Dataset; }
+    }
+
+    public M5CreationParameters(IPruningType pruning, int minleafSize, ILeafType<IRegressionModel> modeltype,
+      IRegressionProblemData problemData, IRandom random, IImpurityType impurity, ResultCollection results) {
+      Impurity1 = impurity;
+      Pruningtype1 = pruning;
+      ProblemData1 = problemData;
+      Random1 = random;
+      LeafType1 = modeltype;
+      Results1 = results;
+      var pruningLeaf = pruning.ModelType(LeafType);
+      MinLeafSize1 = Math.Max(pruningLeaf == null ? 0 : pruningLeaf.MinLeafSize(problemData), Math.Max(minleafSize, modeltype.MinLeafSize(problemData)));
+    }
+  }
+}
Index: branches/M5Regression/HeuristicLab.Algorithms.DataAnalysis/3.4/M5Regression/M5Utilities/M5StaticUtilities.cs
===================================================================
--- branches/M5Regression/HeuristicLab.Algorithms.DataAnalysis/3.4/M5Regression/M5Utilities/M5StaticUtilities.cs	(revision 15430)
+++ branches/M5Regression/HeuristicLab.Algorithms.DataAnalysis/3.4/M5Regression/M5Utilities/M5StaticUtilities.cs	(revision 15430)
@@ -0,0 +1,44 @@
+#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2017 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 <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System;
+using System.Threading;
+using HeuristicLab.Core;
+using HeuristicLab.Data;
+using HeuristicLab.Optimization;
+
+namespace HeuristicLab.Algorithms.DataAnalysis {
+  internal static class M5StaticUtilities {
+    public static ResultCollection RunSubAlgorithm(IAlgorithm alg, int random, CancellationToken cancellation) {
+      if (alg.Parameters.ContainsKey("SetSeedRandomly") && alg.Parameters.ContainsKey("Seed")) {
+        var seed = alg.Parameters["Seed"].ActualValue as IntValue;
+        var setSeed = alg.Parameters["SetSeedRandomly"].ActualValue as BoolValue;
+        if (seed == null || setSeed == null)
+          throw new ArgumentException("SetSeedRandomly and Seed do not have their expected Parametertypes");
+        setSeed.Value = false;
+        seed.Value = random;
+      }
+      if (alg.ExecutionState != ExecutionState.Paused) alg.Prepare();
+      alg.Start(cancellation);
+      return alg.Results;
+    }
+  }
+}
Index: branches/M5Regression/HeuristicLab.Algorithms.DataAnalysis/3.4/M5Regression/M5Utilities/M5UpdateParameters.cs
===================================================================
--- branches/M5Regression/HeuristicLab.Algorithms.DataAnalysis/3.4/M5Regression/M5Utilities/M5UpdateParameters.cs	(revision 15430)
+++ branches/M5Regression/HeuristicLab.Algorithms.DataAnalysis/3.4/M5Regression/M5Utilities/M5UpdateParameters.cs	(revision 15430)
@@ -0,0 +1,63 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2017 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 <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System.Collections.Generic;
+using HeuristicLab.Core;
+using HeuristicLab.Optimization;
+using HeuristicLab.Problems.DataAnalysis;
+
+namespace HeuristicLab.Algorithms.DataAnalysis {
+  internal class M5UpdateParameters {
+    private readonly ILeafType<IRegressionModel> LeafType1;
+    private readonly IRegressionProblemData ProblemData1;
+    private readonly IRandom Random1;
+    private readonly ResultCollection Results1;
+    public ILeafType<IRegressionModel> LeafType {
+      get { return LeafType1; }
+    }
+    private IRegressionProblemData ProblemData {
+      get { return ProblemData1; }
+    }
+    public IRandom Random {
+      get { return Random1; }
+    }
+    public ResultCollection Results {
+      get { return Results1; }
+    }
+
+    public IEnumerable<string> AllowedInputVariables {
+      get { return ProblemData.AllowedInputVariables; }
+    }
+    public string TargetVariable {
+      get { return ProblemData.TargetVariable; }
+    }
+    public IDataset Data {
+      get { return ProblemData.Dataset; }
+    }
+
+    public M5UpdateParameters(ILeafType<IRegressionModel> modeltype, IRegressionProblemData problemData, IRandom random, ResultCollection results) {
+      ProblemData1 = problemData;
+      Random1 = random;
+      LeafType1 = modeltype;
+      Results1 = results;
+    }
+  }
+}
Index: branches/M5Regression/HeuristicLab.Algorithms.DataAnalysis/3.4/M5Regression/M5Utilities/SplitInfo.cs
===================================================================
--- branches/M5Regression/HeuristicLab.Algorithms.DataAnalysis/3.4/M5Regression/M5Utilities/SplitInfo.cs	(revision 15430)
+++ branches/M5Regression/HeuristicLab.Algorithms.DataAnalysis/3.4/M5Regression/M5Utilities/SplitInfo.cs	(revision 15430)
@@ -0,0 +1,85 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2017 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 <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System.Collections.Generic;
+using HeuristicLab.Common;
+
+namespace HeuristicLab.Algorithms.DataAnalysis {
+  internal sealed class SplitInfo : IDeepCloneable {
+    #region Properties
+    public int Position { get; private set; } // position of maximum impurity reduction
+    public double MaxImpurity { get; private set; } // maximum impurity reduction
+    public string SplitAttr { get; private set; } // spliting attribute
+    public double SplitValue { get; private set; } // splitting value
+    #endregion
+
+    #region HLConstructors
+    private SplitInfo(SplitInfo original) {
+      Position = original.Position;
+      MaxImpurity = original.MaxImpurity;
+      SplitValue = original.SplitValue;
+      SplitAttr = original.SplitAttr;
+    }
+    public SplitInfo() {
+      MaxImpurity = -1E20;
+    }
+    public IDeepCloneable Clone(Cloner cloner) {
+      return new SplitInfo(this);
+    }
+    public object Clone() {
+      return new Cloner().Clone(this);
+    }
+    #endregion
+
+    public void AttributeSplit(string attr, IReadOnlyList<double> attribute, IReadOnlyList<double> targets, M5CreationParameters m5CreationParams) {
+      Position = 0;
+      MaxImpurity = -1E20;
+      SplitAttr = attr;
+      SplitValue = 0.0;
+
+      //minSize and order are fixed to 4 and 5 in weka
+      //var order = Math.Max(0, minSize) + 1;
+      //var len = Math.Max(1, targets.Count / order);
+      //len = Math.Max(len, minSize);
+      //var order = 5;
+
+      if (targets.Count < m5CreationParams.MinLeafSize) return;
+
+      var len = m5CreationParams.MinLeafSize;
+      if (targets.Count <= m5CreationParams.MinLeafSize) return;
+      var imp = m5CreationParams.Impurity.GenerateCalculator(len, targets);
+
+      if (imp.Impurity > MaxImpurity) {
+        MaxImpurity = imp.Impurity;
+        SplitValue = (attribute[len - 1] + attribute[len]) / 2;
+        Position = len;
+      }
+      for (var i = len; i < targets.Count - len; i++) {
+        imp.Increment(targets[i], IncrementType.Left);
+        if (attribute[i + 1].IsAlmost(attribute[i]) || imp.Impurity <= MaxImpurity) continue;
+        MaxImpurity = imp.Impurity;
+        SplitValue = (attribute[i] + attribute[i + 1]) / 2;
+        Position = i + 1;
+      }
+    }
+  }
+}
+
Index: branches/M5Regression/HeuristicLab.Algorithms.DataAnalysis/3.4/M5Regression/MetaModels/ComponentReducedLinearModel.cs
===================================================================
--- branches/M5Regression/HeuristicLab.Algorithms.DataAnalysis/3.4/M5Regression/MetaModels/ComponentReducedLinearModel.cs	(revision 15430)
+++ branches/M5Regression/HeuristicLab.Algorithms.DataAnalysis/3.4/M5Regression/MetaModels/ComponentReducedLinearModel.cs	(revision 15430)
@@ -0,0 +1,62 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2017 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 <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System.Collections.Generic;
+using HeuristicLab.Common;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+using HeuristicLab.Problems.DataAnalysis;
+
+namespace HeuristicLab.Algorithms.DataAnalysis {
+  [StorableClass]
+  internal class ComponentReducedLinearModel : RegressionModel, IConfidenceRegressionModel {
+    [Storable]
+    private IConfidenceRegressionModel Model;
+    [Storable]
+    private PrincipleComponentAnalysisStatic Pca;
+
+    [StorableConstructor]
+    private ComponentReducedLinearModel(bool deserializing) : base(deserializing) { }
+    private ComponentReducedLinearModel(ComponentReducedLinearModel original, Cloner cloner) : base(original, cloner) {
+      Model = cloner.Clone(original.Model);
+      Pca = cloner.Clone(original.Pca);
+    }
+    public ComponentReducedLinearModel(string targetVariable, IConfidenceRegressionModel model, PrincipleComponentAnalysisStatic pca) : base(targetVariable) {
+      Model = model;
+      Pca = pca;
+    }
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new ComponentReducedLinearModel(this, cloner);
+    }
+
+    public override IEnumerable<string> VariablesUsedForPrediction {
+      get { return Model.VariablesUsedForPrediction; }
+    }
+    public override IEnumerable<double> GetEstimatedValues(IDataset dataset, IEnumerable<int> rows) {
+      return Model.GetEstimatedValues(Pca.ProjectDataset(dataset), rows);
+    }
+    public override IRegressionSolution CreateRegressionSolution(IRegressionProblemData problemData) {
+      return new ConfidenceRegressionSolution(this, problemData);
+    }
+    public IEnumerable<double> GetEstimatedVariances(IDataset dataset, IEnumerable<int> rows) {
+      return Model.GetEstimatedVariances(Pca.ProjectDataset(dataset), rows);
+    }
+  }
+}
Index: branches/M5Regression/HeuristicLab.Algorithms.DataAnalysis/3.4/M5Regression/MetaModels/DampenedLinearModel.cs
===================================================================
--- branches/M5Regression/HeuristicLab.Algorithms.DataAnalysis/3.4/M5Regression/MetaModels/DampenedLinearModel.cs	(revision 15430)
+++ branches/M5Regression/HeuristicLab.Algorithms.DataAnalysis/3.4/M5Regression/MetaModels/DampenedLinearModel.cs	(revision 15430)
@@ -0,0 +1,94 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2017 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 <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using HeuristicLab.Common;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+using HeuristicLab.Problems.DataAnalysis;
+
+namespace HeuristicLab.Algorithms.DataAnalysis {
+  //mulitdimensional extension of http://www2.stat.duke.edu/~tjl13/s101/slides/unit6lec3H.pdf
+  [StorableClass]
+  internal class DampenedLinearModel : RegressionModel, IConfidenceRegressionModel {
+    [Storable]
+    private IConfidenceRegressionModel Model;
+    [Storable]
+    private double Min;
+    [Storable]
+    private double Max;
+    [Storable]
+    private double Dampening;
+
+    public override IEnumerable<string> VariablesUsedForPrediction {
+      get { return Model.VariablesUsedForPrediction; }
+    }
+    [StorableConstructor]
+    private DampenedLinearModel(bool deserializing) : base(deserializing) { }
+    private DampenedLinearModel(DampenedLinearModel original, Cloner cloner) : base(original, cloner) {
+      Model = cloner.Clone(original.Model);
+      Min = original.Min;
+      Max = original.Max;
+      Dampening = original.Dampening;
+    }
+    public DampenedLinearModel(IConfidenceRegressionModel model, IRegressionProblemData pd, double dampening) : base(model.TargetVariable) {
+      Model = model;
+      Min = pd.TargetVariableTrainingValues.Min();
+      Max = pd.TargetVariableTrainingValues.Max();
+      Dampening = dampening;
+    }
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new DampenedLinearModel(this, cloner);
+    }
+
+    public override IEnumerable<double> GetEstimatedValues(IDataset dataset, IEnumerable<int> rows) {
+      var slow = Sigmoid(-Dampening);
+      var shigh = Sigmoid(Dampening);
+      foreach (var x in Model.GetEstimatedValues(dataset, rows)) {
+        var y = Rescale(x, Min, Max, -Dampening, Dampening);
+        y = Sigmoid(y);
+        y = Rescale(y, slow, shigh, Min, Max);
+        yield return y;
+      }
+    }
+    public override IRegressionSolution CreateRegressionSolution(IRegressionProblemData problemData) {
+      return new ConfidenceRegressionSolution(this, problemData);
+    }
+    public IEnumerable<double> GetEstimatedVariances(IDataset dataset, IEnumerable<int> rows) {
+      return Model.GetEstimatedVariances(dataset, rows);
+    }
+
+    private static double Rescale(double x, double oMin, double oMax, double nMin, double nMax) {
+      var d = oMax - oMin;
+      var nd = nMax - nMin;
+      if (d.IsAlmost(0)) {
+        d = 1;
+        nMin += nd / 2;
+        nd = 0;
+      }
+      return ((x - oMin) / d) * nd + nMin;
+    }
+    private static double Sigmoid(double x) {
+      return 1 / (1 + Math.Exp(-x));
+    }
+  }
+}
Index: branches/M5Regression/HeuristicLab.Algorithms.DataAnalysis/3.4/M5Regression/MetaModels/M5NodeModel.cs
===================================================================
--- branches/M5Regression/HeuristicLab.Algorithms.DataAnalysis/3.4/M5Regression/MetaModels/M5NodeModel.cs	(revision 15430)
+++ branches/M5Regression/HeuristicLab.Algorithms.DataAnalysis/3.4/M5Regression/MetaModels/M5NodeModel.cs	(revision 15430)
@@ -0,0 +1,268 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2017 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 <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Threading;
+using HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Data;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+using HeuristicLab.Problems.DataAnalysis;
+
+namespace HeuristicLab.Algorithms.DataAnalysis {
+  [StorableClass]
+  internal class M5NodeModel : RegressionModel {
+    #region Properties
+    [Storable]
+    internal bool IsLeaf { get; private set; }
+    [Storable]
+    internal IRegressionModel NodeModel { get; private set; }
+    [Storable]
+    internal string SplitAttr { get; private set; }
+    [Storable]
+    internal double SplitValue { get; private set; }
+    [Storable]
+    internal M5NodeModel Left { get; private set; }
+    [Storable]
+    internal M5NodeModel Right { get; private set; }
+    [Storable]
+    internal M5NodeModel Parent { get; set; }
+    [Storable]
+    internal int NumSamples { get; private set; }
+    [Storable]
+    internal int NumParam { get; set; }
+    [Storable]
+    internal int NodeModelParams { get; set; }
+    [Storable]
+    private IReadOnlyList<string> Variables { get; set; }
+
+    private const double DevFraction = 0.05;
+    #endregion
+
+    #region HLConstructors
+    [StorableConstructor]
+    protected M5NodeModel(bool deserializing) : base(deserializing) { }
+    protected M5NodeModel(M5NodeModel original, Cloner cloner) : base(original, cloner) {
+      IsLeaf = original.IsLeaf;
+      NodeModel = cloner.Clone(original.NodeModel);
+      SplitValue = original.SplitValue;
+      SplitAttr = original.SplitAttr;
+      Left = cloner.Clone(original.Left);
+      Right = cloner.Clone(original.Right);
+      Parent = cloner.Clone(original.Parent);
+      NumParam = original.NumParam;
+      NumSamples = original.NumSamples;
+      Variables = original.Variables != null ? original.Variables.ToList() : null;
+    }
+    protected M5NodeModel(string targetAttr) : base(targetAttr) { }
+    protected M5NodeModel(M5NodeModel parent) : base(parent.TargetVariable) {
+      Parent = parent;
+    }
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new M5NodeModel(this, cloner);
+    }
+    public static M5NodeModel CreateNode(string targetAttr, M5CreationParameters m5CreationParams) {
+      return m5CreationParams.LeafType is ILeafType<IConfidenceRegressionModel> ? new ConfidenceM5NodeModel(targetAttr) : new M5NodeModel(targetAttr);
+    }
+    private static M5NodeModel CreateNode(M5NodeModel parent, M5CreationParameters m5CreationParams) {
+      return m5CreationParams.LeafType is ILeafType<IConfidenceRegressionModel> ? new ConfidenceM5NodeModel(parent) : new M5NodeModel(parent);
+    }
+    #endregion
+
+    #region RegressionModel
+    public override IEnumerable<string> VariablesUsedForPrediction {
+      get { return Variables; }
+    }
+    public override IEnumerable<double> GetEstimatedValues(IDataset dataset, IEnumerable<int> rows) {
+      if (!IsLeaf) return rows.Select(row => GetEstimatedValue(dataset, row));
+      if (NodeModel == null) throw new NotSupportedException("M5P has not been built correctly");
+      return NodeModel.GetEstimatedValues(dataset, rows);
+    }
+    public override IRegressionSolution CreateRegressionSolution(IRegressionProblemData problemData) {
+      return new RegressionSolution(this, problemData);
+    }
+    #endregion
+
+    internal void Split(IReadOnlyList<int> rows, M5CreationParameters m5CreationParams, double globalStdDev) {
+      Variables = m5CreationParams.AllowedInputVariables.ToArray();
+      NumSamples = rows.Count;
+      Right = null;
+      Left = null;
+      NodeModel = null;
+      IsLeaf = m5CreationParams.Data.GetDoubleValues(TargetVariable, rows).StandardDeviation() < globalStdDev * DevFraction;
+      if (IsLeaf) return;
+      //Split(rows, m5Params, globalStdDev);
+      var bestSplit = new SplitInfo();
+      var currentSplit = new SplitInfo();
+
+      //find best Attribute for the Split
+      foreach (var attr in m5CreationParams.AllowedInputVariables) {
+        var sortedData = m5CreationParams.Data.GetDoubleValues(attr, rows).Zip(m5CreationParams.Data.GetDoubleValues(TargetVariable, rows), Tuple.Create).OrderBy(x => x.Item1).ToArray();
+        currentSplit.AttributeSplit(attr, sortedData.Select(x => x.Item1).ToArray(), sortedData.Select(x => x.Item2).ToArray(), m5CreationParams);
+        if (!currentSplit.MaxImpurity.IsAlmost(bestSplit.MaxImpurity) && currentSplit.MaxImpurity > bestSplit.MaxImpurity)
+          bestSplit = (SplitInfo) currentSplit.Clone();
+      }
+
+      //if no suitable split exists => leafNode
+      if (bestSplit.SplitAttr == null || bestSplit.Position < 1 || bestSplit.Position > rows.Count - 1) {
+        IsLeaf = true;
+        return;
+      }
+
+      SplitAttr = bestSplit.SplitAttr;
+      SplitValue = bestSplit.SplitValue;
+
+      //split Dataset
+      IReadOnlyList<int> leftRows, rightRows;
+      SplitRows(rows, m5CreationParams.Data, SplitAttr, SplitValue, out leftRows, out rightRows);
+
+      if (leftRows.Count < m5CreationParams.MinLeafSize || rightRows.Count < m5CreationParams.MinLeafSize) {
+        IsLeaf = true;
+        SplitAttr = null;
+        SplitValue = double.NaN;
+        return;
+      }
+
+      //create subtrees
+      Left = CreateNode(this, m5CreationParams);
+      Left.Split(leftRows, m5CreationParams, globalStdDev);
+      Right = CreateNode(this, m5CreationParams);
+      Right.Split(rightRows, m5CreationParams, globalStdDev);
+    }
+
+    internal bool Prune(IReadOnlyList<int> trainingRows, IReadOnlyList<int> testRows, M5CreationParameters m5CreationParams, CancellationToken cancellation, double globalStdDev) {
+      if (IsLeaf) {
+        BuildModel(trainingRows, m5CreationParams.Data, m5CreationParams.Random, m5CreationParams.PruningLeaf, cancellation);
+        NumParam = NodeModelParams;
+        return true;
+      }
+      //split training & holdout data
+      IReadOnlyList<int> leftTest, rightTest;
+      SplitRows(testRows, m5CreationParams.Data, SplitAttr, SplitValue, out leftTest, out rightTest);
+      IReadOnlyList<int> leftTraining, rightTraining;
+      SplitRows(trainingRows, m5CreationParams.Data, SplitAttr, SplitValue, out leftTraining, out rightTraining);
+
+      //prune children frist
+      var lpruned = Left.Prune(leftTraining, leftTest, m5CreationParams, cancellation, globalStdDev);
+      var rpruned = Right.Prune(rightTraining, rightTest, m5CreationParams, cancellation, globalStdDev);
+      NumParam = Left.NumParam + Right.NumParam + 1;
+
+      //TODO check if this reduces quality. It reduces training effort (consideraby for some pruningTypes)
+      if (!lpruned && !rpruned) return false;
+
+      BuildModel(trainingRows, m5CreationParams.Data, m5CreationParams.Random, m5CreationParams.PruningLeaf, cancellation);
+
+      //check if children will be pruned
+      if (!((PruningBase) m5CreationParams.Pruningtype).Prune(this, m5CreationParams, testRows, globalStdDev)) return false;
+
+      //convert to leafNode
+      ((IntValue) m5CreationParams.Results[M5RuleModel.NoCurrentLeafesResultName].Value).Value -= EnumerateNodes().Count(x => x.IsLeaf) - 1;
+      IsLeaf = true;
+      Right = null;
+      Left = null;
+      NumParam = NodeModelParams;
+      return true;
+    }
+
+    internal void InstallModels(IReadOnlyList<int> rows, IRandom random, IDataset data, ILeafType<IRegressionModel> leafType, CancellationToken cancellation) {
+      if (!IsLeaf) {
+        IReadOnlyList<int> leftRows, rightRows;
+        SplitRows(rows, data, SplitAttr, SplitValue, out leftRows, out rightRows);
+        Left.InstallModels(leftRows, random, data, leafType, cancellation);
+        Right.InstallModels(rightRows, random, data, leafType, cancellation);
+        return;
+      }
+      BuildModel(rows, data, random, leafType, cancellation);
+    }
+
+    internal IEnumerable<M5NodeModel> EnumerateNodes() {
+      var queue = new Queue<M5NodeModel>();
+      queue.Enqueue(this);
+      while (queue.Count != 0) {
+        var cur = queue.Dequeue();
+        yield return cur;
+        if (cur.Left == null && cur.Right == null) continue;
+        if (cur.Left != null) queue.Enqueue(cur.Left);
+        if (cur.Right != null) queue.Enqueue(cur.Right);
+      }
+    }
+
+    internal void ToRuleNode() {
+      Parent = null;
+    }
+
+    #region Helpers
+    private double GetEstimatedValue(IDataset dataset, int row) {
+      if (!IsLeaf) return (dataset.GetDoubleValue(SplitAttr, row) <= SplitValue ? Left : Right).GetEstimatedValue(dataset, row);
+      if (NodeModel == null) throw new NotSupportedException("M5P has not been built correctly");
+      return NodeModel.GetEstimatedValues(dataset, new[] {row}).First();
+    }
+
+    private void BuildModel(IReadOnlyList<int> rows, IDataset data, IRandom random, ILeafType<IRegressionModel> leafType, CancellationToken cancellation) {
+      var reducedData = new Dataset(VariablesUsedForPrediction.Concat(new[] {TargetVariable}), VariablesUsedForPrediction.Concat(new[] {TargetVariable}).Select(x => data.GetDoubleValues(x, rows).ToList()));
+      var pd = new RegressionProblemData(reducedData, VariablesUsedForPrediction, TargetVariable);
+      pd.TrainingPartition.Start = 0;
+      pd.TrainingPartition.End = pd.TestPartition.Start = pd.TestPartition.End = reducedData.Rows;
+
+      int noparams;
+      NodeModel = leafType.BuildModel(pd, random, cancellation, out noparams);
+      NodeModelParams = noparams;
+      cancellation.ThrowIfCancellationRequested();
+    }
+
+    private static void SplitRows(IReadOnlyList<int> rows, IDataset data, string splitAttr, double splitValue, out IReadOnlyList<int> leftRows, out IReadOnlyList<int> rightRows) {
+      var assignment = data.GetDoubleValues(splitAttr, rows).Select(x => x <= splitValue).ToArray();
+      leftRows = rows.Zip(assignment, (i, b) => new {i, b}).Where(x => x.b).Select(x => x.i).ToList();
+      rightRows = rows.Zip(assignment, (i, b) => new {i, b}).Where(x => !x.b).Select(x => x.i).ToList();
+    }
+    #endregion
+
+    [StorableClass]
+    private sealed class ConfidenceM5NodeModel : M5NodeModel, IConfidenceRegressionModel {
+      #region HLConstructors
+      [StorableConstructor]
+      private ConfidenceM5NodeModel(bool deserializing) : base(deserializing) { }
+      private ConfidenceM5NodeModel(ConfidenceM5NodeModel original, Cloner cloner) : base(original, cloner) { }
+      public ConfidenceM5NodeModel(string targetAttr) : base(targetAttr) { }
+      public ConfidenceM5NodeModel(M5NodeModel parent) : base(parent) { }
+      public override IDeepCloneable Clone(Cloner cloner) {
+        return new ConfidenceM5NodeModel(this, cloner);
+      }
+      #endregion
+
+      public IEnumerable<double> GetEstimatedVariances(IDataset dataset, IEnumerable<int> rows) {
+        return IsLeaf ? ((IConfidenceRegressionModel) NodeModel).GetEstimatedVariances(dataset, rows) : rows.Select(row => GetEstimatedVariance(dataset, row));
+      }
+
+      private double GetEstimatedVariance(IDataset dataset, int row) {
+        if (!IsLeaf)
+          return ((IConfidenceRegressionModel) (dataset.GetDoubleValue(SplitAttr, row) <= SplitValue ? Left : Right)).GetEstimatedVariances(dataset, row.ToEnumerable()).Single();
+        return ((IConfidenceRegressionModel) NodeModel).GetEstimatedVariances(dataset, new[] {row}).First();
+      }
+
+      public override IRegressionSolution CreateRegressionSolution(IRegressionProblemData problemData) {
+        return new ConfidenceRegressionSolution(this, problemData);
+      }
+    }
+  }
+}
Index: branches/M5Regression/HeuristicLab.Algorithms.DataAnalysis/3.4/M5Regression/MetaModels/M5RuleModel.cs
===================================================================
--- branches/M5Regression/HeuristicLab.Algorithms.DataAnalysis/3.4/M5Regression/MetaModels/M5RuleModel.cs	(revision 15430)
+++ branches/M5Regression/HeuristicLab.Algorithms.DataAnalysis/3.4/M5Regression/MetaModels/M5RuleModel.cs	(revision 15430)
@@ -0,0 +1,189 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2017 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 <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading;
+using HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+using HeuristicLab.Problems.DataAnalysis;
+
+namespace HeuristicLab.Algorithms.DataAnalysis {
+  [StorableClass]
+  internal class M5RuleModel : RegressionModel, IM5MetaModel {
+    internal const string NoCurrentLeafesResultName = "Number of current Leafs";
+
+    #region Properties
+    [Storable]
+    internal string[] SplitAtts { get; private set; }
+    [Storable]
+    private double[] SplitVals { get; set; }
+    [Storable]
+    private RelOp[] RelOps { get; set; }
+    [Storable]
+    protected IRegressionModel RuleModel { get; set; }
+    [Storable]
+    private IReadOnlyList<string> Variables { get; set; }
+    #endregion
+
+    #region HLConstructors
+    [StorableConstructor]
+    protected M5RuleModel(bool deserializing) : base(deserializing) { }
+    protected M5RuleModel(M5RuleModel original, Cloner cloner) : base(original, cloner) {
+      if (original.SplitAtts != null) SplitAtts = original.SplitAtts.ToArray();
+      if (original.SplitVals != null) SplitVals = original.SplitVals.ToArray();
+      if (original.RelOps != null) RelOps = original.RelOps.ToArray();
+      RuleModel = cloner.Clone(original.RuleModel);
+      if (original.Variables != null) Variables = original.Variables.ToList();
+    }
+    private M5RuleModel(string target) : base(target) { }
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new M5RuleModel(this, cloner);
+    }
+    #endregion
+
+    internal static M5RuleModel CreateRuleModel(string target, M5CreationParameters m5CreationParams) {
+      return m5CreationParams.LeafType is ILeafType<IConfidenceRegressionModel> ? new ConfidenceM5RuleModel(target) : new M5RuleModel(target);
+    }
+
+    #region IRegressionModel
+    public override IEnumerable<string> VariablesUsedForPrediction {
+      get { return Variables; }
+    }
+
+    public override IEnumerable<double> GetEstimatedValues(IDataset dataset, IEnumerable<int> rows) {
+      if (RuleModel == null) throw new NotSupportedException("M5P has not been built correctly");
+      return RuleModel.GetEstimatedValues(dataset, rows);
+    }
+
+    public override IRegressionSolution CreateRegressionSolution(IRegressionProblemData problemData) {
+      return new RegressionSolution(this, problemData);
+    }
+    #endregion
+
+    #region IM5Component
+    public void BuildClassifier(IReadOnlyList<int> trainingRows, IReadOnlyList<int> holdoutRows, M5CreationParameters m5CreationParams, CancellationToken cancellation) {
+      Variables = m5CreationParams.AllowedInputVariables.ToList();
+      var tree = M5TreeModel.CreateTreeModel(m5CreationParams.TargetVariable, m5CreationParams);
+      ((IM5MetaModel) tree).BuildClassifier(trainingRows, holdoutRows, m5CreationParams, cancellation);
+      var nodeModel = tree.Root.EnumerateNodes().Where(x => x.IsLeaf).MaxItems(x => x.NumSamples).First();
+
+      var satts = new List<string>();
+      var svals = new List<double>();
+      var reops = new List<RelOp>();
+
+      //extract Splits
+      for (var temp = nodeModel; temp.Parent != null; temp = temp.Parent) {
+        satts.Add(temp.Parent.SplitAttr);
+        svals.Add(temp.Parent.SplitValue);
+        reops.Add(temp.Parent.Left == temp ? RelOp.Lessequal : RelOp.Greater);
+      }
+      nodeModel.ToRuleNode();
+      RuleModel = nodeModel.NodeModel;
+      RelOps = reops.ToArray();
+      SplitAtts = satts.ToArray();
+      SplitVals = svals.ToArray();
+    }
+
+    public void UpdateModel(IReadOnlyList<int> rows, M5UpdateParameters m5UpdateParameters, CancellationToken cancellation) {
+      BuildModel(rows, m5UpdateParameters.Random, m5UpdateParameters.Data, m5UpdateParameters.LeafType, cancellation);
+    }
+    #endregion
+
+    public bool Covers(IDataset dataset, int row) {
+      return !SplitAtts.Where((t, i) => !RelOps[i].Compare(dataset.GetDoubleValue(t, row), SplitVals[i])).Any();
+    }
+
+    public string ToCompactString() {
+      var mins = new Dictionary<string, double>();
+      var maxs = new Dictionary<string, double>();
+      for (var i = 0; i < SplitAtts.Length; i++) {
+        var n = SplitAtts[i];
+        var v = SplitVals[i];
+        if (!mins.ContainsKey(n)) mins.Add(n, double.NegativeInfinity);
+        if (!maxs.ContainsKey(n)) maxs.Add(n, double.PositiveInfinity);
+        if (RelOps[i] == RelOp.Lessequal) maxs[n] = Math.Min(maxs[n], v);
+        else mins[n] = Math.Max(mins[n], v);
+      }
+      if (maxs.Count == 0) return "";
+      var s = new StringBuilder();
+      foreach (var key in maxs.Keys)
+        s.Append(string.Format("{0} ∈ [{1:e2}; {2:e2}] && ", key, mins[key], maxs[key]));
+      s.Remove(s.Length - 4, 4);
+      return s.ToString();
+    }
+
+    #region Helpers
+    private void BuildModel(IReadOnlyList<int> rows, IRandom random, IDataset data, ILeafType<IRegressionModel> leafType, CancellationToken cancellation) {
+      var reducedData = new Dataset(VariablesUsedForPrediction.Concat(new[] {TargetVariable}), VariablesUsedForPrediction.Concat(new[] {TargetVariable}).Select(x => data.GetDoubleValues(x, rows).ToList()));
+      var pd = new RegressionProblemData(reducedData, VariablesUsedForPrediction, TargetVariable);
+      pd.TrainingPartition.Start = 0;
+      pd.TrainingPartition.End = pd.TestPartition.Start = pd.TestPartition.End = reducedData.Rows;
+
+      int noparams;
+      RuleModel = leafType.BuildModel(pd, random, cancellation, out noparams);
+      cancellation.ThrowIfCancellationRequested();
+    }
+    #endregion
+
+    [StorableClass]
+    private sealed class ConfidenceM5RuleModel : M5RuleModel, IConfidenceRegressionModel {
+      #region HLConstructors
+      [StorableConstructor]
+      private ConfidenceM5RuleModel(bool deserializing) : base(deserializing) { }
+      private ConfidenceM5RuleModel(ConfidenceM5RuleModel original, Cloner cloner) : base(original, cloner) { }
+      public ConfidenceM5RuleModel(string targetAttr) : base(targetAttr) { }
+      public override IDeepCloneable Clone(Cloner cloner) {
+        return new ConfidenceM5RuleModel(this, cloner);
+      }
+      #endregion
+
+      public IEnumerable<double> GetEstimatedVariances(IDataset dataset, IEnumerable<int> rows) {
+        return ((IConfidenceRegressionModel) RuleModel).GetEstimatedVariances(dataset, rows);
+      }
+
+      public override IRegressionSolution CreateRegressionSolution(IRegressionProblemData problemData) {
+        return new ConfidenceRegressionSolution(this, problemData);
+      }
+    }
+  }
+
+  internal enum RelOp {
+    Lessequal,
+    Greater
+  }
+
+  internal static class RelOpExtentions {
+    public static bool Compare(this RelOp op, double x, double y) {
+      switch (op) {
+        case RelOp.Greater:
+          return x > y;
+        case RelOp.Lessequal:
+          return x <= y;
+        default:
+          throw new ArgumentOutOfRangeException(op.ToString(), op, null);
+      }
+    }
+  }
+}
Index: branches/M5Regression/HeuristicLab.Algorithms.DataAnalysis/3.4/M5Regression/MetaModels/M5RuleSetModel.cs
===================================================================
--- branches/M5Regression/HeuristicLab.Algorithms.DataAnalysis/3.4/M5Regression/MetaModels/M5RuleSetModel.cs	(revision 15430)
+++ branches/M5Regression/HeuristicLab.Algorithms.DataAnalysis/3.4/M5Regression/MetaModels/M5RuleSetModel.cs	(revision 15430)
@@ -0,0 +1,143 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2017 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 <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Threading;
+using HeuristicLab.Common;
+using HeuristicLab.Data;
+using HeuristicLab.Optimization;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+using HeuristicLab.Problems.DataAnalysis;
+
+namespace HeuristicLab.Algorithms.DataAnalysis {
+  [StorableClass]
+  public class M5RuleSetModel : RegressionModel, IM5MetaModel {
+    private const string NoRulesResultName = "Number of Rules";
+    private const string CoveredInstancesResultName = "Covered Instances";
+
+    #region Properties
+    [Storable]
+    internal List<M5RuleModel> Rules { get; private set; }
+    #endregion
+
+    #region HLConstructors & Cloning
+    [StorableConstructor]
+    protected M5RuleSetModel(bool deserializing) : base(deserializing) { }
+    protected M5RuleSetModel(M5RuleSetModel original, Cloner cloner) : base(original, cloner) {
+      if (original.Rules != null) Rules = original.Rules.Select(cloner.Clone).ToList();
+    }
+    protected M5RuleSetModel(string targetVariable) : base(targetVariable) { }
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new M5RuleSetModel(this, cloner);
+    }
+    #endregion
+
+    internal static M5RuleSetModel CreateRuleModel(string targetAttr, M5CreationParameters m5CreationParams) {
+      return m5CreationParams.LeafType is ILeafType<IConfidenceRegressionModel> ? new ConfidenceM5RuleSetModel(targetAttr) : new M5RuleSetModel(targetAttr);
+    }
+
+    #region RegressionModel
+    public override IEnumerable<string> VariablesUsedForPrediction {
+      get {
+        var f = Rules.FirstOrDefault();
+        return f != null ? (f.VariablesUsedForPrediction ?? new List<string>()) : new List<string>();
+      }
+    }
+    public override IEnumerable<double> GetEstimatedValues(IDataset dataset, IEnumerable<int> rows) {
+      if (Rules == null) throw new NotSupportedException("The classifier has not been built yet");
+      return rows.Select(row => GetEstimatedValue(dataset, row));
+    }
+    public override IRegressionSolution CreateRegressionSolution(IRegressionProblemData problemData) {
+      return new RegressionSolution(this, problemData);
+    }
+    #endregion
+
+    #region IM5Component
+    void IM5MetaModel.BuildClassifier(IReadOnlyList<int> trainingRows, IReadOnlyList<int> holdoutRows, M5CreationParameters m5CreationParams, CancellationToken cancellation) {
+      Rules = new List<M5RuleModel>();
+      var tempTraining = trainingRows;
+      var tempHoldout = holdoutRows;
+      do {
+        var tempRule = M5RuleModel.CreateRuleModel(m5CreationParams.TargetVariable, m5CreationParams);
+        cancellation.ThrowIfCancellationRequested();
+
+        if (!m5CreationParams.Results.ContainsKey(NoRulesResultName)) m5CreationParams.Results.Add(new Result(NoRulesResultName, new IntValue(0)));
+        if (!m5CreationParams.Results.ContainsKey(CoveredInstancesResultName)) m5CreationParams.Results.Add(new Result(CoveredInstancesResultName, new IntValue(0)));
+
+        var t1 = tempTraining.Count;
+        tempRule.BuildClassifier(tempTraining, tempHoldout, m5CreationParams, cancellation);
+        tempTraining = tempTraining.Where(i => !tempRule.Covers(m5CreationParams.Data, i)).ToArray();
+        tempHoldout = tempHoldout.Where(i => !tempRule.Covers(m5CreationParams.Data, i)).ToArray();
+        Rules.Add(tempRule);
+        ((IntValue) m5CreationParams.Results[NoRulesResultName].Value).Value++;
+        ((IntValue) m5CreationParams.Results[CoveredInstancesResultName].Value).Value += t1 - tempTraining.Count;
+      }
+      while (tempTraining.Count > 0);
+    }
+
+    void IM5MetaModel.UpdateModel(IReadOnlyList<int> rows, M5UpdateParameters m5UpdateParameters, CancellationToken cancellation) {
+      foreach (var rule in Rules) rule.UpdateModel(rows, m5UpdateParameters, cancellation);
+    }
+    #endregion
+
+    #region Helpers
+    private double GetEstimatedValue(IDataset dataset, int row) {
+      foreach (var rule in Rules) {
+        var prediction = rule.GetEstimatedValues(dataset, row.ToEnumerable()).Single();
+        if (rule.Covers(dataset, row)) return prediction;
+      }
+      throw new ArgumentException("Instance is not covered by any rule");
+    }
+    #endregion
+
+    [StorableClass]
+    private class ConfidenceM5RuleSetModel : M5RuleSetModel, IConfidenceRegressionModel {
+      #region HLConstructors & Cloning
+      [StorableConstructor]
+      protected ConfidenceM5RuleSetModel(bool deserializing) : base(deserializing) { }
+      private ConfidenceM5RuleSetModel(ConfidenceM5RuleSetModel original, Cloner cloner) : base(original, cloner) { }
+      public ConfidenceM5RuleSetModel(string targetVariable) : base(targetVariable) { }
+      public override IDeepCloneable Clone(Cloner cloner) {
+        return new ConfidenceM5RuleSetModel(this, cloner);
+      }
+      #endregion
+
+      #region IConfidenceRegressionModel
+      public IEnumerable<double> GetEstimatedVariances(IDataset dataset, IEnumerable<int> rows) {
+        if (Rules == null) throw new NotSupportedException("The classifier has not been built yet");
+        return rows.Select(row => GetEstimatedVariance(dataset, row));
+      }
+      public override IRegressionSolution CreateRegressionSolution(IRegressionProblemData problemData) {
+        return new ConfidenceRegressionSolution(this, problemData);
+      }
+      private double GetEstimatedVariance(IDataset dataset, int row) {
+        foreach (var rule in Rules) {
+          var prediction = ((IConfidenceRegressionModel) rule).GetEstimatedVariances(dataset, row.ToEnumerable()).Single();
+          if (rule.Covers(dataset, row)) return prediction;
+        }
+        throw new ArgumentException("Instance is not covered by any rule");
+      }
+      #endregion
+    }
+  }
+}
Index: branches/M5Regression/HeuristicLab.Algorithms.DataAnalysis/3.4/M5Regression/MetaModels/M5TreeModel.cs
===================================================================
--- branches/M5Regression/HeuristicLab.Algorithms.DataAnalysis/3.4/M5Regression/MetaModels/M5TreeModel.cs	(revision 15430)
+++ branches/M5Regression/HeuristicLab.Algorithms.DataAnalysis/3.4/M5Regression/MetaModels/M5TreeModel.cs	(revision 15430)
@@ -0,0 +1,117 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2017 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 <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Threading;
+using HeuristicLab.Common;
+using HeuristicLab.Data;
+using HeuristicLab.Optimization;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+using HeuristicLab.Problems.DataAnalysis;
+
+namespace HeuristicLab.Algorithms.DataAnalysis {
+  [StorableClass]
+  public class M5TreeModel : RegressionModel, IM5MetaModel {
+    private const string NoCurrentLeafesResultName = "Number of current Leafs";
+    #region Properties
+    [Storable]
+    internal M5NodeModel Root { get; private set; }
+    //[Storable]
+    //private M5Parameters M5Params { get; set; }
+    #endregion
+
+    #region HLConstructors & Cloning
+    [StorableConstructor]
+    protected M5TreeModel(bool deserializing) : base(deserializing) { }
+    protected M5TreeModel(M5TreeModel original, Cloner cloner) : base(original, cloner) {
+      Root = cloner.Clone(original.Root);
+    }
+    protected M5TreeModel(string targetVariable) : base(targetVariable) { }
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new M5TreeModel(this, cloner);
+    }
+    #endregion
+
+    internal static M5TreeModel CreateTreeModel(string targetAttr, M5CreationParameters m5CreationParams) {
+      return m5CreationParams.LeafType is ILeafType<IConfidenceRegressionModel> ? new ConfidenceM5TreeModel(targetAttr) : new M5TreeModel(targetAttr);
+    }
+
+    #region RegressionModel
+    public override IEnumerable<string> VariablesUsedForPrediction {
+      get { return Root.VariablesUsedForPrediction ?? new List<string>(); }
+    }
+    public override IEnumerable<double> GetEstimatedValues(IDataset dataset, IEnumerable<int> rows) {
+      if (Root == null) throw new NotSupportedException("The classifier has not been built yet");
+      return Root.GetEstimatedValues(dataset, rows);
+    }
+    public override IRegressionSolution CreateRegressionSolution(IRegressionProblemData problemData) {
+      return new RegressionSolution(this, problemData);
+    }
+    #endregion
+
+    #region IM5Component
+    void IM5MetaModel.BuildClassifier(IReadOnlyList<int> trainingRows, IReadOnlyList<int> holdoutRows, M5CreationParameters m5CreationParams, CancellationToken cancellation) {
+      Root = null;
+      var globalStdDev = m5CreationParams.Data.GetDoubleValues(m5CreationParams.TargetVariable, trainingRows).StandardDeviationPop();
+      Root = M5NodeModel.CreateNode(m5CreationParams.TargetVariable, m5CreationParams);
+      Root.Split(trainingRows, m5CreationParams, globalStdDev);
+      InitializeLeafCounter(m5CreationParams);
+      if (!(m5CreationParams.Pruningtype is NoPruning)) Root.Prune(trainingRows, holdoutRows, m5CreationParams, cancellation, globalStdDev);
+      Root.InstallModels(trainingRows.Union(holdoutRows).ToArray(), m5CreationParams.Random, m5CreationParams.Data, m5CreationParams.LeafType, cancellation);
+    }
+
+    void IM5MetaModel.UpdateModel(IReadOnlyList<int> rows, M5UpdateParameters m5UpdateParameters, CancellationToken cancellation) {
+      Root.InstallModels(rows, m5UpdateParameters.Random, m5UpdateParameters.Data, m5UpdateParameters.LeafType, cancellation);
+    }
+    #endregion
+
+    #region Helpers
+    private void InitializeLeafCounter(M5CreationParameters m5CreationParams) {
+      if (!m5CreationParams.Results.ContainsKey(NoCurrentLeafesResultName))
+        m5CreationParams.Results.Add(new Result(NoCurrentLeafesResultName, new IntValue(Root.EnumerateNodes().Count(x => x.IsLeaf))));
+      else ((IntValue) m5CreationParams.Results[NoCurrentLeafesResultName].Value).Value = Root.EnumerateNodes().Count(x => x.IsLeaf);
+    }
+    #endregion
+
+    [StorableClass]
+    private class ConfidenceM5TreeModel : M5TreeModel, IConfidenceRegressionModel {
+      #region HLConstructors & Cloning
+      [StorableConstructor]
+      protected ConfidenceM5TreeModel(bool deserializing) : base(deserializing) { }
+      private ConfidenceM5TreeModel(ConfidenceM5TreeModel original, Cloner cloner) : base(original, cloner) { }
+      public ConfidenceM5TreeModel(string targetVariable) : base(targetVariable) { }
+      public override IDeepCloneable Clone(Cloner cloner) {
+        return new ConfidenceM5TreeModel(this, cloner);
+      }
+      #endregion
+
+      public IEnumerable<double> GetEstimatedVariances(IDataset dataset, IEnumerable<int> rows) {
+        if (Root == null) throw new NotSupportedException("The classifier has not been built yet");
+        return ((IConfidenceRegressionModel) Root).GetEstimatedVariances(dataset, rows);
+      }
+      public override IRegressionSolution CreateRegressionSolution(IRegressionProblemData problemData) {
+        return new ConfidenceRegressionSolution(this, problemData);
+      }
+    }
+  }
+}
Index: branches/M5Regression/HeuristicLab.Algorithms.DataAnalysis/3.4/M5Regression/MetaModels/PreconstructedLinearModel.cs
===================================================================
--- branches/M5Regression/HeuristicLab.Algorithms.DataAnalysis/3.4/M5Regression/MetaModels/PreconstructedLinearModel.cs	(revision 15430)
+++ branches/M5Regression/HeuristicLab.Algorithms.DataAnalysis/3.4/M5Regression/MetaModels/PreconstructedLinearModel.cs	(revision 15430)
@@ -0,0 +1,124 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2017 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 <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using HeuristicLab.Common;
+using HeuristicLab.Encodings.SymbolicExpressionTreeEncoding;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+using HeuristicLab.Problems.DataAnalysis;
+using HeuristicLab.Problems.DataAnalysis.Symbolic;
+using HeuristicLab.Problems.DataAnalysis.Symbolic.Regression;
+
+namespace HeuristicLab.Algorithms.DataAnalysis {
+  //mulitdimensional extension of http://www2.stat.duke.edu/~tjl13/s101/slides/unit6lec3H.pdf
+  [StorableClass]
+  internal sealed class PreconstructedLinearModel : RegressionModel, IConfidenceRegressionModel {
+    [Storable]
+    public Dictionary<string, double> Coefficients { get; private set; }
+    [Storable]
+    public double Intercept { get; private set; }
+    [Storable]
+    private Dictionary<string, double> Center { get; set; }
+    [Storable]
+    private Dictionary<string, double> Variances { get; set; }
+    [Storable]
+    private double ResidualVariance { get; set; }
+    [Storable]
+    private int SampleSize { get; set; }
+
+    public override IEnumerable<string> VariablesUsedForPrediction {
+      get { return Coefficients.Keys; }
+    }
+    #region HLConstructors
+    [StorableConstructor]
+    private PreconstructedLinearModel(bool deserializing) : base(deserializing) { }
+    private PreconstructedLinearModel(PreconstructedLinearModel original, Cloner cloner) : base(original, cloner) {
+      if (original.Coefficients != null) Coefficients = original.Coefficients.ToDictionary(x => x.Key, x => x.Value);
+      Intercept = original.Intercept;
+      if (original.Center != null) Center = original.Center.ToDictionary(x => x.Key, x => x.Value);
+      if (original.Variances != null) Variances = original.Variances.ToDictionary(x => x.Key, x => x.Value);
+      ResidualVariance = original.ResidualVariance;
+      SampleSize = original.SampleSize;
+    }
+    private PreconstructedLinearModel(Dictionary<string, double> coefficients, double intercept, string targetvariable) : base(targetvariable) {
+      Coefficients = coefficients.ToDictionary(x => x.Key, x => x.Value);
+      Intercept = intercept;
+      Variances = new Dictionary<string, double>();
+      ResidualVariance = 0;
+      SampleSize = 0;
+    }
+    public PreconstructedLinearModel(double intercept, string targetvariable) : base(targetvariable) {
+      Coefficients = new Dictionary<string, double>();
+      Intercept = intercept;
+      Variances = new Dictionary<string, double>();
+      ResidualVariance = 0;
+      SampleSize = 0;
+    }
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new PreconstructedLinearModel(this, cloner);
+    }
+    #endregion
+
+    public static PreconstructedLinearModel CreateConfidenceLinearModel(IRegressionProblemData pd, out double rmse, out double cvRmse) {
+      var inputMatrix = pd.Dataset.ToArray(pd.AllowedInputVariables.Concat(new[] {pd.TargetVariable}), pd.AllIndices);
+      alglib.linearmodel lm;
+      alglib.lrreport ar;
+      var nFeatures = inputMatrix.GetLength(1) - 1;
+      double[] coefficients; // last coefficient is for the constant
+
+      int retVal;
+      alglib.lrbuild(inputMatrix, inputMatrix.GetLength(0), nFeatures, out retVal, out lm, out ar);
+      if (retVal != 1)
+        throw new ArgumentException("Error in calculation of linear regression solution");
+      rmse = ar.rmserror;
+      cvRmse = ar.cvrmserror;
+
+      alglib.lrunpack(lm, out coefficients, out nFeatures);
+      return new PreconstructedLinearModel(pd.AllowedInputVariables.Zip(coefficients, (s, d) => new {s, d}).ToDictionary(x => x.s, x => x.d), coefficients[nFeatures], pd.TargetVariable);
+    }
+
+
+    public override IEnumerable<double> GetEstimatedValues(IDataset dataset, IEnumerable<int> rows) {
+      return rows.Select(row => GetEstimatedValue(dataset, row));
+    }
+
+    public override IRegressionSolution CreateRegressionSolution(IRegressionProblemData problemData) {
+      return new RegressionSolution(this, problemData);
+    }
+
+    public IEnumerable<double> GetEstimatedVariances(IDataset dataset, IEnumerable<int> rows) {
+      return rows.Select(i => GetEstimatedVariance(dataset, i));
+    }
+
+    #region helpers
+    private double GetEstimatedValue(IDataset dataset, int row) {
+      return Intercept + (Coefficients.Count == 0 ? 0 : Coefficients.Sum(s => s.Value * dataset.GetDoubleValue(s.Key, row)));
+    }
+    private double GetEstimatedVariance(IDataset dataset, int row) {
+      if (SampleSize == 0) return 0.0;
+      var sum = (from var in Variances let d = dataset.GetDoubleValue(var.Key, row) - Center[var.Key] select d * d / var.Value).Sum();
+      return ResidualVariance * (1.0 / SampleSize + sum / (SampleSize - 1));
+    }
+    #endregion
+  }
+}
Index: branches/M5Regression/HeuristicLab.Algorithms.DataAnalysis/3.4/M5Regression/Pruning/HoldoutLeafPruning.cs
===================================================================
--- branches/M5Regression/HeuristicLab.Algorithms.DataAnalysis/3.4/M5Regression/Pruning/HoldoutLeafPruning.cs	(revision 15430)
+++ branches/M5Regression/HeuristicLab.Algorithms.DataAnalysis/3.4/M5Regression/Pruning/HoldoutLeafPruning.cs	(revision 15430)
@@ -0,0 +1,67 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2017 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 <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System.Collections.Generic;
+using HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Data;
+using HeuristicLab.Parameters;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+using HeuristicLab.Problems.DataAnalysis;
+
+namespace HeuristicLab.Algorithms.DataAnalysis {
+  [StorableClass]
+  [Item("HoldoutLeafPruning", "Postpruning via a holdout set")]
+  public class HoldoutLeafPruning : PruningBase {
+    private const string HoldoutSizeParameterName = "HoldoutSize";
+    public IFixedValueParameter<PercentValue> HoldoutSizeParameter {
+      get { return Parameters[HoldoutSizeParameterName] as IFixedValueParameter<PercentValue>; }
+    }
+    public double HoldoutSize {
+      get { return HoldoutSizeParameter.Value.Value; }
+    }
+
+    #region Constructors & Cloning
+    [StorableConstructor]
+    protected HoldoutLeafPruning(bool deserializing) : base(deserializing) { }
+    protected HoldoutLeafPruning(HoldoutLeafPruning original, Cloner cloner) : base(original, cloner) { }
+    public HoldoutLeafPruning() : base() {
+      Parameters.Add(new FixedValueParameter<PercentValue>(HoldoutSizeParameterName, new PercentValue(0.2)));
+    }
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new HoldoutLeafPruning(this, cloner);
+    }
+    #endregion
+
+    #region PruningType
+    public override ILeafType<IRegressionModel> ModelType(ILeafType<IRegressionModel> leafType) {
+      return leafType;
+    }
+
+    public override void GenerateHoldOutSet(IReadOnlyList<int> allrows, IRandom random, out IReadOnlyList<int> training, out IReadOnlyList<int> holdout) {
+      training = new List<int>();
+      holdout = new List<int>();
+      foreach (var row in allrows)
+        ((List<int>) (random.NextDouble() < HoldoutSize ? holdout : training)).Add(row);
+    }
+    #endregion
+  }
+}
Index: branches/M5Regression/HeuristicLab.Algorithms.DataAnalysis/3.4/M5Regression/Pruning/HoldoutLinearPruning.cs
===================================================================
--- branches/M5Regression/HeuristicLab.Algorithms.DataAnalysis/3.4/M5Regression/Pruning/HoldoutLinearPruning.cs	(revision 15430)
+++ branches/M5Regression/HeuristicLab.Algorithms.DataAnalysis/3.4/M5Regression/Pruning/HoldoutLinearPruning.cs	(revision 15430)
@@ -0,0 +1,47 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2017 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 <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+using HeuristicLab.Problems.DataAnalysis;
+
+namespace HeuristicLab.Algorithms.DataAnalysis {
+  [StorableClass]
+  [Item("HoldoutLinearPruning", "Postpruning via a holdout set using cheap linear models")]
+  public class HoldoutLinearPruning : HoldoutLeafPruning {
+    #region Constructors & Cloning
+    [StorableConstructor]
+    protected HoldoutLinearPruning(bool deserializing) : base(deserializing) { }
+    protected HoldoutLinearPruning(HoldoutLinearPruning original, Cloner cloner) : base(original, cloner) { }
+    public HoldoutLinearPruning() : base() { }
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new HoldoutLinearPruning(this, cloner);
+    }
+    #endregion
+
+    #region IPruningType
+    public override ILeafType<IRegressionModel> ModelType(ILeafType<IRegressionModel> leafType) {
+      return new LinearLeaf();
+    }
+    #endregion
+  }
+}
Index: branches/M5Regression/HeuristicLab.Algorithms.DataAnalysis/3.4/M5Regression/Pruning/M5LeafPruning.cs
===================================================================
--- branches/M5Regression/HeuristicLab.Algorithms.DataAnalysis/3.4/M5Regression/Pruning/M5LeafPruning.cs	(revision 15430)
+++ branches/M5Regression/HeuristicLab.Algorithms.DataAnalysis/3.4/M5Regression/Pruning/M5LeafPruning.cs	(revision 15430)
@@ -0,0 +1,73 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2017 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 <http://www.gnu.org/licenses/>.
+ */
+#endregion
+#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2017 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 <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System.Collections.Generic;
+using HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+using HeuristicLab.Problems.DataAnalysis;
+
+namespace HeuristicLab.Algorithms.DataAnalysis {
+  [StorableClass]
+  [Item("M5LeafPruning", "M5LeafPruning using the leaf models. Effects vary with the overfitting capability of the leaf model")]
+  public class M5LeafPruning : PruningBase {
+    #region Constructors & Cloning
+    [StorableConstructor]
+    private M5LeafPruning(bool deserializing) : base(deserializing) { }
+    private M5LeafPruning(M5LeafPruning original, Cloner cloner) : base(original, cloner) { }
+    public M5LeafPruning() : base() { }
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new M5LeafPruning(this, cloner);
+    }
+    #endregion
+
+    #region IPruningType
+    public override ILeafType<IRegressionModel> ModelType(ILeafType<IRegressionModel> leafType) {
+      return leafType;
+    }
+
+    public override void GenerateHoldOutSet(IReadOnlyList<int> allrows, IRandom random, out IReadOnlyList<int> training, out IReadOnlyList<int> holdout) {
+      training = allrows;
+      holdout = allrows;
+    }
+    #endregion
+  }
+}
Index: branches/M5Regression/HeuristicLab.Algorithms.DataAnalysis/3.4/M5Regression/Pruning/M5LinearPruning.cs
===================================================================
--- branches/M5Regression/HeuristicLab.Algorithms.DataAnalysis/3.4/M5Regression/Pruning/M5LinearPruning.cs	(revision 15430)
+++ branches/M5Regression/HeuristicLab.Algorithms.DataAnalysis/3.4/M5Regression/Pruning/M5LinearPruning.cs	(revision 15430)
@@ -0,0 +1,53 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2017 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 <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System.Collections.Generic;
+using HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+using HeuristicLab.Problems.DataAnalysis;
+
+namespace HeuristicLab.Algorithms.DataAnalysis {
+  [StorableClass]
+  [Item("M5LinearPruning", "M5Pruning using cheap linear models. This is standard for M5' regression")]
+  public class M5LinearPruning : PruningBase {
+    #region Constructors & Cloning
+    [StorableConstructor]
+    private M5LinearPruning(bool deserializing) : base(deserializing) { }
+    private M5LinearPruning(M5LinearPruning original, Cloner cloner) : base(original, cloner) { }
+    public M5LinearPruning() : base() { }
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new M5LinearPruning(this, cloner);
+    }
+    #endregion
+
+    #region IPruningType
+    public override ILeafType<IRegressionModel> ModelType(ILeafType<IRegressionModel> leafType) {
+      return new LinearLeaf();
+    }
+
+    public override void GenerateHoldOutSet(IReadOnlyList<int> allrows, IRandom random, out IReadOnlyList<int> training, out IReadOnlyList<int> holdout) {
+      training = allrows;
+      holdout = allrows;
+    }
+    #endregion
+  }
+}
Index: branches/M5Regression/HeuristicLab.Algorithms.DataAnalysis/3.4/M5Regression/Pruning/NoPruning.cs
===================================================================
--- branches/M5Regression/HeuristicLab.Algorithms.DataAnalysis/3.4/M5Regression/Pruning/NoPruning.cs	(revision 15430)
+++ branches/M5Regression/HeuristicLab.Algorithms.DataAnalysis/3.4/M5Regression/Pruning/NoPruning.cs	(revision 15430)
@@ -0,0 +1,56 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2017 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 <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System.Collections.Generic;
+using HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+using HeuristicLab.Problems.DataAnalysis;
+
+namespace HeuristicLab.Algorithms.DataAnalysis {
+  [StorableClass]
+  [Item("NoPruning", "No pruning")]
+  public class NoPruning : PruningBase {
+    #region Constructors & Cloning
+    [StorableConstructor]
+    private NoPruning(bool deserializing) : base(deserializing) { }
+    private NoPruning(NoPruning original, Cloner cloner) : base(original, cloner) { }
+    public NoPruning() : base() { }
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new NoPruning(this, cloner);
+    }
+    #endregion
+
+    #region IPruningType
+    public override ILeafType<IRegressionModel> ModelType(ILeafType<IRegressionModel> leafType) {
+      return null;
+    }
+
+    public override void GenerateHoldOutSet(IReadOnlyList<int> allrows, IRandom random, out IReadOnlyList<int> training, out IReadOnlyList<int> holdout) {
+      training = allrows;
+      holdout = allrows;
+    }
+    internal override bool Prune(M5NodeModel node, M5CreationParameters m5CreationParams, IReadOnlyList<int> testRows, double globalStdDev) {
+      return false;
+    }
+    #endregion
+  }
+}
Index: branches/M5Regression/HeuristicLab.Algorithms.DataAnalysis/3.4/M5Regression/Pruning/PruningBase.cs
===================================================================
--- branches/M5Regression/HeuristicLab.Algorithms.DataAnalysis/3.4/M5Regression/Pruning/PruningBase.cs	(revision 15430)
+++ branches/M5Regression/HeuristicLab.Algorithms.DataAnalysis/3.4/M5Regression/Pruning/PruningBase.cs	(revision 15430)
@@ -0,0 +1,76 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2017 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 <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System.Collections.Generic;
+using System.Linq;
+using HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Data;
+using HeuristicLab.Parameters;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+using HeuristicLab.Problems.DataAnalysis;
+
+namespace HeuristicLab.Algorithms.DataAnalysis {
+  public abstract class PruningBase : ParameterizedNamedItem, IPruningType {
+    private const string PruningStrengthParameterName = "PruningStrength";
+
+    public IFixedValueParameter<DoubleValue> PruningStrengthParameter {
+      get { return Parameters[PruningStrengthParameterName] as IFixedValueParameter<DoubleValue>; }
+    }
+
+    public double PruningStrength {
+      get { return PruningStrengthParameter.Value.Value; }
+    }
+
+    #region Constructors & Cloning
+    [StorableConstructor]
+    protected PruningBase(bool deserializing) : base(deserializing) { }
+    protected PruningBase(PruningBase original, Cloner cloner) : base(original, cloner) { }
+    protected PruningBase() : base() {
+      Parameters.Add(new FixedValueParameter<DoubleValue>(PruningStrengthParameterName, "The strength of the pruning. Higher values force the algorithm to create simpler models", new DoubleValue(2.0)));
+    }
+    #endregion
+
+    #region IPruningType
+    public abstract ILeafType<IRegressionModel> ModelType(ILeafType<IRegressionModel> leafType);
+    public abstract void GenerateHoldOutSet(IReadOnlyList<int> allrows, IRandom random, out IReadOnlyList<int> training, out IReadOnlyList<int> holdout);
+    internal virtual bool Prune(M5NodeModel node, M5CreationParameters m5CreationParams, IReadOnlyList<int> testRows, double globalStdDev) {
+      if (testRows.Count == 0) return true;
+      var vars = m5CreationParams.AllowedInputVariables.Concat(new[] {m5CreationParams.TargetVariable}).ToArray();
+      var reducedData = new Dataset(vars, vars.Select(x => m5CreationParams.Data.GetDoubleValues(x, testRows).ToList()));
+      var pd = new RegressionProblemData(reducedData, m5CreationParams.AllowedInputVariables, m5CreationParams.TargetVariable);
+      pd.TrainingPartition.Start = pd.TrainingPartition.End = pd.TestPartition.Start = 0;
+      pd.TestPartition.End = reducedData.Rows;
+
+      var rmsModel = node.NodeModel.CreateRegressionSolution(pd).TestRootMeanSquaredError;
+      var rmsSubTree = node.CreateRegressionSolution(pd).TestRootMeanSquaredError;
+
+      var adjustedRmsModel = rmsModel * PruningFactor(pd.Dataset.Rows, node.NodeModelParams);
+      var adjustedRmsTree = rmsSubTree * PruningFactor(pd.Dataset.Rows, node.Left.NumParam + node.Right.NumParam + 1);
+      return adjustedRmsModel <= adjustedRmsTree || adjustedRmsModel < globalStdDev * 0.0001;
+    }
+    #endregion
+
+    private double PruningFactor(int noInstances, int noParams) {
+      return noInstances <= noParams ? 10.0 : (noInstances + PruningStrength * noParams) / (noInstances - noParams);
+    }
+  }
+}
Index: branches/M5Regression/HeuristicLab.Algorithms.DataAnalysis/3.4/M5Regression/Spliting/OrderImpurityCalculator.cs
===================================================================
--- branches/M5Regression/HeuristicLab.Algorithms.DataAnalysis/3.4/M5Regression/Spliting/OrderImpurityCalculator.cs	(revision 15430)
+++ branches/M5Regression/HeuristicLab.Algorithms.DataAnalysis/3.4/M5Regression/Spliting/OrderImpurityCalculator.cs	(revision 15430)
@@ -0,0 +1,118 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2017 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 <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using HeuristicLab.Common;
+
+namespace HeuristicLab.Algorithms.DataAnalysis {
+  /// <summary>
+  /// Helper class for incremental impurity calculation.
+  /// Used while moving a potential Split along the ordered training Instances
+  /// </summary>
+  internal class OrderImpurityCalculator : IImpurityCalculator {
+    #region Properties
+    private double SqSumLeft { get; set; }
+    private double SqSumRight { get; set; }
+    private double VarLeft { get; set; }
+    private double VarRight { get; set; }
+    private double Order { get; set; }
+    private double VarTotal { get; set; }
+    private int NoInstances { get; set; }
+
+    private double NoLeft { get; set; }
+    private double NoRight { get; set; }
+    private double SumLeft { get; set; }
+    private double SumRight { get; set; }
+    public double Impurity { get; private set; }
+    #endregion
+
+    #region Constructors
+    public OrderImpurityCalculator(int partition, IReadOnlyCollection<double> data, double order) {
+      var values = data;
+      NoInstances = data.Count;
+      VarTotal = values.VariancePop();
+
+      values = data.Take(partition).ToArray();
+      NoLeft = partition;
+      SumLeft = values.Sum();
+      SqSumLeft = values.Sum(x => x * x);
+
+      values = data.Skip(partition).ToArray();
+      NoRight = NoInstances - NoLeft;
+      SumRight = values.Sum();
+      SqSumRight = values.Sum(x => x * x);
+
+      Order = order;
+      Increment(0.0, IncrementType.None);
+    }
+    #endregion
+
+    #region IImpurityCalculator
+    public void Increment(double value, IncrementType type) {
+      double y, yl, yr;
+      var valSq = value * value;
+
+      switch (type) {
+        case IncrementType.Left:
+          NoLeft++;
+          NoRight--;
+          SumLeft += value;
+          SumRight -= value;
+          SqSumLeft += valSq;
+          SqSumRight -= valSq;
+          break;
+        case IncrementType.Right:
+          NoLeft--;
+          NoRight++;
+          SumLeft -= value;
+          SumRight += value;
+          SqSumLeft -= valSq;
+          SqSumRight += valSq;
+          break;
+        case IncrementType.None:
+          break;
+        default:
+          throw new ArgumentOutOfRangeException(type.ToString(), type, null);
+      }
+
+      VarLeft = NoLeft <= 0 ? 0 : Math.Abs(NoLeft * SqSumLeft - SumLeft * SumLeft) / (NoLeft * NoLeft);
+      VarRight = NoRight <= 0 ? 0 : Math.Abs(NoRight * SqSumRight - SumRight * SumRight) / (NoRight * NoRight);
+
+      if (Order <= 0) throw new ArgumentException("Impurity order must be larger than 0");
+      if (Order.IsAlmost(1)) {
+        y = VarTotal;
+        yl = VarLeft;
+        yr = VarRight;
+      }
+      else {
+        y = Math.Pow(VarTotal, 1.0 / Order);
+        yl = Math.Pow(VarLeft, 1.0 / Order);
+        yr = Math.Pow(VarRight, 1.0 / Order);
+      }
+      var t = NoRight + NoLeft;
+      if (NoLeft <= 0.0 || NoRight <= 0.0) Impurity = double.MinValue; //Impurity = 0;
+      else Impurity = y - NoLeft / t * yl - NoRight / t * yr; //  Impurity = y - NoLeft / NoRight * yl - NoRight / NoLeft * yr
+    }
+    #endregion
+  }
+}
Index: branches/M5Regression/HeuristicLab.Algorithms.DataAnalysis/3.4/M5Regression/Spliting/OrderImpurityType.cs
===================================================================
--- branches/M5Regression/HeuristicLab.Algorithms.DataAnalysis/3.4/M5Regression/Spliting/OrderImpurityType.cs	(revision 15430)
+++ branches/M5Regression/HeuristicLab.Algorithms.DataAnalysis/3.4/M5Regression/Spliting/OrderImpurityType.cs	(revision 15430)
@@ -0,0 +1,59 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2017 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 <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System.Collections.Generic;
+using HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Data;
+using HeuristicLab.Parameters;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+
+namespace HeuristicLab.Algorithms.DataAnalysis {
+  [StorableClass]
+  [Item("OrderImpurityType", "A split selector that uses the ratio between Variances^1/Order to determine good splits")]
+  public class OrderImpurityType : ParameterizedNamedItem, IImpurityType {
+    public const string OrderParameterName = "Order";
+    public IFixedValueParameter<DoubleValue> OrderParameter {
+      get { return Parameters[OrderParameterName] as IFixedValueParameter<DoubleValue>; }
+    }
+    public double Order {
+      get { return OrderParameter.Value.Value; }
+    }
+
+    #region Constructors & Cloning
+    [StorableConstructor]
+    private OrderImpurityType(bool deserializing) { }
+    private OrderImpurityType(OrderImpurityType original, Cloner cloner) : base(original, cloner) { }
+    public OrderImpurityType() {
+      Parameters.Add(new FixedValueParameter<DoubleValue>(OrderParameterName, "The exponent in the impurity calculation sum (x_i - x_avg)^Order.", new DoubleValue(4)));
+    }
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new OrderImpurityType(this, cloner);
+    }
+    #endregion
+
+    #region IImpurityType
+    public IImpurityCalculator GenerateCalculator(int partition, IReadOnlyCollection<double> data) {
+      return new OrderImpurityCalculator(partition, data, Order);
+    }
+    #endregion
+  }
+}
Index: branches/M5Regression/HeuristicLab.Algorithms.DataAnalysis/3.4/Nca/ModelCreation/INcaModelCreator.cs
===================================================================
--- branches/M5Regression/HeuristicLab.Algorithms.DataAnalysis/3.4/Nca/ModelCreation/INcaModelCreator.cs	(revision 15428)
+++ branches/M5Regression/HeuristicLab.Algorithms.DataAnalysis/3.4/Nca/ModelCreation/INcaModelCreator.cs	(revision 15430)
@@ -20,8 +20,4 @@
 #endregion
 
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
 using HeuristicLab.Core;
 
Index: branches/M5Regression/HeuristicLab.Algorithms.DataAnalysis/3.4/PCA/PrincipleComponentAnalysis.cs
===================================================================
--- branches/M5Regression/HeuristicLab.Algorithms.DataAnalysis/3.4/PCA/PrincipleComponentAnalysis.cs	(revision 15430)
+++ branches/M5Regression/HeuristicLab.Algorithms.DataAnalysis/3.4/PCA/PrincipleComponentAnalysis.cs	(revision 15430)
@@ -0,0 +1,145 @@
+using System.Collections.Generic;
+using System.Drawing;
+using System.Linq;
+using System.Threading;
+using HeuristicLab.Analysis;
+using HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Data;
+using HeuristicLab.Optimization;
+using HeuristicLab.Parameters;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+using HeuristicLab.Problems.DataAnalysis;
+
+namespace HeuristicLab.Algorithms.DataAnalysis {
+  [StorableClass]
+  [Creatable(CreatableAttribute.Categories.DataAnalysis, Priority = 95)]
+  [Item("PrincipleComponentAnalysis", "Standard Principle Component Analyis")]
+  public sealed class PrincipleComponentAnalysis : FixedDataAnalysisAlgorithm<IRegressionProblem> {
+    private const string NormalizationParameterName = "Normalization";
+    public IFixedValueParameter<BoolValue> NormalizationParameter {
+      get { return Parameters[NormalizationParameterName] as IFixedValueParameter<BoolValue>; }
+    }
+    public bool Normalization {
+      get { return NormalizationParameter.Value.Value; }
+    }
+
+    [StorableConstructor]
+    private PrincipleComponentAnalysis(bool deserializing) : base(deserializing) { }
+    private PrincipleComponentAnalysis(PrincipleComponentAnalysis original, Cloner cloner) : base(original, cloner) { }
+    public PrincipleComponentAnalysis() {
+      Problem = new RegressionProblem();
+      Parameters.Add(new FixedValueParameter<BoolValue>(NormalizationParameterName, "Whether the data should be zero centered and have variance of 1 for each variable, so different scalings are ignored.", new BoolValue(true)));
+    }
+    [StorableHook(HookType.AfterDeserialization)]
+    private void AfterDeserialization() { }
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new PrincipleComponentAnalysis(this, cloner);
+    }
+
+    protected override void Run(CancellationToken cancellationToken) {
+      var data = Problem.ProblemData.Dataset;
+      var attributes = Problem.ProblemData.AllowedInputVariables.ToArray();
+      var solution = PrincipleComponentAnalysisStatic.Create(data, Problem.ProblemData.AllIndices, attributes, Normalization);
+      var res = solution.ProjectData(Problem.ProblemData.Dataset, Problem.ProblemData.AllIndices);
+      Results.Add(new Result("ProjectedData", new DoubleMatrix(res)));
+      Results.Add(new Result("Variances", new DoubleArray(solution.Variances)));
+      CreateScatterPlot(Problem.ProblemData.TargetVariable, res);
+    }
+
+    #region Fancy ScatterPlot
+    private void CreateScatterPlot(string classesName, double[,] lowDimData) {
+      var results = Results;
+      var dataRowNames = new Dictionary<string, List<int>>();
+      var dataRows = new Dictionary<string, ScatterPlotDataRow>();
+      var problemData = Problem.ProblemData;
+
+      //color datapoints acording to classes variable (be it double or string)
+      if (problemData.Dataset.VariableNames.Contains(classesName)) {
+        if (((Dataset) problemData.Dataset).VariableHasType<string>(classesName)) {
+          var classes = problemData.Dataset.GetStringValues(classesName).ToArray();
+          for (var i = 0; i < classes.Length; i++) {
+            if (!dataRowNames.ContainsKey(classes[i])) dataRowNames.Add(classes[i], new List<int>());
+            dataRowNames[classes[i]].Add(i);
+          }
+        }
+        else if (((Dataset) problemData.Dataset).VariableHasType<double>(classesName)) {
+          const int contours = 8;
+          Dictionary<int, string> contourMap;
+          IClusteringModel clusterModel;
+          double[][] borders;
+          CreateClusters(problemData, classesName, contours, out clusterModel, out contourMap, out borders);
+
+          var contourorder = borders.Select((x, i) => new {x, i}).OrderBy(x => x.x[0]).Select(x => x.i).ToArray();
+          for (var i = 0; i < contours; i++) {
+            var c = contourorder[i];
+            var contourname = contourMap[c];
+            dataRowNames.Add(contourname, new List<int>());
+            dataRows.Add(contourname, new ScatterPlotDataRow(contourname, "", new List<Point2D<double>>()));
+            dataRows[contourname].VisualProperties.Color = GetHeatMapColor(i, contours);
+            dataRows[contourname].VisualProperties.PointSize = i + 3;
+          }
+
+          var allClusters = clusterModel.GetClusterValues(problemData.Dataset, problemData.AllIndices).ToArray();
+          for (var i = 0; i < problemData.Dataset.Rows; i++) dataRowNames[contourMap[allClusters[i] - 1]].Add(i);
+        }
+      }
+      else {
+        dataRowNames.Add("Training", problemData.TrainingIndices.ToList());
+        dataRowNames.Add("Test", problemData.TestIndices.ToList());
+      }
+
+      var plotName = "PjoctedDataPlot";
+      var plot = new ScatterPlot(plotName, "");
+      results.Add(new Result(plotName, "Plot of the projected data", plot));
+      foreach (var rowName in dataRowNames.Keys) {
+        if (!plot.Rows.ContainsKey(rowName))
+          plot.Rows.Add(dataRows.ContainsKey(rowName) ? dataRows[rowName] : new ScatterPlotDataRow(rowName, "", new List<Point2D<double>>()));
+        plot.Rows[rowName].Points.Replace(dataRowNames[rowName].Select(i => new Point2D<double>(lowDimData[i, 0], lowDimData[i, 1 % lowDimData.GetLength(1)])));
+      }
+    }
+
+    private static void CreateClusters(IDataAnalysisProblemData data, string target, int contours, out IClusteringModel contourCluster, out Dictionary<int, string> contourNames, out double[][] borders) {
+      contourCluster = KMeansClustering.CreateKMeansSolution(new ClusteringProblemData((Dataset) data.Dataset, new[] {target}), contours, 3).Model;
+
+      borders = Enumerable.Range(0, contours).Select(x => new[] {double.MaxValue, double.MinValue}).ToArray();
+      var clusters = contourCluster.GetClusterValues(data.Dataset, data.AllIndices).ToArray();
+      var targetvalues = data.Dataset.GetDoubleValues(target).ToArray();
+      foreach (var i in data.AllIndices) {
+        var cl = clusters[i] - 1;
+        var clv = targetvalues[i];
+        if (borders[cl][0] > clv) borders[cl][0] = clv;
+        if (borders[cl][1] < clv) borders[cl][1] = clv;
+      }
+
+      contourNames = new Dictionary<int, string>();
+      for (var i = 0; i < contours; i++)
+        contourNames.Add(i, "[" + borders[i][0] + ";" + borders[i][1] + "]");
+    }
+
+    private static Color GetHeatMapColor(int contourNr, int noContours) {
+      var hue = contourNr / (double) noContours;
+      const double saturation = 0.999f;
+      const double value = 0.999f;
+
+      if (hue > 0.999f) { hue = 0.999f; }
+      if (hue < 0.001f) { hue = 0.001f; }
+
+      var h6 = hue * 6f;
+      if (h6.IsAlmost(6f)) { h6 = 0f; }
+      var ihue = (int) h6;
+      var p = value * (1f - saturation);
+      var q = value * (1f - saturation * (h6 - ihue));
+      var t = value * (1f - saturation * (1f - (h6 - ihue)));
+      switch (ihue) {
+        case 0: return Color.FromArgb((int) (value * 255), (int) (t * 255), (int) (p * 255));
+        case 1: return Color.FromArgb((int) (q * 255), (int) (value * 255), (int) (p * 255));
+        case 2: return Color.FromArgb((int) (p * 255), (int) (value * 255), (int) (t * 255));
+        case 3: return Color.FromArgb((int) (p * 255), (int) (q * 255), (int) (value * 255));
+        case 4: return Color.FromArgb((int) (t * 255), (int) (p * 255), (int) (value * 255));
+        default: return Color.FromArgb((int) (value * 255), (int) (p * 255), (int) (q * 255));
+      }
+    }
+    #endregion
+  }
+}
Index: branches/M5Regression/HeuristicLab.Algorithms.DataAnalysis/3.4/PCA/PrincipleComponentAnalysisStatic.cs
===================================================================
--- branches/M5Regression/HeuristicLab.Algorithms.DataAnalysis/3.4/PCA/PrincipleComponentAnalysisStatic.cs	(revision 15430)
+++ branches/M5Regression/HeuristicLab.Algorithms.DataAnalysis/3.4/PCA/PrincipleComponentAnalysisStatic.cs	(revision 15430)
@@ -0,0 +1,156 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2017 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 <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System.Collections.Generic;
+using System.Linq;
+using HeuristicLab.Common;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+using HeuristicLab.Problems.DataAnalysis;
+
+namespace HeuristicLab.Algorithms.DataAnalysis {
+  [StorableClass]
+  public class PrincipleComponentAnalysisStatic : IDeepCloneable {
+    #region Properties
+    [Storable]
+    private double[,] Matrix { get; set; }
+    [Storable]
+    public double[] Variances { get; private set; }
+    [Storable]
+    public string[] Variables { get; private set; }
+    [Storable]
+    private double[] Deviations { get; set; }
+    [Storable]
+    private double[] Means { get; set; }
+    public string[] Names {
+      get { return Variables.Select((_, x) => "pc" + x).ToArray(); }
+    }
+    #endregion
+
+    #region HLConstructors
+    [StorableConstructor]
+    protected PrincipleComponentAnalysisStatic(bool deserializing) { }
+    protected PrincipleComponentAnalysisStatic(PrincipleComponentAnalysisStatic original, Cloner cloner) {
+      if (original.Variances != null) Variances = original.Variances.ToArray();
+      if (original.Variables != null) Variables = original.Variables.ToArray();
+      if (original.Matrix == null) return;
+      Matrix = new double[original.Matrix.GetLength(0), original.Matrix.GetLength(1)];
+      for (var i = 0; i < original.Matrix.GetLength(0); i++)
+      for (var j = 0; j < original.Matrix.GetLength(1); j++)
+        Matrix[i, j] = original.Matrix[i, j];
+    }
+    private PrincipleComponentAnalysisStatic() { }
+    public IDeepCloneable Clone(Cloner cloner) {
+      return new PrincipleComponentAnalysisStatic(this, cloner);
+    }
+    public object Clone() {
+      return new Cloner().Clone(this);
+    }
+    #endregion
+
+    #region Static Interface
+    public static PrincipleComponentAnalysisStatic Create(IDataset dataset, IEnumerable<int> rows, IEnumerable<string> variables, bool normalize = false) {
+      var res = new PrincipleComponentAnalysisStatic();
+      res.BuildPca(dataset, rows, variables, normalize);
+      return res;
+    }
+    #endregion
+
+    public IRegressionProblemData ProjectProblem(IRegressionProblemData pd) {
+      var projected = ProjectData(pd.Dataset, pd.AllIndices);
+      return CreateProblemData(pd, projected);
+    }
+    public IDataset ProjectDataset(IDataset data) {
+      var projected = ProjectData(data, Enumerable.Range(0, data.Rows));
+      return CreateDataset(data, projected);
+    }
+    public double[,] ProjectData(IDataset dataset, IEnumerable<int> rows) {
+      var instances = rows.ToArray();
+      var result = new double[instances.Length, Variables.Length];
+      for (var r = 0; r < instances.Length; r++)
+      for (var i = 0; i < Variables.Length; i++) {
+        var val = (dataset.GetDoubleValue(Variables[i], instances[r]) - Means[i]) / Deviations[i];
+        for (var j = 0; j < Variables.Length; j++)
+          result[r, j] += val * Matrix[i, j];
+      }
+      return result;
+    }
+    public double[,] ReverseProjection(IDataset dataset, IEnumerable<int> rows, IEnumerable<string> pcaComponents) {
+      var instances = rows.ToArray();
+      var components = pcaComponents.ToArray();
+
+      var result = new double[instances.Length, Variables.Length];
+      for (var r = 0; r < instances.Length; r++)
+      for (var i = 0; i < components.Length; i++) {
+        var val = dataset.GetDoubleValue(components[i], instances[r]);
+        for (var j = 0; j < Variables.Length; j++)
+          result[r, j] += (val + Means[j]) * Deviations[j] * Matrix[j, i];
+      }
+      return result;
+    }
+
+    #region Helpers
+    private IRegressionProblemData CreateProblemData(IRegressionProblemData pd, double[,] pcs) {
+      var data = CreateDataset(pd.Dataset, pcs);
+      var res = new RegressionProblemData(data, Names, pd.TargetVariable);
+      res.TestPartition.Start = pd.TestPartition.Start;
+      res.TestPartition.End = pd.TestPartition.End;
+      res.TrainingPartition.Start = pd.TrainingPartition.Start;
+      res.TrainingPartition.End = pd.TrainingPartition.End;
+      return res;
+    }
+    private IDataset CreateDataset(IDataset data, double[,] pcs) {
+      var n = Names;
+      var n2 = data.DoubleVariables.Where(x => !Variables.Contains(x)).ToArray();
+      return new Dataset(n.Concat(n2),
+        n.Select((_, x) => Enumerable.Range(0, pcs.GetLength(0)).Select(r => pcs[r, x]).ToList())
+          .Concat(n2.Select(x => data.GetDoubleValues(x).ToList())));
+    }
+    private void BuildPca(IDataset dataset, IEnumerable<int> rows, IEnumerable<string> variables, bool normalize) {
+      var instances = rows.ToArray();
+      var attributes = variables.ToArray();
+      Means = normalize
+        ? attributes.Select(v => dataset.GetDoubleValues(v, instances).Average()).ToArray()
+        : attributes.Select(x => 0.0).ToArray();
+      Deviations = normalize
+        ? attributes.Select(v => dataset.GetDoubleValues(v, instances).StandardDeviationPop()).Select(x => x.IsAlmost(0.0) ? 1 : x).ToArray()
+        : attributes.Select(x => 1.0).ToArray();
+
+      var data = new double[instances.Length, attributes.Length];
+
+      for (var j = 0; j < attributes.Length; j++) {
+        var i = 0;
+        foreach (var v in dataset.GetDoubleValues(attributes[j], instances)) {
+          data[i, j] = (v - Means[j]) / Deviations[j];
+          i++;
+        }
+      }
+
+      int info;
+      double[] variances;
+      double[,] matrix;
+      alglib.pcabuildbasis(data, instances.Length, attributes.Length, out info, out variances, out matrix);
+      Matrix = matrix;
+      Variances = variances;
+      Variables = attributes;
+    }
+    #endregion
+  }
+}
Index: branches/M5Regression/HeuristicLab.Algorithms.DataAnalysis/3.4/RandomForest/RandomForestRegressionSolution.cs
===================================================================
--- branches/M5Regression/HeuristicLab.Algorithms.DataAnalysis/3.4/RandomForest/RandomForestRegressionSolution.cs	(revision 15428)
+++ branches/M5Regression/HeuristicLab.Algorithms.DataAnalysis/3.4/RandomForest/RandomForestRegressionSolution.cs	(revision 15430)
@@ -20,10 +20,8 @@
 #endregion
 
-using System;
 using HeuristicLab.Common;
 using HeuristicLab.Core;
 using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
 using HeuristicLab.Problems.DataAnalysis;
-using HeuristicLab.Problems.DataAnalysis.Symbolic.Regression;
 
 namespace HeuristicLab.Algorithms.DataAnalysis {
Index: branches/M5Regression/HeuristicLab.Algorithms.DataAnalysis/3.4/TimeSeries/AutoregressiveModeling.cs
===================================================================
--- branches/M5Regression/HeuristicLab.Algorithms.DataAnalysis/3.4/TimeSeries/AutoregressiveModeling.cs	(revision 15428)
+++ branches/M5Regression/HeuristicLab.Algorithms.DataAnalysis/3.4/TimeSeries/AutoregressiveModeling.cs	(revision 15430)
@@ -26,5 +26,4 @@
 using HeuristicLab.Core;
 using HeuristicLab.Data;
-using HeuristicLab.Encodings.SymbolicExpressionTreeEncoding;
 using HeuristicLab.Optimization;
 using HeuristicLab.Parameters;
Index: branches/M5Regression/HeuristicLab.Algorithms.DataAnalysis/3.4/kMeans/KMeansClusteringSolution.cs
===================================================================
--- branches/M5Regression/HeuristicLab.Algorithms.DataAnalysis/3.4/kMeans/KMeansClusteringSolution.cs	(revision 15428)
+++ branches/M5Regression/HeuristicLab.Algorithms.DataAnalysis/3.4/kMeans/KMeansClusteringSolution.cs	(revision 15430)
@@ -20,8 +20,4 @@
 #endregion
 
-using System;
-using System.Collections.Generic;
-using System.Drawing;
-using System.Linq;
 using HeuristicLab.Common;
 using HeuristicLab.Core;
