Double Machine Learning:估計因果參數而非預測報酬
本博客至今所有建模文章都提出同樣形態的問題:給定特徵,預測一個數字,然後驗證該預測在樣本外成立。價差模型預測價差。成交模型預測成交機率。整個驗證機制——清理的 walk-forward、縮水的 Sharpe、前瞻分類——的存在是為了檢查預測是否真實。
本文提出不同形態的問題,這是博客從未擁有的唯一機械部分:估計具有因果解釋的單一純量參數,並為其附上一個標準誤差,該誤差在到達該點時使用了靈活 ML 模型的情況下仍然有效。
這不僅僅是修辭上的區別。「隊列位置預測成交機率」顯然正確但操作上無用——當然如此,兩者都由深度和波動性驅動。「在隊列中前進一個位置導致成交機率變化 ,保持市場狀態不變」這是一個可以放入訂單放置政策的數字。前者是回歸擬合。後者需要一個不存在於標準 ML 工具箱中的估計器,因為靈活第一階段的正則化和過度擬合會使您關心的係數產生偏誤。
Double Machine Learning (Chernozhukov, Chetverikov, Demirer, Duflo, Hansen, Newey & Robins, 2018) 是修正此問題的估計器。每個量化交易員都聽說過:相關性不意味因果性。DML 是這句話之後的部分。
為何樸素回歸失敗

在博客自己的領域中建立問題。我們想要隊列位置對成交機率的因果效應:
- :觀測 處的休市限價單是否在時間範圍內成交。
- :放置時的隊列位置(由層級大小標準化)。
- :干擾因素——實現波動性、報價價差、深度不平衡、層級大小、一天中的時間、制度標籤。這些是博客已經在 spread modeling with machine learning 中計算的市場狀態變量。
因果參數是 ,在
其中 捕捉市場狀態與成交結果之間的(可能複雜、非線性)關係。
處理並非隨機分配。您位於隊列前列是因為層級薄,或因為您在平靜時期發布,或因為訂單簿對您有利。相同條件獨立驅動您是否成交。這就是干擾。
方法 1:忽略干擾因素。 將 對 單獨回歸。估計吸收與兩者都相關的每個干擾因素的效應。教科書式的遺漏變量偏誤:薄層級既給您好的隊列位置又給您高成交率,因此您誇大了位置本身的價值。
方法 2:帶控制的線性回歸。 將 對 和 回歸。這僅在 真正線性時才有效。訂單簿動態並非如此——成交/波動性關係有閾值,深度不平衡效應按制度翻轉符號。錯誤指定 會重新引入偏誤。
方法 3:ML 預測。 在 上擬合梯度提升模型。您獲得良好的樣本外判別,但完全沒有因果解釋。模型捕捉每個預測模式,無論因果與否;正則化以偏誤 的方式縮小處理的貢獻;且沒有可信賴的標準誤差。
這是核心張力。ML 擅長預測,但對因果參數的樸素應用會產生偏誤、非正態、不可靠的估計。
部分線性模型

