Skip to content
CURRENT
-7 → -6 (+1) over 24 captures ATL @ GB spread -7 → -6 house House backtest last 10: 6–4 · 90-day all-market 55.3% (n=8163) · 20h ago Wire Seahawks plan to have Sam Darnold back at practice Wednesday Wire Cardinals CB Will Johnson (neck) could miss rest of season Wire Rams WR Puka Nacua (hip) inactive for 'MNF' vs. Giants
Access: Anonymous access. Content follows.
how-the-sausage-is-made

Build an NFL Spread Model in TensorFlow.js From Scratch

Read the price, role, and market first A TensorFlow.js NFL betting model tutorial: define the architecture, prep the data, train in the browser, and evaluate against the closing spread.

8 sections

Shark Snip Editorial

House byline of the Shark Snip analytics desk — numbers sourced from the data pipeline, not vibes.

Key takeaways (from article sections)

  • Write the prediction contract first
  • Begin with a baseline the network must beat
  • Choose an architecture for the data you have
  • Split through time
  • Train with guardrails, not hope
  • Evaluate the decision, not just the label
  • Prove browser parity
  • Publish an honest empty state

A browser model is not impressive because it runs in a browser. It is impressive only when the prediction can be reconstructed from information that existed before kickoff. TensorFlow.js gives you a convenient runtime, but it cannot protect you from stale features, a contaminated split, or a market quote collected after the decision.

The useful version of this tutorial starts before the network. Define the wager, define the timestamp, define the label, and make every missing input explicit. Then build the smallest model that can challenge a plain baseline. The old copy skipped that discipline and filled the gap with uncited benchmark scores, device timings, architecture folklore, and example games. Those claims are gone.

Write the prediction contract first

A spread model needs one stable point of view. Decide which team is positive, how pushes are represented, which market snapshot is the benchmark, and when the prediction is considered published. Store those choices with every row. A sign convention that changes between training and grading can make a model look wrong when the real defect is bookkeeping.

The feature row should contain only fields available at the declared cutoff. Team ratings, rest, projected availability, weather, and market context can all be useful, but each needs an observed time. A value corrected after the game cannot quietly replace the pregame value in the training table.

Keep unavailable and neutral separate. Missing quarterback status does not mean healthy. Missing weather does not mean calm. Return an error value with a cure such as “refresh the availability snapshot” or “exclude this event from training” rather than substituting a plausible default.

Begin with a baseline the network must beat

Before adding hidden layers, fit a transparent baseline on the same rows and the same time splits. A market-only baseline shows how much information is already in the quote. A compact linear model shows whether your engineered features carry anything beyond that quote. If the neural model cannot improve probability quality or calibration on untouched future games, keep the baseline.

This comparison catches more defects than another tuning pass. When every model appears brilliant, inspect the split. When every added feature helps, inspect the timestamps. When the network mirrors the market almost perfectly, check whether the closing line has leaked into a decision-time model.

Use the Brier score guide for probability scoring and the calibration guide for confidence. Neither metric should be read without the evaluation window and the number of graded predictions.

Choose an architecture for the data you have

Most spread datasets are small tables, not image corpora. A compact dense network is a candidate because it can learn interactions without demanding a huge artifact. That is not a license to add layers until the validation curve looks exciting. Capacity should grow only when an error analysis identifies structure the current model cannot express.

Put architecture settings in a typed configuration object. Name the feature count, activation, regularization, optimizer, stopping rule, and seed. The training function should return either a versioned artifact or a typed failure with a cure. A failed tensor conversion, an empty fold, or an incompatible feature schema must never fall through to a prediction.

Normalize numeric inputs with statistics learned from the training period only. Apply the same stored transform to validation, test, and live rows. Recomputing normalization on the full dataset lets the future influence the past even when the target column never appears in the features.

Split through time

Random shuffling is friendly to sports models because team strength, roster state, and market behavior repeat across nearby games. It is also the wrong test for a model that will face tomorrow. Train on earlier events, tune on a later block, and reserve a still-later block for the decision you intend to publish.

Do not keep peeking at the final block. Once a result changes your architecture, feature list, or stopping rule, that block has joined the development process. Advance the cutoff and create a new untouched evaluation period.

Save the prediction from every forward fold. Those out-of-fold rows support calibration, error review, and later stacking without asking a meta-model to learn from in-sample confidence.

Train with guardrails, not hope

Training should stop for a declared reason. Monitor validation loss, preserve the best checkpoint, and record the seed and feature schema beside the artifact. A run that ends because the tab closed is not a model version. A run that cannot be replayed is not evidence.

Add negative controls. Shuffle the labels and confirm the apparent signal disappears. Remove the market feature and see how much independent information remains. Train on the market feature alone and compare it with the richer model. These tests are designed to make the model fail for the right reasons.

Inspect prediction distributions as well. A network that emits almost the same probability for every game may be stable but useless. A network that lives at the extremes may be overconfident. Calibration should determine how much disagreement is actionable, not the drama of the raw output.

Evaluate the decision, not just the label

