Winning Kaggle the Reproducible Way

Interactive chapter

This page shows the chapter notebook with its saved results. Constructed examples do not measure competition gains.

Chapter 18: Final Submission Selection

Try the decision first

How much public evidence does it take before the public leaderboard picks as well as a local validation set?

Write your expectation before opening the worked results. Use the chapter activity to compare supported inputs. To change the calculation itself, run the notebook on GitHub.

Your answers stay on this page until you download them. They are not sent to a server.

Open the chapter activity

Worked notebook and saved results

How much public evidence does it take before the public leaderboard picks as well as a local validation set?

Late in a competition the candidates are close, and the public leaderboard is the loudest evidence available. Measuring how often it picks the best candidate tells you when to lean on it and when to lean on local, paired evidence.

Constructed data. The sizes of the effects depend on this generator, on twelve candidates and on a 1,000-row local set; the direction (more rows pick better, pooling beats either source) is the claim, not the numbers.

The experiment

Five constructed binary tasks. For each, twelve gradient-boosting variants (learning rate, leaf count, L2 penalty) are fitted on 2,500 rows and scored by log loss on a pool of 12,000 further rows; the pool mean is each candidate's true loss. In each of 300 random splits per task, 2,000 pool rows form the hidden test set, divided into public rows (the control sets their share) and private rows, and 1,000 other rows form a local validation set. Three rules submit the candidate with the lowest loss on the public rows, on the local rows, or on both pooled. Regret is the true loss of the submitted candidate minus the true loss of the best candidate.

Calculation code
import numpy as np
from sklearn.ensemble import HistGradientBoostingClassifier

from kaggle_companion.activities._common import clean

SEED = 18
WORLDS = 5          # independent training sets, each with its own twelve fitted candidates
DRAWS = 300         # random hidden splits per training set
N_TRAIN, N_POOL = 2500, 12000
N_TEST, N_LOCAL = 2000, 1000   # hidden test rows (public + private) and a separate local validation set
# Twelve gradient-boosting variants: learning rate x leaf count x L2 penalty. All are reasonable, so they sit close together.
CONFIGS = [(lr, leaves, l2) for lr in (0.04, 0.08) for leaves in (4, 6, 10) for l2 in (0.0, 8.0)]
RULES = ("public", "local", "pooled")


def candidate_losses(seed):
    """Fit every candidate once and return each pool row's log loss under each candidate (rows x candidates)."""
    rng = np.random.default_rng(seed)
    w = rng.normal(0, 0.45, 8)

    def rows(n):
        X = rng.normal(size=(n, 8))
        logit = X @ w + 0.6 * X[:, 0] * X[:, 1] + 0.5 * np.maximum(X[:, 2], 0) - 0.2
        return X, (rng.random(n) < 1 / (1 + np.exp(-logit))).astype(int)

    X_train, y_train = rows(N_TRAIN)
    X_pool, y_pool = rows(N_POOL)       # a large pool: its mean loss is the "true" loss of each candidate
    columns = []
    for lr, leaves, l2 in CONFIGS:
        model = HistGradientBoostingClassifier(learning_rate=lr, max_leaf_nodes=leaves, l2_regularization=l2,
                                               max_iter=50, early_stopping=False, random_state=0)
        columns.append(np.clip(model.fit(X_train, y_train).predict_proba(X_pool)[:, 1], 1e-3, 1 - 1e-3))
    p = np.column_stack(columns)
    return -(y_pool[:, None] * np.log(p) + (1 - y_pool[:, None]) * np.log(1 - p))


