σμimplied vol · KKmax(S−K,0)udβρᵢⱼfat tailsPnL · drawdownyield · TdSₜ = μSₜ dt + σSₜ dWₜC = S·N(d₁) − K·e⁻ʳᵀ·N(d₂)σₚ² = wᵀΣwd₁ = [ln(S/K) + (r + σ²⁄2)T] ⁄ σ√T∂V/∂t + ½σ²S²·∂²V/∂S² + rS·∂V/∂S − rV = 0Sharpe = (Rₚ − R_f) ⁄ σₚVaR₉₉ = μ − 2.33σρ = Cov(X,Y) ⁄ σₓσᵧE[Rₚ] = Σ wᵢ·E[Rᵢ]φ(x) = e^(−x²/2) ⁄ √2πE[Rᵢ] = R_f + βᵢ(E[Rₘ] − R_f)dXₜ = θ(μ − Xₜ)dt + σ dWₜσ²ₜ = ω + α·ε²ₜ₋₁ + β·σ²ₜ₋₁C − P = S − K·e⁻ʳᵀΔ = ∂V/∂S Γ = ∂²V/∂S²p = (e^(rΔt) − d) ⁄ (u − d)rₜ = ln(Pₜ ⁄ Pₜ₋₁)E[Xₜ₊₁ | ℱₜ] = Xₜf* = (bp − q) ⁄ bz = (x − μ) ⁄ σP(N=k) = λᵏe^(−λ) ⁄ k!Θ = −∂V/∂Tν = S·φ(d₁)·√Tmin wᵀΣw s.t. wᵀμ = μ*∫Σ∂∞λ
σμimplied vol · KKmax(S−K,0)udβρᵢⱼfat tailsPnL · drawdownyield · TdSₜ = μSₜ dt + σSₜ dWₜC = S·N(d₁) − K·e⁻ʳᵀ·N(d₂)σₚ² = wᵀΣwd₁ = [ln(S/K) + (r + σ²⁄2)T] ⁄ σ√T∂V/∂t + ½σ²S²·∂²V/∂S² + rS·∂V/∂S − rV = 0Sharpe = (Rₚ − R_f) ⁄ σₚVaR₉₉ = μ − 2.33σρ = Cov(X,Y) ⁄ σₓσᵧE[Rₚ] = Σ wᵢ·E[Rᵢ]φ(x) = e^(−x²/2) ⁄ √2πE[Rᵢ] = R_f + βᵢ(E[Rₘ] − R_f)dXₜ = θ(μ − Xₜ)dt + σ dWₜσ²ₜ = ω + α·ε²ₜ₋₁ + β·σ²ₜ₋₁C − P = S − K·e⁻ʳᵀΔ = ∂V/∂S Γ = ∂²V/∂S²p = (e^(rΔt) − d) ⁄ (u − d)rₜ = ln(Pₜ ⁄ Pₜ₋₁)E[Xₜ₊₁ | ℱₜ] = Xₜf* = (bp − q) ⁄ bz = (x − μ) ⁄ σP(N=k) = λᵏe^(−λ) ⁄ k!Θ = −∂V/∂Tν = S·φ(d₁)·√Tmin wᵀΣw s.t. wᵀμ = μ*∫Σ∂∞λ
uantCraft Academyالمسارات
Ctrl K
AO
+1.2k متعلّم
تسجيل الدخولانضم ↗
المسارات
AO
+1.2k متعلّم
تسجيل الدخول
  • English
  • Français
  • Español
  • العربية
  • Português
  • Deutsch
  • 日本語
  • 中文
مسار Python›الوحدة 11 · أنظمة الإنتاج والنماذج المتقدمة›الموضوع 11.11·~1 س 30 دخبير

الشبكات العصبية للتنبؤ

الموضع في المسارالوحدة 11 من 11 · الموضوع 11 من 13
11.11 الشبكات العصبية للتنبؤ
—درجة المختبر— / 100إجمالي XP—التتابع—

دالة بمقابض وطريقة لتدويرها

الشبكة العصبية مجرد دالة بأرقام كثيرة قابلة للضبط هي الأوزان. تضرب الطبقة المدخلات بمصفوفة أوزان وتضيف انحيازًا؛ ثم تُطبَّق لاخطية مثل ReLU (max(x, 0))؛ ويغذي الناتج الطبقة التالية. وبتكديسها هكذا تستطيع هذه الدوال تقريب علاقات معقدة جدًا. والتدريب يعني اختيار الأوزان لتطابق التنبؤات أهدافًا معروفة: قِس عدم المطابقة بـخسارة (للتنبؤ برقم هي متوسط مربع الخطأ) واحسب كيف تتغير الخسارة مع كل وزن وادفع كل وزن قليلًا في الاتجاه الذي يخفضها. وهذه الدفعة المكررة آلاف المرات هي الانحدار التدريجي.

