Index: branches/2847_M5Regression/HeuristicLab.Algorithms.DataAnalysis/3.4/M5Regression/LeafTypes/M5Leaf.cs
===================================================================
--- branches/2847_M5Regression/HeuristicLab.Algorithms.DataAnalysis/3.4/M5Regression/LeafTypes/M5Leaf.cs	(revision 16538)
+++ branches/2847_M5Regression/HeuristicLab.Algorithms.DataAnalysis/3.4/M5Regression/LeafTypes/M5Leaf.cs	(revision 16847)
@@ -26,14 +26,14 @@
 using HeuristicLab.Common;
 using HeuristicLab.Core;
-using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
 using HeuristicLab.Problems.DataAnalysis;
+using HEAL.Attic;
 
 namespace HeuristicLab.Algorithms.DataAnalysis {
-  [StorableClass]
-  [Item("M5Leaf", "A leaf type that uses linear models as leaf models. This is the standard for M5' regression")]
+  [StorableType("58517042-5318-4087-B098-AC75F0208BA0")]
+  [Item("M5Leaf", "A leaf type that uses regularized linear models with feature selection as leaf models.")]
   public class M5Leaf : LeafBase {
     #region Constructors & Cloning
     [StorableConstructor]
-    private M5Leaf(bool deserializing) : base(deserializing) { }
+    private M5Leaf(StorableConstructorFlag _) : base(_) { }
     private M5Leaf(M5Leaf original, Cloner cloner) : base(original, cloner) { }
     public M5Leaf() { }
@@ -47,9 +47,9 @@
       get { return false; }
     }
-    public override IRegressionModel Build(IRegressionProblemData pd, IRandom random, CancellationToken cancellationToken, out int noParameters) {
+    public override IRegressionModel Build(IRegressionProblemData pd, IRandom random, CancellationToken cancellationToken, out int numberOfParameters) {
       if (pd.Dataset.Rows == 0) throw new ArgumentException("The number of training instances is too small to create an M5 leaf model");
 
       if (pd.Dataset.Rows == 1)
-        return new ConstantLeaf().Build(pd, random, cancellationToken, out noParameters);
+        return new ConstantLeaf().Build(pd, random, cancellationToken, out numberOfParameters);
 
       var means = pd.AllowedInputVariables.ToDictionary(n => n, n => pd.Dataset.GetDoubleValues(n, pd.TrainingIndices).Average());
@@ -57,9 +57,9 @@
       var used = pd.AllowedInputVariables.Where(v => !variances[v].IsAlmost(0.0)).ToList();
 
-      var classMean = pd.TargetVariableTrainingValues.Average();
-      var classVar = pd.TargetVariableTrainingValues.Variance();
+      var targetMean = pd.TargetVariableTrainingValues.Average();
+      var targetVariance = pd.TargetVariableTrainingValues.Variance();
 
-      var model = FindBestModel(variances, means, classMean, classVar, pd, used);
-      noParameters = 1 + model.Coefficients.Count;
+      var model = FindBestModel(variances, means, targetMean, targetVariance, pd, used);
+      numberOfParameters = 1 + model.Coefficients.Count;
       return model;
     }
@@ -69,10 +69,10 @@
     #endregion
 
-    private static PreconstructedLinearModel FindBestModel(Dictionary<string, double> variances, Dictionary<string, double> means, double cMean, double cVar, IRegressionProblemData pd, IList<string> variables) {
+    private static PreconstructedLinearModel FindBestModel(Dictionary<string, double> variances, Dictionary<string, double> means, double yMean, double yVariance, IRegressionProblemData pd, IList<string> variables) {
       Dictionary<string, double> coeffs;
       double intercept;
       do {
-        coeffs = DoRegression(pd, variables, variances, means, cMean, 1.0e-8, out intercept);
-        variables = DeselectColinear(variances, coeffs, cVar, pd, variables);
+        coeffs = DoRegression(pd, variables, variances, means, yMean, 1.0e-8, out intercept);
+        variables = DeselectColinear(variances, coeffs, yVariance, pd, variables);
       }
       while (coeffs.Count != variables.Count);
@@ -88,11 +88,11 @@
         improved = false;
         currentNumAttributes--;
-        // Find attribute with smallest SC
-        var candidate = variables.ToDictionary(v => v, v => Math.Abs(coeffs[v] * Math.Sqrt(variances[v] / cVar)))
+        // Find attribute with smallest SC (variance-scaled coefficient)
+        var candidate = variables.ToDictionary(v => v, v => Math.Abs(coeffs[v] * Math.Sqrt(variances[v] / yVariance)))
           .OrderBy(x => x.Value).Select(x => x.Key).First();
 
         var currVariables = variables.Where(v => !v.Equals(candidate)).ToList();
         var currentIntercept = 0.0;
-        var currentCoeffs = DoRegression(pd, currVariables, variances, means, cMean, 1.0e-8, out currentIntercept);
+        var currentCoeffs = DoRegression(pd, currVariables, variances, means, yMean, 1.0e-8, out currentIntercept);
         var currentMse = CalculateSE(currentCoeffs, currentIntercept, pd, currVariables);
         var currentAkaike = currentMse / fullMse * (numInst - numAtts) + 2 * currentNumAttributes;
@@ -115,16 +115,5 @@
     }
 
-    private static Dictionary<string, double> DoRegression(IRegressionProblemData pd, IList<string> variables, Dictionary<string, double> variances, Dictionary<string, double> means, double cmean, double ridge, out double intercept) {
-      //if (pd.TrainingIndices.Count() > variables.Count) {
-      //  var pd2 = new RegressionProblemData(pd.Dataset, variables, pd.TargetVariable);
-      //  pd2.TestPartition.End = pd.TestPartition.End;
-      //  pd2.TestPartition.Start = pd.TestPartition.Start;
-      //  pd2.TrainingPartition.End = pd.TrainingPartition.End;
-      //  pd2.TrainingPartition.Start = pd.TrainingPartition.Start;
-      //
-      //  double x1, x2;
-      //  var lm = PreconstructedLinearModel.CreateLinearModel(pd2, out x1, out x2);
-      //  intercept = lm.Intercept;
-      //  return lm.Coefficients;
+    private static Dictionary<string, double> DoRegression(IRegressionProblemData pd, IList<string> variables, Dictionary<string, double> variances, Dictionary<string, double> means, double yMean, double ridge, out double intercept) {
 
       var n = variables.Count;
@@ -182,5 +171,5 @@
       if (coefficients == null) throw new ArgumentException("No linear model could be built");
 
-      intercept = cmean;
+      intercept = yMean;
       var res = new Dictionary<string, double>();
       for (var i = 0; i < n; i++) {
@@ -193,6 +182,6 @@
     }
 
-    private static IList<string> DeselectColinear(Dictionary<string, double> variances, Dictionary<string, double> coeffs, double cVar, IRegressionProblemData pd, IList<string> variables) {
-      var candidates = variables.ToDictionary(v => v, v => Math.Abs(coeffs[v] * Math.Sqrt(variances[v] / cVar))).Where(x => x.Value > 1.5).OrderBy(x => -x.Value).ToList();
+    private static IList<string> DeselectColinear(Dictionary<string, double> variances, Dictionary<string, double> coeffs, double yVariance, IRegressionProblemData pd, IList<string> variables) {
+      var candidates = variables.ToDictionary(v => v, v => Math.Abs(coeffs[v] * Math.Sqrt(variances[v] / yVariance))).Where(x => x.Value > 1.5).OrderBy(x => -x.Value).ToList();
       if (candidates.Count == 0) return variables;
       var c = candidates.First().Key;
