Calculating the `trainError` seems to require two Spark stages.  Is this because we call `numRows` twice, forcing `trainVsTest` to be evaluated twice?  Should we cache `trainVsTest` to speed this up?  Or should the second `numRows` call be replaced with a call to `featurizedData.numRows`, since that dataset should have the same number of rows and already be cached?