Enumerating Grid Search and Avoiding Hyperparameter Explosion
You are building a hyperparameter optimization service that must enumerate every grid-search combination. The input is a Python dict mapping parameter names to candidate values, for example {'learning_rate': [0.1, 0.2], 'feature': ['A', 'B'], 'batch': [10, 20]}.
Constraints & Assumptions
-
The enumerator should be lazy and memory efficient.
-
It should support any number of parameters.
-
The output for each combination should be a dict mapping parameter name to chosen value.
-
Discuss alternatives when the full Cartesian product is too large.
Clarifying Questions to Ask
-
Should the generator preserve input key order?
-
How should empty grids or empty candidate lists be handled?
-
Are candidate values hashable or serializable?
-
Is exhaustive grid search required, or can the service sample candidates?
Part 1 - Python Generator
Write a Python generator that lazily yields all combinations as dictionaries.
What This Part Should Cover
-
Use
itertools.product
or recursive backtracking.
-
Avoid materializing all combinations in memory.
-
Yield one dict per combination.
-
Explain time complexity as the product of candidate-list lengths and space complexity per yielded item.
Part 2 - Avoiding Combinatorial Explosion
Discuss practical alternatives for huge grids.
What This Part Should Cover
-
Include random search, Bayesian optimization, Hyperband, successive halving, Sobol or Latin hypercube sampling, adaptive search, and coarse-to-fine grids.
-
Use early stopping, pruning, parallelism, warm starts, and budget constraints.
-
Prioritize high-impact hyperparameters and narrow ranges using prior knowledge.
-
Track experiment metadata for reproducibility.
Follow-up Questions
-
How would you count combinations without enumerating them?
-
What should happen if one parameter has an empty candidate list?
-
When is random search better than grid search?