DML 在結構框架內運作。主力是部分線性回歸 (PLR):
- 是感興趣的因果參數。
- 是煩函數——結果中由市場狀態解釋的部分。
- 是另一個煩函數——給定市場狀態的處理條件期望(連續處理設置中的「propensity」)。
- 和 是結構殘差。
關鍵見解: 是低維的,但 和 可以任意複雜。我們希望 ML 處理煩函數,同時仍在標量上提供有效推斷。
為何「雙重」?
兩個 ML 模型,不是一個:
- 結果模型: —— 僅從市場狀態預測結果。
- 處理模型: —— 僅從市場狀態預測處理。
形成殘差
並通過將 對 回歸來估計 :
這是 Frisch-Waugh-Lovell 的加強版:用 ML 而非線性投影將干擾因素部分化,然後從殘差變異中讀取處理效應。
Neyman 正交性:為何有效
樸素部分外方法(估計 ,減去,回歸)失敗,因為 中的 ML 估計誤差直接傳播到 。DML 分數構建為 Neyman 正交——對煩函數中的小干擾不敏感。
PLR 的正交分數:
其中 。正交條件是
直觀上,分數僅使用 和 中獨立於 的變異,且一個煩函數中的誤差被另一個補償。如果 稍微過高預測處理, 稍微太小,但來自錯誤估計 的 中對應誤差會向補償方向推動。偏誤變成二階——兩個第一階誤差的乘積——而非一階。
正式地,如果兩個煩擾估計器以 速度收斂(溫和;大多數合理的 ML 方法通過),則
因此 以參數速度收斂且漸近正態。
交叉擬合:為何在此必須
僅正交性不夠。如果煩擾模型在用於估計 的相同行上擬合,第一階過度擬合會污染第二階段——具體傷害值得精確說明,因為它不是您習慣的傷害。在其他地方,過度擬合作為膨脹的驗證分數出現:您注意到它,您打折它,您繼續。在這裡它作為 的偏移點估計出現,伴隨仍然狹窄且仍然以錯誤數字為中心的信賴區間。沒有可疑的分數。估計器只是安靜地撒謊。
交叉擬合打破依賴:每個觀察的煩擾預測來自未包含它的模型,且 從池化的 held-out 殘差估計。機制是普通的 K-fold 機械,在 spread modeling with machine learning 中涵蓋;下面重要的是您給它哪些折疊。
DML 算法逐步
輸入:數據 ,ML 方法 和 ,折疊
步驟 1 —— 分割:將 分割為 個不相交折疊。
步驟 2 —— 交叉擬合煩擾模型:對於 ,在折疊 的補集上訓練 和 ,然後對於 計算 和 。
步驟 3 —— 估計:
步驟 4 —— 推斷:
帶有區間 。
信賴區間僅對一個問題有效
這是決定 DML 結果是否有價值的警告,也是大多數該方法應用默默崩潰的地方。
上述漸近正態性是關於一個預先指定的處理、一個預先指定的干擾因素集、一個預先指定的分數的陳述。預先固定這些,運行估計器一次,區間意味它所說的。嘗試三個候選處理,或四個干擾因素集,或交換學習器直到 p 值看起來更好,您就不再在做推斷——您在運行搜索,報告的 p 值是最大值的 p 值,不是單次抽樣的。
博客已經測量了這樣做的效果。在 the deflated Sharpe ratio study 中,在零真實邊緣的純噪聲上的搜索產生 1.000 的樸素虛假發現率——未調整測試每次都觸發——而贏家的中位數樸素 p 值接近 0.0007。關於 Neyman 正交性的沒有任何保護您免受此害。正交性修正煩擾估計的偏誤;它沒有說規格搜索的偏誤。在嘗試六個規格後獲得的 1e-05 DML p 值,完全應該獲得與任何其他從網格中提取的贏家相同的 Bonferroni/Holm/BHY 處理,其中 設置為您實際運行的規格數量。
這對工具的便利特性有直接的實際後果。DoubleMLData 接受 d_cols 中的列表,並會在一個摘要表中愉快地返回三個處理效應:
dml_data_multi = dml.DoubleMLData(
df, y_col='filled', d_cols=['queue_pos', 'toxicity', 'spread_at_post'],
x_cols=confounder_cols,
)
三行、三個 p 值,以及摘要表未提及的多重測試問題。如果您讀取全部三個,請調整全部三個。如果只有一個是預先註冊的問題,請這樣說,並明確將其他兩個視為探索性。
時間序列上的交叉擬合:清理、禁運、自定義折疊