The target tells you whether a side covered. The market row tells you whether the decision was available. Keep the sportsbook, spread, attached price, capture time, and publication time together. Grade the original quote rather than a later number that flatters the pick.

Report a betting record only as wins, losses, pushes, ATS win rate, named window, and sample size. This module has no cited prediction ledger, so it publishes no record. It also makes no claim about closing movement, profitability, or a production model.

Bucket calibration by the probabilities the model actually issued, then examine the region where a card would be published. A good overall score can hide a broken decision region. The model earns deployment only when its confidence behaves sensibly where the product uses it.

Prove browser parity

Training and inference may use different backends. Export the artifact, reload it through the exact browser path, and send fixed feature rows through both runtimes. Compare outputs within a declared tolerance. Include missing fields, extreme values, and schema errors in the fixture.

Measure cold start and steady-state inference on supported devices rather than repeating generic speed claims. Record the browser, backend, device class, artifact version, and batch shape beside each observation. This article declares no such benchmark rows, so it names no timing or size.

Version the feature schema independently from the weights. A retrain on newer data is not the same change as adding a feature. The consumer should reject an incompatible artifact with a cure string rather than quietly rearranging columns.

Publish an honest empty state

A browser can finish training and still produce nothing worth betting. The honest result is “no deployable model from this evaluation window,” followed by the reason: no improvement over baseline, poor calibration, unstable seeds, stale inputs, or runtime mismatch.

Keep the experiment ledger in the same place as the artifact. The framework comparison explains when a table may favor boosted trees, while the tracking guide covers the receipt trail once a prediction becomes a published selection.

This module teaches the build order: data contract, baseline, time split, compact candidate, calibration, runtime parity, and only then publication. It does not certify a TensorFlow.js edge. That claim must come from a cited pregame table and a graded ATS ledger.

Model calibration from graded predictions

Calibration points render only when a verified source binds prediction probabilities to settled outcomes for the same observations.

Expected value from graded outcomes

Expected-value cells render only when a verified source binds observed win outcomes to the price paid for the same bets.

Frequently asked questions

Why start with binary cover instead of predicted margin?
A cover target gives a first model one clear grading rule and makes probability calibration easy to inspect. Margin can be added later when the data contract and settlement logic are stable. The important choice is not which target sounds richer; it is whether the target matches the market snapshot and can be reproduced without leakage.
What is the smallest feature set that can work?
There is no universal winning set. Begin with a market baseline and a compact group of pregame team-strength, rest, availability, and context features whose timestamps you can prove. Add a feature only when it improves untouched future predictions and survives an ablation.
How long should training take?
Training time depends on the rows, architecture, backend, browser, and device. This module carries no benchmark table, so it publishes no duration. Measure the exact model file on supported devices and store the environment with the result.
Can I add a derived feature?
Yes, when the value can be computed from information available at the prediction cutoff. Give the feature a typed schema, a provenance timestamp, a missing-state policy, and an ablation test. Reject the row with a cure when those requirements are not met.

Build a free model in 60 seconds →

Go →
7m read time
0 players/teams
8 key angles

Angles in this read

  • Edge meter Positive expected value is presented as a meter, not a guarantee.
  • Probability bands Ranges and uncertainty are shown as bands rather than fake certainty.
  • Model sparkline Model output and projection movement get a tiny sparkline rhythm.
  • Line arrow Spread, total, and price movement sections get directional cues.
  • Line reveal Pretext-measured lines reveal without reflowing the article.
  • Entity chip Player and team names are surfaced as scannable chips.

This article does not name specific players or teams, so its context stays limited to model, price and weather from the post itself.

Terms found in this article
modelpriceweatherclient side modelingtensorflow js
Share this guide Help another reader make a sharper decision.

Get picks in your inbox

One email, every slate — ranked edges, no touts. Unsubscribe any time.

Start free — pick NFL

Go →

Continue with evidence

Related reading and source status

Related Reads

Inside the Six-Stage Reveal When Training Finishes — on the Advanced Canvas — Shark Snip
Betting Tools

Inside the Six-Stage Reveal When Training Finishes — on the Advanced Canvas

A finished training run on /build/[slug] plays a fixed six-stage reveal, grade first, timed to the exact millisecond in the source.

Sep 11, 2026 5 min read
The Screen That Shows Your Backend Before Training Starts — on the Advanced Canvas — Shark Snip
Betting Tools

The Screen That Shows Your Backend Before Training Starts — on the Advanced Canvas

Pre-Train Preview on /build/[slug] names the exact backend a run will use, from a single side-effect-free probe, before training starts.

Sep 11, 2026 5 min read
Eight Lattice Slots, and the 56 Modules That Can Fill Them — Shark Snip
Betting Tools

Eight Lattice Slots, and the 56 Modules That Can Fill Them

The /build board holds eight fixed slots filled from a live, growing list of pieces, not a four-tier gallery.

Sep 11, 2026 6 min read

query: loadMergedBlogPostCards + scoreRelated · n = 3

No data

No graded source picks match this article yet

The public.source_accuracy_scores 90-day query returned no rows for this article's inferred sport.