Model Development · Topic 4 of 5

Cross Validation and Grid Search

Databricks ML Associate: cross validation vs a train validation split, CrossValidator in Spark ML, and counting the models a grid search trains.

  • 5 min
  • Includes a diagram
In a nutshell
  • Cross-validation averages k scores per setting; a train-validation split uses one score.
  • Cross-validation is more reliable but costs about k times more compute.
  • CrossValidator needs an estimator, a param grid and an evaluator; numFolds defaults to 3.

What it is

To pick hyperparameters you need a score on data the model did not train on. A train-validation split holds out one part of the training data once. Cross-validation (k-fold) splits the training data into k folds, trains k times, and each time scores on the fold that was left out.

Spark ML offers both as estimators: TrainValidationSplit and CrossValidator. Each takes a model or pipeline, a grid of hyperparameter settings and an evaluator, then refits the best setting on all the training data.

Training dataSplit into k foldsTrain on k minus 1 foldsscore the held out foldAverage k scores per settingRefit best settingon all training data

How it works

Cross-validation versus a train-validation split

Train-validation splitk-fold cross-validation
Models per setting1k
Score per settingOne validation scoreAverage of k scores
ReliabilityDepends on one random splitMore stable, every row is validated once
Compute costLowAbout k times higher
Best forLarge data, tight time budgetSmaller data, when a fair comparison matters

The benefit of cross-validation is a more reliable estimate that uses all the training rows for both training and validation. The downside is cost: with 5 folds, every setting trains 5 models instead of 1.

Keep a separate test set outside both methods. Cross-validation chooses hyperparameters; the test set gives the final, unbiased score.

Performing cross-validation in Spark ML

from pyspark.ml.tuning import CrossValidator, ParamGridBuilder
from pyspark.ml.evaluation import RegressionEvaluator
grid = (ParamGridBuilder().addGrid(rf.maxDepth, [4, 8, 12])
        .addGrid(rf.numTrees, [50, 100]).build())
cv = CrossValidator(estimator=pipeline, estimatorParamMaps=grid,
                    evaluator=RegressionEvaluator(labelCol="price", metricName="rmse"),
                    numFolds=3, parallelism=4, seed=42)
cv_model = cv.fit(train_df)

cv.fit() returns a CrossValidatorModel. Its bestModel is the pipeline refitted on all of train_df with the best setting, and avgMetrics holds the average score of each grid setting in grid order.

ParameterMeaning
estimatorThe model or whole pipeline to tune
estimatorParamMapsThe grid from ParamGridBuilder
evaluatorThe metric used to compare settings
numFoldsk, default 3
parallelismHow many models train at the same time, default 1

The evaluator knows whether larger is better: RMSE is minimized, R squared and AUC are maximized. TrainValidationSplit has the same shape with trainRatio (default 0.75) instead of numFolds.

Pipeline inside cross-validation, or cross-validation inside the pipeline

PlacementWhat happensTrade-off
Pipeline as the CrossValidator estimatorEvery fold refits all preprocessing stagesNo leakage between folds, more work
CrossValidator as the last pipeline stagePreprocessing is fitted once on all training dataFaster, but fold scores see preprocessing learned from held out rows

Put the whole pipeline inside the CrossValidator when preprocessing learns statistics (imputer means, scaler values). Put the CrossValidator inside the pipeline when the earlier stages are cheap to share and you want speed.

Counting the models trained

Counting models: a grid of 3 x 2 values gives 6 settings; 3-fold cross-validation trains 6 x 3 = 18 models, the setting with the best average metric is refit once on all the data, so 19 models are trained in total. The formula is grid settings x folds + 1 for cross-validation, and grid settings + 1 for a train-validation split. The +1 is the final refit of the best setting on all training data.

GridMethodModels trained
3 maxDepth x 2 numTrees = 6 settings3-fold CrossValidator6 x 3 + 1 = 19
6 settingsTrainValidationSplit6 + 1 = 7
4 x 3 x 2 = 24 settings5-fold CrossValidator24 x 5 + 1 = 121
Hyperopt with max_evals=30, each trial using 3-fold CVfmin30 x 3 = 90, plus any final refit you run

Multiply the number of values of every parameter to get the settings first. Parallelism changes how fast the models train, not how many.

How the exam asks about this

  • "A grid of 4 regParam values and 3 elasticNetParam values with 5 folds." That is 4 x 3 x 5 + 1 = 61 models.
  • "The dataset is huge and tuning must finish quickly." Use a train-validation split, which trains one model per setting.
  • "The tuned pipeline must score new data." Use cv_model.bestModel, already refitted on all training data.

What to remember for the exam

  • Cross-validation averages k scores per setting; a train-validation split uses one score.
  • Cross-validation is more reliable but costs about k times more compute.
  • CrossValidator needs an estimator, a param grid and an evaluator; numFolds defaults to 3.
  • Models trained = settings x k + 1 for CrossValidator, settings + 1 for TrainValidationSplit.
  • bestModel is refitted on the full training data; avgMetrics lists each setting's average score.
  • Keep a separate test set for the final score.
Watch out

Grid size is the product of the value counts, not their sum. Three parameters with 3, 4 and 5 values give 60 settings, not 12.

Common mistakes

Forgetting the final refit. After choosing the best setting, CrossValidator and TrainValidationSplit train one more model on all training data. Leave out the +1 and the count is wrong.

Reporting the cross-validation score as the final result. The best average was selected from many settings, so it is optimistic. Score bestModel on a held out test set.

Assuming parallelism reduces the work. Raising parallelism trains several models at once. The total number of models stays the same.

Check yourself

  • How many models does a 5-fold CrossValidator train over a grid of 2 x 5 settings?

    10 settings x 5 folds = 50, plus one refit of the best setting, so 51 models.

  • What is the main downside of cross-validation compared with a train-validation split?

    Compute cost, since each setting trains k models instead of one.

  • What does CrossValidatorModel.bestModel contain?

    The estimator or pipeline refitted on all the training data with the best hyperparameter setting.

Topic 4 of 5 in Model Development

Test yourself on Model Development

The full Databricks Machine Learning Associate question bank has 600 questions, with timed practice exams and an explanation for every answer.

This study guide is independent and is not affiliated with, endorsed by, or sponsored by Databricks. Vendor names, certification names and exam codes are trademarks of their respective owners and are used for identification only.