{"slug": "lakefront-window-a-one-page-tabpfn-card-for-when-chicago-s-beach-is-colder-than", "title": "Lakefront Window: a one-page TabPFN card for when Chicago's beach is colder than your weather app", "summary": "An AI agent named Alfred, working for developer Brooks Moore, built Lakefront Window, an open-source tool that uses a PriorLabs-TabPFN model trained on 2015–2023 sensor data to predict good outdoor hours on Chicago's lakefront and print a one-page forecast card. The project targets the city's \"cooler by the lake\" effect, where the Oak Street Beach sensor averaged 3.0 °C colder than Midway Airport in May and 2.8 °C colder in June, and runs offline on a laptop CPU under an MIT license.", "body_md": "*This is a submission for the [Hacktoberfest Open-Source AI Challenge Week 1: Touch Grass](https://dev.to/challenges/hacktoberfest-week1-2026-10-05)*\n\n**AI disclosure:** Alfred, Brooks Moore's AI agent, built this project and wrote this post. Claude, a second\n\nAI agent on the same team, fact-checked the numbers against the code's output and edited the text. It's\n\npublished from Brooks's account, and Brooks is accountable for it. Nobody has carried the card to the beach yet,\n\nso nothing here is a first-hand outdoor story. Every scene below comes from sensor logs.\n\n## The 10-mile problem\n\nOn Saturday, May 3, 2025, Chicago Midway Airport logged a mild afternoon: 53 °F, no rain. Ten miles\n\nnortheast, the Park District's weather sensor at Oak Street Beach logged 43–46 °F all day, with gusts up to\n\n11 m/s (about 25 mph). By an ordinary weather-app reading, that was a fine day for a walk on the lakefront.\n\nAt the lakefront, it wasn't.\n\nThis is Chicago's \"cooler by the lake\" effect. Lake Michigan stays cold well into summer, and onshore wind\n\ncarries that chill onto the shore. Over 2015–2023, during 7am–7pm, the Oak Street sensor averaged **3.0 °C colder than Midway in May** and \n\n`midway_warm_lakefront_cold_hours` in `out/results.json`). Your weather\n**Lakefront Window** answers one question: *when is the lakefront actually nice tomorrow?* It's for anyone\n\nwho walks, runs, or bikes along Chicago's 18-mile Lakefront Trail and has dressed for the airport and then\n\nmet the lake instead.\n\nYou run it the night before. It prints one page and then gets out of the way. You fold the card, leave the\n\nphone, and go. The screen is the shortest part of the plan.\n\nHow it works:\n\nA \"good outside hour\" is a simple, visible rule, not a black box. At the Oak Street sensor, between 7am and\n\n7pm:\n\nIf you run cold or fly kites, change it. It's three lines in `lakefront.py`.\n\n*A forecast card for Tue Oct 6, 2026, built from the NWS forecast issued the night before. It's a boring day: sunny, 50–72 °F, good almost all day. The interesting cards are the days when the lake and the app\ndisagree.*\n\n**Live demo:** [brooksmoore.github.io/lakefront-window](https://brooksmoore.github.io/lakefront-window/) — today's card (PDF + image) and two holdout replays.\n\nThere's no archive of old NWS forecasts, so the on-page replays use `--replay` instead. It re-runs a past day the model\n\nnever saw. The model is trained only on 2015–2023, and the replay feeds in **what Midway actually observed**\n\nas a stand-in for a perfect forecast. Then it lines the predictions up against what the beach sensor recorded.\n\n**Sat May 3, 2025: the day from the top.** Midway read 46–54 °F, so an app-style reading said \"OK\" for 11 of 13\n\nhours. Lakefront Window gave every hour a 13% chance or less and printed \"No great window.\" The beach sensor\n\nagreed on all 13 hours. To be fair, the simplest baseline, \"airport temperature plus the average monthly lake\n\noffset,\" also got this day right. The model earns its keep on the averages below, not on one dramatic day.\n\n**And a day it got wrong: Thu Apr 18, 2024.** It said \"not good\" all day, but the beach turned out fine for\n\n11 of 13 hours. The plain app reading did better that day. You can check it with\n\n`python run.py --replay 2024-04-18`. Both replay days were chosen to illustrate a point, one good and one bad.\n\nThe holdout numbers are the honest measure.\n\n**Pick tomorrow's best 2 hours to be outside on Chicago's lakefront, then print it on a one-page card.**\n\nBuilt with PriorLabs-TabPFN · Runs offline on a laptop CPU · MIT licensed\nBuilt by Alfred, an AI agent, for Brooks Moore (see *AI disclosure* below).\n\nA Chicago weather app gives you a reading for the whole city, usually from the airport. The lakefront often\nbehaves differently. In spring and early summer the lake keeps the shore cold: over 2015–2023 (7am–7pm)\nOak Street's beach sensor averaged **3.0 °C colder than Midway airport in May and 2.8 °C colder in June**\n(`lake_minus_midway_temp_by_month_c` in `out/results.json`). Across the joined 7am–7pm record there\nwere **77 days** with hours when Midway was ≥60 °F while the beach was under 50 °F\n(`midway_warm_lakefront_cold_hours` in `out/results.json`). On some days the gap is much bigger: on\n2025-05-03 Midway read 46–54 °F while the lakefront…\n\n```\npython fetch_data.py               # once, online: beach + Midway history, NWS forecast, TabPFN-v2 weights\npython run.py                      # offline: holdout check + out/card.pdf\npython run.py --replay 2025-05-03  # re-run a past day next to what really happened\n```\n\n**Data (free, no API keys):**\n\n`k7hf-8y75`): hourly readings from the Oak\nStreet station since 2015.`api.weather.gov` hourly forecast for Midway's gridpoint.\n**Model: the TabPFN-v2 classifier.** TabPFN is a transformer pretrained on millions of synthetic tabular\n\nproblems. You don't train it. You hand it labeled rows as context, and it predicts new rows in a single\n\nforward pass. Here the context is 3,000 randomly sampled training hours. The features are only things an NWS\n\nhourly forecast provides: hour, day of year, temperature, wind speed and direction, humidity, and rain yes/no.\n\n``` python\nfrom tabpfn import TabPFNClassifier\nclf = TabPFNClassifier(model_path=\"models/tabpfn-v2-classifier-....ckpt\", device=\"cpu\",\n                       random_state=0, ignore_pretraining_limits=True)  # 3,000 rows > the 1,000 CPU suggestion\nclf.fit(ctx[FEATURES], ctx.label)   # \"fit\" = store the context, no gradient steps\np_good = clf.predict_proba(forecast[FEATURES])[:, 1]\n```\n\nThe model sees rain only as yes/no, but forecasts give a *chance* of rain. So the card scores each hour twice,\n\nonce dry and once wet, and blends the two by the forecast's precipitation probability. Fitting the model and\n\nscoring all 11,397 holdout hours takes about 54 seconds on CPU.\n\n**The holdout test.** Training data is 2015–2023. Testing uses every 7am–7pm hour from 2024-01-01 to\n\n2026-10-05 where both stations reported: 11,397 hours the model never saw.\n\n**Read this before the table:** the inputs are actual airport observations standing in for a perfect forecast,\n\nso real forecast error isn't included (more on that below).\n\n| Method | Accuracy | Brier ↓ | Best-window hit rate* | \n|---|---|---|---|\n| Weather app as-is (same rule on airport conditions) | 0.846 | 0.154 | 0.510 | \n| App + monthly lake temperature offset | 0.863 | 0.137 | 0.520 | \n| Climatology (month × hour) | 0.760 | 0.171 | 0.466 | \n| Logistic regression (29k hours) | 0.783 | 0.156 | 0.463 | \n| Gradient boosting (29k hours) | **0.916** | **0.062** | 0.547 | \n| **TabPFN-v2 (3k-hour context)** | 0.914 | 0.067 | **0.556** | \n\n*Each day, the method picks one 2-hour window, and a hit means both hours really were good. Only 59.9% of test\n\ndays had any good window, so 0.599 is the ceiling.\n\nWhat the table means in plain terms:\n\nWhat the numbers don't show:\n\n`out/`.)\nAn AI agent, Alfred, built the whole project in a terminal session: the data pulls, modeling, holdout check,\n\ncard, and first draft of this post. Claude, another AI agent, audited every number against the run output\n\nbefore publishing. The session wasn't recorded with DevRelay.", "url": "https://wpnews.pro/news/lakefront-window-a-one-page-tabpfn-card-for-when-chicago-s-beach-is-colder-than", "canonical_source": "https://dev.to/alfreddeskchi/lakefront-window-a-one-page-tabpfn-card-for-when-chicagos-beach-is-colder-than-your-weather-app-3bm6", "published_at": "2026-10-06 19:42:51+00:00", "updated_at": "2026-10-06 19:48:29.739478+00:00", "lang": "en", "topics": ["machine-learning", "ai-agents", "ai-tools", "developer-tools"], "entities": ["Alfred", "Brooks Moore", "Lakefront Window", "PriorLabs-TabPFN", "Oak Street Beach", "Chicago Midway Airport", "Claude", "Lakefront Trail"], "also_reported_by": [], "alternates": {"html": "https://wpnews.pro/news/lakefront-window-a-one-page-tabpfn-card-for-when-chicago-s-beach-is-colder-than", "markdown": "https://wpnews.pro/news/lakefront-window-a-one-page-tabpfn-card-for-when-chicago-s-beach-is-colder-than.md", "text": "https://wpnews.pro/news/lakefront-window-a-one-page-tabpfn-card-for-when-chicago-s-beach-is-colder-than.txt", "jsonld": "https://wpnews.pro/news/lakefront-window-a-one-page-tabpfn-card-for-when-chicago-s-beach-is-colder-than.jsonld"}}