Versio: 1.0, 15.5.2026 Tarkoitus: Konteksti Claude Codelle MVP-kehityksen aloittamiseen. Cinian ennakointi-tarjooman pilotti, joka yhdistää kvantitatiivisen nowcasting-mallin agenttiseen tilannekuvaan.
Nowcasting-agentti energiahuoltovarmuuden seurantaan. Tuottaa reaaliaikaisen numeerisen estimaatin Suomen sähköhuoltovarmuusmittarista (julkaisuviive ~kvartaali) korkeampifrekvenssisistä avoimista indikaattoreista, päivittää estimaattia uutta dataa saapuessa, ja tuottaa LLM-kerroksen kautta luettavan selityksen siitä mistä muutos johtuu — mukaan lukien geopoliittiset ajurit kuten Hormuzin salmen tilanne ja LNG-markkinan reaktiot.
Differentiaattori suhteessa Wahlbergin Vantaa-demoon: kvalitatiivisen tilannekuvan päälle numeerinen, validoitavissa oleva malli, jonka tarkkuus voidaan todentaa jälkikäteen oikeaa virallista lukua vastaan.
Asiakkaat: Huoltovarmuuskeskus (HVK), TEM, suuret kaupungit (Helsinki, Vantaa, Espoo, Tampere), energiayhtiöt, Traficom. Pilotti todennäköisesti HVK tai Vantaa (Wahlbergin tiimin jatkumo).
Kolme toisiaan tukevaa pilaria:
nowcast_lstm Python-kirjaston (PyPI), joka käyttää PyTorchia ja madaltaa implementointikynnystä. Käytämme tätä metodologisena runkona.Tärkeä rajaus: Malli ei “ennusta Hormuzin sulkemista” — se mittaa miten markkinoiden hinnoittelema riski kehittyy ja päivittää huoltovarmuusestimaattien epävarmuusvälejä. Tämä erottaa tuotteen spekulatiivisesta “AI-ennustaa-sodan” -hypestä.
[Data Layer] [Model Layer] [Agent Layer] [UI Layer]
───────────── ───────────── ───────────── ─────────────
Tilastokeskus API ──┐
Eurostat API ──┤
Fingrid API ──┼─→ Data Collector ──→ nowcast_lstm ──→ Nowcast Agent ──┐
Nord Pool ──┤ Agent (orchestr.) (10 networks, (runs model, │
ENTSO-E ──┤ X13 seasonal adj., mean of outputs, produces estimate │
TTF/Brent (Eikon) ──┤ stationarity, MAE/RMSE vs + confidence) │
AIS Hormuz (avoin) ──┤ ARMA gap-filling) ARMA benchmark) ├─→ Dashboard
GPR Index ──┤ ↓ │ (Streamlit
Caldara-Iacoviello ──┤ │ tai HTML)
Polymarket ──┘ Explainer Agent │
(LLM: sensitivity │
analysis + skenaario│
-peilaus + tekstinen│
selitys) ────┘
Komponentit:
nowcast_lstm odottaa (rivi per kuukausi, kvartaalimuuttujilla NaN väliriveissä).nowcast_lstm-kirjasto, 10 verkon keskiarvo (Hopp:n metodologia stokastisuuden hillitsemiseksi), oletushyperparametrit aluksi, grid search myöhemmin. Benchmark: ARMA. Validointimittarit: MAE ja RMSE, t-testi LSTM vs ARMA.Vaihtoehto A (suositus aloitukseen): Suomen sähkön nettotuonti / sähköomavaraisuusaste, neljännesvuosittain, Tilastokeskuksen energiatase, viive ~3 kk. Pitkä historia (>15 v), selkeä kausivaihtelu, hyvät korreloivat indikaattorit.
Vaihtoehto B (yksinkertaisempi): Suomen kuukausittainen sähkön kokonaiskulutus, Tilastokeskus tai Energiavirasto, viive ~6 viikkoa. Helpompi mallintaa, mutta vähemmän “huoltovarmuus”-kytköstä.
Vaihtoehto C (vaativampi mutta vaikuttavin): Kriittisten tavararyhmien tuontivolyymit (polttoaineet, lääkkeet, lannoitteet), Tulli, viive ~6 viikkoa.
Aloitetaan A:lla. Jos data ei aukea helposti, fallback B.
Kotimainen energia:
Eurooppa-konteksti:
Globaali/geopoliittinen:
Kausitasaus: Kaikki Hopp:n ohjeen mukaan X13-ARIMA-SEATS, kasvuasteiksi muunnettuina. statsmodels.tsa.x13 toimii.
Asiakkaan kanssa määritellään kolme skenaariota; tämä on osa konsultointia, ei automaatio:
Malli tuottaa ehdollisen estimaatin per skenaario + agentti seuraa indikaattoreita ja päivittää skenaarioiden todennäköisyydet (Polymarket-tyyppisten ennustemarkkinoiden ja GPR-indeksin avulla).
| Päivä | Tehtävä | Deliverable |
|---|---|---|
| 1–2 | Data-pipeline | Toimiva ETL Tilastokeskus + Eurostat + Fingrid + Nord Pool → Pandas DataFrame oikeassa muodossa |
| 3 | nowcast_lstm-asennus ja ensimmäinen ajo |
Baseline-malli ajossa, default-hyperparametrit, MAE/RMSE-tulos |
| 4 | ARMA-benchmark ja vintage-backtest | Hopp:n tyylinen taulukko: ARMA vs LSTM, 5 vintagea |
| 5 | Geopoliittiset indikaattorit | Brent + TTF + GPR + Hormuz AIS pipelineen, mallin uudelleenajo |
| 6 | Explainer Agent v1 | LangGraph-pipeline joka tuottaa LLM-selityksen mallin outputista |
| 7 | Skenaariokerros | Kolme skenaariota määritelty, ehdolliset estimaatit |
| 8–9 | Streamlit-UI | Aikajana, luottamusväli, indikaattoritaulu, LLM-selitys, skenaariotodennäköisyydet |
| 10 | Hyperparametrien tuning | Grid search, paras MAE/RMSE valittu |
| 11 | Vintage-backtest viimeisille 12 kk:lle | “Näin malli olisi näyttänyt joka kuukausi takautuvasti” |
| 12 | Pitch deck | 10 sliden esitys: ongelma, ratkaisu, demo, tieteellinen pohja, hinnoittelu |
| 13 | Sisäinen demo Idalle ja Pontukselle | Feedback, säätö |
| 14 | Kontakti pilottiasiakkaaseen (HVK tai Vantaa) | Tapaaminen sovittu |
Resurssitarve: Sun oma aika, RTX 3060 työasema (riittää 10 LSTM-verkon kouluttamiseen), Anthropic API-budjetti LLM-selittäjälle (~50–100 €/kk).
nowcast-huoltovarmuus/
├── README.md
├── pyproject.toml
├── .env.example # API-avaimet (Fingrid, ENTSO-E jos vaatii)
├── data/
│ ├── raw/ # API:sta haettu raakadata
│ ├── processed/ # Kausitasattua, normalisoitua
│ └── models/ # Talletetut LSTM-mallit (dill)
├── src/
│ ├── collectors/
│ │ ├── tilastokeskus.py # Pohjautuu sun TKI-dashboard-koodiin
│ │ ├── eurostat.py
│ │ ├── fingrid.py
│ │ ├── nordpool.py
│ │ ├── entsoe.py
│ │ ├── geopolitics.py # Brent, TTF, GPR, AIS Hormuz, Polymarket
│ │ └── base.py # Yhteinen rajapinta
│ ├── preprocessing/
│ │ ├── seasonal.py # X13-ARIMA-SEATS
│ │ ├── stationarity.py
│ │ └── alignment.py # Mixed-frequency yhdistäminen
│ ├── model/
│ │ ├── nowcast_model.py # nowcast_lstm wrapper
│ │ ├── arma_benchmark.py
│ │ ├── vintage_backtest.py
│ │ └── metrics.py # MAE, RMSE, t-test
│ ├── agents/
│ │ ├── data_collector.py # LangGraph: orkestroi collectorit
│ │ ├── nowcaster.py # Ajaa mallin
│ │ ├── explainer.py # LLM-selitys
│ │ └── scenario.py # Skenaariokerros
│ └── ui/
│ └── streamlit_app.py
├── notebooks/
│ ├── 01_data_exploration.ipynb
│ ├── 02_baseline_lstm.ipynb
│ ├── 03_vintage_backtest.ipynb
│ └── 04_explainer_prototype.ipynb
└── tests/
└── test_collectors.py
nowcast_huoltovarmuus_brief.md)nowcast_lstm-kirjaston README PyPI:stäuv paketinhallintaan. Kirjoita testit jokaiselle collectorille. Älä yritä rakentaa mallikerrosta ennen kuin data-pipeline tuottaa puhdasta Pandas DataFramea jossa on sähköhuoltovarmuuden kohdesarja sekä vähintään 10 input-saraketta oikealla taajuudella.”from nowcast_lstm.LSTM import LSTM
# data: Pandas DataFrame, sarakkeet: date, target_col, feature1, feature2, ...
# Rivit kuukausifrekvenssissä, kvartaalimuuttujilla NaN väliriveissä
model = LSTM(
data=training_data,
target_variable="sahkohuoltovarmuus",
n_timesteps=12, # 12 kuukauden ikkuna
fill_na_func=np.nanmean, # ARMA myöhemmin
fill_ragged_edges_func="ARMA",
n_models=10, # 10 verkon keskiarvo
train_episodes=200,
batch_size=30,
decay=0.98,
n_hidden=20,
n_layers=2,
dropout=0,
criterion="MSE",
optimizer="Adam",
optimizer_parameters={"lr": 1e-2}
)
model.train()
predictions = model.predict(test_data)
for vintage in ["2_months_before", "1_month_before", "month_of", "1_month_after", "2_months_after"]:
artificial_data = simulate_vintage(full_data, vintage, publication_lags)
pred = model.predict(artificial_data)
mae = mean_absolute_error(actuals, pred)
rmse = root_mean_squared_error(actuals, pred)
# Vertaa ARMA-benchmarkkiin t-testillä
from langgraph.graph import StateGraph
class NowcastState(TypedDict):
current_nowcast: float
previous_nowcast: float
input_changes: dict[str, float]
scenario_probabilities: dict[str, float]
explanation: str
def explain_node(state):
prompt = f"""
Sähköhuoltovarmuusestimaatti muuttui {state['previous_nowcast']} -> {state['current_nowcast']}.
Suurimmat input-muutokset: {top_n_changes(state['input_changes'], 5)}.
Skenaariotodennäköisyydet: {state['scenario_probabilities']}.
Kirjoita 3-4 lauseen tilannekuva suomeksi huoltovarmuusvastaavalle.
Yhdistä numeerinen muutos geopoliittiseen tilanteeseen jos GPR-indeksi tai
Hormuz-indikaattorit muuttuivat merkittävästi. Älä spekuloi syillä joita
data ei tue.
"""
response = anthropic_client.messages.create(...)
return {"explanation": response.content[0].text}
graph = StateGraph(NowcastState)
graph.add_node("explain", explain_node)
# jne.
Yhteenveto Claude Codelle: Aloita data-pipelinellä. Älä lähde rakentamaan mallia ennen kuin saat puhtaan DataFramen. Pidä koodi modulaarisena niin että samaa pipelineä voi käyttää muille kohdesarjoille (logistiikka, elintarvike) myöhemmin. Validointi joka kerros (testit collectoreille, validointi mallille, vintage-backtest agentille).