Dem Modell vergleichbare Eingaben geben
Ein Preis von 250 bedeutet einem Modell nichts: Er hängt von der Aktie ab und steigt mit der Zeit, sodass die Werte von 2020 denen von 2010 nie ähneln. Feature Engineering macht Rohdaten zu Eingaben, die über Zeit und Assets vergleichbar sind: Renditen statt Preise, Volatilität statt Spannen, standardisierte Scores statt Niveaus. Gute Merkmale tragen mehr zum Ergebnis bei als die Modellwahl, und jedes darf nur beschreiben, was an dem Tag bekannt war.
import numpy as np
prices = np.array([100.0, 101.0, 99.0, 102.0, 104.0, 103.0, 106.0])
window = 3
momentum = np.full(len(prices), np.nan)
momentum[window:] = prices[window:] / prices[:-window] - 1 # the return over the last 3 days
print(np.round(momentum, 4)) # nan for the first 3 days: no price 3 days backFenster, die zurückblicken
Die meisten Merkmale sind Statistiken eines zurückblickenden Fensters: der letzten n Werte bis einschließlich heute. Momentum vergleicht heute mit vor n Tagen; die rollierende Volatilität ist die Standardabweichung der letzten n Renditen; der rollierende Z-Score sagt, wie viele Fenster-Standardabweichungen heute vom Fenstermittel entfernt liegt. Mit sliding_window_view erhält man alle Fenster als Zeilen einer Matrix und berechnet die Statistik entlang einer Achse, ohne Schleife. Die ersten n - 1 Tage haben kein vollständiges Fenster und bleiben nan.
import numpy as np
prices = np.array([100.0, 101.0, 99.0, 102.0, 104.0, 103.0, 106.0])
returns = np.diff(prices) / prices[:-1]
window = 3
windows = np.lib.stride_tricks.sliding_window_view(returns, window) # every 3-day window as a row
vol = np.full(len(returns), np.nan)
vol[window - 1:] = windows.std(axis=1, ddof=1)
print(np.round(vol, 4)) # nan nan then one value per complete window
p_windows = np.lib.stride_tricks.sliding_window_view(prices, window)
z = np.full(len(prices), np.nan)
z[window - 1:] = (prices[window - 1:] - p_windows.mean(axis=1)) / p_windows.std(axis=1, ddof=1)
print(np.round(z, 3)) # how unusual each price is for its last 3 days# Features put prices of different stocks on the same footing
import numpy as np
cheap = np.array([5.0, 5.2, 5.1, 5.4, 5.5])
dear = np.array([500.0, 520.0, 510.0, 540.0, 550.0]) # ten times the price, the same movements
print(cheap[-1] / cheap[-3] - 1, dear[-1] / dear[-3] - 1) # identical momentum, about 0.0784 for both
print(dear[-1] - dear[-3], cheap[-1] - cheap[-3]) # price changes (40.0 and 0.4) would not be comparableDas Ziel blickt voraus
Was das Modell vorhersagt, ist das Ziel, meist die Rendite der nächsten h Tage: prices[t + h] / prices[t] - 1. Es ist die einzige Spalte, die nach vorn schauen darf, und für die letzten h Tage nan, weil die Zukunft noch nicht eingetreten ist; diese Zeilen entfernt man vor dem Training. Ein häufiger Fehler ist ein Merkmal, das das Ziel versehentlich enthält, etwa ein zentriertes Fenster, eine über alle Daten berechnete Statistik oder eine als Eingabe wiederverwendete künftige Rendite. Der Test ist einfach: Ein Merkmal an Tag t darf sich nicht ändern, wenn spätere Tage hinzukommen.
import numpy as np
def forward_return(prices, horizon):
out = np.full(len(prices), np.nan)
out[:-horizon] = prices[horizon:] / prices[:-horizon] - 1
return out
def momentum(prices, window):
out = np.full(len(prices), np.nan)
out[window:] = prices[window:] / prices[:-window] - 1
return out
prices = np.array([100.0, 101.0, 99.0, 102.0, 104.0, 103.0, 106.0])
print(np.round(momentum(prices, 2), 4)) # looks back: known on each day
print(np.round(forward_return(prices, 2), 4)) # looks forward: the target, nan for the last 2 days
# The prefix test: a feature computed on the first 5 days equals the first 5 values of the full computation
print(np.allclose(momentum(prices[:5], 2), momentum(prices, 2)[:5], equal_nan=True)) # Truet berechnet werden kann, und prüfen Sie es mit dem Präfixtest oben.- Machen Sie aus Preisen vergleichbare Merkmale: Momentum
prices[t] / prices[t - n] - 1, rollierende Volatilität, rollierender Z-Score, jeweils über ein zurückblickendes Fenster inklusive heute. sliding_window_viewliefert jedes Fenster als Zeile, Statistiken brauchen also keine Schleife; die erstenn - 1Tage bleibennan.- Die künftige Rendite
prices[t + h] / prices[t] - 1ist das Ziel, nie ein Merkmal; prüfen Sie jedes Merkmal mit dem Präfixtest.
Als Nächstes: Walk-forward-Validierung, ein Modell in der Reihenfolge testen, in der die Zeit tatsächlich fließt.
Lab: Was bewertet wird
- Mit
momentumden Trend messen25 Pkt. - Mit
rolling_voldas jüngste Risiko verfolgen25 Pkt. - Mit
rolling_zscorezeigen, wie ungewöhnlich heute ist25 Pkt. - Mit
forward_returndas Ziel definieren25 Pkt.