Physics-constrained multi-task ensembles for predicting seven polymer properties from PSMILES
Predict seven physical properties of a polymer β thermal, electronic, optical and dielectric β from its repeat unit written as a PSMILES string. Scored on the unweighted mean RΒ² across all seven, which means a property with 221 training labels counts exactly as much as one with 4,143.
Our final system is a five-model ensemble combined by a per-property cross-fitted
Ridge and then corrected by an explicit, affine-fitted physics stage. The
central modelling idea is treating the dielectric constant not as a fitted
correlation but as an exact decomposition, Ξ΅ = nΒ² + Ξ΅_ionic, licensed by how the
reference DFPT calculations are defined.
π Read the full journey β how we got here, what broke, and the two discoveries that decided it.
| Private leaderboard | 0.917 β π₯ 3rd out of 145 teams |
| Public leaderboard | 0.924 |
| Mean out-of-fold RΒ² | 0.9234 |
| CV β LB transfer gap | +0.0006 |
| Training cost | 380 fitted models Β· 3 h 01 m on two Tesla T4 |
| Inference | seconds, for all 4,940 test rows |
| target | LightGBM | XGBoost | CatBoost | Multi-task NN | Periodic GNN | Ridge stack | + physics |
|---|---|---|---|---|---|---|---|
tg |
0.9176 | 0.9166 | 0.9092 | 0.9025 | 0.9162 | 0.9274 | 0.9274 |
egc |
0.9185 | 0.9197 | 0.9157 | 0.8849 | 0.8999 | 0.9307 | 0.9307 |
egb |
0.9310 | 0.9337 | 0.9270 | 0.9324 | 0.9387 | 0.9551 | 0.9551 |
eps |
0.8247 | 0.8266 | 0.8369 | 0.8049 | 0.8200 | 0.8514 | 0.8758 |
nc |
0.8766 | 0.8775 | 0.8798 | 0.8942 | 0.9055 | 0.9164 | 0.9331 |
ei |
0.8367 | 0.8250 | 0.8353 | 0.8532 | 0.8777 | 0.8725 | 0.8978 |
eea |
0.8758 | 0.8775 | 0.8922 | 0.8940 | 0.9264 | 0.9367 | 0.9438 |
| MEAN | 0.8830 | 0.8824 | 0.8852 | 0.8809 | 0.8978 | 0.9129 | 0.9234 |
- The stack beats its best member by +0.0151 β that is what decorrelation buys.
- Physics adds a further +0.0105, concentrated exactly where the relations reach:
ei+0.0250,eps+0.0244,nc+0.0168,eea+0.0070.
| # | Milestone | Public LB | |
|---|---|---|---|
| 1 | Inherited baseline (fingerprints β trees) | 0.883 | ββββββ |
| 2 | Leak fixes + honest cross-fitting | 0.898 | ββββββββββββββββββ |
| 3 | Periodic GNN + Ξ΅ = nΒ² + Ξ΅_ionic |
0.916 | βββββββββββββββββββββββββββββββββ |
| 4 | Round-2 archive integrated | 0.919 | βββββββββββββββββββββββββββββββββββ |
| 5 | Final submission (ppp-v3-g.ipynb) |
0.924 | βββββββββββββββββββββββββββββββββββββββ |
For scale: at our mid-competition leaderboard snapshot, first place on the public board stood at 0.917 β we finished the finale above it, at 0.924.
That +0.0006 gap is the number we are proudest of, and it is not luck. We started Round 3 with an inherited pipeline whose OOF read 0.903 and whose leaderboard read 0.883 β a β0.020 lie. Closing it took a deliberate leak hunt (four separate leaks, all of one shape) and the removal of early stopping everywhere: a model that picks its iteration count by watching the rows it is then scored on reports a number it cannot reproduce out of sample.
ANRF AISEHack 2.0 β a national AI-for-Science hackathon hosted on Kaggle, with the Grand Finale at IIT Madras. Three elimination rounds, each a private community competition scored on mean RΒ² across polymer properties.
flowchart LR
R1["<b>ROUND 1</b><br/>2 properties<br/>145 teams<br/><br/><b>30th</b>"]
R2["<b>ROUND 2</b><br/>7 properties<br/>76 teams<br/><br/><b>6th</b>"]
R3["<b>ROUND 3 Β· FINALE</b><br/>7 properties<br/>+ 3 judged themes<br/>10 finalists<br/><br/><b>3rd of 145</b> π₯"]
R1 -->|qualified| R2 -->|qualified| R3
style R1 fill:#f5f5f5,stroke:#999,color:#000
style R2 fill:#e0f0ef,stroke:#00807F,color:#000
style R3 fill:#fdf0d9,stroke:#B8790B,stroke-width:3px,color:#000
| Round | Task | Field | Our result |
|---|---|---|---|
| Round 1 | Predict two polymer properties from SMILES | 145 teams | 30th |
| Round 2 | Expanded to all seven properties | 76 teams | 6th |
| Round 3 β Finale | Seven properties + robustness, explainability and polymer invariance | 10 finalists | 3rd π₯ |
145 teams entered the hackathon; 10 survived to the finale, where we placed 3rd.
Round 3 deliberately moved the goal past raw accuracy. From the competition overview: "the challenge moves beyond raw accuracy to robustness and trust β two qualities that separate a research prototype from a model that materials scientists can actually rely on." It also added a 5.97 M-molecule auxiliary SMILES corpus and a hard rule set β one notebook execution does everything, no external data, no pretrained weights, no uploaded artifacts, seeds fixed and printed.
This repository contains our Round 3 work. Rounds 1 and 2 are kept locally but are not published here.
| Property | Symbol | Domain | Train rows | Test rows | Range |
|---|---|---|---|---|---|
| Glass transition temperature | tg |
thermal | 4,143 | 2,763 | β109.8 β 495.0 |
| Chain bandgap | egc |
electronic | 2,028 | 1,352 | 0.02 β 9.86 |
| Bulk bandgap | egb |
electronic | 337 | 224 | 0.51 β 10.11 |
| Dielectric constant | eps |
dielectric | 229 | 153 | 2.61 β 9.09 |
| Refractive index | nc |
optical | 229 | 153 | 1.56 β 2.76 |
| Ionisation energy | ei |
electronic | 222 | 148 | 4.03 β 9.84 |
| Electron affinity | eea |
electronic | 221 | 147 | 0.39 β 5.14 |
Score = mean( RΒ²_tg , RΒ²_egc , RΒ²_egb , RΒ²_eps , RΒ²_nc , RΒ²_ei , RΒ²_eea ) β UNWEIGHTED
tg has 4,143 training rows and eea has 221 β and they count exactly the
same. The five smallest properties are 5/7 of the score sitting on under 4% of
the rows.
So: model per target, or standardise per target before any shared loss. Never
optimise one pooled loss on raw targets β tg reaches 495 and nc reaches 2.76,
so tg would swallow the gradient and every other property would quietly collapse
to its mean.
Two data traps that cost us time β worth knowing before you start
The published test row count is wrong. The Kaggle data page says "4,497 data
points". test.csv has 4,940 rows β 4,497 counts unique molecules. A
4,497-row submission is rejected. One inherited notebook carried a
len(test_df) != 4497 warning that fired on every correct run.
target_type values are lowercase (tg egc egb eps nc ei eea). Matching
"Tg" does not raise β it silently matches zero rows and scores nan. There is
an assertion at import time in src/metric.py for exactly this reason.
There are no free lookups, but there is a shortcut. Only 2 of 4,940 test rows have their exact (canonical SMILES, property) key in training. But 1,063 of 4,133 test polymers appear in training under some other property β which is what makes co-observed partner features legitimate, and what dictates the fold design.
flowchart TD
IN["<b>12,345 PSMILES</b><br/>train 7,405 Β· test 4,940<br/>every repeat unit has exactly two * points"]
CANON["<b>CANONICALISE AT INGEST</b> (RDKit)<br/>10,605 raw strings β 8,990 distinct molecules<br/><i>makes every later stage a function of the MOLECULE</i>"]
FEAT["<b>FEATURISE β 3,037 columns</b><br/>Morgan r2/r3 Β· atom-pair Β· torsion Β· MACCS<br/>RDKit descriptors Β· SMARTS groups Β· intensive twins<br/>+ leak-guarded co-observed partner block"]
ARCH["<b>ROUND-2 ARCHIVE</b><br/><i>host-sanctioned</i><br/>6,165 tg/egc labels<br/>β +2,446 training rows<br/>β‘ partner labels 15.3%β38.1%<br/>β’ measured override"]
GBDT["LightGBM Β· XGBoost Β· CatBoost<br/>70 models each"]
NN["Multi-task NN<br/>6 seeds Γ 10 folds"]
GNN["<b>Periodic GNN</b><br/>4 seeds Γ 110 epochs<br/><i>best single model 0.8978</i>"]
STACK["<b>PER-PROPERTY CROSS-FITTED RIDGE STACK</b><br/>five columns β one Ridge per target<br/>OOF 0.9129"]
PHYS["<b>TWO-PASS PHYSICS BLEND</b> β every relation AFFINE-FITTED<br/>ei = egc + eea Β· eea = ei β egc Β· egb β egc<br/><b>eps = ncΒ² + Ξ΅_ionic</b> β a DFPT identity, not a regression<br/>OOF 0.9233"]
POST["Partner regression β clip to observed range"]
OUT["<b>ARCHIVE OVERRIDE β submission.csv</b><br/>measured truth on 2,450 of 4,940 test rows<br/>applied AFTER clipping<br/><b>Public LB 0.924</b>"]
IN --> CANON --> FEAT
ARCH -.-> FEAT
FEAT --> GBDT & NN & GNN
GBDT & NN & GNN --> STACK --> PHYS --> POST --> OUT
ARCH -.->|measured values never perturbed| OUT
style IN fill:#ffffff,stroke:#999,color:#000
style CANON fill:#e0f0ef,stroke:#00807F,color:#000
style FEAT fill:#ffffff,stroke:#999,color:#000
style ARCH fill:#fdf0d9,stroke:#B8790B,stroke-width:2px,color:#000
style GBDT fill:#f5f5f5,stroke:#999,color:#000
style NN fill:#f5f5f5,stroke:#999,color:#000
style GNN fill:#e0f0ef,stroke:#00807F,stroke-width:2px,color:#000
style STACK fill:#e0f0ef,stroke:#00807F,color:#000
style PHYS fill:#fdf0d9,stroke:#B8790B,stroke-width:2px,color:#000
style POST fill:#ffffff,stroke:#999,color:#000
style OUT fill:#e0f0ef,stroke:#00807F,stroke-width:3px,color:#000
The full annotated pipeline, with every number taken from the saved outputs of the submitted run:
Five base models, fold-averaged, with no early stopping anywhere. Each model first averages its own fold replicas into one vector; those five vectors enter a per-property Ridge as five columns. There is no plain averaging across models anywhere, and the combiner is cross-fitted so its weights never see the rows they are scored on.
Per-property KFold, not polymer-grouped folds. This is the opposite of the usual advice, and it is measured:
| scheme | partner availability for validation rows |
|---|---|
| polymer-grouped folds | 0% |
| per-property KFold | ~96% |
| the actual test set | 88β99% |
Holding out a whole polymer removes the other properties measured on it β but at
test time those properties are in train.csv for nearly every DFT-block row.
Grouped CV would have measured a harder problem than the one being scored. (Within
a single property there are essentially zero duplicate canonical polymers, so plain
KFold is already leakage-safe.)
Physics applied after stacking, not as a feature. A tree splits one axis at a
time and cannot cheaply represent a sum of two columns, so ei = egc + eea is
wasted as one feature among 3,037. As an explicit post-stack blend it is worth
+0.0250 on ei.
Three of our five relations were nearly exact when applied raw. Two were not:
| target | expression | raw RΒ² | affine-fitted RΒ² |
|---|---|---|---|
ei |
egc + eea |
0.963 | 0.965 |
eea |
ei β egc |
0.971 | 0.973 |
egb |
egc |
0.892 | 0.928 |
eps |
ncΒ² |
0.336 | 0.855 |
nc |
sqrt(eps) |
0.171 | 0.837 |
That collapse to 0.336 is not noise β it is physics. Maxwell's relation holds at optical frequency, but the dataset tabulates the static dielectric constant. A DFPT calculation accounts for exactly two contributions and nothing else β an electronic part and an ionic part β and those are stored as separate fields in the dataset of record. Since the electronic part is nΒ², the shortfall is exactly the ionic term:
An identity, not a regression β so eps β ncΒ² is not a residual to be absorbed
by an intercept. It is a physical quantity with its own structureβproperty
relationship, and it can be modelled.
Two independent checks that this was real rather than convenient:
eps β ncΒ²is positive on all 134 co-observed molecules (mean +0.767, min +0.024). A generic empirical residual would cross zero; an ionic contribution cannot be negative.- Our own blind affine fit had already converged on a = 1.040, b = 0.615 β a slope of one and an intercept equal to the mean ionic term. The regression was rediscovering the decomposition on its own, with the ionic part pinned to a single constant.
Naming it correctly makes the constant predictable:
| approach | RΒ² on covered eps rows |
|---|---|
direct eps model |
0.7129 |
ncΒ² + constant ionic term (what a global affine gives) |
0.8514 |
ncΒ² + structure-predicted ionic term |
0.9573 |
The lesson: reading where the data came from paid more than any amount of further tuning. The same fit, correctly named, went from a constant to a model.
The official baseline notebook shipped with the competition fetches two Google
Drive files. Their -O names are swapped: the file being written to
test.csv is in fact a labelled table of 6,171 tg/egc values from the
Round-2 release.
We asked the hosts directly whether it was in scope, and they confirmed it β
their own baseline downloads it. The loader (Round 3/src/archive.py) then
validates the file rather than trusting the filename, declares itself in the
compliance audit, and falls back to running archive-free if it is unavailable.
Measured against Round 3: 3,719 of its labels were already in train.csv and
2,450 correspond to test rows, with values agreeing on 3,717 of 3,719 overlaps β
the same measurements, not a second dataset. Used three ways:
- +2,446 training rows β 7,405 β 9,851 (+33%). The boosters are
per-property so they only see more
tg/egc, but the NN and GNN share one trunk across seven heads, so a larger abundant-target block improves the representation the five scarce targets ride on. - Partner labels β
true_egctest coverage 15.3% β 38.1%. - A measured override on 2,450 of 4,940 test rows (49.6%), applied after clipping so a real measurement is never perturbed downstream.
The prediction we got wrong, and kept in the log
We wrote: "this cannot move cross-validation β CV rows gain no label they did not already have." That was wrong: CV moved +0.0149 (3-fold LightGBM, 0.8514 β 0.8663).
The archive supplies true_egc for polymers whose own egc row sits in the
held-out fold β a value no training fold could otherwise see. Not a leak of the
scored label, and the numbers prove it: tg moved +0.0004 and egc
+0.0000, exactly as drop_leaky() guarantees, while the entire gain landed on
the five targets that consume egc as a source (egb +0.0202, eps +0.0508,
nc +0.0209, ei +0.0110).
And it is conservative, not optimistic: with the archive present, true_egc
coverage on test rows (73.9β77.7%) exceeds coverage on CV rows
(65.9β73.0%) for every one of those five targets.
A repeat unit is not a molecule with two dangling stubs: the two * points are
the same bond to the neighbouring unit. So we drop both dummies, bond their
neighbours, and flag the wrap-around edge β the network then encodes an infinite
chain.
It became our best single model (0.8978) and the most complementary one: worse
than the boosters on egc, far better on eea (0.9264 vs 0.8758) and ei
(0.8777 vs 0.8367). It is the only member not built on the shared 3,037-column
matrix, so its errors are structurally decorrelated. Adding it took the stack
from 0.8713 to 0.9129.
And the readout is an invariance decision, not a hyperparameter. A sum
readout scales with repeat-unit count; a mean does not. Measured on an
untrained network β a property of the architecture, not of any fit:
| readout | rewriting | median |Ξ| | max |Ξ| |
|---|---|---|---|
| mean+max (shipped) | permutational | 0.00 | 0.00 |
| mean+max (shipped) | repetition (dimer) | 1.11eβ4 | 1.06eβ3 |
| sum (conventional) | repetition (dimer) | 4.79eβ1 | 2.49 |
Four orders of magnitude β which is why we never use a sum readout.
Round 3 scored robustness, explainability and invariance alongside accuracy. We treated all three as machine-checked deliverables the notebook proves at runtime, not claims on a slide.
| claim | status | evidence |
|---|---|---|
| Re-representation (atom ordering) | β EXACT | 2,000 rewritings Γ 400 molecules β 0 string mismatches; 3,037 feature columns Γ 150 molecules β max |Ξ| = 0.000e+00; end-to-end predictions β max |Ξ| = 0.000e+00 |
| Repetition (monomer vs dimer) | ~97% of polymers give structurally identical node environments; served by intensive twins, mean+max readout and chain-extension augmentation | |
| Translational (different cut point) | β not guaranteed | diagnosed openly: the wrap-around edge is forced to a generic single bond and carries a positional flag, both cut-point dependent by definition |
Canonicalising at ingest is the mechanism: it makes every downstream stage a
deterministic function of the molecule, and canonical(rewrite(s)) == canonical(s) for any valid rewriting. It was never hypothetical β 67.6% of the
supplied SMILES strings are non-canonical.
Computed inside LightGBM via pred_contrib=True β the same algorithm the shap
package implements, deliberately with no external dependency that could fail to
install mid-run.
tgβ intensive twins carry 25.4% of attribution, ring counts lead. Chain stiffness dominates, exactly as free-volume theory predicts. (The invariance design choice turned out to be the biggest accuracy lever on the biggest property.)egcβrd_FractionCSP3tops the list: an spΒ³-rich backbone localises electrons and widens the gap; conjugation narrows it.egbβ the fitted partner combination is 26.0% andtrue_egc10.3%. The relationegb β egcappears in the attribution rather than being asserted by us.nc/epsβ molar-refractivity surface descriptors appear for both, reproducing refractive index as electronic polarisability from an independent direction.
One molecule is explained end to end, with additivity verified against the model's own output to 3.98eβ13.
Every prediction ships a flag saying whether the model has seen chemistry like it. 22.2% of molecules are out of domain, and the flag predicts error:
| target | RΒ² in-domain | RΒ² out-of-domain | MAE in | MAE out |
|---|---|---|---|---|
tg |
0.938 | 0.884 | 17.77 | 25.31 |
egc |
0.941 | 0.900 | 0.248 | 0.371 |
eps |
0.914 | 0.816 | 0.197 | 0.298 |
ei |
0.918 | 0.861 | 0.191 | 0.268 |
eea |
0.953 | 0.917 | 0.157 | 0.244 |
Two details separate a useful flag from a constant: use unfolded Morgan
substructure hashes (folded 2,048-bit fingerprints are degenerate at this corpus
size β every bit is occupied), and cap the * points as methyl first (no corpus
molecule carries an attachment point, so comparing raw makes every polymer novel by
definition).
An honest negative result we chose to report: we tested the 5.97 M auxiliary corpus as a model input and it was worth +0.0012 β noise. An SVD embedding of it is a linear re-expression of the Morgan fingerprint the trees already see in full. We repurposed it as a trust signal rather than discarding it.
AISE2.0/
βββ README.md this file
βββ LICENSE MIT (code only β the data is not ours to license)
βββ CLAUDE.md repo-wide orientation
βββ Round 3/ the finale β everything below is Round 3
βββ CLAUDE.md the operational contract: ground truth, rules, workflow
βββ src/ β
source of truth for all modelling
βββ submissions/ exported Kaggle notebooks + saved OOF/test vectors
βββ experiments/LOG.md β
every scored run, dead ends included
βββ context/ the Kaggle pages (overview, rules, data, leaderboard)
βββ documents/ reports, slides, the journey write-up
βββ scripts/ notebook linting, execution, diagram generation
βββ .claude/ skills, agents and hooks used during the sprint
βββ data/ β οΈ NOT IN GIT β see "Getting the data"
src/ β the harness
| file | role |
|---|---|
data.py Β· paths.py |
loading, canonical dedupe, Kaggle/local path resolution |
smiles_utils.py |
canonicalisation, and the three polymer rewritings (permute / translate / oligomerise) |
features.py |
3,037-column featuriser, keyed by canonical SMILES |
partners.py |
co-observed partner features + the leakage guard |
archive.py |
the host-sanctioned Round-2 label table, validated on load |
physics.py |
the five relations, affine-fitted β never applied raw |
splits.py Β· oof.py |
fold design; base models β cross-fitted stack β two-pass physics |
models/ |
trees.py, mtnn.py, gnn.py, cnn.py, simple.py |
configs/ |
lgbm.py, lgbm_physics.py, ridge_baseline.py |
cv.py Β· predict.py |
the two entry points every other tool derives from |
invariance.py Β· explain.py Β· report.py |
the judged deliverables |
check_submission.py Β· export_notebook.py |
submission gate; notebook generator |
A config is exactly two functions β fit(train_df, seed, targets=None) and
predict(state, df) β and CV, inference, the invariance audit and the
explainability report all derive from that pair. What CV measured is literally
what gets submitted.
The competition data is deliberately not in this repository. Rule Β§4.b of the
competition rules: "You agree not to transmit, duplicate, publish, redistribute or
otherwise provide or make available the Competition Data to any party not
participating in the Competition." (smile_r3.csv is also 314 MB, which exceeds
GitHub's 100 MB per-file limit outright.)
Download from the competition data page
into Round 3/data/:
Round 3/data/
βββ train.csv 7,409 rows (smiles, target, target_type) long format
βββ test.csv 4,940 rows (id, smiles, target_type)
βββ sample_submission.csv a format illustration, not a template
βββ PI1M.csv 995,800 polymer SMILES with * wildcards
βββ smile_r3.csv 5,973,370 small-molecule SMILES (no wildcards)
βββ base_line_model.ipynb the host's official baseline
There is no system pandas, rdkit or lightgbm β use the project venv:
cd "Round 3"
uv venv --python 3.12 .venv
uv pip install --python .venv/bin/python -r requirements-dev.txtEvery command below is run from Round 3/.
# Score a config β the gate every idea passes before it gets a submission slot
./.venv/bin/python -m src.cv --config lgbm # ~377 s, the local reference
./.venv/bin/python -m src.cv --config lgbm_physics # +0.0288, 4x the noise floor
./.venv/bin/python -m src.cv --config ridge_baseline # host baseline equivalent, 4 s
# Full fit -> submission.csv (~55 s for lgbm)
./.venv/bin/python -m src.predict --config lgbm --out submission.csv
# Validate before uploading β always
./.venv/bin/python -m src.check_submission submission.csv
# The judged deliverables
./.venv/bin/python -m src.invariance --config lgbm # invariance certificate
./.venv/bin/python -m src.explain --config lgbm # per-target TreeSHAP report
# The full five-model ensemble (long)
./.venv/bin/python -m src.run_ensemble --models lgbm,xgb,cb,mtnn,gnn --folds 10
# Regenerate the Kaggle notebook from src/
./.venv/bin/python -m src.export_notebook \
--models lgbm,xgb,cb,mtnn,gnn --out submissions/final.ipynbRuns are appended automatically to experiments/LOG.md.
The harness prints a noise floor β a delta smaller than 2Γ it is not an
improvement, and we said so out loud rather than claiming a win.
src/paths.py resolves the data at runtime (/kaggle/input/aisehack-2-0, then
/kaggle/input, then local data/), so the exported notebook runs unmodified.
Attach the Round-2 archive as a Kaggle Dataset if internet is off β otherwise the
pipeline warns and runs archive-free rather than failing.
β οΈ Two platform traps that each cost hours
LightGBM must be imported before PyTorch. They bundle separate OpenMP runtimes;
on macOS, torch-first makes LightGBM segfault inside __init_from_np2d with no
traceback. The same duplicate-runtime trap also deadlocks β one local run sat at
0% CPU and 63 MB RSS for 44 minutes. Linux (and therefore Kaggle) is unaffected, but
the import order costs nothing and makes the notebook run anywhere.
For local runs: OMP_NUM_THREADS=4 KMP_DUPLICATE_LIB_OK=TRUE, and do not run two
model jobs at once.
Notebook print()s are block-buffered when stdout is a file. A cell can look
stalled for minutes while its output sits in an 8 KB buffer. Run verifiers with
PYTHONUNBUFFERED=1 before concluding anything is stuck.
Round 3/submissions/ holds the full experimental record, not just the winner.
| notebook | public LB | what it is |
|---|---|---|
ppp-v3-g.ipynb |
0.924 | β THE SUBMISSION. Private LB 0.917, 3rd place. 5 models, archive as training rows + override, 3 h 01 m |
ppp-v3-g-fixed.ipynb |
β | the same, with two crash points repaired |
ppp-v4-g.ipynb |
0.919 | 2 h 53 m variant, higher seed counts, archive not in training |
round3_v2.ipynb |
0.922 | an independently built sibling pipeline β our second final pick |
round3_final.ipynb |
β | sibling pipeline; records the host confirmation on the archive |
final.ipynb |
β | generated by src/export_notebook.py from src/ |
aisehack3-1.ipynb |
0.883 | the incumbent we started Round 3 with (OOF ~0.903) |
aisehack3-2/5/6.ipynb |
β | intermediate iterations |
stack_only.ipynb |
β | stack-only variant, built for CV-to-LB calibration |
round-3-aisehack.ipynb |
β | "v2" β never scored; documented risks, not a safe default |
pie-net-v3-checkpoint-run-2.ipynb |
β | β rejected β rule violation. Imports checkpoints from a previous Kaggle run (Β§6.2.2/Β§6.2.4). Kept for the record; never submitted |
submissions/oof_and_preds/ holds saved OOF and test vectors for every base model,
so a blending experiment costs seconds instead of a full rerun.
| document | |
|---|---|
| π The journey | The full narrative β what led to what, every failure, and the lessons. Start here. |
| π Technical report (PDF) | The formal write-up Β· LaTeX source |
| π Finale presentation (PDF) | The slides presented at IIT Madras |
| π Mid-point check-in | The interim status report |
| π§ͺ Experiment log | Every scored run and every dead end, with noise floors |
The full list is in journey.md.
The five that generalise beyond this competition:
- Fix your ruler before you build. Our first instinct was to improve a 0.903. The right move was to ask why 0.903 became 0.883. Every improvement measured with a broken validation is a coin flip.
- Be suspicious of your biggest wins. The size of a measured gain correlated almost perfectly with the probability it was a leak: +0.069 was a leak, +0.042 was a leak, +0.008 was a leak. The real gains were +0.003 to +0.010 and arrived slowly.
- Leaks have one shape β a value that is itself a model output, used as an input, closing a cycle back to the row's own label. Once we named the shape we found the rest quickly. And prove the leak exists before proving the guard removes it: a guard that passes without a demonstrable leak proves nothing.
- Read where your data came from. The largest physics gain came from a 2020 DFPT paper and a 2016 dataset description; the second largest came from reading the host's own baseline notebook line by line. Neither was a modelling idea.
- Only new information ever paid. Every purely derived feature failed. What worked: partner labels, a new model class, more data, truer structure, and an exact physical identity. If a feature is a deterministic function of columns the model already has, a good model already has it.
The physics and architecture choices are grounded in published work, principally from the Ramprasad group, whose datasets these targets originate from.
- Chen, Kim, Batra et al. & Ramprasad, Frequency-dependent dielectric constant prediction of polymers using machine learning, npj Comput. Mater. 6, 61 (2020) β source of the ionic decomposition.
- Huan, Mannodi-Kanakkithodi, Kim, Sharma, Pilania & Ramprasad, A polymer dataset for accelerated property prediction and design, Sci. Data 3, 160012 (2016) β the dataset of record; stores Ξ΅_electronic and Ξ΅_ionic as separate fields.
- Gurnani, Kuenneth, Toland & Ramprasad, Polymer informatics at scale with multitask graph neural networks, Chem. Mater. 35, 1560 (2023) β polyGNN; source of the periodic graph.
- Kuenneth, Rajan, Tran, Chen, Kim & Ramprasad, Polymer informatics with multi-task learning, Patterns 2, 100238 (2021) β the shared-trunk design, and the origin of this property set.
- Lightstone, Chen, Kim, Batra & Ramprasad, Refractive index prediction models for polymers using machine learning, J. Appl. Phys. 127, 215105 (2020).
- Gilmer, Schoenholz, Riley, Vinyals & Dahl, Neural message passing for quantum chemistry, ICML (2017).
- Lundberg & Lee, A unified approach to interpreting model predictions, NeurIPS (2017); Lundberg et al., Nat. Mach. Intell. 2, 56 (2020) β SHAP / TreeSHAP.
- Venkatram, Batra et al. & Ramprasad, Predicting crystallization tendency of polymers using multi-fidelity information fusion, J. Phys. Chem. B (2020) β ancestor of the partner features.
- Liu et al., Open Polymer Challenge: Post-Competition Report, arXiv:2512.08896 (2025) β independently corroborates chain extension as a top-solution strategy.
- Tran, Kim, Chen, Chandrasekaran, Batra et al., Machine-learning predictions of polymer properties with Polymer Genome, J. Appl. Phys. 128, 171104 (2020) β our external benchmark.
ANRF AISEHack 2026 Β· Grand Finale, IIT Madras Β· π₯ 3rd out of 145 teams
Public LB 0.924 Β· Private LB 0.917 Β· mean OOF RΒ² 0.9234 Β· 380 models Β· 3 h 01 m on one Tesla T4
Invariance Ξ = 0 exactly, certified at three levels Β· TreeSHAP per property, additivity verified to 4eβ13 A single reproducible Kaggle notebook: all seeds fixed, no wall-clock branching, no artifact imported that the run did not itself create.
Code released under the MIT License. Competition data is not included and is not ours to redistribute.