標準 DML 假設 i.i.d. 觀察。訂單簿數據不是,失敗模式是博客已經詳細記錄的模式:相鄰行共享重疊的前瞻窗口,因此簡單的 TimeSeriesSplit 仍然會跨越折疊邊界洩漏答案。參見 spread modeling with machine learning 以了解清理的禁運 walk-forward 實現以及為何需要至少 horizon 行間隙的原因,以及 the look-ahead bias taxonomy 以了解完整的洩漏目錄及其測量幅度。
真正的 DML 特定部分是如何將清理的折疊交給估計器,因為 set_sample_splitting 有一個讓人絆倒的契約:
import numpy as np
import doubleml as dml
def purged_folds(n: int, n_splits: int, horizon: int):
"""帶有 `horizon` 行清理/禁運間隙的擴展窗口折疊。
與 spread-modeling 文章中清理的 walk-forward CV 相同構造:
間隙移除訓練行前瞻窗口與驗證行之間的重疊。
"""
fold_size = n // (n_splits + 1)
for k in range(1, n_splits + 1):
train_end = fold_size * k
val_start = train_end + horizon
val_end = val_start + fold_size
if val_end > n:
break
yield np.arange(0, train_end - horizon), np.arange(val_start, val_end)
folds = list(purged_folds(len(df), n_splits=5, horizon=HORIZON))
dml_plr = dml.DoubleMLPLR(dml_data, ml_l=ml_l, ml_m=ml_m)
// 元組列表的列表。一次重複:
dml_plr.set_sample_splitting([folds])
dml_plr.fit()
需要注意兩件事,沒有一件從庫文檔中明顯:
-
清理的 walk-forward 折疊不覆蓋每一行。 清理間隙和初始訓練塊從不是任何人的測試折疊,因此 從嚴格少於 個殘差估計。這是正確行為,不是錯誤,但這意味著方差公式中的有效 是池化測試行的數量——檢查它而非假設。
-
n_rep重複在此不 free。 對隨機 K-fold,重複交叉擬合和平均是廉價的方差減少。對確定性時間順序分割只有一個分割,因此n_rep不購買任何東西也不隱藏任何東西;穩定性必須來自在不同數據窗口上重新運行。
對於面板結構(同期多個符號),DoubleML 支持聚類穩健標準誤——按符號聚類,而非按時間,參見 multi-symbol validation 以了解博客關於何時真正確立跨工具結果的立場。
測量案例:隊列位置與成交機率

