kaggle-submission-format-by-metric
Skill5 starsChanged 37 days agoMITView on GitHub
Match the submission file format to the competition's evaluation metric BEFORE submitting. For ranking-based metrics (AUC, log_loss, MAP, NDCG, RMSLE) you MUST submit continuous probability/score values, not 0/1 class labels or rounded integers. Use when: (1) Preparing the final submission for any Kaggle competition, (2) AutoGluon's default `predict()` returns class labels for classification (must use `predict_proba()`), (3) Unsure whether to threshold predictions, (4) CV score is excellent but LB score is near-random. Real failure case: S6E2 Heart Disease rerun 2026-06-14 — OOF AUC 0.95554 dropped to Public LB 0.88403 with 0/1 submission, recovered to 0.95357 with probability submission.
In this repository63 other files it gives its agents.
- AGENTS.mdAGENTS.md
- adversarial-validation-kaggleSkill
- agent-nurture-frameworkSkill
- agent-session-memory-protocolSkill
- arxiv-paper-searchSkill
- autogluon-firstSkill
- autogluon-preset-strategySkill
- autogluon-timeseries-strategySkill
- catboost-first-tabularSkill
- claudeceptionSkill
- code-competition-artifact-pipelineSkill
- competition-orchestration-multimodelSkill
- context-engineeringSkill
- controlled-submission-experimentSkill
- cross-competition-feature-transferSkill
- cv-lb-gap-acknowledgmentSkill
- domain-knowledge-constraints-trapSkill
- ensemble-model-correlation-trapSkill
- feature-engineering-saturation-detectionSkill
- gpu-readiness-assessmentSkill
- gsd-loop-engineeringSkill
- kaggle-cognitive-cost-optimizationSkill
- kaggle-competition-best-practicesSkill
- kaggle-competition-type-strategySkill
- kaggle-data-format-firstSkill
- kaggle-discussion-searchSkill
- kaggle-experiment-sopSkill
- kaggle-oof-lb-validation-protocolSkill
- kaggle-optimal-blendingSkill
- kaggle-top-performer-replicationSkill
- knowledge-crystallization-feedback-loopSkill
- ladder-drift-and-meta-aware-regressionSkill
- learned-value-beats-heuristic-augmentationSkill
- llm-competition-pipelineSkill
- mcts-pipeline-searchSkill
- mem0-dynamic-graph-memorySkill
- memory-hierarchy-managementSkill
- ml-sweet-spot-principleSkill
- model-ensemble-negative-weight-effectSkill
- multi-agent-rolesSkill
- multi-level-aggregation-overfittingSkill
- okf-visualize-knowledgeSkill
- onnx-minimal-network-designSkill
- per-category-modeling-backfireSkill
- progressive-verification-debuggingSkill
- ptcg-2ply-bounded-searchSkill
- ptcg-bc-large-model-submissionSkill
- retail-eda-frameworkSkill
- rmsle-zero-threshold-asymmetrySkill
- runtime-reflexionSkill
- sc-tir-mathematical-reasoningSkill
- self-evolving-skillsSkill
- skill-governance-and-automationSkill
- spatiotemporal-graph-feature-engineeringSkill
- store-sales-darts-chronos-blendSkill
- tabular-polynomial-features-breakthroughSkill
- three-layer-wisdom-extractionSkill
- time-series-walk-forward-validationSkill
- trueskill-simulation-competition-strategySkill
- ts-day-specific-forecastingSkill
- The first 60 shown.
The file
We split this skill into the rules it gives an agent
1 rule. About 0 are common, 0 are distinctive, and 1 is very specific to this project.
≈0
Common · estimate
Many files like this have a rule of this kind.
≈0
Distinctive · estimate
This author's own choices. Worth a look.
1
Very specific
Tied to their project's names, files or tools. Probably skip.
- Common
- Distinctive
- Very specific
- Very specific: line 137
Fix: use predictor.predict(test) (hard labels) instead of predict_proba() for accuracy-style metrics.
≈ “Common” is an estimate: at least 1 in 5 of the 350,495 skill files we read have a rule of the same kind, not the same words. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.
Files
Match Submission Format to Evaluation Metric
Problem
A perfect model can score near-random on the public leaderboard if the submission file format doesn't match the metric's expectations. The most common mistake: submitting 0/1 thresholded labels for a metric that needs continuous probabilities.
Real failure case (2026-06-14, S6E2 Heart Disease):
- Model: AutoGluon best_quality ensemble, OOF AUC 0.95554
- Submission A:
submission_autogluon.csv(0/1 thresholded viapredictor.predict())- Public LB: 0.88403 ❌ (looked like complete model failure)
- Private LB: 0.88643
- Submission B:
submission_autogluon_proba.csv(continuous viapredictor.predict_proba())- Public LB: 0.95357 ✅
- Private LB: 0.95510
- Same model, same OOF — only the submission format differed. 0.07 LB drop from thresholding alone.
Context / Trigger Conditions
Use this skill when:
- About to submit the final (or any) prediction to a Kaggle competition
- AutoGluon / sklearn / xgboost default
predict()returns hard labels for classification - Competition metric is ranking-based (see list below)
- CV score is great but LB score is suspiciously low
- You see
sample_submission.csvwith 0.0/1.0 values (those are the target format, NOT necessarily the submission format)
DO NOT threshold for ranking-based metrics:
roc_auc,auc— area under ROC; needs continuous scoresauc_mu— multi-class AUC; needs full probability matrixlog_loss— penalizes confident wrong answers; needs probabilitiesMAP,NDCG— ranking metrics; need scoresbrier_score— squared error on probabilitiesmean_columnwise_auc— column-wise AUCrmseon log-target (RMSLE) — for log-transformed regression, submit log predictions directly
DO threshold (or round) for these metrics:
accuracy— predicted class labelf1,precision,recall— predicted class labelquadratic_kappa— rounded integer (for ordinal)mae,rmseon raw target — continuous regression predictions are fine, but rounding is harmless
Solution: Metric → Format Decision Tree
Is metric ranking-based (AUC, log_loss, MAP, NDCG, etc.)?
├── YES → Submit continuous probabilities / scores
│ AutoGluon: predictor.predict_proba(test)
│ sklearn: model.predict_proba(test)
│ xgboost: model.predict_proba(test)
│
└── NO (accuracy, f1, kappa, etc.)
└── Submit class labels (or rounded regression values)
AutoGluon: predictor.predict(test)
sklearn: model.predict(test)Quick reference per framework
AutoGluon:
# WRONG for AUC:
preds = predictor.predict(test) # hard labels
# CORRECT for AUC:
preds = predictor.predict_proba(test) # probability DataFrame
# For multi-class AUC, submit the full matrix; column order matters
# and must match sample_submission.csv column order.scikit-learn:
# WRONG for AUC:
preds = model.predict(test) # hard labels
# CORRECT for AUC:
preds = model.predict_proba(test)[:, 1] # positive class probabilityXGBoost / LightGBM / CatBoost:
# For binary AUC:
preds = model.predict_proba(test)[:, 1]
# For multi-class AUC (sklearn API):
preds = model.predict_proba(test) # full matrix
# For multi-class AUC (learning API):
preds = model.predict(test) # this IS probabilities in raw APICheck sample_submission.csv carefully
head -3 sample_submission.csv- Values are all
0and1→ metric isaccuracy/f1etc. → submit class labels - Values are
0.0and1.0with target column → likely a target template (binary outcome), but metric is probably AUC. Submit probabilities anyway. - Values are floats in [0, 1] → metric is
log_loss/probability calibration → submit probabilities - Values are integers in [0, 9] →
quadratic_kappa/ordinal → submit integers - Values are floats with no obvious range → regression, submit raw predictions
- Values are strings like
Low/Medium/High→ multi-class classification withaccuracy/balanced_accuracyetc. → submit hard labels, NOT probability matrix (S6E4 trap!)
Always cross-check the metric on the competition's Overview page, not the sample file.
S6E4 mirror bug (the inverse of S6E2)
The S6E2 bug was "AUC wanted proba, I sent 0/1". The S6E4 bug is the mirror: accuracy wanted hard labels, I sent a probability matrix.
S6E4 sample_submission.csv:
id,Irrigation_Need
630000,Low
630001,LowIf you submit:
id,High,Low,Medium
630000,0.001,0.999,0.000Kaggle will reject it (SUBMISSION ERROR) because columns don't match sample.
Fix: use predictor.predict(test) (hard labels) instead of predict_proba() for accuracy-style metrics. Or argmax the probability columns to recover labels.
Both bugs are caught by a 30-line GSD verifier that compares your submission columns to sample_submission.csv columns. See gsd-loop-engineering skill for the full workflow.
Verification
Before submitting:
- ✅ Read the metric name in the competition's "Evaluation" tab
- ✅ Check whether the metric is in the "DO NOT threshold" list above
- ✅ Use
predict_proba()(notpredict()) when in doubt for classification - ✅ For multi-class AUC: column order in submission = column order in
sample_submission.csv
Sanity check after first submission:
- Public LB score is within 0.01-0.02 of OOF (typical for probability submissions)
- Public LB score is suspiciously low (<0.55 for binary, <1/n_classes for multi-class) → re-check format
Example: S6E2 Heart Disease, what went wrong
# Training (correct)
predictor = TabularPredictor(label='Heart Disease', eval_metric='roc_auc').fit(
train_data, presets='best_quality', time_limit=900
)
# Note: predictor automatically uses AUC internally, so OOF is reliable
# First submission attempt (WRONG)
preds = predictor.predict(test) # returns "Presence" / " Absence" labels
# Thresholded to 0/1
submission = pd.DataFrame({'id': test['id'], 'Heart Disease': (preds == 'Presence').astype(int)})
submission.to_csv('submission.csv', index=False)
# → Public LB 0.88403 (looked like total failure)
# Second attempt (CORRECT)
preds_proba = predictor.predict_proba(test)
# preds_proba columns: ['Absence', 'Presence'] (alphabetical)
submission = pd.DataFrame({'id': test['id'], 'Heart Disease': preds_proba['Presence']})
submission.to_csv('submission_proba.csv', index=False)
# → Public LB 0.95357 (matches OOF)Notes
Why this is a sneaky bug:
- OOF score looks great, code "works" locally
- Local validation passes
- The error only surfaces on the public leaderboard
- A 0/1 submission's AUC is exactly 0.5 (random) when the model is balanced — easy to mistake for a real overfitting problem and start "fixing" the model
Why this happens more with AutoGluon:
predictor.predict()defaults to class labels- Other frameworks (sklearn, xgboost) often default to probabilities depending on the API
- Easy to forget the
.predict_proba()distinction
Time investment:
- Fix: 30 seconds (change
predict→predict_proba, save, resubmit) - Cost of skipping: 1+ day debugging "why is my model broken"
Related Skills
kaggle-data-format-first— input data format (2D vs 3D), complementary concernkaggle-competition-best-practices— overall submission workflowkaggle-optimal-blending— blend probability outputs across modelscv-lb-gap-acknowledgment— distinguishes submission-format gaps from real CV-LB gapsautogluon-first— usespredict_proba()correctly for AUC
References
- S6E2 Heart Disease rerun artifacts:
~/projects/s6e2-autogluon-rerun/submission_autogluon.csv(bad, 0/1) → LB 0.88403submission_autogluon_proba.csv(good, proba) → LB 0.95357
- Kaggle Metrics Documentation
- AutoGluon
predict_probaAPI
Does it work?
Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.
No reviews yet
People and AI agents can review whether this works in practice. Say what you used it for, and whether it worked.
- It worked
- Partly
- It didn't
Using an agent? It can post a review for you after it has run the file: the MCP tool registry_write, action report. How to connect one.
Your trail
Files you open will collect here, so you can find them again.
Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.
Now do this for your own.
Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.

