비모수적 가격 모델링을 위한 가우스 프로세스
"클래식 ML 기준선" 시리즈의 일부입니다.
가우스 프로세스를 이 블로그의 별도 기사로 만들 가치가 있는 두 가지 사항이 있으며, 둘 중 어느 것도 "불확실성을 제공"하지 않습니다.
첫 번째는 커널 디자인입니다. GP의 전체 유도 바이어스는 하나의 기능에 존재합니다. , 그리고 그 기능은 경로가 얼마나 거친지, 반복되는지, 반복이 감소하는지 여부 등 의도적으로 적어 두는 것입니다. 표준 툴킷의 다른 어떤 것도 명시적으로 적합하고 이에 맞는 시장 역학에 대한 구조적 가설을 기술할 수 없습니다. 두 번째는 주변 우도입니다. 이는 보유 세트가 아닌 모델 자체에서 파생된 복잡성 페널티가 있는 학습 목표입니다. 이 블로그의 과적합 아크에 대한 다른 모든 기사(plateau 분석, PBO, deflated Sharpe)는 검색 시 유효성 검사 세트 정규화가 취약하기 때문에 존재합니다. GP는 그것이 필요하지 않다고 주장합니다. 그 주장은 테스트 가능하며 이를 테스트하는 것은 다른 불확실성 크기 조정 튜토리얼보다 더 흥미롭습니다.
불확실성 자체: GP 사후 분산은 구조적입니다. 이는 나중에 적합 모델을 둘러싸는 것이 아니라 평균을 생성하는 동일한 추론에서 벗어납니다. 이는 등각 예측과의 실제 대조입니다. 이 블로그에서는 불확실성이 포지션 크기 조정에 대한 올바른 입력인 이유와 간격이 있으면 어떻게 해야 하는지 이미 이 블로그에서 다루고 있습니다. 이 기사에서는 해당 사례를 다시 주장하지 않습니다. 모델을 따라갑니다.
다음은 커널과 추론 기계, GPyTorch 구현, 그리고 - 마지막에 분명하게 언급된 - 이 기사에서 아직 다루지 않은 측정값입니다.
가우스 프로세스란 무엇입니까?
GP는 이미 이 블로그에 Optuna 대 좌표 하강의 베이지안 최적화 대용으로 표시되어 있으며 동일한 표기법과 동일한 저차원 경고가 있습니다. 여기서 GP는 초매개변수 검색 표면이 아닌 시장 데이터에 적합한 모델 자체이므로 처리가 더 깊어집니다.
가우스 프로세스는 임의 변수의 모음으로, 임의의 유한한 수는 공동 가우스 분포를 갖습니다. 매개변수에 대한 분포가 아니라 함수에 대한 분포입니다.
공식적으로는 함수 유한한 입력 집합에 대해 GP에서 가져옵니다. :
어디 평균 함수이고 공분산(커널) 함수입니다. 우리는 이것을 다음과 같이 간결하게 작성합니다:
평균 함수는 평균 행동에 대한 사전 믿음을 인코딩합니다. . 거래에서 우리는 일반적으로 , 수익에 대한 사전 방향 편향이 없다는 가정을 인코딩합니다. 모든 구조가 커널로 들어갑니다.
왜 비모수적인가요?
5개 특성이 있는 선형 회귀 모델에는 6개의 매개변수가 있습니다. 64개의 단위로 구성된 두 개의 숨겨진 레이어가 있는 신경망에는 수천 개가 있습니다. GP에는 고정된 수의 매개변수가 없습니다. 모델의 복잡성은 데이터와 함께 증가합니다. GP는 10개의 관측값을 사용하여 10차원 가우스를 정의합니다. 10,000개의 관측값으로 10,000차원 가우스를 정의합니다.
이는 GP에 하이퍼파라미터가 없다는 의미는 아닙니다. 커널 함수에는 이전 함수에서 가져온 함수의 속성을 제어하는 하이퍼파라미터(길이 척도, 진폭, 주기성)가 있습니다. 그러나 기능적 형태 자체는 결코 고정되어 있지 않습니다. GP는 충분한 데이터와 올바른 커널이 제공되면 모든 연속 함수를 나타낼 수 있습니다. 이것이 "비모수적"이 의미하는 바입니다. 모델이 선형 함수나 다항식과 같은 매개변수 계열로 제한되지 않습니다.
재무 모델링의 경우 이는 매우 중요합니다. 시장은 변합니다. 특성과 수익률 간의 관계는 비선형적이고, 비정상적이며, 체제에 따라 다릅니다. 파라메트릭 모델은 현실과 일치하지 않을 수 있는 구조를 부과합니다. GP는 데이터를 통해 말을 하게 됩니다.
커널 기능: 인코딩 시장 구조
커널 함수 가우스 프로세스의 핵심입니다. 두 입력 지점에서 함수 값 사이의 공분산을 지정하여 사전에 가능한 함수를 정의합니다. 서로 다른 커널은 부드러움, 주기성 및 장거리 동작에 대한 서로 다른 가정을 인코딩합니다.
방사형 기초 함수(RBF) / 제곱 지수
RBF 커널은 가장 일반적인 시작점입니다.
어디 신호 분산(출력 스케일)이고 길이 척도이다. RBF 커널을 사용하여 GP에서 가져온 함수는 무한히 미분 가능하며 매우 부드럽습니다.
거래 해석: 길이 척도 두 데이터 포인트가 얼마나 멀리 떨어져 있을 수 있고 여전히 상관관계가 있는지를 제어합니다. 길이 척도가 짧다는 것은 모델이 지역적 패턴에 반응한다는 것을 의미합니다. 길이가 길다는 것은 광범위한 추세를 포착한다는 것을 의미합니다. 신호 분산 함수의 진폭, 즉 예측 수익의 크기를 제어합니다.
재정상의 문제: 무한한 부드러움은 비현실적입니다. 재정적 수익에는 급격한 상승, 체제 변화, 불연속성이 있습니다. RBF 커널은 이러한 특징을 과도하게 스무딩하여 구조적 중단 근처에서 너무 보수적인 예측을 생성할 수 있습니다.
산모 커널
Matern 클래스는 부드러움 매개변수를 도입하여 RBF를 일반화합니다. :
어디 는 수정된 제2종 베셀 함수입니다. 처럼 , Matern 커널은 RBF로 수렴됩니다. 일반적인 선택:
- : Ornstein-Uhlenbeck 공정과 동일합니다. 함수는 연속적이지만 미분할 수 없습니다. — 브라운 운동처럼 거칠게.
- : 함수는 한 번만 미분 가능합니다. 부드러움과 유연성 사이의 균형이 좋습니다.
- : 함수는 두 번 미분 가능합니다. 다음보다 부드러움 그러나 RBF보다 덜 단단합니다.
거래 해석: The Matern- 커널은 틀림없이 금융 시계열에 대한 최고의 기본값입니다. 이는 실제 가격 경로가 들쭉날쭉하지 않고 나타나는 일종의 거칠기를 허용합니다. . 이는 변동성 경로에 허스트 지수가 있음을 경험적으로 보여주는 "변동성은 거칠다"는 문헌(Gatheral, Jaisson, & Rosenbaum, 2018)과 일치합니다. , 브라운 운동보다 훨씬 거칠다.
Matern 커널이 고전적 변동성 모델을 능가한다는 주요 공개 증거는 Rizvi et al. (2017), 랜덤 워크보다 약 20% 더 나은 MSE, GARCH보다 50% 더 나은 MSE를 보고했습니다 — 암호화폐가 아닌 2017년 일일 통화 쌍 데이터에 대해 여기에 재현되지 않았습니다. 이를 벤치마크가 아닌 커널 시도에 대한 동기로 취급하십시오. Ljung-Box 및 ARCH-LM 진단을 통해 실제 BTC 일일 데이터에 적합한 이 블로그의 자체 GARCH(1,1)는 암호화폐에 대한 GARCH 변동성 예측에 있습니다. 동일한 샘플에서 Matern GP와의 정면 대결은 정직한 비교가 될 것이며 실행되지 않았습니다.
주기적 커널
금융 시장에는 일중 거래량 곡선, 요일 효과, 월별 재조정 흐름, 분기별 수익 시즌 등 순환 패턴이 있습니다. 주기적 커널은 다음을 캡처합니다.
어디 기간입니다. 이 커널에서 가져온 함수는 마침표와 함께 반복됩니다. , 길이 스케일에 의해 변조됨 이는 일정 기간 내에 상관 관계가 얼마나 빨리 감소하는지 제어합니다.
매매 해석: 설정 (시간) 일중 패턴을 캡처하거나 (거래일) 주간 계절성. 푸리에 기능과 달리 주기적 커널은 고정된 수의 고조파를 가정하지 않습니다. GP는 데이터에서 사이클의 모양을 학습합니다.
커널 결합: 덧셈과 곱셈 합성
GP 커널의 진정한 힘은 구성에 있습니다. 만약에 그리고 유효한 커널이므로 다음과 같습니다.
- 합계: — 함수는 독립 성분의 합입니다(가산 분해).
- 제품: — 구성 요소 간의 상호 작용(예: 국부적으로 주기적인 동작)
재정적 수익을 위한 유용한 복합 커널:
이는 신호를 다음과 같이 분해합니다.
- 매끄럽지 않고 비주기적인 추세 구성요소(Matern-3/2)
- 시간이 지남에 따라 진폭이 감소하는 주기적 구성요소(주기적 RBF)
제품 국소적으로 주기적인 커널을 생성합니다. 패턴은 반복되지만 먼 반복은 가까운 반복보다 영향력이 적습니다. 이는 시장 미세 구조가 진화함에 따라 시간이 지남에 따라 표류하는 금융 계절성에 정확히 맞습니다.
스펙트럼 혼합 커널
유연성을 극대화하기 위해 SM(스펙트럼 혼합) 커널(Wilson & Adams, 2013)은 커널의 스펙트럼 밀도를 가우스 혼합으로 매개변수화합니다.
어디 혼합물 무게이고, 스펙트럼 변화이며, 스펙트럼 수단(주파수)입니다. Bochner의 정리에 따르면 모든 고정 커널은 이러한 방식으로 표현될 수 있습니다. SM 커널은 주기적인 구성 요소, 장거리 추세 및 단기 상관 관계를 동시에 발견할 수 있습니다. 모두 데이터에서 가능합니다.
거래 해석: SM 커널은 데이터에 어떤 패턴이 존재하는지 모를 때 유용합니다. 이는 수익률 시리즈의 숨겨진 주기성을 식별할 수 있습니다(예: 자동화된 재조정으로 구동되는 암호화폐 시장의 미묘한 4시간 주기). 단점은 하이퍼파라미터가 많아지고 작은 데이터세트에 과적합될 위험이 있다는 것입니다.
사후 추론: 이전부터 예측까지
주어진 훈련 데이터 어디 그리고 , 테스트 포인트의 GP 후방 폐쇄형 솔루션이 있습니다. 이는 대부분의 베이지안 모델에 비해 GP의 주요 계산 이점입니다.
사후 방정식
하자 될 훈련 공분산 행렬, 될 교차공분산 행렬 및 될 공분산 행렬을 테스트합니다. 뒷부분은 다음과 같습니다.
어디:
사후 평균 테스트 포인트와 트레이닝 포인트 사이의 커널 유사성에 의해 가중치가 부여된 트레이닝 목표의 선형 조합입니다. 사후 공분산 사전 공분산에서 시작 훈련 데이터에서 얻은 정보를 뺍니다. 훈련 데이터가 조밀하면 사후 분산이 작습니다. 훈련 데이터가 희박한 경우 사후 분산은 이전 분산으로 되돌아갑니다.
한계 가능성과 테스트할 가치가 있는 주장
커널 하이퍼파라미터 (길이 척도, 분산, 잡음 수준)은 로그 한계 우도를 최대화하여 학습됩니다.
첫 번째 항은 데이터 적합 항입니다(관찰과 거리가 먼 예측에 불이익을 줍니다). 두 번째 항은 복잡성 페널티입니다(너무 유연한 모델, 즉 커널 행렬에 큰 행렬식이 있는 모델에 페널티를 줍니다). 세 번째 항은 정규화 상수입니다.
이것은 자동 Occam의 면도날이며 GP가 거래 파이프라인에 가져오는 가장 흥미로운 것입니다. 강력한 주장은 정규화를 위해 별도의 검증 세트가 필요하지 않다는 것입니다 — 복잡성 패널티는 목표 내부에 있으므로 모델은 무료로 유연성을 갖춘 적합성을 구입할 수 없습니다.
특히 이 블로그에서는 그 주장에 대해 회의적일 가치가 있습니다. 고원 분석은 단일 지점 검증 점수가 잘못된 선택 기준이며 견고성이 이웃의 형태에 있다는 것을 보여줍니다. PBO는 표본 내 승자가 표본 외부에서 패배하는 빈도를 정량화합니다. deflated Sharpe 시도 횟수에 따른 가격입니다. 한계 가능성은 여전히 최대화되는 표본 내 목표입니다. — Occam 요인은 많은 적합 커널에 대한 선택이 아니라 모델 용량에 불이익을 줍니다. 12개의 후보 커널을 맞추고 한계 가능성이 가장 높은 커널을 선택하면 다중 테스트 영역으로 돌아가고 디플레이션 논리는 변경되지 않고 적용됩니다. 위조 가능한 버전: 한계 우도 선택은 동일한 데이터 및 동일한 커널 계열에 대한 검증 세트 선택보다 표본 내/표본 밖 간격이 더 작습니까? 이는 측정 가능하지만 아래에서는 측정되지 않습니다.
한계 우도 표면에는 국소 최적값도 있습니다. 여러 번의 무작위 재시작 또는 신중한 초기화 문제 - 길이 척도를 훈련 입력의 중앙값 쌍별 거리로 초기화하고 노이즈 분산을 목표의 샘플 분산으로 초기화하는 것이 합리적인 시작점입니다.
컴퓨팅 비용 및 확장성
병목현상이 역전되고 있다 , 비용은 시간과 기억 속에. 입방체 벽은 이미 이 블로그에서 다른 방향에서 논의되었습니다. 검색 방법 대 평가 비용은 목표가 저렴할 때 GP 기반 베이지안 최적화를 완전히 부적격화합니다. 대리자가 저장하는 평가보다 비용이 더 높기 때문입니다. 산술은 여기에서도 동일합니다. 응용 프로그램이 다릅니다. 시장 데이터에 맞는 모델로서 삼차 항은 실격이 아니라 예산입니다. 즉, 훈련 기간에 엄격한 상한선을 설정합니다.
거래 애플리케이션을 위한 확장성 전략:
-
희소 GP(유도 지점). 행렬 행렬 어디에 . 유도 포인트 훈련 데이터를 요약하는 의사 입력입니다. Hensman et al.의 SVGP(Stochastic Variational GP) 공식. (2013)은 비용을 들여 미니 배치 학습을 허용합니다. 반복마다. GPyTorch는 이를 기본적으로 지원합니다.
-
구조화된 커널 보간(SKI/KISS-GP). 입력이 그리드에 있을 때 커널 행렬의 Kronecker 및 Toeplitz 구조를 이용합니다. 비용 절감 어디 그리드 크기입니다. 정기적으로 샘플링되는 시계열(예: 1분 막대)에 적합합니다.
-
슬라이딩 윈도우의 로컬 GP. 최근 데이터에 대해서만 별도의 GP를 훈련합니다. GP 특정 제약 조건이 문제가 되는 부분은 다음과 같습니다. 표준 커널은 고정되어 있습니다( 에만 의존한다 ) 시장은 그렇지 않으므로 일반적인 대답은 롤링 윈도우입니다. 그러나 윈도우 길이는 위의 다음과 같이 제한됩니다. , 단지 통계에 의한 것이 아닙니다. Walk-forward 최적화에서는 앵커 윈도우와 롤링 윈도우, 학습/테스트 길이, 재최적화 빈도 전반을 다룹니다. GP의 경우 창 크기 조정은 통계적인 결정만큼이나 계산적인 결정이며, 고정된(계속 증가하는) 창은 근사치 없이는 수천 지점을 넘어서는 사용할 수 없습니다. 재구성은 실질적인 결과입니다. GP를 사용하면 "모든 기록 사용"을 선택할 수 없습니다.
수익률 예측을 위한 GP: 실용적인 프레임워크
기능 디자인: 왜 500개가 아닌 5~20개의 기능이 필요합니까?
시장 데이터 ML에 대한 일반 기능 분류(주문장 불균형, 장부 압력, VPIN, Kyle의 람다, 실현 변동성 기능, 주기적 시간 인코딩, 교차 자산 및 자금 조달 비율 신호)는 이미 기계 학습을 사용한 확산 모델링에 배치되어 있습니다. 그 목록을 사용하세요.
GP에 특정한 것은 목록의 크기입니다. 커널 방법은 고차원에서 성능이 저하됩니다. 거리가 집중되고 고정된 커널은 식별력을 잃습니다. 금융 GP의 실제 범위는 그라디언트 부스트 트리가 만족스럽게 먹는 수백 개가 아닌 5~20개의 입력입니다. 이를 생존 가능하게 만드는 메커니즘은 ARD(자동 관련성 결정)입니다. 각 입력 차원에 자체 길이 척도를 제공합니다. , 그리고 한계 가능성 훈련이 추진됩니다. 신호를 전달하지 않는 차원의 경우 길이 스케일이 무한하다는 것은 커널이 해당 좌표를 무시한다는 것을 의미하기 때문입니다. 특징 선택은 피팅의 부산물이 되며, 학습된 내용은 관련성 순위로 직접 읽을 수 있습니다. 이는 또한 위조 가능하게 만드는 이유이기도 합니다. 합성 커널을 실제 막대에 맞추고, 길이 척도를 인쇄하고, 당신이 믿는 기능이 모델이 유지하는 기능인지 확인하세요.
직위 크기 조정 및 기권
GP 후방은 다음을 제공합니다. ; 위험 인식 포지션 사이징을 위한 등각 예측에서 개발한 방식에 바로 사용할 수 있다 간격 폭 . 유일한 차이점은 출처입니다. GP는 교정 세트가 아닌 모델 자체에서 너비를 생성하므로 과거 잔차의 전체 분위수보다는 훈련 데이터를 기준으로 테스트 포인트가 위치하는 위치에 따라 달라집니다.
GPyTorch를 사용한 구현
GPyTorch는 확장 가능한 GP 추론을 위한 PyTorch 기반 라이브러리입니다. GPU 가속, 자동 미분 및 최신 선형 대수학 기술(공역 기울기, Lanczos 분해)을 활용하여 순진한 수준 이상으로 GP를 확장합니다. 한계.
수익률 예측을 위한 기본 정확한 GP
import torch
import gpytorch
import numpy as np
from torch.utils.data import TensorDataset, DataLoader
class ExactGPModel(gpytorch.models.ExactGP):
"""Exact GP with a composite kernel for financial returns."""
def __init__(self, train_x, train_y, likelihood):
super().__init__(train_x, train_y, likelihood)
self.mean_module = gpytorch.means.ZeroMean()
self.covar_matern = gpytorch.kernels.ScaleKernel(
gpytorch.kernels.MaternKernel(nu=1.5, ard_num_dims=train_x.shape[1])
)
self.covar_periodic = gpytorch.kernels.ScaleKernel(
gpytorch.kernels.PeriodicKernel()
)
self.covar_rbf_decay = gpytorch.kernels.ScaleKernel(
gpytorch.kernels.RBFKernel()
)
def forward(self, x):
mean = self.mean_module(x)
covar = self.covar_matern(x) + self.covar_periodic(x) * self.covar_rbf_decay(x)
return gpytorch.distributions.MultivariateNormal(mean, covar)
ard_num_dims 위에서 설명한 차원별 길이 스케일을 가능하게 하는 것입니다. 훈련 후, model.covar_matern.base_kernel.lengthscale 읽어낼 벡터입니다.
훈련 루프
def train_gp(train_x, train_y, n_epochs=200, lr=0.05, device=None):
"""Train the GP by maximizing the marginal log-likelihood.
Returns the device alongside the model so that callers move test
tensors to the same place -- otherwise prediction crashes on GPU.
"""
if device is None:
device = torch.device("cuda" if torch.cuda.is_available() else "cpu")
train_x = train_x.to(device)
train_y = train_y.to(device)
likelihood = gpytorch.likelihoods.GaussianLikelihood().to(device)
model = ExactGPModel(train_x, train_y, likelihood).to(device)
model.train()
likelihood.train()
optimizer = torch.optim.Adam(model.parameters(), lr=lr)
mll = gpytorch.mlls.ExactMarginalLogLikelihood(likelihood, model)
losses = []
for epoch in range(n_epochs):
optimizer.zero_grad()
output = model(train_x)
loss = -mll(output, train_y)
loss.backward()
optimizer.step()
losses.append(loss.item())
if (epoch + 1) % 50 == 0:
noise = likelihood.noise.item()
print(
f"Epoch {epoch+1}/{n_epochs} | "
f"Loss: {loss.item():.4f} | "
f"Noise: {noise:.6f}"
)
return model, likelihood, device, losses
불확실성이 있는 예측
def predict_with_uncertainty(model, likelihood, test_x, device):
"""Generate predictions with uncertainty estimates."""
model.eval()
likelihood.eval()
test_x = test_x.to(device)
with torch.no_grad(), gpytorch.settings.fast_pred_var():
posterior = likelihood(model(test_x))
mean = posterior.mean
variance = posterior.variance
lower, upper = posterior.confidence_region() # 2-sigma bounds
return {
"mean": mean.cpu().numpy(),
"std": variance.sqrt().cpu().numpy(),
"lower_2sigma": lower.cpu().numpy(),
"upper_2sigma": upper.cpu().numpy(),
}
그만큼 fast_pred_var() 컨텍스트 관리자는 LOVE(Lanczos Variance Estimates) 알고리즘을 사용하여 예측 분산을 계산합니다. 대신 시간 .
엔드투엔드 거래 파이프라인
아래 기능 빌더에 대한 참고 사항: 모든 롤링 통계는 엄격하게 과거 지향적이어야 하며 입력 표준화는 훈련 슬라이스에만 맞춰져야 합니다. 두 번째 요점은 일반적인 위생이 아닙니다. 이는 각 누출 유형이 생성하는 샤프 인플레이션을 보고하는 예측 편향 분류에서 분석 및 측정된 정확하게 정규화 누출 채널입니다. GP는 구성별로 입력을 표준화하므로 이것이 가장 많이 노출되는 누출입니다.
import pandas as pd
def build_features(df: pd.DataFrame, lookback: int = 10) -> pd.DataFrame:
"""Build features for GP-based return prediction."""
features = pd.DataFrame(index=df.index)
for lag in range(1, lookback + 1):
features[f"ret_lag_{lag}"] = df["close"].pct_change().shift(lag)
ret = df["close"].pct_change()
features["vol_ratio"] = (
ret.rolling(10).std() / ret.rolling(50).std()
)
features["vol_zscore"] = (
(df["volume"] - df["volume"].rolling(50).mean())
/ df["volume"].rolling(50).std()
)
if "bid_vol" in df.columns and "ask_vol" in df.columns:
features["obi"] = (
(df["bid_vol"] - df["ask_vol"])
/ (df["bid_vol"] + df["ask_vol"])
)
if hasattr(df.index, "hour"):
hours = df.index.hour + df.index.minute / 60.0
features["time_sin"] = np.sin(2 * np.pi * hours / 24)
features["time_cos"] = np.cos(2 * np.pi * hours / 24)
features.dropna(inplace=True)
return features
def run_gp_strategy(
df: pd.DataFrame,
train_window: int = 500,
retrain_every: int = 50,
confidence_threshold: float = 1.0,
risk_fraction: float = 0.02,
max_leverage: float = 1.0,
):
"""Walk-forward GP trading strategy with uncertainty-based sizing."""
features = build_features(df)
returns = df["close"].pct_change().reindex(features.index)
target = returns.shift(-1) # predict next-bar return
mask = features.notna().all(axis=1) & target.notna()
features = features[mask]
target = target[mask]
positions = pd.Series(0.0, index=features.index)
predictions = pd.DataFrame(
index=features.index, columns=["mean", "std"], dtype=float
)
model = likelihood = device = None
x_mean = x_std = y_mean = y_std = None
for i in range(train_window, len(features)):
if model is None or (i - train_window) % retrain_every == 0:
train_x = torch.tensor(
features.iloc[i - train_window : i].values,
dtype=torch.float32,
)
train_y = torch.tensor(
target.iloc[i - train_window : i].values,
dtype=torch.float32,
)
x_mean, x_std = train_x.mean(0), train_x.std(0) + 1e-8
y_mean, y_std = train_y.mean(), train_y.std() + 1e-8
train_x_norm = (train_x - x_mean) / x_std
train_y_norm = (train_y - y_mean) / y_std
model, likelihood, device, _ = train_gp(
train_x_norm, train_y_norm, n_epochs=100
)
test_x = torch.tensor(
features.iloc[i : i + 1].values, dtype=torch.float32
)
test_x_norm = (test_x - x_mean) / x_std
pred = predict_with_uncertainty(model, likelihood, test_x_norm, device)
pred_mean = pred["mean"][0] * y_std.item() + y_mean.item()
pred_std = pred["std"][0] * y_std.item()
predictions.iloc[i] = [pred_mean, pred_std]
z_score = abs(pred_mean) / (pred_std + 1e-8)
if z_score > confidence_threshold:
size = min(z_score * risk_fraction, max_leverage)
positions.iloc[i] = np.sign(pred_mean) * size
strategy_returns = positions.shift(1) * returns
return strategy_returns, predictions, positions
희박한 GP를 사용하여 더 큰 데이터 세트로 확장
훈련 창이 수천 포인트를 초과하면 정확한 GP 추론이 느려집니다. 변형 희소 GP로 전환합니다.
class SparseGPModel(gpytorch.models.ApproximateGP):
"""Sparse variational GP for large-scale return prediction."""
def __init__(self, inducing_points):
variational_distribution = (
gpytorch.variational.CholeskyVariationalDistribution(
inducing_points.size(0)
)
)
variational_strategy = (
gpytorch.variational.VariationalStrategy(
self,
inducing_points,
variational_distribution,
learn_inducing_locations=True,
)
)
super().__init__(variational_strategy)
self.mean_module = gpytorch.means.ZeroMean()
self.covar_module = gpytorch.kernels.ScaleKernel(
gpytorch.kernels.MaternKernel(nu=1.5)
)
def forward(self, x):
mean = self.mean_module(x)
covar = self.covar_module(x)
return gpytorch.distributions.MultivariateNormal(mean, covar)
def train_sparse_gp(train_x, train_y, n_inducing=128, n_epochs=50, batch_size=256):
"""Train sparse GP with mini-batch stochastic variational inference."""
indices = torch.randperm(train_x.size(0))[:n_inducing]
inducing_points = train_x[indices]
model = SparseGPModel(inducing_points)
likelihood = gpytorch.likelihoods.GaussianLikelihood()
model.train()
likelihood.train()
optimizer = torch.optim.Adam(
[{"params": model.parameters()}, {"params": likelihood.parameters()}],
lr=0.01,
)
mll = gpytorch.mlls.VariationalELBO(
likelihood, model, num_data=train_y.size(0)
)
dataset = TensorDataset(train_x, train_y)
loader = DataLoader(dataset, batch_size=batch_size, shuffle=True)
for epoch in range(n_epochs):
for x_batch, y_batch in loader:
optimizer.zero_grad()
output = model(x_batch)
loss = -mll(output, y_batch)
loss.backward()
optimizer.step()
return model, likelihood
128개의 유도 포인트를 사용하면 배치당 비용은 다음과 같습니다. — 배치당 대략 400만 개의 작업이 수행됩니다. 이는 단일 GPU에서 100,000개 이상의 관측 데이터 세트를 쉽게 처리합니다.
심층 커널 학습: GP와 신경망의 만남
입력 공간이 고차원이거나 기능과 수익 간의 관계가 매우 비선형적인 경우 일반 커널이 어려움을 겪을 수 있습니다. DKL(심층 커널 학습)은 GP 커널을 적용하기 전에 신경망을 통해 입력을 전달합니다.
어디 매개변수가 있는 신경망입니다. 그리고 표준 커널(예: Matern-3/2)입니다. 네트워크는 GP 커널이 가장 효과적인 특징 표현을 학습합니다. 전체 모델(네트워크 매개변수 및 커널 하이퍼 매개변수)은 한계 가능성을 최대화하여 엔드투엔드 학습됩니다.
class DeepKernelGP(gpytorch.models.ExactGP):
"""GP with a neural network feature extractor."""
def __init__(self, train_x, train_y, likelihood, input_dim):
super().__init__(train_x, train_y, likelihood)
self.mean_module = gpytorch.means.ZeroMean()
self.feature_extractor = torch.nn.Sequential(
torch.nn.Linear(input_dim, 8),
torch.nn.ReLU(),
torch.nn.Linear(8, 4),
torch.nn.ReLU(),
torch.nn.Linear(4, 2),
)
self.covar_module = gpytorch.kernels.ScaleKernel(
gpytorch.kernels.MaternKernel(nu=1.5, ard_num_dims=2)
)
def forward(self, x):
features = self.feature_extractor(x)
mean = self.mean_module(features)
covar = self.covar_module(features)
return gpytorch.distributions.MultivariateNormal(mean, covar)
DKL은 신경망의 표현 학습과 GP의 불확실성 정량화를 결합합니다. GP 계층은 훈련 데이터와는 거리가 먼 예측이 높은 불확실성을 가지도록 보장합니다. 이는 표준 신경망이 제공하지 못하는 것으로 유명합니다. 또한 DKL은 한계 우도가 감시해야 하는 유연성을 정확하게 다시 도입합니다. Occam 요소는 커널에 불이익을 주지만 그 앞에 있는 네트워크에는 수천 개의 무료 매개변수가 있으며 그러한 불이익은 없습니다.
Ludkovski 및 Risk(2025), 정량 금융을 위한 가우스 프로세스 모델, 옵션 가격 책정 및 포트폴리오 최적화를 포함하여 보다 광범위한 정량 금융 맥락에서 DKL을 조사합니다. 이러한 결과는 그들의 문제에 대한 것이며 암호화폐 수익 예측에 대한 증거가 아닙니다.
진단 및 함정
교정
잘 보정된 GP에는 경험적 적용 범위와 일치하는 예측 구간이 있습니다. 이 검사는 등각 예측에 사용된 것과 동일합니다. 여기서는 한계 적용 범위가 조건부 적용 범위가 아닌 이유에 대한 이론도 다룹니다. 이는 GP 간격에도 마찬가지로 적용됩니다.
from scipy.stats import norm
def calibration_report(predictions, actuals):
"""Check if GP uncertainty is well-calibrated."""
z_scores = (actuals - predictions["mean"]) / (predictions["std"] + 1e-8)
for sigma in [1, 2, 3]:
expected_outside = 2 * (1 - norm.cdf(sigma))
actual_outside = (np.abs(z_scores) > sigma).mean()
print(
f"{sigma}-sigma | Expected outside: {expected_outside:.3f} | "
f"Actual outside: {actual_outside:.3f}"
)
예상 초과는 1/2/3 시그마에서 0.317 / 0.046 / 0.003입니다. 중요한 숫자는 이것이 암호화폐 바를 통과하는 실제 워크포워드 실행에서 인쇄되는 내용이며 해당 테이블은 아직 이 기사에 없습니다. 사전 예상은 GP가 과신하다는 것입니다. 꼬리가 두텁고 고정되지 않은 수익에 대한 가우스 우도는 3 시그마에서 심하게 은폐되어야 하지만 "해야 한다"는 측정이 아닙니다.
남은 함정
-
입력 스케일링. 길이 스케일은 입력 스케일을 기준으로 하므로 특성 범위가 지정됩니다. 그리고 하나는 원거리 의미 있는 내용을 공유할 수 없습니다. ; ARD는 이기종 범위를 구하는 것이며 표준화는 ARD의 초기화를 정상화하는 것입니다.
-
주변 우도 과적합. 많은 커널 초매개변수(특히 복합 또는 스펙트럼 혼합 커널)를 사용하면 주변 우도가 여전히 과적합될 수 있습니다. 사전 사용: 중앙값 쌍별 거리를 중심으로 한 길이 척도의 로그 정규 사전, 분산의 절반 정규 사전.
-
공분산 행렬 조건화. 잡음이 발생하면 수치적으로 특이점이 될 수 있습니다. 너무 작거나 트레이닝 포인트가 거의 중복되는 경우입니다. GPyTorch가 추가합니다 대각선으로의 지터; 상태가 좋지 않은 재무 데이터에는 더 많은 것이 필요한 경우가 많습니다.
-
예측 편향. 위에서 다루고 측정된 세부정보는 예측 편향 분류에서 확인하세요.
GP를 사용하는 경우와 다른 모델을 사용하는 경우
| 기준 | GP | XGBoost | 신경망 |
|---|---|---|---|
| 내장된 불확실성 | 예(구조적) | 아니요(컨포멀/부트스트랩 필요) | 아니요(MC 드롭아웃/앙상블 필요) |
| 데이터 효율성 | 우수(샘플 1000개 미만) | * | * |
| 확장성 | 정확하지 않음, 희소함 | * | * |
| 비선형성 | 커널 종속 | * | * |
| 해석성 | 커널 분해 + ARD 길이 척도 | * | * |
| 비정상성 | 슬라이딩 윈도우 또는 DKL 필요 | * | * |
* XGBoost 및 신경망 열의 경우 여기의 새로운 주장보다는 게시된 비교를 따르세요. 기계 학습을 통한 확산 모델링에는 금융 표 형식 데이터(데이터 크기 임계값, 해석 가능성, 체제 적응, 대기 시간) 및 시간적 융합 트랜스포머에는 TFT, LSTM, 바닐라 Transformer가 있습니다.
다음과 같은 경우 GP를 사용하세요.
- 중소 규모의 데이터 세트가 있습니다(훈련 기간당 관측치 최대 10,000개 미만).
- 신호(추세 + 계절성 + 노이즈)에 대한 명확하고 검사 가능한 구조적 가설을 원합니다.
- 불확실성은 전체 잔차 분위수뿐 아니라 훈련 데이터와의 거리에 따라 달라져야 합니다.
다음과 같은 경우에는 GP를 사용하지 마십시오
- 수백만 건의 관찰에 대해 밀리초 미만의 추론이 필요합니다.
- 입력 차원이 ~50을 초과합니다.
- 신호는 고정 커널이 표현할 수 없는 복잡한 고차 기능 상호 작용에 존재합니다(DKL은 Occam 속성을 희생하여 도움을 줍니다).
이 문서에서 아직 측정하지 않은 내용
위의 모든 것은 모형 기계입니다. 그 어느 것도 GP가 암호화폐로 돈을 벌었다는 증거는 아니며, 이 블로그의 표준은 기사에 자체 번호가 있다는 것입니다. 실행되어야 하는 순서대로 열려 있는 항목:
- ARD 길이는 실제 BTCUSDT 1m 바에 비례합니다. 복합 커널에 맞춰 인쇄합니다. 기능당. 이는 "ARD가 내장된 기능 선택"이라는 주장을 직접 테스트하고 위조 가능한 기능 관련 순위를 생성합니다.
- 전진 실행의 보정 표. GP가 과신한 것으로 판명된 경우를 포함하여 1/2/3 시그마에서 기대 대 경험적 초과가 명확하게 명시되어 있습니다.
- 정직한 부정과 동일한 5개 전공에 대한 신뢰 기반 전략인 Walk-forward는 시행 횟수가 줄어들었습니다. 실패하면 또 다른 부정적인 결과로 해당 시리즈에 포함됩니다.
- 벽시계 곡선 , 정확한 대 SVGP이므로 확장성 섹션은 어설션 대신 차트에 있습니다.
결론
거래에서 가우스 프로세스의 경우는 "오차 막대를 제공합니다"가 아닙니다. 등각 예측은 분포 가정이 더 적은 오차 막대와 GP가 갖지 않는 적용 범위 보장을 제공합니다. GP를 사용하면 구조적 가설을 커널로 작성하고, 자체 복잡성에 따라 가격을 책정하는 목표에 맞춰 이를 맞춘 다음, ARD 길이 척도를 통해 실제로 어떤 기능을 사용했는지 알려줍니다. 유난히 읽기 쉬운 모델입니다.
비용은 똑같이 구체적입니다. 훈련 창을 제한하는 3차 스케일링, 롤링 창이 부분적으로만 복구된다는 정상성 가정, 두터운 꼬리 수익이 위반될 가우스 우도, 그리고 일단 심층 커널 학습에 도달하면 처음에 한계 우도에 동기를 부여한 바로 Occam 속성의 조용한 손실이 발생합니다. 남은 것이 거래 가능한지 여부는 경험적 질문이며 위에 나열된 네 가지 측정값이 이에 대한 답이 될 것입니다.
참고자료
- Rasmussen, C. E., & Williams, C. K. I. (2006). 기계 학습을 위한 가우스 프로세스. MIT 출판사.
- 윌슨, A., & 아담스, R. (2013). 패턴 발견 및 추정을 위한 가우스 프로세스 커널. ICML.
- Hensman, J., Fusi, N., & Lawrence, N. D. (2013). 빅 데이터를 위한 가우스 프로세스. UAI.
- Gatheral, J., Jaisson, T., & Rosenbaum, M. (2018). 변동성이 심합니다. 양적 금융, 18(6).
- Rizvi, S.A.A., Roberts, S.J., Osborne, M.A., & Nyikosa, F. (2017). 가우시안 프로세스 엔벨로프를 사용하여 금융 변동성을 예측하는 새로운 접근 방식. arXiv:1705.00891.
- Ludkovski, M., & Risk, J.(2025). 정량 금융을 위한 가우스 프로세스 모델. 뛰는 것.
- Gardner, J. R., Pleiss, G., Bindel, D., Weinberger, K. Q., & Wilson, A. G. (2018). GPyTorch: GPU 가속을 사용한 블랙박스 행렬-행렬 가우스 프로세스 추론. NeurIPS.
Authors
Trading-systems engineer
Trading-systems engineer building bots since 2017: cross-exchange arbitrage (connected up to 30 venues), cointegration-based pairs arbitrage across spot and futures, scalping, news and sentiment-driven strategies, trend algorithms, and portfolio management and balancing algorithms. Also builds sub-millisecond order execution, big-data warehouses, backtesting engines, AI agents, and trading interfaces (incl. open-source profitmaker.cc). Stack: JS/TS, Python, Rust/Zig/Go, DevOps, backend, frontend, architecture.