Spark
Random Forests
Machine Learning
Seed Variability
Data Science

Spark Random Forests Different results with same seed

ML System Design practice on Codemia

Design recommenders, ranking systems and training pipelines the way ML interviews actually ask for them, with worked solutions.

Practice ML system design

Introduction

Setting the same seed in Spark does not always guarantee identical random forest results across runs. The seed controls the algorithm's random choices, but Spark still executes training in a distributed system where row order, partitioning, and floating-point reductions can vary. If you need stable results, you have to control the input pipeline as well as the model seed.

What the Seed Actually Controls

In Spark ML, the seed parameter affects stochastic parts of the algorithm such as sampling and feature selection. It does not freeze every detail of distributed execution.

A typical training setup looks like this:

python
1from pyspark.ml.classification import RandomForestClassifier
2from pyspark.sql import SparkSession
3
4spark = SparkSession.builder.getOrCreate()
5
6train_df = spark.createDataFrame([
7    (0.0, [0.1, 1.0]),
8    (1.0, [0.2, 0.9]),
9    (0.0, [0.9, 0.1]),
10    (1.0, [1.0, 0.2]),
11], ["label", "features"])
12
13rf = RandomForestClassifier(
14    labelCol="label",
15    featuresCol="features",
16    numTrees=20,
17    maxDepth=4,
18    seed=1234,
19)
20
21model = rf.fit(train_df)
22print(model.toDebugString)

If everything upstream is identical, the seed usually helps. But if the DataFrame arrives with different partition boundaries or row ordering, the resulting trees can still differ.

Why Results Can Change Anyway

Three sources of variation matter most in Spark.

1. Partitioning and Row Order

Spark DataFrames are distributed collections, not ordered tables. If the input is produced by joins, file scans, or shuffles, the row order can change between runs. Some ML algorithms behave slightly differently when ties or split candidates are encountered in a different order.

2. Floating-Point Aggregation

Distributed computation changes the order in which partial statistics are combined. Floating-point addition is not perfectly associative, so tiny numeric differences can appear. In tree algorithms, a tiny difference in impurity gain can change which split wins when candidate splits are close.

3. Pipeline Stages Before the Forest

If you split the data randomly, sample it, or assemble features in a non-deterministic way before calling fit, the random forest sees different training data even though the forest seed itself is fixed.

Make the Pipeline More Deterministic

If you want repeatable models, stabilize the data before training.

python
1from pyspark.ml.classification import RandomForestClassifier
2from pyspark.sql import SparkSession
3from pyspark.sql.functions import col
4
5spark = SparkSession.builder.getOrCreate()
6
7stable_df = raw_df.orderBy(col("id")).repartition(8).cache()
8stable_df.count()
9
10rf = RandomForestClassifier(
11    labelCol="label",
12    featuresCol="features",
13    numTrees=50,
14    maxDepth=6,
15    seed=1234,
16)
17
18model = rf.fit(stable_df)

This does not create a legal guarantee of bit-for-bit identity across every cluster environment, but it removes two major sources of drift:

  • unstable row order
  • changing partition layout from lazy recomputation

The count() call materializes the cached DataFrame so later stages do not rebuild it differently.

Stabilize Train/Test Splits Too

Many "same seed, different result" reports are really about data splitting rather than the forest itself. If you do a random split, fix that seed and preserve the resulting DataFrames.

python
1train_df, test_df = stable_df.randomSplit([0.8, 0.2], seed=42)
2train_df = train_df.cache()
3test_df = test_df.cache()
4train_df.count()
5test_df.count()

If you rerun the split from an unstable upstream DataFrame, the resulting partitions can still vary. That is why the ordering and caching step comes first.

Know What Level of Reproducibility You Need

There is a difference between statistical reproducibility and byte-for-byte reproducibility.

For most data science work, it is enough that repeated runs with the same seed produce very similar metrics. Exact tree structure identity is a stricter goal and is harder in distributed systems.

If exact reproducibility matters for audits, you should also pin:

  • Spark version
  • JVM version
  • cluster size and executor settings
  • input files and their ordering
  • preprocessing code and partition logic

Common Pitfalls

  • Assuming the model seed controls every distributed operation in the pipeline.
  • Training on a DataFrame whose row order changes between runs.
  • Comparing results across different cluster sizes or Spark versions.
  • Forgetting to fix the seed on randomSplit or other sampling steps.
  • Expecting bit-for-bit identical trees when only statistical stability is actually required.

Summary

  • In Spark, a fixed random forest seed does not automatically make the whole pipeline deterministic.
  • Row order, partitioning, and floating-point aggregation can still change the trained model.
  • Sort, repartition, cache, and materialize the training data before fitting.
  • Fix the seeds for train/test splitting and any earlier sampling steps.
  • Decide whether you need exact reproducibility or only stable model quality, because those are different goals.

Related reading
Course
Beginner
27 lessons
10 hours
System Design Fundamentals

Build a strong foundation in designing scalable, reliable distributed systems.

View the course
Track what you have practised

A free account saves your progress, solutions and study plan across every problem on Codemia.

ML System Design practice on Codemia

Design recommenders, ranking systems and training pipelines the way ML interviews actually ask for them, with worked solutions.

Practice ML system design

All Rights Reserved.