S&P 500 옵션 시퀀스 모델을 위한 공유 모델 모집단 관리
코드 Machine Learning for Trading
요약
이 노트북은 S&P 500 옵션을 대상으로 선언된 3개 모델 시퀀스 학습 집단 중 NLinear 모델을 실행합니다. 이 모델을 학습하기 전에 전체 집단의 요청과 체크포인트를 확정하므로, 후속 노트북에서 같은 스냅샷을 기준으로 LSTM 및 PatchTST 모델을 실행할 수 있습니다. 장치도 학습 정체성의 일부로 간주합니다. CPU와 GPU 연산에서 서로 다른 학습 가중치가 나올 수 있으므로, 표준 장치가 아닌 경우 별도의 집단 이름이 필요합니다.
이 워크플로는 재현성과 완전성을 중시합니다. 모집단 구성을 기록하고, NLinear 요청이 고유한지 확인하며, 반환된 체크포인트가 완전한지 검증합니다. 시퀀스는 데이터 누락 구간을 안전하게 처리하도록 구성했다고 설명하며, 학습된 상태의 저장, 재시작 지원, 대상 키 확인을 포함합니다. 이 문서는 모델 성능을 보고하거나 아키텍처를 비교하거나 트레이딩 가치를 입증하지 않습니다. 모델링 워크플로의 실행 및 식별 관리 절차를 설명하며, 모델 분석과 백테스팅은 후속 작업으로 남겨 둡니다.
핵심 아이디어
- NLinear 모델을 실행하기 전에 전체 구성과 체크포인트 모집단을 확정합니다.
- CPU 및 GPU 실행에서 서로 다른 가중치가 나올 수 있으므로 학습 장치를 모델 정체성에 포함합니다.
- 모집단 스냅샷은 한 모델 실행에 실패가 발생하거나 갱신될 때도 선언된 구성을 보존하는 데 도움이 됩니다.
- 노트북은 NLinear 요청이 고유한지, 체크포인트가 완전한지 확인합니다.
- 성능 및 트레이딩에 관한 결론은 이 노트북의 범위에 포함되지 않습니다.
태그
전문
# 09_deep_learning.py
```py
# ---
# jupyter:
# jupytext:
# cell_metadata_filter: tags,-all
# text_representation:
# extension: .py
# format_name: percent
# format_version: '1.3'
# jupytext_version: 1.19.3
# kernelspec:
# display_name: Python 3 (ipykernel)
# language: python
# name: python3
# ---
# %% [markdown]
# # S&P 500 Options: NLinear
#
# This notebook snapshots the complete three-model sequence population before fitting its NLinear
# member. `09a_lstm` and `09b_patchtst` execute the other declared members against the same
# immutable population. Every configured checkpoint remains eligible for model analysis and
# backtesting.
#
# Prerequisites: `03_financial_features`, `04_model_based_features`, and `05_evaluation`.
# %%
"""Fit NLinear within the declared S&P 500 options sequence population."""
import polars as pl
from case_studies.research import supersedes_for_run
from case_studies.sp500_options.research_workflow import (
ALL_LABELS,
declared_dl_device,
model_request_catalog,
open_study,
published_dl_device,
resolve_model_requests,
resolved_model_plan,
run_official_model_subset,
run_resolved_model_requests,
snapshot_official_model_catalog,
)
# %% tags=["parameters"]
EXECUTION_TIER = "canonical"
WORKSPACE: str = ""
PREVIEW_REDUCTIONS: dict = {}
DEVICE: str = ""
SEQUENCE_CONFIGS = ("nlinear", "lstm_h64", "patchtst")
POPULATION_NAME: str = ""
SUPERSEDES_POPULATION: str = "7a9dc8881c9e"
# %% [markdown]
# ### The device the population was fitted on
#
# A network trained on a GPU and the same network trained on a CPU accumulate their sums in a
# different order and reach different weights, so the device is part of what the fitted model is
# and sits inside the training identity rather than beside it. The device this population was
# fitted on is declared once, in `modeling.dl.device` in `config/setup.yaml`, and read from there
# by all four deep-learning notebooks rather than retyped in each. On a machine with no NVIDIA
# card the run stops here rather than quietly training something else: set `DEVICE="cpu"` and pass
# a `POPULATION_NAME` to fit the same requests there, under a name of their own.
# %%
CANONICAL_POPULATION_NAME = "sp500-options-sequence-validation-v1"
published_device = published_dl_device()
device = declared_dl_device(DEVICE)
population_name = POPULATION_NAME or CANONICAL_POPULATION_NAME
if device != published_device and population_name == CANONICAL_POPULATION_NAME:
raise ValueError(
f"this run fits on {device!r}, not the published {published_device!r}, so its "
f"identities are not the ones {CANONICAL_POPULATION_NAME!r} holds; pass "
f"POPULATION_NAME to give them a population of their own"
)
print(f"training device: {device} (declared: {published_device})")
# %% [markdown]
# ## Complete sequence request population
#
# The case-wide table is resolved before the first member executes. Canonical execution snapshots
# all configuration-checkpoint identities so a failed member cannot disappear from later analysis.
#
# **A name holds one generation at a time**, and this notebook is the only one that writes this
# population - `09a_lstm` and `09b_patchtst` execute members of a snapshot that already exists.
# Anything that moves a training identity moves every prediction hash with it, so the members
# this run computes are no longer the members an earlier snapshot under the same name declared,
# and those two notebooks then refuse their own work as undeclared. `SUPERSEDES_POPULATION`
# names the snapshot such a run retires, and the value is part of what the population is hashed
# over. The value here names the snapshot this run retires; it is empty only for the first
# snapshot under a name.
#
# `create` refuses a changed member list under an existing name unless this names the current
# snapshot, so the parameter is what makes refreshing this population possible at all. Without
# it the refit stops at the write with the hash it needs, which is the right failure but not
# one this notebook could act on.
# %%
study = open_study(execution_tier=EXECUTION_TIER, workspace=WORKSPACE or None)
all_requests = model_request_catalog(
"deep_learning",
labels=ALL_LABELS,
config_names=SEQUENCE_CONFIGS,
)
all_resolved = resolve_model_requests(
study,
all_requests,
execution_tier=EXECUTION_TIER,
overrides={"device": device},
preview_reductions=PREVIEW_REDUCTIONS,
)
resolved_model_plan(all_resolved)
# %% [markdown]
# ## Execute NLinear
#
# NLinear shares the gap-safe sequence construction, fold boundaries, fitted-state persistence,
# restart, and exact eligible-key checks used by the other sequence configurations.
# %%
nlinear_resolved = tuple(
request for request in all_resolved if request.spec["config_name"] == "nlinear"
)
if len(nlinear_resolved) != 1:
raise ValueError("the sequence population must contain exactly one NLinear request")
if EXECUTION_TIER == "canonical":
population = snapshot_official_model_catalog(
study,
all_requests,
population_name=population_name,
resolved_requests=all_resolved,
supersedes=supersedes_for_run(
study,
population_name=population_name,
declared=SUPERSEDES_POPULATION or None,
execution_tier=EXECUTION_TIER,
),
)
execution, population = run_official_model_subset(
study,
nlinear_resolved,
population=population,
)
else:
if not WORKSPACE or not PREVIEW_REDUCTIONS:
raise ValueError("preview execution requires WORKSPACE and PREVIEW_REDUCTIONS")
execution = run_resolved_model_requests(study, nlinear_resolved)
population = None
# %% tags=["results"]
catalog = execution.catalog_rows.select(
"family",
"label",
"config_name",
"checkpoint_kind",
"checkpoint_value",
"execution_tier",
"complete",
"training_hash",
"prediction_hash",
).sort("checkpoint_value")
if catalog.filter(~pl.col("complete")).height:
raise RuntimeError("NLinear execution returned a partial checkpoint")
catalog
# %% [markdown]
# The NLinear checkpoint artifacts are complete. The official sequence population remains open
# until `09a_lstm` and `09b_patchtst` publish their declared members.
```출처의 라이선스에 따라 출처를 표시하고 전문을 공개합니다. 라이선스: MIT
이 요약은 원문을 바탕으로 Stratmill의 리서치 에이전트가 작성했으며, 원문을 복사한 것이 아닙니다.