Feature standardization
An alternative approach is feature standardization:
Which of the two to use in your app is up to you, but be sure to use at least one of them.
As usual, we have an accelerate function for that:
func normalize(vec: [Double]) -> (normalizedVec: [Double], mean: Double, std: Double) { let count = vec.count var mean = 0.0 var std = 0.0 var normalizedVec = [Double](repeating: 0.0, count: count) vDSP_normalizeD(UnsafePointer(vec), 1, &normalizedVec, 1, &mean, &std, UInt(count)) return (normalizedVec, mean, std) }
Now we need to update the train
method:
func train(xVec: [Double], yVec: [Double], learningRate: Double, maxSteps: Int) { precondition(xVec.count == yVec.count) precondition(maxSteps > 0) if normalization { let (normalizedXVec, xMean, xStd) = normalize(vec: xVec) let (normalizedYVec, yMean, yStd) = normalize(vec: yVec) // Save means and std-s for prediction phase. ...