def run(public_fraction):
    n_public = int(public_fraction * N_TEST)
    stats = {rule: {"regret": [], "best": [], "rank": [], "optimism": []} for rule in RULES}
    gaps = []
    for w in range(WORLDS):
        loss = candidate_losses(SEED * 100 + w)
        truth = loss.mean(0)                                   # true log loss of each candidate
        best = int(np.argmin(truth))
        gaps.append(np.sort(truth)[1] - truth[best])
        rng = np.random.default_rng(SEED * 1000 + w)
        for _ in range(DRAWS):
            order = rng.permutation(len(loss))
            test, local = order[:N_TEST], order[N_TEST:N_TEST + N_LOCAL]
            public, private = test[:n_public], test[n_public:]
            private_loss = loss[private].mean(0)               # what the final standings will use
            scores = {"public": loss[public].mean(0), "local": loss[local].mean(0),
                      "pooled": (loss[public].sum(0) + loss[local].sum(0)) / (n_public + N_LOCAL)}
            for rule, score in scores.items():
                pick = int(np.argmin(score))                   # the candidate each evidence source would submit
                stats[rule]["regret"].append(truth[pick] - truth[best])
                stats[rule]["best"].append(pick == best)
                stats[rule]["rank"].append(1 + int((private_loss < private_loss[pick]).sum()))
                stats[rule]["optimism"].append(truth[pick] - score[pick])   # how much better the evidence said it was
    return clean({
        "public_fraction": public_fraction, "public_rows": n_public, "private_rows": N_TEST - n_public,
        "local_rows": N_LOCAL, "candidates": len(CONFIGS), "worlds": WORLDS, "draws": WORLDS * DRAWS,
        "gap_to_second": float(np.mean(gaps)),
        "rules": {rule: {"regret": float(np.mean(s["regret"])), "p_best": float(np.mean(s["best"])),
                         "private_rank": float(np.mean(s["rank"])), "optimism": float(np.mean(s["optimism"])),
                         "regret_se": float(np.std(s["regret"]) / np.sqrt(len(s["regret"])))}
                  for rule, s in stats.items()},
    }, digits=6)   # regrets are a few ten-thousandths of log loss: keep enough digits to tell the rules apart

Measure it across the control

The control is share of the 2,000 hidden test rows that are public. Each value below runs the whole experiment from the generator up.

Calculation code
import pandas as pd
from kaggle_companion.activities.ch18 import explain

VALUES = [0.05, 0.1, 0.25, 0.5]
results = {value: run(value) for value in VALUES}
table = pd.DataFrame({str(v): explain(results[v], v)['metrics'] for v in VALUES})
print(table.to_string())
                               0.05      0.1     0.25      0.5
Public rule picks the best    0.529    0.594    0.711    0.781
Local rule picks the best     0.796    0.796    0.796    0.796
Pooled rule picks the best    0.811    0.818    0.847    0.884
Public rule regret          0.00269  0.00162  0.00076  0.00050
Public winner's optimism    0.00628  0.00277  0.00116  0.00059

Look at it

The figure shows the default setting, share of the 2,000 hidden test rows that are public = 0.1.

Calculation code
import matplotlib.pyplot as plt
from kaggle_companion.activities.ch18 import draw, NCOLS, HEIGHT

DEFAULT = 0.1
fig, axes = plt.subplots(1, NCOLS, figsize=(6.6 if NCOLS == 1 else 10.4, HEIGHT), layout='constrained')
draw(axes, results[DEFAULT], DEFAULT)
plt.show()
Saved figure from this chapter calculation

What the result says

With 200 public rows out of 2000, the public rule submits the best of 12 candidates in 0.594 of splits and the 1000-row local rule in 0.796. Mean regret is 0.00162 against 0.00044, so 0.00162 - 0.00044 = 0.00118. Local rows pick better than the 200 public rows. Pooling gives 0.00039. The public winner's score is 0.00277 better than its true loss, so a winning public score overstates it.

Apply this to your competition

Book location: Chapter 18, Simulating Public/Private Split Stability.

Technical corrections

Apply a lesson from this chapter

Select a lesson whose conditions match your project. State how you would test it and what would make you reject it.

Reassemble stacked-response predictions by entity keys

Conditions

  • one long-format model predicts multiple targets per entity

Action

  • Proposed: check identical entity keys for each target before recombining wide outputs.

Check

  • Proposed: assert key vectors and cardinalities match or join target outputs explicitly on ID before binding.

Limits

  • Assertions/joins are proposed. Sorting alone does not prove all three target subsets contain identical entities.

Find source links and value grades in the lesson atlas

Verify required submission columns before judging a model

