[AI] [FEAT]: PatchTST 중장기 추세 예측 모델 구현#312
Conversation
|
Warning Rate limit exceeded
⌛ How to resolve this issue?After the wait time has elapsed, a review can be triggered using the We recommend that you space out your commits to avoid hitting the rate limit. 🚦 How do rate limits work?CodeRabbit enforces hourly rate limits for each developer per organization. Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout. Please see our FAQ for further information. ℹ️ Review info⚙️ Run configurationConfiguration used: Organization UI Review profile: CHILL Plan: Pro Run ID: 📒 Files selected for processing (3)
WalkthroughRevIN 초기화 단순화, PatchTST 모델을 단일 출력에서 다중 지평선 출력으로 변경하고 전체 학습 파이프라인(DataLoader → 전처리 → 시퀀스 생성 → 학습)과 DataFrame 기반 추론 래퍼, 스케일러 저장/로딩을 도입했습니다. 기타 .gitignore 항목이 추가되었습니다. Changes
Sequence Diagram(s)sequenceDiagram
participant User
participant Trainer as train.py
participant Loader as SISCDataLoader
participant Preproc as Preprocessing
participant SeqBuilder as build_sequences()
participant Model as PatchTST_Model
participant Checkpoint as Checkpoint
User->>Trainer: train()
Trainer->>Loader: DB에서 OHLCV 로드
Loader-->>Trainer: raw_data (티커별)
Trainer->>Preproc: add_technical_indicators(), add_multi_timeframe_features()
Preproc-->>Trainer: 특징 포함된 DataFrame
Trainer->>SeqBuilder: MinMaxScaler, seq_len로 시퀀스 생성
SeqBuilder-->>Trainer: X, y (정규화됨)
Trainer->>Model: 배치별 학습
Model-->>Trainer: 손실값 반환
Trainer->>Checkpoint: model.state_dict(), scaler pickle 저장
sequenceDiagram
participant User
participant Wrapper as PatchTSTWrapper
participant Scaler as MinMaxScaler
participant Model as PatchTST_Model
User->>Wrapper: predict(df)
Wrapper->>Wrapper: 입력 길이/열 검증, 누락 열 제로 채움
alt scaler와 충분한 데이터 존재
Wrapper->>Scaler: transform(window)
Scaler-->>Wrapper: 스케일된 입력
Wrapper->>Model: 마지막 seq_len 윈도우 전달
Model-->>Wrapper: logits (n_outputs)
Wrapper->>Wrapper: sigmoid -> {patchtst_1d,...}
Wrapper-->>User: 결과 dict
else
Wrapper-->>User: _default_output() (모두 0.5)
end
Estimated code review effort🎯 4 (Complex) | ⏱️ ~60 minutes Possibly related issues
Suggested reviewers
Poem
🚥 Pre-merge checks | ✅ 2 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (2 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Actionable comments posted: 7
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@AI/modules/signal/models/PatchTST/train.py`:
- Around line 211-218: The pipeline currently fits the MinMaxScaler via
build_sequences(..., fit_scaler=True) on the entire dataset then calls
train_test_split(..., shuffle=True), causing leakage (overlapping windows across
X/Y and tickers). Fix by splitting data into train/val first (use time-ordered
or group-aware split instead of shuffle, e.g., split by timestamp or ticker
groups) and then fit the scaler only on the training set (call scaler.fit on
data used by build_sequences for train or use build_sequences(...,
fit_scaler=True) only for the train partition and build_sequences(...,
fit_scaler=False) or scaler.transform for validation); ensure functions
referenced (MinMaxScaler, build_sequences, train_test_split, X_train/X_val,
y_train/y_val) reflect this ordering so val transforms use the train-fitted
scaler only.
- Around line 125-127: 현재 분기문이 "if len(sub) <= seq_len + max_horizon: continue"로
쓰여 있어 경계 길이(len(sub) == seq_len + max_horizon)인 경우에도 샘플을 건너뛰고 있습니다; 이를 고치려면 해당
조건을 "len(sub) < seq_len + max_horizon"으로 변경해 경계 케이스를 허용하도록 하세요 (참조 변수: sub,
seq_len, max_horizon, 그리고 이후에 계산되는 num_samples).
- Around line 182-187: The broad except swallowing preprocessing errors in the
loop hides which tickers failed; update the try/except around the calls to
add_technical_indicators and add_multi_timeframe_features so that on exception
you log the ticker identifier (from df_t or its source variable) and the
exception details (exception message/trace), increment a failure counter, and if
failures exceed a small threshold abort training (raise or return) instead of
silently continuing; ensure the log includes the symbols processed and use the
existing processed list handling so only successful df_t are appended.
- Around line 172-173: The code currently forces training on only the first 50
tickers by creating tickers_sample = raw_df['ticker'].unique()[:50] and
filtering raw_df, which should be optional; add a config flag (e.g.,
sample_first_n or smoke_test_mode) and default it to disabled so the default
behavior uses all tickers, and only when the flag is set use the existing
sampling logic (apply the tickers_sample selection to raw_df). Update the code
paths that reference tickers_sample/raw_df to honor the new config flag and
document the flag name in the config used by the training entrypoint.
In `@AI/modules/signal/models/PatchTST/wrapper.py`:
- Around line 184-190: The checkpoint currently saves only
self.model.state_dict() in save(), which prevents safe restoration because
load() reconstructs a new model from default config; update save() (and the
similar save at the other location) to also serialize the model/configuration
(architecture hyperparameters used to build the model: e.g., seq_len,
position_embedding size, number_of_heads, patch_size, etc.) alongside the
state_dict (e.g., save a dict {"config": self.config, "state_dict":
self.model.state_dict()}); then modify load() to read that config from the
checkpoint and call build(saved_config) to instantiate the model with the exact
architecture before loading state_dict into it so position_embedding and head
shapes match. Ensure references to save(), load(), build(), self.model,
state_dict, position_embedding, and head are used when locating and changing the
code.
- Around line 35-45: FEATURE_COLUMNS in wrapper.py is ordered differently than
in train.py causing misaligned scaler statistics and wrong predictions; update
wrapper.py to use the exact same feature ordering as build_sequences()/train.py
(ensure ma5_ratio is the second column as in train.py:71-84) by either importing
shared FEATURE_COLUMNS and HORIZONS from a common constants module or by copying
the identical list used by build_sequences(), and verify predict() uses the same
feature positions and scaler fitted order as the training pipeline.
- Around line 5-10: Docstring promises daily_routine.py will call
PatchTSTWrapper.predict, but the pipeline still uses TransformerSignalModel;
update the pipeline to instantiate and use PatchTSTWrapper instead of (or
alongside, behind a flag replacing) TransformerSignalModel: import
PatchTSTWrapper, create wrapper = PatchTSTWrapper(config) in the same
initialization location, call wrapper.load(model_path, scaler_path) where models
are loaded, and replace the TransformerSignalModel.predict call with
wrapper.predict(df) (or add an adapter to match the existing predict call
signature). Ensure any differences in return format are normalized so downstream
code remains compatible.
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
Run ID: 38d9c266-a635-4ee9-aee9-00cf30653f3b
📒 Files selected for processing (4)
.gitignoreAI/modules/signal/models/PatchTST/architecture.pyAI/modules/signal/models/PatchTST/train.pyAI/modules/signal/models/PatchTST/wrapper.py
| 역할: 학습된 PatchTST 모델을 파이프라인(daily_routine.py)과 연결 | ||
|
|
||
| 파이프라인이 이 wrapper를 쓰는 방식: | ||
| wrapper = PatchTSTWrapper(config) | ||
| wrapper.load(model_path, scaler_path) | ||
| result = wrapper.predict(df) |
There was a problem hiding this comment.
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
set -e
fd 'daily_routine.py$' AI -x sed -n '80,170p' {}
rg -nP --type=py '\bPatchTSTWrapper\b|\bbuild_transformer_model\s*\(' AIRepository: SISC-IT/sisc-web
Length of output: 4936
🏁 Script executed:
cat -n AI/modules/signal/models/PatchTST/wrapper.py | head -20Repository: SISC-IT/sisc-web
Length of output: 744
🏁 Script executed:
rg -n 'PatchTSTWrapper' AI/pipelines/daily_routine.pyRepository: SISC-IT/sisc-web
Length of output: 42
파이프라인 통합이 아직 완료되지 않았습니다.
이 wrapper의 docstring(5-10줄)에서는 AI/pipelines/daily_routine.py가 PatchTSTWrapper.predict()를 호출하는 방식으로 사용될 것을 명시하고 있습니다. 그러나 현재 daily_routine.py는 TransformerSignalModel을 사용하고 있으며, PatchTSTWrapper는 전혀 호출되지 않습니다. 따라서 이 PR의 목표인 파이프라인 통합이 아직 달성되지 않았습니다.
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@AI/modules/signal/models/PatchTST/wrapper.py` around lines 5 - 10, Docstring
promises daily_routine.py will call PatchTSTWrapper.predict, but the pipeline
still uses TransformerSignalModel; update the pipeline to instantiate and use
PatchTSTWrapper instead of (or alongside, behind a flag replacing)
TransformerSignalModel: import PatchTSTWrapper, create wrapper =
PatchTSTWrapper(config) in the same initialization location, call
wrapper.load(model_path, scaler_path) where models are loaded, and replace the
TransformerSignalModel.predict call with wrapper.predict(df) (or add an adapter
to match the existing predict call signature). Ensure any differences in return
format are normalized so downstream code remains compatible.
|
확인 완료 고생했습니다. |
관련 이슈
#311
작업 내용
테스트
Summary by CodeRabbit
New Features
Refactor