- Timestamp:
- 07/15/17 10:29:40 (7 years ago)
- Location:
- stable
- Files:
-
- 12 edited
- 1 copied
Legend:
- Unmodified
- Added
- Removed
-
stable
- Property svn:mergeinfo changed
/trunk/sources merged: 14862-14863,14911,14936,15156-15158,15164,15169,15207-15209,15225,15227,15234,15248
- Property svn:mergeinfo changed
-
stable/HeuristicLab.Algorithms.DataAnalysis
- Property svn:mergeinfo changed
/trunk/sources/HeuristicLab.Algorithms.DataAnalysis merged: 14862-14863,14911,14936,15156-15158,15164,15169,15207-15209,15225,15227,15234,15248
- Property svn:mergeinfo changed
-
stable/HeuristicLab.Algorithms.DataAnalysis/3.4/KernelRidgeRegression/KernelFunctions/CicularKernel.cs
r14892 r15249 25 25 using HeuristicLab.Persistence.Default.CompositeSerializers.Storable; 26 26 27 namespace HeuristicLab.Algorithms.DataAnalysis .KernelRidgeRegression{27 namespace HeuristicLab.Algorithms.DataAnalysis { 28 28 [StorableClass] 29 29 [Item("CircularKernel", "A circular kernel function 2*pi*(acos(-d)-d*(1-d²)^(0.5)) where n = ||x-c|| and d = n/beta \n As described in http://crsouza.com/2010/03/17/kernel-functions-for-machine-learning-applications/")] 30 30 public class CircularKernel : KernelBase { 31 32 #region HLConstructors & Boilerplate33 31 [StorableConstructor] 34 32 protected CircularKernel(bool deserializing) : base(deserializing) { } 35 [StorableHook(HookType.AfterDeserialization)] 36 private void AfterDeserialization() { } 33 37 34 protected CircularKernel(CircularKernel original, Cloner cloner) : base(original, cloner) { } 38 public CircularKernel() { 39 } 35 36 public CircularKernel() { } 37 40 38 public override IDeepCloneable Clone(Cloner cloner) { 41 39 return new CircularKernel(this, cloner); 42 40 } 43 #endregion44 41 45 42 protected override double Get(double norm) { 43 if (Beta == null) throw new InvalidOperationException("Can not calculate kernel distance while Beta is null"); 46 44 var beta = Beta.Value; 47 45 if (Math.Abs(beta) < double.Epsilon) return double.NaN; … … 53 51 // 4*pi*n^3 / (beta^4 * sqrt(1-n^2/beta^2) 54 52 protected override double GetGradient(double norm) { 53 if (Beta == null) throw new InvalidOperationException("Can not calculate kernel distance gradient while Beta is null"); 55 54 var beta = Beta.Value; 56 55 if (Math.Abs(beta) < double.Epsilon) return double.NaN; -
stable/HeuristicLab.Algorithms.DataAnalysis/3.4/KernelRidgeRegression/KernelFunctions/GaussianKernel.cs
r14891 r15249 27 27 using HeuristicLab.Persistence.Default.CompositeSerializers.Storable; 28 28 29 namespace HeuristicLab.Algorithms.DataAnalysis .KernelRidgeRegression{29 namespace HeuristicLab.Algorithms.DataAnalysis { 30 30 [StorableClass] 31 31 [Item("GaussianKernel", "A kernel function that uses Gaussian function exp(-n²/beta²). As described in http://crsouza.com/2010/03/17/kernel-functions-for-machine-learning-applications/")] 32 32 public class GaussianKernel : KernelBase { 33 34 #region HLConstructors & Boilerplate35 33 [StorableConstructor] 36 34 protected GaussianKernel(bool deserializing) : base(deserializing) { } 37 [StorableHook(HookType.AfterDeserialization)] 38 private void AfterDeserialization() { } 35 39 36 protected GaussianKernel(GaussianKernel original, Cloner cloner) : base(original, cloner) { } 37 40 38 public GaussianKernel() { 41 39 } 40 42 41 public override IDeepCloneable Clone(Cloner cloner) { 43 42 return new GaussianKernel(this, cloner); 44 43 } 45 #endregion46 44 47 45 protected override double Get(double norm) { 46 if (Beta == null) throw new InvalidOperationException("Can not calculate kernel distance while Beta is null"); 48 47 var beta = Beta.Value; 49 48 if (Math.Abs(beta) < double.Epsilon) return double.NaN; … … 54 53 //2 * n²/b²* 1/b * exp(-n²/b²) 55 54 protected override double GetGradient(double norm) { 55 if (Beta == null) throw new InvalidOperationException("Can not calculate kernel distance gradient while Beta is null"); 56 56 var beta = Beta.Value; 57 57 if (Math.Abs(beta) < double.Epsilon) return double.NaN; -
stable/HeuristicLab.Algorithms.DataAnalysis/3.4/KernelRidgeRegression/KernelFunctions/IKernel.cs
r14887 r15249 21 21 22 22 23 namespace HeuristicLab.Algorithms.DataAnalysis.KernelRidgeRegression { 23 using System; 24 25 namespace HeuristicLab.Algorithms.DataAnalysis { 24 26 public interface IKernel : ICovarianceFunction { 25 27 double? Beta { get; set; } // a kernel parameter 26 28 IDistance Distance { get; set; } // the distance function to use 29 30 event EventHandler BetaChanged; 31 event EventHandler DistanceChanged; 27 32 } 28 33 } -
stable/HeuristicLab.Algorithms.DataAnalysis/3.4/KernelRidgeRegression/KernelFunctions/InverseMultiquadraticKernel.cs
r14891 r15249 25 25 using HeuristicLab.Persistence.Default.CompositeSerializers.Storable; 26 26 27 namespace HeuristicLab.Algorithms.DataAnalysis .KernelRidgeRegression{27 namespace HeuristicLab.Algorithms.DataAnalysis { 28 28 [StorableClass] 29 29 [Item("InverseMultiquadraticKernel", "A kernel function that uses the inverse multi-quadratic function 1 / sqrt(1+||x-c||²/beta²). Similar to http://crsouza.com/2010/03/17/kernel-functions-for-machine-learning-applications/ with beta as a scaling factor.")] 30 30 public class InverseMultiquadraticKernel : KernelBase { 31 private const double C = 1.0; 31 32 32 private const double C = 1.0;33 #region HLConstructors & Boilerplate34 33 [StorableConstructor] 35 34 protected InverseMultiquadraticKernel(bool deserializing) : base(deserializing) { } 36 [StorableHook(HookType.AfterDeserialization)] 37 private void AfterDeserialization() { } 35 38 36 protected InverseMultiquadraticKernel(InverseMultiquadraticKernel original, Cloner cloner) : base(original, cloner) { } 37 39 38 public InverseMultiquadraticKernel() { } 39 40 40 public override IDeepCloneable Clone(Cloner cloner) { 41 41 return new InverseMultiquadraticKernel(this, cloner); 42 42 } 43 #endregion44 43 45 44 protected override double Get(double norm) { 45 if (Beta == null) throw new InvalidOperationException("Can not calculate kernel distance while Beta is null"); 46 46 var beta = Beta.Value; 47 47 if (Math.Abs(beta) < double.Epsilon) return double.NaN; … … 52 52 //n²/(b³(n²/b² + C)^1.5) 53 53 protected override double GetGradient(double norm) { 54 if (Beta == null) throw new InvalidOperationException("Can not calculate kernel distance gradient while Beta is null"); 54 55 var beta = Beta.Value; 55 56 if (Math.Abs(beta) < double.Epsilon) return double.NaN; -
stable/HeuristicLab.Algorithms.DataAnalysis/3.4/KernelRidgeRegression/KernelFunctions/KernelBase.cs
r14887 r15249 28 28 using HeuristicLab.Persistence.Default.CompositeSerializers.Storable; 29 29 30 namespace HeuristicLab.Algorithms.DataAnalysis .KernelRidgeRegression{30 namespace HeuristicLab.Algorithms.DataAnalysis { 31 31 [StorableClass] 32 32 public abstract class KernelBase : ParameterizedNamedItem, IKernel { 33 33 34 #region Parameternames35 34 private const string DistanceParameterName = "Distance"; 36 #endregion 37 #region Parameterproperties 38 public ValueParameter<IDistance> DistanceParameter { 39 get { return Parameters[DistanceParameterName] as ValueParameter<IDistance>; } 35 36 public IValueParameter<IDistance> DistanceParameter { 37 get { return (IValueParameter<IDistance>)Parameters[DistanceParameterName]; } 40 38 } 41 39 42 40 [Storable] 43 public double? Beta { get; set; } 44 #endregion 45 #region Properties 41 private double? beta; 42 public double? Beta { 43 get { return beta; } 44 set { 45 if (value != beta) { 46 beta = value; 47 RaiseBetaChanged(); 48 } 49 } 50 } 51 46 52 public IDistance Distance { 47 53 get { return DistanceParameter.Value; } 48 set { DistanceParameter.Value = value; } 54 set { 55 if (DistanceParameter.Value != value) { 56 DistanceParameter.Value = value; 57 } 58 } 49 59 } 50 51 #endregion52 60 53 61 [StorableConstructor] 54 62 protected KernelBase(bool deserializing) : base(deserializing) { } 55 [StorableHook(HookType.AfterDeserialization)]56 private void AfterDeserialization() { }57 63 58 64 protected KernelBase(KernelBase original, Cloner cloner) 59 65 : base(original, cloner) { 60 Beta = original.Beta; 66 beta = original.beta; 67 RegisterEvents(); 61 68 } 62 69 … … 64 71 Parameters.Add(new ValueParameter<IDistance>(DistanceParameterName, "The distance function used for kernel calculation")); 65 72 DistanceParameter.Value = new EuclideanDistance(); 73 RegisterEvents(); 74 } 75 76 [StorableHook(HookType.AfterDeserialization)] 77 private void AfterDeserialization() { 78 RegisterEvents(); 79 } 80 81 private void RegisterEvents() { 82 DistanceParameter.ValueChanged += (sender, args) => RaiseDistanceChanged(); 66 83 } 67 84 … … 82 99 public ParameterizedCovarianceFunction GetParameterizedCovarianceFunction(double[] p, int[] columnIndices) { 83 100 if (p.Length != GetNumberOfParameters(columnIndices.Length)) throw new ArgumentException("Illegal parametrization"); 84 var myClone = (KernelBase)Clone( new Cloner());101 var myClone = (KernelBase)Clone(); 85 102 myClone.SetParameter(p); 86 103 var cov = new ParameterizedCovarianceFunction { … … 101 118 return dist.Get(r1, r2); 102 119 } 120 121 #region events 122 public event EventHandler BetaChanged; 123 public event EventHandler DistanceChanged; 124 125 protected void RaiseBetaChanged() { 126 var handler = BetaChanged; 127 if (handler != null) handler(this, EventArgs.Empty); 128 } 129 130 protected void RaiseDistanceChanged() { 131 var handler = DistanceChanged; 132 if (handler != null) handler(this, EventArgs.Empty); 133 } 134 #endregion 103 135 } 104 136 } -
stable/HeuristicLab.Algorithms.DataAnalysis/3.4/KernelRidgeRegression/KernelFunctions/MultiquadraticKernel.cs
r14891 r15249 25 25 using HeuristicLab.Persistence.Default.CompositeSerializers.Storable; 26 26 27 namespace HeuristicLab.Algorithms.DataAnalysis .KernelRidgeRegression{27 namespace HeuristicLab.Algorithms.DataAnalysis { 28 28 [StorableClass] 29 29 // conditionally positive definite. (need to add polynomials) see http://num.math.uni-goettingen.de/schaback/teaching/sc.pdf … … 32 32 33 33 private const double C = 1.0; 34 #region HLConstructors & Boilerplate 34 35 35 [StorableConstructor] 36 36 protected MultiquadraticKernel(bool deserializing) : base(deserializing) { } 37 [StorableHook(HookType.AfterDeserialization)]38 private void AfterDeserialization() { }39 protected MultiquadraticKernel(MultiquadraticKernel original, Cloner cloner)40 : base(original, cloner) { }41 37 42 public MultiquadraticKernel() { 43 } 38 protected MultiquadraticKernel(MultiquadraticKernel original, Cloner cloner) : base(original, cloner) { } 39 40 public MultiquadraticKernel() { } 41 44 42 public override IDeepCloneable Clone(Cloner cloner) { 45 43 return new MultiquadraticKernel(this, cloner); 46 44 } 47 #endregion 45 48 46 protected override double Get(double norm) { 47 if (Beta == null) throw new InvalidOperationException("Can not calculate kernel distance while Beta is null"); 49 48 var beta = Beta.Value; 50 49 if (Math.Abs(beta) < double.Epsilon) return double.NaN; … … 55 54 //-n²/(d³*sqrt(C+n²/d²)) 56 55 protected override double GetGradient(double norm) { 56 if (Beta == null) throw new InvalidOperationException("Can not calculate kernel distance gradient while Beta is null"); 57 57 var beta = Beta.Value; 58 58 if (Math.Abs(beta) < double.Epsilon) return double.NaN; -
stable/HeuristicLab.Algorithms.DataAnalysis/3.4/KernelRidgeRegression/KernelFunctions/PolysplineKernel.cs
r14892 r15249 27 27 using HeuristicLab.Persistence.Default.CompositeSerializers.Storable; 28 28 29 namespace HeuristicLab.Algorithms.DataAnalysis .KernelRidgeRegression{29 namespace HeuristicLab.Algorithms.DataAnalysis { 30 30 [StorableClass] 31 31 // conditionally positive definite. (need to add polynomials) see http://num.math.uni-goettingen.de/schaback/teaching/sc.pdf … … 33 33 public class PolysplineKernel : KernelBase { 34 34 35 #region Parameternames36 35 private const string DegreeParameterName = "Degree"; 37 #endregion 38 #region Parameterproperties 36 39 37 public IFixedValueParameter<DoubleValue> DegreeParameter { 40 get { return Parameters[DegreeParameterName] as IFixedValueParameter<DoubleValue>; }38 get { return (IFixedValueParameter<DoubleValue>)Parameters[DegreeParameterName]; } 41 39 } 42 #endregion 43 #region Properties 40 44 41 public DoubleValue Degree { 45 42 get { return DegreeParameter.Value; } 46 43 } 47 #endregion48 44 49 #region HLConstructors & Boilerplate50 45 [StorableConstructor] 51 46 protected PolysplineKernel(bool deserializing) : base(deserializing) { } 52 [StorableHook(HookType.AfterDeserialization)] 53 private void AfterDeserialization() { } 47 54 48 protected PolysplineKernel(PolysplineKernel original, Cloner cloner) : base(original, cloner) { } 49 55 50 public PolysplineKernel() { 56 51 Parameters.Add(new FixedValueParameter<DoubleValue>(DegreeParameterName, "The degree of the kernel. Needs to be greater than zero.", new DoubleValue(1.0))); 57 52 } 53 58 54 public override IDeepCloneable Clone(Cloner cloner) { 59 55 return new PolysplineKernel(this, cloner); 60 56 } 61 #endregion62 57 63 58 protected override double Get(double norm) { 59 if (Beta == null) throw new InvalidOperationException("Can not calculate kernel distance gradient while Beta is null"); 64 60 var beta = Beta.Value; 65 61 if (Math.Abs(beta) < double.Epsilon) return double.NaN; … … 70 66 //-degree/beta * (norm/beta)^degree 71 67 protected override double GetGradient(double norm) { 68 if (Beta == null) throw new InvalidOperationException("Can not calculate kernel distance gradient while Beta is null"); 72 69 var beta = Beta.Value; 73 70 if (Math.Abs(beta) < double.Epsilon) return double.NaN; -
stable/HeuristicLab.Algorithms.DataAnalysis/3.4/KernelRidgeRegression/KernelFunctions/ThinPlatePolysplineKernel.cs
r14892 r15249 27 27 using HeuristicLab.Persistence.Default.CompositeSerializers.Storable; 28 28 29 namespace HeuristicLab.Algorithms.DataAnalysis .KernelRidgeRegression{29 namespace HeuristicLab.Algorithms.DataAnalysis { 30 30 [StorableClass] 31 31 // conditionally positive definite. (need to add polynomials) see http://num.math.uni-goettingen.de/schaback/teaching/sc.pdf … … 33 33 public class ThinPlatePolysplineKernel : KernelBase { 34 34 35 #region Parameternames36 35 private const string DegreeParameterName = "Degree"; 37 #endregion 38 #region Parameterproperties 36 39 37 public IFixedValueParameter<DoubleValue> DegreeParameter { 40 get { return Parameters[DegreeParameterName] as IFixedValueParameter<DoubleValue>; }38 get { return (IFixedValueParameter<DoubleValue>)Parameters[DegreeParameterName]; } 41 39 } 42 #endregion43 #region Properties44 40 public DoubleValue Degree { 45 41 get { return DegreeParameter.Value; } 46 42 } 47 #endregion48 43 49 #region HLConstructors & Boilerplate50 44 [StorableConstructor] 51 45 protected ThinPlatePolysplineKernel(bool deserializing) : base(deserializing) { } 52 [StorableHook(HookType.AfterDeserialization)] 53 private void AfterDeserialization() { } 46 54 47 protected ThinPlatePolysplineKernel(ThinPlatePolysplineKernel original, Cloner cloner) : base(original, cloner) { } 48 55 49 public ThinPlatePolysplineKernel() { 56 50 Parameters.Add(new FixedValueParameter<DoubleValue>(DegreeParameterName, "The degree of the kernel. Needs to be greater than zero.", new DoubleValue(2.0))); 57 51 } 52 58 53 public override IDeepCloneable Clone(Cloner cloner) { 59 54 return new ThinPlatePolysplineKernel(this, cloner); 60 55 } 61 #endregion62 56 63 57 protected override double Get(double norm) { 58 if (Beta == null) throw new InvalidOperationException("Can not calculate kernel distance while Beta is null"); 64 59 var beta = Beta.Value; 65 60 if (Math.Abs(beta) < double.Epsilon) return double.NaN; … … 71 66 // (Degree/beta) * (norm/beta)^Degree * log(norm/beta) 72 67 protected override double GetGradient(double norm) { 68 if (Beta == null) throw new InvalidOperationException("Can not calculate kernel distance gradient while Beta is null"); 73 69 var beta = Beta.Value; 74 70 if (Math.Abs(beta) < double.Epsilon) return double.NaN; -
stable/HeuristicLab.Algorithms.DataAnalysis/3.4/KernelRidgeRegression/KernelRidgeRegression.cs
r14888 r15249 29 29 using HeuristicLab.Parameters; 30 30 using HeuristicLab.Persistence.Default.CompositeSerializers.Storable; 31 using HeuristicLab.PluginInfrastructure; 31 32 using HeuristicLab.Problems.DataAnalysis; 32 33 33 namespace HeuristicLab.Algorithms.DataAnalysis .KernelRidgeRegression{34 namespace HeuristicLab.Algorithms.DataAnalysis { 34 35 [Item("Kernel Ridge Regression", "Kernelized ridge regression e.g. for radial basis function (RBF) regression.")] 35 36 [Creatable(CreatableAttribute.Categories.DataAnalysisRegression, Priority = 100)] … … 57 58 58 59 #region parameter properties 59 public ValueParameter<IKernel> KernelParameter {60 get { return ( ValueParameter<IKernel>)Parameters[KernelParameterName]; }60 public IConstrainedValueParameter<IKernel> KernelParameter { 61 get { return (IConstrainedValueParameter<IKernel>)Parameters[KernelParameterName]; } 61 62 } 62 63 … … 102 103 public KernelRidgeRegression() { 103 104 Problem = new RegressionProblem(); 104 Parameters.Add(new ValueParameter<IKernel>(KernelParameterName, "The kernel", new GaussianKernel())); 105 var values = new ItemSet<IKernel>(ApplicationManager.Manager.GetInstances<IKernel>()); 106 Parameters.Add(new ConstrainedValueParameter<IKernel>(KernelParameterName, "The kernel", values, values.OfType<GaussianKernel>().FirstOrDefault())); 105 107 Parameters.Add(new FixedValueParameter<BoolValue>(ScaleInputVariablesParameterName, "Set to true if the input variables should be scaled to the interval [0..1]", new BoolValue(true))); 106 108 Parameters.Add(new FixedValueParameter<DoubleValue>(LambdaParameterName, "The log10-transformed weight for the regularization term lambda [-inf..+inf]. Small values produce more complex models, large values produce models with larger errors. Set to very small value (e.g. -1.0e15) for almost exact approximation", new DoubleValue(-2))); 107 Parameters.Add(new FixedValueParameter<DoubleValue>(BetaParameterName, "The beta parameter for the kernel", new DoubleValue(2)));109 Parameters.Add(new FixedValueParameter<DoubleValue>(BetaParameterName, "The inverse width of the kernel ]0..+inf]. The distance between points is divided by this value before being plugged into the kernel.", new DoubleValue(2))); 108 110 } 109 [StorableHook(HookType.AfterDeserialization)]110 private void AfterDeserialization() { }111 111 112 112 public override IDeepCloneable Clone(Cloner cloner) { … … 125 125 126 126 public static IRegressionSolution CreateRadialBasisRegressionSolution(IRegressionProblemData problemData, ICovarianceFunction kernel, double lambda, bool scaleInputs, out double rmsError, out double looCvRMSE) { 127 var model = new KernelRidgeRegressionModel(problemData.Dataset, problemData.TargetVariable, problemData.AllowedInputVariables, problemData.TrainingIndices, scaleInputs, kernel, lambda);127 var model = KernelRidgeRegressionModel.Create(problemData.Dataset, problemData.TargetVariable, problemData.AllowedInputVariables, problemData.TrainingIndices, scaleInputs, kernel, lambda); 128 128 rmsError = double.NaN; 129 129 if (problemData.TestIndices.Any()) { -
stable/HeuristicLab.Algorithms.DataAnalysis/3.4/KernelRidgeRegression/KernelRidgeRegressionModel.cs
r14892 r15249 28 28 using HeuristicLab.Problems.DataAnalysis; 29 29 30 namespace HeuristicLab.Algorithms.DataAnalysis .KernelRidgeRegression{30 namespace HeuristicLab.Algorithms.DataAnalysis { 31 31 [StorableClass] 32 32 [Item("KernelRidgeRegressionModel", "A kernel ridge regression model")] … … 39 39 private readonly string[] allowedInputVariables; 40 40 public string[] AllowedInputVariables { 41 get { return allowedInputVariables ; }41 get { return allowedInputVariables.ToArray(); } 42 42 } 43 43 … … 81 81 yOffset = original.yOffset; 82 82 yScale = original.yScale; 83 if (original.kernel != null) 84 kernel = cloner.Clone(original.kernel); 83 kernel = original.kernel; 85 84 } 86 85 public override IDeepCloneable Clone(Cloner cloner) { … … 88 87 } 89 88 90 public KernelRidgeRegressionModel(IDataset dataset, string targetVariable, IEnumerable<string> allowedInputVariables, IEnumerable<int> rows, 91 bool scaleInputs, ICovarianceFunction kernel, double lambda = 0.1) : base(targetVariable) { 92 if (kernel.GetNumberOfParameters(allowedInputVariables.Count()) > 0) throw new ArgumentException("All parameters in the kernel function must be specified."); 93 name = ItemName; 94 description = ItemDescription; 95 this.allowedInputVariables = allowedInputVariables.ToArray(); 89 public static KernelRidgeRegressionModel Create(IDataset dataset, string targetVariable, IEnumerable<string> allowedInputVariables, IEnumerable<int> rows, 90 bool scaleInputs, ICovarianceFunction kernel, double lambda = 0.1) { 96 91 var trainingRows = rows.ToArray(); 97 this.kernel = (ICovarianceFunction)kernel.Clone();98 this.lambda = lambda; 92 var model = new KernelRidgeRegressionModel(dataset, targetVariable, allowedInputVariables, trainingRows, scaleInputs, kernel, lambda); 93 99 94 try { 100 if (scaleInputs) 101 scaling = CreateScaling(dataset, trainingRows); 102 trainX = ExtractData(dataset, trainingRows, scaling); 95 int info; 96 int n = model.trainX.GetLength(0); 97 alglib.densesolverreport denseSolveRep; 98 var gram = BuildGramMatrix(model.trainX, lambda, kernel); 99 var l = new double[n, n]; 100 Array.Copy(gram, l, l.Length); 101 102 double[] alpha = new double[n]; 103 double[,] invG; 103 104 var y = dataset.GetDoubleValues(targetVariable, trainingRows).ToArray(); 104 yOffset = y.Average();105 yScale = 1.0 / y.StandardDeviation();106 105 for (int i = 0; i < y.Length; i++) { 107 y[i] -= yOffset; 108 y[i] *= yScale; 109 } 110 int info; 111 int n = trainX.GetLength(0); 112 alglib.densesolverreport denseSolveRep; 113 var gram = BuildGramMatrix(trainX, lambda); 114 var l = new double[n, n]; Array.Copy(gram, l, l.Length); 115 116 double[,] invG; 106 y[i] -= model.yOffset; 107 y[i] *= model.yScale; 108 } 117 109 // cholesky decomposition 118 110 var res = alglib.trfac.spdmatrixcholesky(ref l, n, false); 119 if (res == false) { //t hrow new ArgumentException("Could not decompose matrix. Is it quadratic symmetric positive definite?");111 if (res == false) { //try lua decomposition if cholesky faild 120 112 int[] pivots; 121 113 var lua = new double[n, n]; … … 127 119 invG = lua; // rename 128 120 alglib.rmatrixluinverse(ref invG, pivots, n, out info, out rep); 129 if (info != 1) throw new ArgumentException("Could not invert Gram matrix.");130 121 } else { 131 122 alglib.spdmatrixcholeskysolve(l, n, false, y, out info, out denseSolveRep, out alpha); … … 135 126 invG = l; // rename 136 127 alglib.spdmatrixcholeskyinverse(ref invG, n, false, out info, out rep); 137 if (info != 1) throw new ArgumentException("Could not invert Gram matrix.");138 }128 } 129 if (info != 1) throw new ArgumentException("Could not invert Gram matrix."); 139 130 140 131 var ssqLooError = 0.0; … … 142 133 var pred_i = Util.ScalarProd(Util.GetRow(gram, i).ToArray(), alpha); 143 134 var looPred_i = pred_i - alpha[i] / invG[i, i]; 144 var error = (y[i] - looPred_i) / yScale;135 var error = (y[i] - looPred_i) / model.yScale; 145 136 ssqLooError += error * error; 146 137 } 147 LooCvRMSE = Math.Sqrt(ssqLooError / n); 138 139 Array.Copy(alpha, model.alpha, n); 140 model.LooCvRMSE = Math.Sqrt(ssqLooError / n); 148 141 } catch (alglib.alglibexception ae) { 149 142 // wrap exception so that calling code doesn't have to know about alglib implementation 150 143 throw new ArgumentException("There was a problem in the calculation of the kernel ridge regression model", ae); 151 144 } 145 return model; 146 } 147 148 private KernelRidgeRegressionModel(IDataset dataset, string targetVariable, IEnumerable<string> allowedInputVariables, int[] rows, 149 bool scaleInputs, ICovarianceFunction kernel, double lambda = 0.1) : base(targetVariable) { 150 this.allowedInputVariables = allowedInputVariables.ToArray(); 151 if (kernel.GetNumberOfParameters(this.allowedInputVariables.Length) > 0) throw new ArgumentException("All parameters in the kernel function must be specified."); 152 name = ItemName; 153 description = ItemDescription; 154 155 this.kernel = (ICovarianceFunction)kernel.Clone(); 156 this.lambda = lambda; 157 if (scaleInputs) scaling = CreateScaling(dataset, rows, this.allowedInputVariables); 158 trainX = ExtractData(dataset, rows, this.allowedInputVariables, scaling); 159 var y = dataset.GetDoubleValues(targetVariable, rows).ToArray(); 160 yOffset = y.Average(); 161 yScale = 1.0 / y.StandardDeviation(); 162 alpha = new double[trainX.GetLength(0)]; 152 163 } 153 164 … … 155 166 #region IRegressionModel Members 156 167 public override IEnumerable<double> GetEstimatedValues(IDataset dataset, IEnumerable<int> rows) { 157 var newX = ExtractData(dataset, rows, scaling);168 var newX = ExtractData(dataset, rows, allowedInputVariables, scaling); 158 169 var dim = newX.GetLength(1); 159 170 var cov = kernel.GetParameterizedCovarianceFunction(new double[0], Enumerable.Range(0, dim).ToArray()); … … 175 186 176 187 #region helpers 177 private double[,] BuildGramMatrix(double[,] data, double lambda) {188 private static double[,] BuildGramMatrix(double[,] data, double lambda, ICovarianceFunction kernel) { 178 189 var n = data.GetLength(0); 179 190 var dim = data.GetLength(1); … … 190 201 } 191 202 192 private ITransformation<double>[] CreateScaling(IDataset dataset, int[] rows) {193 var trans = new ITransformation<double>[allowedInputVariables. Length];203 private static ITransformation<double>[] CreateScaling(IDataset dataset, int[] rows, IReadOnlyCollection<string> allowedInputVariables) { 204 var trans = new ITransformation<double>[allowedInputVariables.Count]; 194 205 int i = 0; 195 206 foreach (var variable in allowedInputVariables) { … … 205 216 } 206 217 207 private double[,] ExtractData(IDataset dataset, IEnumerable<int> rows, ITransformation<double>[] scaling = null) {218 private static double[,] ExtractData(IDataset dataset, IEnumerable<int> rows, IReadOnlyCollection<string> allowedInputVariables, ITransformation<double>[] scaling = null) { 208 219 double[][] variables; 209 220 if (scaling != null) {
Note: See TracChangeset
for help on using the changeset viewer.