Conditions

  • a challenge excludes a named class column

Action

  • Proposed conditional application: Check the submission schema and remove excluded class columns before upload.

Check

  • Proposed check: Compare generated columns, ordering and row IDs against the official schema; round-trip a small known prediction fixture before upload.

Limits

  • The excluded author040column is challenge-specific; general schema validation requires the current task contract.

Find source links and value grades in the lesson atlas

Enforce order and nonnegativity in quantile predictions

Conditions

  • separate quantile regressors yield incoherent forecasts

Action

  • Proposed conditional application: Clip negative forecasts and enforce lower quantile ≤ median ≤ upper quantile.

Check

  • Proposed check: Assert nonnegativity/order and compare pinball loss plus empirical coverage before/after correction.

Limits

  • Nonnegativity only applies to nonnegative targets; ordering does not ensure calibrated intervals.

Find source links and value grades in the lesson atlas

Route corrupt sequences through an explicit fallback

Conditions

  • corrupt short landmark sequences produce unreliable text outputs

Action

  • Proposed adaptation of source observation: Compare confidence/length-based fallback routing against ordinary decoding using a task-appropriate fallback.

Check

  • Proposed verification: Measure edit distance separately on corrupt and clean validation inputs and tune thresholds out of sample.

Limits

  • The dummy phrase exploits the competition’s phrase distribution and metric; it is not an appropriate universal production answer.

Find source links and value grades in the lesson atlas

Train at the precision used for exported inference

Conditions

  • padded training must export to variable-length fp16 TFLite inference

Action

  • Proposed conditional application: Compare fp16 training with fp32 training when the exported inference path uses fp16.

Check

  • Proposed check: Evaluate matched models before and after export on identical sequences under both precisions; inspect conversion parity.

Limits

  • Training/export precision and CV/LB evaluation differ; no universal causal drop is established.

Find source links and value grades in the lesson atlas

Prefer a validated structured classifier and usable OCR over heavier alternatives

Conditions

  • structured metadata and text parsing compete with expensive LLM inference

Action

  • Proposed adaptation of source observation: Compare structured and LLM classifiers plus parsing alternatives by complete-task F1 and runtime.

Check

  • Proposed verification: Evaluate the same references and quantify downstream quality gained per additional parsing minute.

Limits

  • Negative results were not exhaustively tuned and higher-quality OCR may help under larger budgets.

Find source links and value grades in the lesson atlas

Evaluate confidence-based fallback with coverage-risk curves

Conditions

  • a scientific surrogate can send difficult cases to a costly reference solver
  • a confidence head identifies difficult simulation cases

Action

  • Proposed adaptation of source observation: Plot quality versus retained coverage and compare confidence ranking with domain-based difficulty before proposing simulator fallback.
  • Proposed conditional application: Measure prediction quality against retained coverage and test simulator fallback for rejected cases.

Check

  • Proposed verification: Evaluate complete hybrid quality including rejected cases and solver cost.
  • Proposed check: Plot error versus retained coverage, then compare total hybrid error/runtime including fallback cases.

Limits

  • Higher score after discarding cases does not improve full-population quality; fallback was not demonstrated and weighted blending failed only preliminarily.
  • The source does not establish when the selective-risk analysis occurred or give a numeric full-population baseline; approximately 0.83+ is a retained-subset result.
  • Selective R2 is not full-coverage improvement; fallback may be expensive and confidence may correlate with geography.
  • Approximately 0.83+ is a retained-subset result for one model at approximately ninety percent coverage; the full-population numeric baseline and timing of the analysis are not established.

Find source links and value grades in the lesson atlas

Mask targets that are legitimately overridden at submission

Conditions

  • Evaluation outputs have legitimate prescribed replacement rules.

Action

  • Exclude targets replaced by the documented output rule from learned loss.

Check

  • Audit target-mask correspondence with evaluation rules and compare retained-target quality against unmasked training.

Limits

  • Physical replacement details are linked elsewhere; no isolated mask ablation is supplied.
  • Training fidelity mixture and batch-size tuning are separate choices.

Find source links and value grades in the lesson atlas

