اثاثوں کی قیمت بندی کے لیے مشروط آٹو انکوڈرز
خلاصہ
یہ نفاذ اثاثوں کی قیمت بندی کے لیے ایک مشروط آٹو انکوڈر بیان کرتا ہے۔ بیٹا نیٹ ورک ہر اسٹاک کی خصوصیات کو مخفی فیکٹر لوڈنگز میں نقش کرتا ہے، جبکہ خطی فیکٹر نیٹ ورک زیرِ انتظام پورٹ فولیو منافع کو فیکٹر منافع میں نقش کرتا ہے۔ ماڈل متعلقہ لوڈنگز اور فیکٹر قدروں کا مجموعہ لے کر اسٹاک منافع کی پیش گوئی کرتا ہے، جس سے ایک طرف ایکسپوژر کمپنی کی خصوصیات کے ساتھ بدل سکتا ہے اور دوسری طرف فیکٹر پورٹ فولیو کے انسٹرومنٹس سے اخذ ہوتے ہیں۔
کوڈ سیکھے گئے لوڈنگز اور فیکٹرز تک رسائی کے طریقے بھی فراہم کرتا ہے، جو ماڈل کے اجزا کا معائنہ کرنے میں مدد دے سکتے ہیں۔ اس کی L1 سزا صرف بیٹا نیٹ ورک کی مخفی تہوں کے وزن پر لاگو ہوتی ہے؛ بایسز اور آخری لوڈنگ تہہ اس سے خارج ہیں، اور اگر کوئی مخفی تہہ نہ ہو تو سزا صفر آتی ہے۔ یہ تجرباتی مطالعے کے بجائے ساختی حوالہ ہے: اس میں تربیت کا طریقہ، ڈیٹاسیٹ، پیش گوئی کے نتائج یا اثاثوں کی قیمت بندی کے دوسرے ماڈلز سے موازنہ شامل نہیں۔
اہم خیالات
- بیٹا نیٹ ورک اسٹاک کی خصوصیات کو اس اسٹاک کی مخفی فیکٹر لوڈنگز میں بدلتا ہے۔
- ایک خطی نیٹ ورک زیرِ انتظام پورٹ فولیو کے ان پٹس کو فیکٹر منافع میں بدلتا ہے۔
- پیش گوئی شدہ منافع لوڈنگ اور فیکٹر کی ضربوں کے مجموعے سے بنتا ہے۔
- ریگولرائزر مخفی بیٹا نیٹ ورک وزنوں میں sparsity کو فروغ دیتا ہے، جبکہ آؤٹ پٹ تہہ کو سزا نہیں دیتا۔
- یہ نفاذ ماڈل کی ساخت متعین کرتا ہے، مگر تجرباتی جانچ فراہم نہیں کرتا۔
ٹیگز
مکمل متن
# cae.py
```py
"""Conditional Autoencoder for Asset Pricing (GKX 2021).
Architecture:
- ConditionalAutoencoder: predicted return = dot(betas, factors)
Reference: Gu, Kelly, Xiu (2021) "Autoencoder Asset Pricing Models"
"""
from __future__ import annotations
import torch
import torch.nn as nn
class BetaNetwork(nn.Module):
"""Maps stock characteristics to per-stock factor loadings."""
def __init__(self, n_characteristics: int, n_factors: int, hidden_units: tuple = (32,)):
super().__init__()
layers: list[nn.Module] = []
in_features = n_characteristics
for units in hidden_units:
layers.append(nn.Linear(in_features, units))
layers.append(nn.ReLU())
in_features = units
layers.append(nn.Linear(in_features, n_factors))
self.network = nn.Sequential(*layers)
def forward(self, x: torch.Tensor) -> torch.Tensor:
return self.network(x)
class FactorNetwork(nn.Module):
"""Maps managed portfolio returns to factor returns (linear, no activation)."""
def __init__(self, n_instruments: int, n_factors: int):
super().__init__()
self.linear = nn.Linear(n_instruments, n_factors, bias=False)
def forward(self, x: torch.Tensor) -> torch.Tensor:
return self.linear(x)
class ConditionalAutoencoder(nn.Module):
"""Conditional Autoencoder for Asset Pricing (GKX Architecture).
Architecture:
- Beta Network: characteristics -> ReLU -> factor loadings (with L1 regularization)
- Factor Network: managed portfolios -> factor returns (linear)
- Output: dot product of betas and factors
Args:
n_characteristics: Number of stock characteristics (L)
n_instruments: Number of managed portfolio instruments (L+1 typically)
n_factors: Number of latent factors (K)
hidden_units: Tuple of hidden layer sizes for BetaNetwork
"""
def __init__(
self,
n_characteristics: int,
n_instruments: int,
n_factors: int = 6,
hidden_units: tuple = (32,),
):
super().__init__()
self.n_factors = n_factors
self.n_characteristics = n_characteristics
self.n_instruments = n_instruments
self.beta_net = BetaNetwork(n_characteristics, n_factors, hidden_units)
self.factor_net = FactorNetwork(n_instruments, n_factors)
def forward(self, characteristics: torch.Tensor, portfolios: torch.Tensor) -> torch.Tensor:
"""Forward pass.
Args:
characteristics: (batch_size, n_characteristics) per-stock
portfolios: (batch_size, n_instruments) managed portfolio features
Returns:
predicted_returns: (batch_size,)
"""
betas = self.beta_net(characteristics) # (batch, n_factors)
factors = self.factor_net(portfolios) # (batch, n_factors)
pred = (betas * factors).sum(dim=1)
return pred
def get_betas(self, characteristics: torch.Tensor) -> torch.Tensor:
"""Extract factor loadings."""
return self.beta_net(characteristics)
def get_factors(self, portfolios: torch.Tensor) -> torch.Tensor:
"""Extract factor returns."""
return self.factor_net(portfolios)
def l1_regularization(model: ConditionalAutoencoder, lambda_l1: float) -> torch.Tensor:
"""L1 regularization on BetaNetwork hidden Dense weights only.
Matches the GKX (2021) reference, which applies ``kernel_regularizer='L1'``
only to the *hidden* Dense layers. We exclude biases (sparsity is not
meaningful) and the final output ``Linear(in, n_factors)`` layer (factor
loadings should not be pushed to zero by an external regularizer — the
autoencoder itself learns their magnitudes).
"""
layers = [m for m in model.beta_net.network if isinstance(m, nn.Linear)]
if len(layers) <= 1:
# No hidden layers (CA0 — direct linear projection); no L1 to apply.
return torch.zeros((), device=next(model.parameters()).device)
hidden_layers = layers[:-1] # exclude the final output Linear
l1 = sum(layer.weight.abs().sum() for layer in hidden_layers)
return lambda_l1 * l1
```ماخذ کا حوالہ دیتے ہوئے مکمل متن دکھایا گیا ہے، ماخذ کے لائسنس کے تحت۔ لائسنس: MIT
یہ خلاصہ اصل ماخذ سے Stratmill کے تحقیقی ایجنٹ نے لکھا ہے؛ یہ ماخذ کی نقل نہیں۔