Proses Gaussian untuk Pemodelan Harga Bukan Parametrik
Sebahagian daripada siri "garis dasar ML Klasik".
Dua perkara menjadikan proses Gaussian bernilai artikel berasingan di blog ini, dan kedua-duanya tidak "ia memberi anda ketidakpastian."
Yang pertama ialah reka bentuk kernel. Keseluruhan bias induktif GP hidup dalam satu fungsi , dan fungsi itu ialah sesuatu yang anda tulis dengan sengaja: betapa kasarnya laluan itu, sama ada ia berulang, sama ada ulangan itu mereput. Tiada apa-apa lagi dalam kit alat standard membolehkan anda menyatakan hipotesis struktur tentang dinamik pasaran yang secara eksplisit dan kemudian sesuai dengannya. Yang kedua ialah kemungkinan kecil — objektif latihan dengan penalti kerumitan yang diperoleh daripada model itu sendiri, bukan daripada set yang ditahan. Setiap artikel lain dalam arka overfitting pada blog ini (analisis dataran tinggi, PBO, deflated Sharpe-set terkurang kerana pengesahan-pengujian tetap) wujud kurang. Seorang GP mendakwa tidak memerlukannya. Tuntutan itu boleh diuji, dan mengujinya lebih menarik daripada tutorial saiz ketidakpastian yang lain.
Mengenai ketidakpastian itu sendiri: varians posterior GP ialah struktur — ia keluar daripada inferens yang sama yang menghasilkan min, dan bukannya dililitkan pada model yang dipasang selepas itu. Itulah kontras sebenar dengan ramalan konformal, yang sudah merangkumi di blog ini mengapa ketidakpastian adalah input yang tepat untuk saiz kedudukan dan perkara yang perlu dilakukan dengan selang apabila anda mempunyai satu. Artikel ini tidak menghujahkan semula kes itu; ia mengikuti model.
Apa yang berikut ialah mesin inti dan inferens, pelaksanaan GPyTorch, dan — dinyatakan dengan jelas pada penghujung — ukuran yang belum ada pada artikel ini.
Apakah Proses Gaussian?
GP sudah muncul di blog ini sebagai pengganti pengoptimuman Bayesian dalam keturunan Optuna lwn. koordinat, dengan tatatanda yang sama dan kaveat berdimensi rendah yang sama. Di sini GP ialah model itu sendiri, dipasang untuk memasarkan data dan bukannya pada permukaan carian hiperparameter, jadi rawatan berjalan lebih mendalam.
Proses Gaussian ialah himpunan pembolehubah rawak, sebarang nombor terhingga yang mempunyai taburan Gaussian bersama. Ia adalah pengedaran ke atas fungsi, bukan pengedaran ke atas parameter.
Secara formal, fungsi diambil daripada GP jika untuk sebarang set input terhingga :
di mana ialah fungsi min dan ialah fungsi kovarians (kernel). Kami menulis ini padat sebagai:
Fungsi min mengekodkan kepercayaan terdahulu tentang kelakuan purata bagi . Dalam perdagangan, kita biasanya menetapkan , mengekodkan andaian bahawa kami tidak mempunyai berat sebelah arah sebelumnya pada pulangan. Semua struktur masuk ke dalam kernel.
Mengapa Bukan Parametrik?
Model regresi linear dengan 5 ciri mempunyai 6 parameter. Rangkaian saraf dengan dua lapisan tersembunyi 64 unit mempunyai beribu-ribu. GP tidak mempunyai bilangan parameter tetap — kerumitan model bertambah dengan data. Dengan 10 pemerhatian, GP mentakrifkan Gaussian 10 dimensi. Dengan 10,000 pemerhatian, ia mentakrifkan Gaussian 10,000 dimensi.
Ini tidak bermakna GP tidak mempunyai hiperparameter. Fungsi kernel mempunyai hiperparameter (skala panjang, amplitud, berkala) yang mengawal sifat fungsi yang diambil daripada sebelumnya. Tetapi bentuk berfungsi itu sendiri tidak pernah tetap. GP boleh mewakili sebarang fungsi berterusan, diberikan data yang mencukupi dan kernel yang betul. Inilah maksud "bukan parametrik" — model tidak terhad kepada keluarga parametrik seperti fungsi linear atau polinomial.
Untuk pemodelan kewangan, ini berharga. Pasaran berubah. Hubungan antara ciri dan pulangan adalah tidak linear, tidak pegun dan bergantung kepada rejim. Model parametrik mengenakan struktur yang mungkin tidak sepadan dengan realiti. GP membiarkan data bercakap.
Fungsi Kernel: Pengekodan Struktur Pasaran
Fungsi kernel adalah jiwa proses Gaussian. Ia mentakrifkan fungsi mana yang berkemungkinan a priori dengan menentukan kovarians antara nilai fungsi pada mana-mana dua titik input. Kernel yang berbeza mengekodkan andaian yang berbeza tentang kelancaran, keberkalaan dan kelakuan jarak jauh.
Fungsi Asas Jejari (RBF) / Eksponen Kuasa Dua
Kernel RBF ialah titik permulaan yang paling biasa:
di mana ialah varians isyarat (skala output) dan ialah skala panjang. Fungsi yang diambil daripada GP dengan kernel RBF boleh dibezakan secara tak terhingga — sangat lancar.
Tafsiran dagangan: Skala panjang mengawal sejauh mana dua titik data boleh dan masih berkorelasi. Skala panjang pendek bermakna model bertindak balas kepada corak tempatan; skala panjang bermakna ia menangkap arah aliran yang luas. Varians isyarat mengawal amplitud fungsi — berapa besar pulangan yang diramalkan.
Masalah untuk kewangan: Kelancaran yang tidak terhingga adalah tidak realistik. Pulangan kewangan mempunyai lonjakan, perubahan rejim dan ketidaksinambungan. Kernel RBF boleh mengatasi ciri-ciri ini, menghasilkan ramalan yang terlalu konservatif berhampiran kerosakan struktur.
Inti Induk
Kelas Matern menyamaratakan RBF dengan memperkenalkan parameter kelancaran :
di mana ialah fungsi Bessel yang diubah suai bagi jenis kedua. Sebagai , kernel Matern menumpu kepada RBF. Pilihan biasa:
- : Setara dengan proses Ornstein-Uhlenbeck. Fungsi berterusan tetapi tidak boleh dibezakan — kasar, seperti gerakan Brownian.
- : Fungsi sekali boleh dibezakan. Keseimbangan yang baik antara kelancaran dan fleksibiliti.
- : Fungsi dua kali boleh dibezakan. Lebih licin daripada tetapi kurang tegar daripada RBF.
Tafsiran perdagangan: The Matern- kernel boleh dikatakan lalai terbaik untuk siri masa kewangan. Ia membenarkan jenis kekasaran yang ditunjukkan oleh laluan harga sebenar tanpa bergerigi . Ini sejajar dengan kesusasteraan "volatiliti adalah kasar" (Gatheral, Jaisson, & Rosenbaum, 2018), yang secara empirik menunjukkan bahawa laluan turun naik mempunyai eksponen Hurst di sekeliling , jauh lebih kasar daripada gerakan Brown.
Bukti terbitan utama untuk biji Matern yang mengalahkan model turun naik klasik ialah Rizvi et al. (2017), yang melaporkan kira-kira 20% lebih baik MSE daripada berjalan rawak dan 50% lebih baik daripada GARCH — pada data pasangan mata wang harian 2017, bukan kripto dan tidak diterbitkan semula di sini. Anggap ia sebagai motivasi untuk mencuba kernel, bukan sebagai penanda aras. Kesesuaian GARCH(1,1) blog ini pada data harian BTC sebenar, dengan diagnostik Ljung-Box dan ARCH-LM, berada dalam ramalan turun naik GARCH untuk crypto; head-to-head menentang GP Matern pada sampel yang sama akan menjadi perbandingan yang jujur, dan ia belum dijalankan.
Kernel Berkala
Pasaran kewangan mempunyai corak kitaran: keluk volum urusniaga harian, kesan hari-dalam-minggu, aliran pengimbangan semula bulanan, musim pendapatan suku tahunan. Kernel berkala menangkap ini:
di mana ialah tempoh. Fungsi yang diambil daripada kernel ini berulang dengan noktah , dimodulasi oleh skala panjang yang mengawal seberapa cepat korelasi itu mereput dalam satu tempoh.
Tafsiran dagangan: Set (jam) untuk menangkap corak intraday, atau (hari dagangan) untuk bermusim mingguan. Tidak seperti ciri Fourier, kernel berkala tidak menganggap bilangan harmonik yang tetap - GP mempelajari bentuk kitaran daripada data.
Menggabungkan Inti: Komposisi Aditif dan Multiplikatif
Kuasa sebenar inti GP terletak pada komposisi. Jika dan adalah kernel yang sah, begitu juga:
- Jumlah: — fungsi ialah jumlah komponen bebas (penguraian aditif)
- Produk: — interaksi antara komponen (cth., tingkah laku berkala setempat)
Inti komposit yang berguna untuk pulangan kewangan:
Ini menguraikan isyarat menjadi:
- Komponen aliran aperiodik yang tidak lancar (Matern-3/2)
- Komponen berkala yang amplitudnya mereput dari semasa ke semasa (Berkala RBF)
Produk mencipta kernel berkala tempatan: corak berulang, tetapi ulangan jauh mempunyai pengaruh yang kurang daripada yang berdekatan. Ini betul-betul tepat untuk kemusim kewangan, yang hanyut dari semasa ke semasa apabila struktur mikro pasaran berkembang.
Inti Campuran Spektrum
Untuk fleksibiliti maksimum, kernel campuran spektrum (SM) (Wilson & Adams, 2013) parameter ketumpatan spektrum kernel sebagai campuran Gaussians:
di mana ialah berat campuran, ialah varians spektrum, dan adalah cara spektrum (frekuensi). Dengan teorem Bochner, sebarang isirong pegun boleh diwakili dengan cara ini. Kernel SM boleh menemui komponen berkala, arah aliran jarak jauh dan korelasi jarak pendek secara serentak — semuanya daripada data.
Tafsiran perdagangan: Kernel SM berguna apabila anda tidak mengetahui corak yang wujud dalam data. Ia boleh mengenal pasti berkala tersembunyi dalam siri pulangan (cth., kitaran halus 4 jam dalam pasaran crypto yang didorong oleh pengimbangan semula automatik). Kelemahannya ialah lebih banyak hiperparameter dan risiko terlampau padat dengan set data kecil.
Inferens Posterior: Dari Sebelum ke Ramalan
Data latihan yang diberi di mana dan , GP posterior pada titik ujian mempunyai penyelesaian bentuk tertutup. Ini adalah kelebihan pengiraan utama GP berbanding kebanyakan model Bayesian.
Persamaan Posterior
biarlah menjadi matriks kovarians latihan, menjadi matriks kovarian silang, dan menjadi matriks kovarian ujian. Bahagian belakang ialah:
di mana:
Min posterior ialah gabungan linear sasaran latihan, ditimbang oleh persamaan inti antara mata ujian dan latihan. Kovarians posterior bermula dari kovarians sebelumnya dan menolak maklumat yang diperoleh daripada data latihan. Di mana data latihan adalah padat, varians posterior adalah kecil. Apabila data latihan adalah jarang, varians posterior kembali kepada sebelumnya.
Kemungkinan Marginal, dan Tuntutan Berbaloi Diuji
Hiperparameter kernel (skala panjang, varians, tahap hingar) dipelajari dengan memaksimumkan kemungkinan marginal log:
Istilah pertama ialah istilah kesesuaian data (menghukum ramalan jauh daripada pemerhatian). Istilah kedua ialah penalti kerumitan (menghukum model yang terlalu fleksibel — iaitu, di mana matriks kernel mempunyai penentu yang besar). Sebutan ketiga ialah pemalar normalisasi.
Ini adalah pisau cukur Occam automatik, dan ia adalah perkara paling menarik yang dibawa oleh GP ke saluran paip perdagangan. Versi tuntutan yang kukuh ialah tiada set pengesahan berasingan diperlukan untuk regularisasi — penalti kerumitan berada di dalam objektif, jadi model tidak boleh membeli muat dengan fleksibiliti secara percuma.
Tuntutan itu patut diragui pada blog ini secara khusus. Analisis Plateau menunjukkan bahawa skor pengesahan satu mata ialah kriteria pemilihan yang tidak baik dan keteguhan hidup dalam bentuk kejiranan; PBO mengukur kekerapan pemenang dalam sampel kehilangan sampel; deflated Sharpe dalam bilangan percubaan. Kemungkinan kecil masih merupakan objektif dalam sampel yang dimaksimumkan — faktor Occam menghukum model kapasiti, bukan pemilihan ke atas banyak isirong yang dipasang. Jika anda memuatkan dua belas biji calon dan memilih satu yang mempunyai kemungkinan marginal terbaik, anda kembali ke wilayah ujian berbilang dan logik deflasi digunakan tidak berubah. Versi boleh dipalsukan: adakah pemilihan kemungkinan marginal menghasilkan jurang dalam sampel/luar sampel yang lebih kecil daripada pemilihan set pengesahan pada data yang sama dan keluarga inti yang sama? Itu boleh diukur dan tidak diukur di bawah.
Permukaan kemungkinan kecil juga mempunyai optima setempat. Mula semula rawak berbilang atau perkara permulaan yang berhati-hati — memulakan skala panjang kepada jarak median berpasangan bagi input latihan dan varians hingar kepada varians sampel sasaran ialah titik permulaan yang munasabah.
Kos Pengiraan dan Kebolehskalaan
Kesesakan adalah terbalik , yang kos dalam masa dan dalam ingatan. Dinding padu sudah dipertikaikan di blog ini dari arah lain: kaedah carian vs. kos penilaian membatalkan kelayakan pengoptimuman Bayesian berasaskan GP secara langsung apabila objektifnya murah, kerana kos pengganti lebih tinggi daripada penilaian yang dijimatkannya. Aritmetik adalah sama di sini; aplikasinya berbeza. Sebagai model yang dipasang pada data pasaran, istilah padu bukanlah kehilangan kelayakan tetapi belanjawan: ia menetapkan siling keras pada tetingkap latihan.
Strategi kebolehskalaan untuk aplikasi perdagangan:
-
GP jarang (mata induksi). Gantikan matriks dengan an matriks di mana . Titik dorongan adalah pseudo-input yang meringkaskan data latihan. Formulasi SVGP (Stochastic Variational GP) oleh Hensman et al. (2013) membenarkan latihan kumpulan mini dengan kos setiap lelaran. GPyTorch menyokong ini secara asli.
-
Interpolasi kernel berstruktur (SKI/KISS-GP). Mengeksploitasi struktur Kronecker dan Toeplitz dalam matriks kernel apabila input terletak pada grid. Mengurangkan kos kepada di mana ialah saiz grid. Sesuai untuk siri masa sampel yang kerap (cth., bar 1 minit).
-
GP tempatan pada tingkap gelongsor. Latih GP berasingan pada data terkini sahaja. Di sinilah kekangan khusus GP menggigit: kernel standard adalah pegun ( bergantung hanya pada ) dan pasaran tidak, jadi jawapan biasa ialah tetingkap bergulir — tetapi panjang tetingkap dibatasi di atas oleh , bukan hanya dengan statistik. Pengoptimuman berjalan ke hadapan meliputi tingkap berlabuh lwn. bergolek, panjang kereta api/ujian dan kekerapan pengoptimuman semula secara umum; untuk GP, saiz tetingkap ialah keputusan pengiraan sama seperti keputusan statistik, dan tetingkap yang berlabuh (berkembang) sememangnya tidak tersedia melepasi beberapa ribu mata tanpa anggaran. Pembingkaian semula itu adalah akibat praktikal: dengan GP anda tidak boleh memilih "menggunakan semua sejarah."
GP untuk Ramalan Pulangan: Rangka Kerja Praktikal
Reka Bentuk Ciri: Mengapa 5-20 Ciri, Bukan 500
Taksonomi ciri umum untuk ML data pasaran — ketidakseimbangan buku pesanan, tekanan buku, VPIN, Kyle's lambda, ciri turun naik yang direalisasikan, pengekodan masa kitaran, isyarat rentas aset dan kadar pembiayaan — telah pun dibentangkan dalam pemodelan penyebaran dengan pembelajaran mesin; gunakan senarai itu.
Apa yang khusus GP ialah saiz senarai. Kaedah kernel merosot dalam dimensi tinggi: jarak menumpukan, dan kernel pegun kehilangan diskriminasi. Julat praktikal untuk GP kewangan ialah 5-20 input, bukan beratus-ratus pokok yang dirangsang kecerunan dengan gembira makan. Mekanisme yang menjadikan ini boleh bertahan ialah ARD (Penentuan Perkaitan Automatik): berikan setiap dimensi input skala panjangnya sendiri , dan dorongan latihan berkemungkinan marginal untuk dimensi yang tidak membawa isyarat, kerana skala panjang tak terhingga bermakna kernel mengabaikan koordinat itu. Pemilihan ciri menjadi hasil sampingan daripada pemasangan, dan yang dipelajari boleh dibaca secara langsung sebagai kedudukan perkaitan — yang juga menjadikannya boleh dipalsukan: muatkan kernel komposit pada bar sebenar, cetak skala panjang dan lihat sama ada ciri yang anda percayai adalah ciri yang disimpan oleh model.
Saiz Kedudukan dan Pantang
Posterior GP memberi secara langsung, jadi ia jatuh terus ke dalam saiz nisbah tepi dan penapis tanpa perdagangan yang dibangunkan dalam Ramalan Konformal untuk Pengukuran Kedudukan Sedar Risiko, dengan lebar selang . Satu-satunya perbezaan ialah asal: GP menghasilkan lebar daripada model itu sendiri dan bukannya daripada set penentukuran, jadi ia berbeza dengan tempat titik ujian terletak relatif kepada data latihan dan bukannya dengan kuantiti global sisa masa lalu.
Pelaksanaan dengan GPyTorch
GPyTorch ialah perpustakaan berasaskan PyTorch untuk inferens GP berskala. Ia memanfaatkan pecutan GPU, pembezaan automatik, dan teknik algebra linear moden (kecerunan konjugat, penguraian Lanczos) untuk menskalakan GP melebihi naif had.
Asas GP Tepat untuk Ramalan Pulangan
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 itulah yang membolehkan skala panjang setiap dimensi yang dibincangkan di atas. Selepas latihan, model.covar_matern.base_kernel.lengthscale ialah vektor untuk dibaca.
Gelung Latihan
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
Ramalan dengan Ketidakpastian
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(),
}
The fast_pred_var() pengurus konteks menggunakan algoritma LOVE (Lanczos Variance Estimates) untuk mengira varians ramalan dalam masa bukannya .
Talian Dagangan Hujung-ke-Hujung
Nota tentang pembina ciri di bawah: setiap statistik bergulir mestilah berpandangan ke belakang, dan penyeragaman input mesti dipasang pada kepingan latihan sahaja. Perkara kedua itu bukanlah kebersihan generik — ia adalah saluran kebocoran normalisasi yang dibedah dan diukur dalam taksonomi bias pandang ke hadapan, yang melaporkan inflasi Sharpe yang dihasilkan oleh setiap jenis kebocoran. GP menyeragamkan inputnya melalui pembinaan, jadi ini adalah kebocoran yang paling terdedah kepadanya.
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
Menskalakan kepada Set Data yang Lebih Besar dengan GP Jarang
Apabila tetingkap latihan melebihi beberapa ribu mata, inferens GP yang tepat menjadi perlahan. Tukar kepada GP jarang variasi:
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
Dengan 128 mata dorongan, kos setiap kelompok ialah — kira-kira 4 juta operasi setiap kelompok. Ini dengan mudah mengendalikan set data sebanyak 100,000+ pemerhatian pada satu GPU.
Pembelajaran Kernel Dalam: GP Memenuhi Rangkaian Neural
Apabila ruang input berdimensi tinggi atau hubungan antara ciri dan pulangan adalah sangat tidak linear, kernel biasa mungkin bergelut. Pembelajaran inti dalam (DKL) menghantar input melalui rangkaian saraf sebelum menggunakan kernel GP:
di mana ialah rangkaian saraf dengan parameter dan ialah kernel standard (cth., Matern-3/2). Rangkaian mempelajari perwakilan ciri di mana kernel GP paling berkesan. Keseluruhan model — parameter rangkaian dan hiperparameter kernel — dilatih hujung ke hujung dengan memaksimumkan kemungkinan kecil.
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 menggabungkan pembelajaran perwakilan rangkaian saraf dengan kuantifikasi ketidakpastian GP. Lapisan GP memastikan ramalan yang jauh daripada data latihan mempunyai ketidakpastian yang tinggi — sesuatu yang gagal disediakan oleh rangkaian saraf standard. Perhatikan juga bahawa DKL memperkenalkan semula dengan tepat fleksibiliti kebarangkalian kecil yang sepatutnya dikawal: faktor Occam menghukum kernel, tetapi rangkaian di hadapannya mempunyai beribu-ribu parameter bebas dan tiada penalti sedemikian.
Ludkovski dan Risiko (2025), Model Proses Gaussian untuk Kewangan Kuantitatif, kaji DKL dalam konteks kewangan kuantitatif yang lebih luas termasuk penentuan harga opsyen dan pengoptimuman portfolio; keputusan tersebut adalah milik mereka, mengenai masalah mereka, dan bukan bukti tentang ramalan pulangan crypto.
Diagnostik dan Perangkap
Penentukuran
GP yang ditentukur dengan baik mempunyai selang ramalan yang sepadan dengan liputan empirikal. Semakan adalah sama yang digunakan dalam ramalan konformal — yang turut merangkumi teori mengapa liputan marginal bukan liputan bersyarat, had yang dikenakan pada selang GP sama seperti:
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}"
)
Jangkaan melebihi adalah 0.317 / 0.046 / 0.003 pada 1/2/3 sigma. Nombor yang penting ialah apa yang dicetak ini pada larian berjalan ke hadapan sebenar di atas bar kripto, dan jadual itu belum ada dalam artikel ini lagi. Jangkaan sebelum ini ialah GP terlalu yakin — kemungkinan Gaussian pada pulangan berekor gemuk dan tidak pegun sepatutnya menyamar dengan teruk pada 3 sigma — tetapi "sepatutnya" bukan ukuran.
Baki Perangkap
-
Penskalaan input. Skala panjang adalah relatif kepada skala input, jadi julat ciri dan satu berkisar tidak boleh berkongsi yang bermakna ; ARD ialah perkara yang menyelamatkan julat heterogen, dan penyeragaman ialah perkara yang menjadikan permulaan ARD waras.
-
Melebihkan kemungkinan marginal. Dengan banyak hiperparameter isirong (terutamanya isirong campuran komposit atau spektrum), kemungkinan marginal masih boleh terlalu muat. Gunakan priors: log-normal prior pada skala panjang berpusat pada median jarak berpasangan, prior separuh normal pada varians.
-
Pengkondisian matriks kovarian. boleh menjadi numerik tunggal apabila bunyi terlalu kecil atau apabila titik latihan hampir digandakan. GPyTorch menambah jitter ke pepenjuru; data kewangan yang berhawa dingin selalunya memerlukan lebih banyak lagi.
-
Bincang pandang ke hadapan. Dilindungi di atas dan, secara terperinci yang diukur, dalam taksonomi bias pandang ke hadapan.
Bila Menggunakan GP vs. Model Lain
| Kriteria | GP | XGBoost | Rangkaian Neural |
|---|---|---|---|
| Ketidakpastian terbina dalam | Ya (struktur) | Tidak (perlu conformal/bootstrap) | Tidak (perlu MC keciciran/ensembel) |
| Kecekapan data | Cemerlang (<1000 sampel) | * | * |
| Kebolehskalaan | Lemah tepat, baik jarang | * | * |
| Ketaklinieran | Bergantung kepada kernel | * | * |
| Kebolehtafsiran | Penguraian inti + skala panjang ARD | * | * |
| Tidak pegun | Memerlukan tingkap gelongsor atau DKL | * | * |
* Untuk lajur XGBoost dan rangkaian saraf, tunda kepada perbandingan yang diterbitkan dan bukannya penegasan baharu di sini: pemodelan penyebaran dengan pembelajaran mesin mempunyai jadual gradient-boosting-vs-deep-learning untuk data jadual kewangan (ambang kebolehsuaian saiz data, ketetapan, ketetapan); transformer gabungan temporal mempunyai TFT lwn. LSTM lwn vanila Transformer.
Gunakan GP apabila:
- Anda mempunyai set data kecil hingga sederhana (di bawah ~10,000 pemerhatian setiap tetingkap latihan)
- Anda mahukan hipotesis struktur yang jelas dan boleh diperiksa tentang isyarat (trend + bermusim + hingar)
- Ketidakpastian mesti berbeza dengan jarak dari data latihan, bukan hanya dengan kuantiti sisa global
Jangan gunakan GP apabila:
- Anda memerlukan inferens sub-milisaat ke atas berjuta-juta pemerhatian
- Dimensi input melebihi ~50
- Isyarat hidup dalam interaksi ciri tertib tinggi yang kompleks yang tidak dapat diwakili oleh kernel pegun (DKL membantu, dengan kos hartanah Occam)
Perkara Yang Belum Diukur Perkara Ini
Semua di atas adalah jentera model. Tiada satu pun daripada itu adalah bukti bahawa GP membuat wang dari crypto, dan piawaian blog ini ialah artikel itu membawa nombornya sendiri. Item terbuka, mengikut urutan ia harus dijalankan:
- Skala panjang ARD pada bar 1m BTCUSDT sebenar. Muatkan kernel komposit, cetak setiap ciri. Ini secara langsung menguji tuntutan "ARD ialah pemilihan ciri terbina dalam" dan menghasilkan kedudukan perkaitan ciri yang boleh dipalsukan.
- Jadual penentukuran daripada larian berjalan ke hadapan. Jangkaan lwn. melebihi empirikal pada 1/2/3 sigma, dinyatakan dengan jelas, termasuk kes di mana GP ternyata terlalu yakin.
- Strategi berpagar keyakinan, berjalan ke hadapan, pada lima jurusan yang sama seperti negatif jujur, dikempiskan untuk kiraan percubaan. Jika gagal, ia dimasukkan ke dalam siri itu sebagai satu lagi keputusan negatif.
- Jam dinding lengkung untuk , tepat lwn. SVGP, jadi bahagian kebolehskalaan terletak pada carta dan bukannya penegasan.
Kesimpulan
Kes untuk proses Gaussian dalam perdagangan bukanlah "mereka memberi anda bar ralat" — ramalan selaras memberi anda bar ralat dengan andaian pengagihan yang lebih sedikit dan jaminan perlindungan yang tidak dimiliki oleh GP. Kesnya ialah GP membuat anda menulis hipotesis struktur anda sebagai kernel, menyesuaikannya dengan objektif yang menetapkan harga dalam kerumitannya sendiri, dan kemudian memberitahu anda ciri anda yang mana ia benar-benar digunakan melalui skala panjang ARD. Itu adalah model yang luar biasa boleh dibaca.
Kosnya adalah sama konkrit: penskalaan padu yang menghadkan tetingkap latihan anda, andaian pegun bahawa tingkap rolling hanya dibaiki sebahagiannya, kemungkinan Gaussian bahawa pulangan berekor lemak akan dilanggar, dan — sebaik sahaja anda mencapai pembelajaran inti yang mendalam — kehilangan senyap harta Occam yang memotivasikan kemungkinan kecil di tempat pertama. Sama ada apa yang tinggal boleh didagangkan ialah soalan empirikal, dan empat ukuran yang disenaraikan di atas adalah perkara yang akan menjawabnya.
Rujukan
- Rasmussen, C. E., & Williams, C. K. I. (2006). Proses Gaussian untuk Pembelajaran Mesin. MIT Press.
- Wilson, A., & Adams, R. (2013). Inti Proses Gaussian untuk Penemuan Corak dan Ekstrapolasi. ICML.
- Hensman, J., Fusi, N., & Lawrence, N. D. (2013). Proses Gaussian untuk Data Besar. UAI.
- Gatheral, J., Jaisson, T., & Rosenbaum, M. (2018). Kemeruapan adalah kasar. Kewangan Kuantitatif, 18(6).
- Rizvi, S. A. A., Roberts, S. J., Osborne, M. A., & Nyikosa, F. (2017). Pendekatan Novel untuk Meramalkan Kemeruapan Kewangan dengan Sampul Proses Gaussian. arXiv:1705.00891.
- Ludkovski, M., & Risiko, J. (2025). Model Proses Gaussian untuk Kewangan Kuantitatif. Springer.
- Gardner, J. R., Pleiss, G., Bindel, D., Weinberger, K. Q., & Wilson, A. G. (2018). GPyTorch: Inferens Proses Gaussian Matriks Blackbox Matrix dengan Pecutan GPU. NeurIPS.
Pengarang
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.