Select predictions by expected metric quality rather than confidence

Conditions

  • the detection metric does not penalize omitted instances

Action

  • Proposed conditional application: Learn per-prediction AP using category, confidence, mask and attribute features, then select the best prediction per image.

Check

  • Proposed check: Fit quality regressor on OOF proposals; compare confidence/AP selection on separate images and report omitted-instance recall.

Limits

  • Single-instance selection exploits this metric and harms full garment detection; AP-derived inputs can leak.

Find source links and value grades in the lesson atlas

Plan model porting for a constrained inference runtime

Conditions

  • training framework differs from required mobile inference runtime

Action

  • Proposed adaptation of source observation: Maintain an equivalent deployment architecture, transfer weights and export the final artifact; consider cached decoding.

Check

  • Proposed verification: Proposed: compare logits and decoded outputs across frameworks and profile the exported artifact.

Limits

  • Manual porting needs careful numerical parity checks; supported operations and conversion tooling change.

Find source links and value grades in the lesson atlas

Map supplemental test IDs explicitly to submission IDs

Conditions

  • features use supplemental test rows beyond submission rows

Action

  • Proposed adaptation of source observation: Maintain an explicit ID mapping when generating features on the full supplemental dataset.

Check

  • Proposed verification: Assert one-to-one coverage and submission order after joining predictions to requested IDs.

Limits

  • The packet does not establish how supplemental rows affect each feature or their gain.

Find source links and value grades in the lesson atlas

Carry padding masks through the exported sequence path

Conditions

  • training uses padded sequences but inference uses variable sequence length

Action

  • Proposed conditional application: Mask padded time positions through feature extraction and encoder layers and verify the converted model on variable-length examples.

Check

  • Proposed check: Compare padded versus unpadded outputs and original versus exported outputs across short, long, and all-missing sequences.

Limits

  • Mask semantics and padded convolutions are framework-dependent; historical conversion instructions are not proof of current parity.

Find source links and value grades in the lesson atlas

Measure exported artifact size under mixed precision

Conditions

  • deployed sequence ensemble has a strict artifact-size cap

Action

  • Proposed adaptation of source observation: Measure the actual exported ensemble size and compare fp16 with fp32.

Check

  • Proposed verification: Check post-export accuracy, supported operators and total artifact bytes including metadata.

Limits

  • The final artifact was very close to its cap; mixed precision can introduce numerical failures.

Find source links and value grades in the lesson atlas

Budget multi-stage expert inference by complete artifact pipeline

Conditions

  • expert ensembles have many preprocessing and prediction stages

Action

  • Proposed adaptation of source observation: Persist stage artifacts and estimate complete runtime/memory before choosing experts over a global baseline.

Check

  • Proposed verification: Check row-ID assembly and marginal expert contribution against total cost.

Limits

  • Expert selection mechanics are absent and listed runtime depends strongly on hardware/RAM.

Find source links and value grades in the lesson atlas

Separate postcompetition fusion improvements from the submitted recipe

Conditions

  • a solution writeup includes experiments performed after the deadline

Action

  • Proposed recipe: label weighted-box-fusion variants by timing and compare their speed as well as scores.

Check

  • Proposed check: Keep submitted and later recipes separately versioned and compare fusion quality and latency on untouched boxes with matched inputs.

Limits

  • Postcompetition fusion was not part of the submitted recipe; baseline0.220has noexplicitpublicmetriclabel, so comparison context remains limited.

Find source links and value grades in the lesson atlas

Persist the full preprocessing contract for inference

Conditions

  • models require imputation selection scaling and category encoders

Action

  • Proposed: reload fitted preprocessing artifacts and apply them in their original order before prediction.

Check

  • Proposed: compare training and inference feature names, order and transformed values on a stored sample; keep transforms fold-local during validation.

Limits

  • This source shows an implementation, without an isolated gain, execution result, or confirmed final-submission provenance. Historical dependencies and dataset assumptions require local checks.

Find source links and value grades in the lesson atlas

Carry transformed row identity into submissions

Conditions

  • feature transformations may retain or remove source rows