# A one-hidden-layer network: relu(x @ w1 + b1) @ w2 + b2
import numpy as np

def relu(x):
    return np.maximum(x, 0.0)

def mlp_forward(x, w1, b1, w2, b2):
    return relu(x @ w1 + b1) @ w2 + b2

x = np.array([[1.0, 2.0], [0.5, -1.0]])                       # two samples, two features
w1 = np.array([[1.0, -1.0], [0.5, 1.0]])                      # two hidden units
b1 = np.array([0.0, 0.5])
w2 = np.array([1.0, 2.0])
print(relu(np.array([-1.5, 0.0, 2.0])))                       # [0. 0. 2.]
print(mlp_forward(x, w1, b1, w2, 0.1))                        # [5.1 0.1]   a prediction for each sample; the second sample's hidden values are switched off by the relu

الانحدار التدريجي على أبسط نموذج

يستعمل تدريب الشبكة الانتشار العكسي للحصول على المشتقات لكن الفكرة مكتملة أصلًا لنموذج خطي y ~ x @ w + b. فلمتوسط مربع الخطأ مشتقة 2/n * x.T @ err بالنسبة إلى w و2 * mean(err) بالنسبة إلى b حيث err = التنبؤ - الهدف. ابدأ من الأصفار واطرح معدل التعلم مضروبًا في المشتقة وكرّر. ومعدل التعلم الكبير جدًا يتجاوز الهدف ويتباعد والصغير جدًا يزحف. وقِّس المتغيرات أولًا (متوسط صفر وتباين واحد) ليلائم معدل واحد كلها. وتحسب مكتبات مثل PyTorch المشتقات تلقائيًا لكنها تؤدي هذه الحلقة بالضبط.

# Gradient descent on a line: start at zero and walk downhill on the mean squared error
import numpy as np

def mse_loss(pred, target):
    return float(np.mean((pred - target) ** 2))

def train_linear(x, y, lr, epochs):
    n, d = x.shape
    w, b = np.zeros(d), 0.0
    for _ in range(epochs):
        err = x @ w + b - y
        w = w - lr * 2 / n * x.T @ err
        b = b - lr * 2 * float(np.mean(err))
    return w, float(b)

x = np.array([[0.0], [1.0], [2.0], [3.0]])
y = np.array([1.0, 3.0, 5.0, 7.0])                          # exactly y = 2x + 1
for epochs in (0, 10, 2000):
    w, b = train_linear(x, y, 0.05, epochs)
    print(epochs, np.round(w, 3), round(b, 3), round(mse_loss(x @ w + b, y), 6))
# 0 [0.] 0.0 21.0          the zero start
# 10 [2.009] 0.958 0.00092   already close
# 2000 [2.] 1.0 0.0          the line y = 2x + 1 is found

لماذا يصعب على الشبكة التنبؤ بالعوائد

تستطيع الشبكة مطابقة أي شيء تقريبًا وهذا هو الخطر مع البيانات المالية: العوائد ضجيج في معظمها، فيحفظ النموذج المرن ضجيج فترة التدريب ويفشل في التالية. وفرط التعلم يظهر خطأ تدريب أدنى بكثير من الخطأ على بيانات لم تُرَ. والدفاعات هي ما رأيناه في المواضيع السابقة: قارن بخط أساس بسيط (نموذج خطي أو التنبؤ بصفر) وقيّم على بيانات لاحقة فقط بـالتحقق المتقدم (walk-forward) دون خلط الزمن، واستعمل متغيرات قليلة وشبكة صغيرة، وأضف تنظيمًا (اضمحلال الأوزان، dropout) وإيقافًا مبكرًا، وخذ متوسط عدة شبكات بدأت ببذور مختلفة. فإن لم تتفوق الشبكة بوضوح على الخط الخطي خارج العينة فاستعمل النموذج الخطي.

# Overfitting in miniature: a flexible fit to pure noise looks great in-sample and useless afterwards
import numpy as np

