Changeset 15164
- Timestamp:
- 07/06/17 15:56:54 (7 years ago)
- Location:
- trunk/sources/HeuristicLab.Algorithms.DataAnalysis/3.4/KernelRidgeRegression
- Files:
-
- 4 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/sources/HeuristicLab.Algorithms.DataAnalysis/3.4/KernelRidgeRegression/KernelFunctions/PolysplineKernel.cs
r15158 r15164 57 57 58 58 protected override double Get(double norm) { 59 if (Beta == null) throw new InvalidOperationException("Can not calculate kernel distance while Beta is null");59 if (Beta == null) throw new InvalidOperationException("Can not calculate kernel distance gradient while Beta is null"); 60 60 var beta = Beta.Value; 61 61 if (Math.Abs(beta) < double.Epsilon) return double.NaN; -
trunk/sources/HeuristicLab.Algorithms.DataAnalysis/3.4/KernelRidgeRegression/KernelFunctions/ThinPlatePolysplineKernel.cs
r15158 r15164 66 66 // (Degree/beta) * (norm/beta)^Degree * log(norm/beta) 67 67 protected override double GetGradient(double norm) { 68 if (Beta == null) throw new InvalidOperationException("Can not calculate kernel distance while Beta is null");68 if (Beta == null) throw new InvalidOperationException("Can not calculate kernel distance gradient while Beta is null"); 69 69 var beta = Beta.Value; 70 70 if (Math.Abs(beta) < double.Epsilon) return double.NaN; -
trunk/sources/HeuristicLab.Algorithms.DataAnalysis/3.4/KernelRidgeRegression/KernelRidgeRegression.cs
r15156 r15164 123 123 124 124 public static IRegressionSolution CreateRadialBasisRegressionSolution(IRegressionProblemData problemData, ICovarianceFunction kernel, double lambda, bool scaleInputs, out double rmsError, out double looCvRMSE) { 125 var model = new KernelRidgeRegressionModel(problemData.Dataset, problemData.TargetVariable, problemData.AllowedInputVariables, problemData.TrainingIndices, scaleInputs, kernel, lambda);125 var model = KernelRidgeRegressionModel.Create(problemData.Dataset, problemData.TargetVariable, problemData.AllowedInputVariables, problemData.TrainingIndices, scaleInputs, kernel, lambda); 126 126 rmsError = double.NaN; 127 127 if (problemData.TestIndices.Any()) { -
trunk/sources/HeuristicLab.Algorithms.DataAnalysis/3.4/KernelRidgeRegression/KernelRidgeRegressionModel.cs
r14936 r15164 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.