I am trying to implement a module to determine the best value for the smoothing parameter of a smoothing spline interpolation of a given dataset. To calculate the cross-validation score of a given interpolation I have the following code:
CrossValidateScore[dat_?MatrixQ, p : (_?NumericQ | Automatic) : Automatic] :=
Module[{n = Length[dat], pv = p, i, cvs, xa, ya}, {xa, ya} = Transpose[dat];
Off[InterpolatingFunction::dmval];
cvs = 0;
For[i = 1, i <= n, i++,
cvs +=
Power[ya[[i]] - SmoothingSplineFunction[Delete[dat, {i}], p][xa[[i]]], 2]
];
cvs/n
]
where SmoothingSplineFunction is J.M. excellent implementation of Reinsch's smoothing spline provided here. Basically, what the code does is set aside the data (xi,yi) in turn, spline interpolate the remaining data, and sums fits to the left out values to get a cross–validated error sum of squares.
Now what I do is run through a certain range of parameters with the module
SplineCrossValidation[dat_?MatrixQ,pmax_,pmin_,psteps_] :=
Module[{n = Length[dat], pv, i, cvspl, stp},
cvspl = {};
stp = (pmax - pmin)/psteps;
For[i = 1, i <= psteps + 1, i++,
AppendTo[
cvspl, {pmin + (i - 1)*stp,
CrossValidateScore[dat, pmin + (i - 1)*stp]}]
];
cvspl
]
and then select the parameter p that minimizes the score, for example:
cvs = SplineCrossValidation[data, 1, 0.5, 1000];
bestsp = cvs[[Flatten[Position[Part[cvs , All, 2], Min[Part[cvs , All, 2]]]][[1]], 1]]
The problem is that this procedure becomes very slow pretty soon, especially when the size of the data set grows.
Any suggestion on how to improve performance please? Or has any of you implemented an efficient cross validation procedure?