rng = np.random.default_rng(5)
x_train, x_test = rng.normal(size=(30, 12)), rng.normal(size=(1000, 12))      # 12 features that mean nothing
y_train, y_test = rng.normal(0, 0.01, size=30), rng.normal(0, 0.01, size=1000)  # next-day returns: pure noise

w = np.linalg.lstsq(x_train, y_train, rcond=None)[0]                          # a model with 12 free weights fitted to 30 points
train_mse = np.mean((x_train @ w - y_train) ** 2)
test_mse = np.mean((x_test @ w - y_test) ** 2)
baseline_mse = np.mean(y_test ** 2)                                           # predict zero
print(train_mse < baseline_mse, test_mse > baseline_mse)                      # True True   better in-sample, worse than zero out of sample
# The learning rate matters: a small one settles, one that is too large overshoots and the error blows up
import numpy as np

x = np.array([[1.0], [2.0], [3.0]])
y = np.array([2.0, 4.0, 6.0])

def final_errors(lr, epochs):
    w, b, errors = np.zeros(1), 0.0, []
    for _ in range(epochs):
        err = x @ w + b - y
        errors.append(float(np.mean(err ** 2)))
        w = w - lr * 2 / len(y) * x.T @ err
        b = b - lr * 2 * float(np.mean(err))
    return errors

small, large = final_errors(0.05, 30), final_errors(0.5, 30)
print(small[-1] < small[0])                          # True   the error shrinks
print(large[-1] > 1000 * large[0])                   # True   the error explodes: the steps are too big
ابدأ بخط الأساس المملّقبل أي شبكة، طابِق نموذجًا خطيًا بالمتغيرات نفسها واحتفظ بخطئه خارج العينة رقمًا يجب تجاوزه. سجّل البذرة ونافذة البيانات والمعاملات الفائقة لكل تشغيل لأن التدريب العصبي عشوائي وتتغير النتائج من تشغيل لآخر. وقِس المتغيرات بإحصاءات فترة التدريب وحدها لا بالعينة كاملة وإلا سرّبت المستقبل. وتذكّر أن ميزة تنبؤ صغيرة لا قيمة لها إن كانت تكاليف التداول أكبر منها.
  • الطبقة هي relu(x @ w + b)؛ والشبكة تكدّس طبقات، وتقيس الخسارة (متوسط مربع الخطأ في التنبؤ) بُعد التنبؤات عن الأهداف.
  • التدريب انحدار تدريجي: للنموذج الخطي w -= lr * 2/n * x.T @ err وb -= lr * 2 * mean(err)؛ وقِس المتغيرات واضبط معدل التعلم.
  • العوائد ضجيج في معظمها: قارن بخط أساس خطي وتحقق بـ walk-forward واستعمل شبكات صغيرة منظَّمة وتوقف حين يختفي المكسب خارج العينة.

التالي: التعلم المعزَّز للتداول، تعلّم سياسة من المكافآت بدل الإجابات الموسومة.

المختبر: ما الذي يُقيَّم

  • أطفئ السالب باستخدام relu25 نقطة
  • شغّل الشبكة أمامًا باستخدام mlp_forward25 نقطة
  • قِس الخطأ باستخدام mse_loss25 نقطة
  • تعلّم بالنزول باستخدام train_linear25 نقطة
المستكشف · lab-140-1
▾ lab-140-1
…
bash · داخل المتصفح
learner@quantcraft:~/lab-140-1$
لم يتم تحميل Python بعدPythonLn 1, Col 1Spaces: 4UTF-8

هل تريد إعادة ضبط هذا الموضوع؟

سيعود كل ما في lab-140-1 إلى الملفات الابتدائية وستُمسح الطرفية. ستفقد حلّك الحالي ولا يمكن التراجع عن ذلك.

سيُعاد ضبطه
  • main.py ← الشيفرة الابتدائية
  • سجل الطرفية ومخرجات الاختبارات
  • التغييرات غير المُرسلة
سيُحتفظ به
  • أفضل درجة في المختبر
  • نقاط XP والتتابع
  • تقدّم المحاضرة والملاحظات

سجّل الدخول لتشغيل الكود الخاص بك.

قراءة كل المحاضرات مجانية. أنشئ حسابًا أو سجّل الدخول لتشغيل الكود وتنفيذ الاختبارات وتسليم هذا المختبر.

  • بيئة تطوير داخل المتصفح مع طرفية bash — لا حاجة لتثبيت أي شيء
  • تصحيح فوري ونقاط خبرة ومكانك في المسار
إنشاء حسابتسجيل الدخول
أو
المتابعة عبر GitHub