Action

  • Proposed: retrieve output IDs using the transformed feature index before pairing with predictions.

Check

  • Proposed: assert one prediction per transformed row and reset or explicitly align the index of both IDs and prediction series.

Limits

  • The prediction Series uses a default index while selected IDs retain source indices, so alignment must be checked when transformations change row indices.

Find source links and value grades in the lesson atlas

Carry manifest IDs through batched ensemble inference

Conditions

  • submission rows require stable identifiers

Action

  • Proposed conditional application: Return manifest indices from the dataset and sort the completed index/prediction table before writing the submission.

Check

  • Proposed check: Shuffle manifest/input order and assert one prediction per original ID with exact submission membership.

Limits

  • Implementation only; duplicate/missing IDs still require explicit checks.

Find source links and value grades in the lesson atlas

Archive raw and rank predictions separately

Conditions

  • ordinal model comparison uses rank-based calibration

Action

  • Proposed: save both raw predictions and their double-argsort ranks as distinct artifacts.

Check

  • Proposed: test tie handling and compare raw versus rank calibration on validation; assert ID order before reusing stored predictions.

Limits

  • The calibration function is imported and not shown; double argsort imposes an order on ties. The source does not establish an improved rank-calibration result.

Find source links and value grades in the lesson atlas

Reserve a structurally simpler final candidate when two submissions are allowed

Conditions

  • two final submissions can hedge model-selection uncertainty

Action

  • Proposed adaptation of source observation: Select a competitive simpler candidate alongside the strongest validation candidate when their failure risks differ.

Check

  • Proposed verification: Use comparable holdouts and examine prediction disagreement rather than assuming complexity alone predicts generalization.

Limits

  • The author’s assertion that simpler means less overfitting is not a proven mechanism; no paired private errors are reported here.

Find source links and value grades in the lesson atlas

Preserve precision at scientific normalization boundaries

Conditions

  • large-scale physical targets need de-normalization

Action

  • Proposed conditional application: Store/process original values in FP64, cast model inputs to FP32, then upcast predictions before de-normalization.

Check

  • Proposed check: Compare inverse-transform errors in FP32/FP64 on large-magnitude targets against high-precision reference.

Limits

  • Upcasting cannot recover information already lost in model output; storage/preprocessing cost increases.

Find source links and value grades in the lesson atlas

Separate training and tuning stages for newly released data

Conditions

  • competition releases additional labeled data midstream

Action

  • Proposed adaptation of source observation: Track release provenance and keep training, tuning and OOF prediction artifacts separate across stages.

Check

  • Proposed verification: Audit split provenance and ensure OOF rows were unseen by producing models.

Limits

  • The packet gives orchestration but not the full split protocol; historical data releases are competition-specific.

Find source links and value grades in the lesson atlas

Preserve resource-limited experiment status

Conditions

  • label-priority experiments compete with a submission deadline

Action

  • Proposed adaptation of source observation: Track which models actually use the experimental loss and stop expanding unsupported changes when the budget is exhausted.

Check

  • Proposed verification: Compare primary and secondary-label performance against the standard loss before retaining it.

Limits

  • The source reports an unfinished resource-limited attempt, not proof of failure.

Find source links and value grades in the lesson atlas

Map classifier indices to required submission labels

Conditions

  • model outputs zero-based classes but the submission expects one-based labels

Action

  • Proposed conditional application: Translate raw labels 0–4 into submission labels 1–5.

Check

  • Proposed check: Assert mapping on all five classes, output label range and sample-submission schema.

Limits

  • Offset applies only to this declared label mapping, not arbitrary ordered categories.

Find source links and value grades in the lesson atlas

Keep per-model training and inference configuration together

Conditions

  • many architecture and hyperparameter configurations are being tested

Action

  • Proposed recipe: store model-specific YAML configurations and track training and validation measurements.

Check

  • Proposed check: Bind config and metric logs to code/data hashes and checkpoints and regenerate one model's inference outputs from its saved configuration.

Limits

  • Configuration files alone omit mutable data and dependencies unless versioned; source supplies no verified replay.

Find source links and value grades in the lesson atlas