這是文章中項目已經有數據的唯一因果問題,它應該被運行而非提出。隊列位置分析 已經涵蓋真實訂單簿數據上的位置估計、FIFO 機制、排水率和成交時間;成交模擬 涵蓋成交機率建模和對實際成交的校準循環。兩者都產生成交的預測模型。DML 將相同輸入轉換為因果估計。
預先註冊的規格(在查看估計之前):
- 結果 :在
HORIZON快照內成交(二元)。 - 處理 :放置時的標準化隊列位置。
- 干擾因素 :1s 實現波動性、以 bps 為單位的報價價差、深度不平衡、發布時的層級大小、以 tick 為單位的距離中點距離、一天中的時間編碼、制度標籤。
from sklearn.ensemble import GradientBoostingRegressor
import doubleml as dml
confounder_cols = [
'rv_1s', 'spread_bps', 'depth_imbalance', 'level_size',
'dist_from_mid_ticks', 'tod_sin', 'tod_cos', 'regime',
]
dml_data = dml.DoubleMLData(
df, y_col='filled', d_cols='queue_pos_norm', x_cols=confounder_cols,
)
ml_l = GradientBoostingRegressor(n_estimators=300, max_depth=5)
ml_m = GradientBoostingRegressor(n_estimators=300, max_depth=5)
dml_plr = dml.DoubleMLPLR(dml_data, ml_l=ml_l, ml_m=ml_m, score='partialling out')
dml_plr.set_sample_splitting([folds])
dml_plr.fit()
print(dml_plr.summary)
dml_plr.sensitivity_analysis()
print(dml_plr.sensitivity_summary)
要報告的結果是四列比較,不是單一係數:僅 上 的樸素 OLS 估計、 和 上 的線性控制估計、帶有其標準誤差的 DML 估計,以及靈敏度分析的穩健值——未觀察干擾因素需要多強才能使效應無效。樸素和 DML 列之間的差距是真正感興趣的數量:它是隊列位置的表面價值中有多少是市場狀態的偽裝。
此處的零或負 是可發布的結果,且比乾淨的正結果更適合本博客。如果一旦波動性和層級大小被部分化,隊列位置的因果效應就崩潰,那是關於訂單放置政策的直接發現:位置不是賺取成交的東西,獲得位置的條件才是。
因子因果分析
因子投資的標準方法是關聯的:按特徵排序、形成多空投資組合、觀察報酬不同。DML 啟用不同的測試——估計特徵對報酬的直接因果效應,抵消其他特徵的干擾效應。如果效應在 DML 下消失,因子不是獨立因果;它是代理。
這是因子懷疑論的第二種獨立形式,值得明確說明它與博客已經發布的內容的關係。The deflated Sharpe ratio 從選擇側攻擊因子動物園:有足夠的試驗,因子可能看起來顯著只是因為您看了很多次。DML 從干擾側攻擊它:因子可能在單次誠實測試上顯著,仍然是條件集中其他東西的代理。因子必須通過兩者才有意思,且兩種失敗模式是獨立的——通過一個並不告訴您關於另一個的任何事。
DML 不能做什麼
-
它要求干擾因素被觀察。 如果未觀察變量同時驅動處理和結果,DML 有偏,且沒有 ML 精緻性修正識別問題。靈敏度分析有界風險;它不消除風險。
-
它估計平均效應。 如果隊列位置的效應在制度間急劇變化,點估計是您樣本制度混合的平均值。對於異質性使用 Interactive Regression Model (
DoubleMLIRM) 或因果森林。 -
它假設結構模型。 部分線性規格要求處理以特定方式進入結果方程。如果真實過程根本不同,DML 自信地錯誤。
-
它不發現因果結構。 DML 估計預先指定的處理的效應。它不告訴您哪些變量是原因。
-
它不免除您多重測試。 重複上述點因為它是最常跳過的點:正交性去偏煩擾估計,而非規格搜索。
實用註記
樣本大小。 DML 需要煩擾模型以 收斂,實踐中這意味著足夠的行讓 ML 模型以任何方式近似 和 。與其信任取整數的閾值,不如像 multi-symbol validation 那樣實證建立充分性——檢查估計是否在工具和子週期上成立,並將不穩定性視為其信號。
學習器選擇。 DML 特定事實狹窄但有用:給定 收斂,學習器影響 的效率(區間寬度),而非其一致性。哪些學習器值得在表格市場數據上觸及,以及為何梯度提升是默認值,已經在 spread modeling with machine learning 中涵蓋。如果 在學習器間實質移動,那不是選擇菜單——這是煩函數估計不良的證據,根據上述部分,選擇最友好的會將練習變成搜索。
結論
DML 給博客帶來了它沒有的東西:一種將市場微結構主張聲明為帶有可辯護標準誤差的因果參數,而非帶有良好驗證分數的預測的方法。
三個承重想法是:
- 正交化分數,使第一階誤差補償到二階。
- 交叉擬合,在時間序列數據上使用清理和禁運折疊,使第一階過度擬合無法移動 。
- 預先指定,使您報告的區間是您實際獲得的區間。
估計器是容易的部分。困難部分不變:決定哪些干擾因素重要,論證識別假設成立,以及抵抗再次運行規格的衝動。
參考文獻
DML 血統短且 worth 一行:它是 Robinson (1988) 的部分線性模型,ML 替換核估計器,達到半參數效率界限,具有追溯 Neyman C() 測試的正交條件,以及在靶向學習 (TMLE) 文獻中的近親。Chernozhukov 等人的貢獻是展示這可以用任意 ML 學習器運作,同時保持 一致、漸近正態推斷。
- Chernozhukov, V., Chetverikov, D., Demirer, M., Duflo, E., Hansen, C., Newey, W., & Robins, J. (2018). Double/Debiased Machine Learning for Treatment and Structural Parameters. The Econometrics Journal, 21(1), C1-C68.
- Robinson, P. M. (1988). Root-N-Consistent Semiparametric Regression. Econometrica, 56(4), 931-954.
- Bach, P., Chernozhukov, V., Kurz, M. S., & Spindler, M. (2022). DoubleML — An Object-Oriented Implementation of Double Machine Learning in Python. Journal of Machine Learning Research, 23(53), 1-6.
- Facure, M. (2022). Causal Inference for the Brave and True. Chapter 22: Debiased/Orthogonal Machine Learning.
- Cahan, E., Bai, J., & Ng, S. (2024). Causal Factor Investing. Quantitative Finance.
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.