Double Machine Learning: Ước Lượng Tham Số Nhân Quả Thay Vì Dự Báo Lợi Nhuận
Mọi bài viết mô hình hóa trên blog này cho đến nay đều đặt cùng một hình thức câu hỏi: cho các đặc điểm, dự báo một con số, sau đó xác nhận rằng dự báo đó tồn tại ngoài mẫu. Các mô hình spread dự báo spread. Các mô hình fill dự báo xác suất fill. Toàn bộ bộ máy xác nhận — walk-forward đã được làm sạch, Sharpe đã giảm bớt, phân loại look-ahead — tồn tại để kiểm tra xem một dự báo có thực hay không.
Bài viết này đặt một hình thức câu hỏi khác, và là mảnh máy duy nhất mà blog chưa bao giờ có: ước lượng một tham số vô hướng duy nhất có ý nghĩa nhân quả, và gắn một sai số chuẩn cho nó tồn tại qua việc một mô hình ML linh hoạt đã được sử dụng để đạt được điều đó.
Đó không phải là một sự khác biệt tu từ. "Vị trí hàng đợi dự báo xác suất fill" là đúng tầm thường và vô tích sự về mặt hoạt động — tất nhiên là nó vậy, cả hai đều được thúc đẩy bởi độ sâu và biến động. "Di chuyển một vị trí вперед trong hàng đợi gây ra sự thay đổi của trong xác suất fill, giữ trạng thái thị trường cố định" là một con số bạn có thể đưa vào chính sách đặt lệnh. Cái đầu tiên là một sự khớp hồi quy. Cái thứ hai yêu cầu một bộ ước lượng không tồn tại trong hộp công cụ ML tiêu chuẩn, vì regularization và overfitting trong giai đoạn đầu linh hoạt bias chính hệ số mà bạn quan tâm.
Double Machine Learning (Chernozhukov, Chetverikov, Demirer, Duflo, Hansen, Newey & Robins, 2018) là bộ ước lượng sửa chữa điều này. Mọi nhà giao dịch định lượng đã nghe điều này: tương quan không phải là nhân quả. DML là phần đến sau câu đó.
Tại Sao Hồi Quy Tươn Thất Bại

Thiết lập câu hỏi trong lãnh thổ của blog. Chúng tôi muốn tác động nhân quả của vị trí hàng đợi lên xác suất fill:
- : liệu lệnh giới hạn đang nghỉ tại quan sát được fill trong đường chân trời.
- : vị trí hàng đợi tại thời điểm đặt (được chuẩn hóa bởi kích thước cấp độ).
- : các yếu tố gây nhiễu — biến động đã thực hiện, spread được báo giá, sự mất cân bằng độ sâu, kích thước cấp độ, thời gian trong ngày, nhãn chế độ. Đây là các biến trạng thái thị trường mà blog đã tính trong mô hình hóa spread với machine learning.
Tham số nhân quả là trong
nơi nắm bắt mối quan hệ (có thể phức tạp, phi tuyến tính) giữa trạng thái thị trường và kết quả fill.
Can thiệp không được gán ngẫu nhiên. Bạn ở gần đầu hàng đợi bởi vì cấp độ mỏng, hoặc bởi vì bạn đăng trong giai đoạn yên tĩnh, hoặc bởi vì sổ lệch về hướng có lợi cho bạn. Cùng điều kiện thúc đẩy độc lập việc bạn có được fill hay không. Đó là sự nhiễu.
Cách tiếp cận 1: Bỏ qua các yếu tố gây nhiễu. Hồi quy trên một mình. Ước lượng hấp thụ tác động của mọi yếu tố gây nhiễu tương quan với cả hai. Bias biến bị bỏ lỡ trong giáo trình: các cấp độ mỏng mang lại cả một vị trí hàng đợi tốt và tỷ lệ fill cao, vì vậy bạn thổi phồng giá trị của vị trí đó.
Cách tiếp cận 2: Hồi quy tuyến tính với các kiểm soát. Hồi quy trên và . Điều này chỉ hoạt động nếu thực sự tuyến tính. Động thái của sổ không phải như vậy — mối quan hệ fill/biến động có ngưỡng, tác động của mất cân bằng độ sâu thay đổi dấu hiệu theo chế độ. Đặc tả sai reintroduces bias.
Cách tiếp cận 3: Dự báo ML. Khớp một mô hình gradient boosted trên . Bạn có được phân biệt ngoài mẫu tốt, và không có ý nghĩa nhân quả nào. Mô hình nắm bắt mọi pattern dự báo, nhân quả hay không; regularization thu nhỏ đóng góp của can thiệp theo những cách bias ; và không có sai số chuẩn nào bạn có thể tin.
Đây là căng thẳng cốt lõi. ML tốt trong dự báo, nhưng áp dụng naif cho một tham số nhân quả tạo ra các ước lượng bị bias, không chuẩn, không đáng tin cậy.
Mô Hình Tuyến Tính Một Phần

DML hoạt động trong một cấu trúc cấu trúc. Công nhân chính là hồi quy tuyến tính một phần (PLR):
- là tham số nhân quả được quan tâm.
- là một hàm gây phiền — phần của kết quả được giải thích bởi trạng thái thị trường.
- là một hàm gây phiền khác — kỳ vọng có điều kiện của can thiệp đã cho trạng thái thị trường ("propensity" trong bối cảnh can thiệp liên tục).
- và là các thặng dư cấu trúc.
Sự hiểu biết chính: thấp chiều, nhưng và có thể phức tạp tùy ý. Chúng tôi muốn ML xử lý các hàm gây phiền trong khi vẫn cung cấp suy luận hợp lệ trên vô hướng.
Tại Sao "Kép"?
Hai mô hình ML, không phải một:
- Mô hình kết quả: — dự báo kết quả từ trạng thái thị trường một mình.
- Mô hình can thiệp: — dự báo can thiệp từ trạng thái thị trường một mình.
Tạo thặng dư
và ước lượng bằng cách hồi quy trên :
Đây là Frisch-Waugh-Lovell trên steroid: loại bỏ các yếu tố gây nhiễu bằng ML thay vì chiếu tuyến tính, sau đó đọc tác động can thiệp từ biến thiên thặng dư.
Trực Giao Neyman: Tại Sao Nó Hoạt Động
Cách tiếp cận partial-out naif (ước lượng , trừ, hồi quy) thất bại vì các sai số ước lượng ML trong truyền thẳng vào . Điểm DML được xây dựng để Neyman trực giao — không nhạy cảm với các nhiễu loạn nhỏ trong các hàm gây phiền.
Điểm trực giao cho PLR:
nơi . Điều kiện trực giao là
Theo trực giác, điểm chỉ sử dụng biến thiên trong và độc lập với , và các sai số trong một hàm gây phiền được bù đắp bởi cái kia. Nếu dự báo can thiệp hơi quá nhiều, hơi quá nhỏ, nhưng sai số tương ứng trong từ việc ước lượng sai đẩy theo hướng bù đắp. Bias trở thành thứ hai — sản phẩm của hai sai số giai đoạn đầu — thay vì thứ nhất.
Một cách chính thức, nếu cả hai bộ ước lượng gây phiền hội tụ tại tốc độ (nhẹ; hầu hết các phương pháp ML hợp lý vượt qua), thì
vậy hội tụ tại tốc độ tham số và bình thường tiệm cận.
Cross-Fitting: Tại Sao Bắt Buộc Ở Đây
Chỉ trực giao là không đủ. Nếu các mô hình gây phiền được khớp trên cùng các hàng được sử dụng để ước lượng , overfitting giai đoạn đầu làm ô nhiễm giai đoạn hai — và thiệt hại cụ thể worth stating chính xác, bởi vì nó không phải là thiệt hại bạn quen. Ở nơi khác, overfitting xuất hiện như một điểm xác thực phồng lên: bạn nhận thấy nó, bạn chiết khấu nó, bạn tiếp tục. Ở đây nó xuất hiện như một ước lượng điểm bị dịch chuyển cho , với một khoảng tin cậy vẫn hẹp và vẫn tập trung vào số sai. Không có điểm nào để nghi ngờ. Bộ ước lượng chỉ đơn giản là nói dối một cách im lặng.
Cross-fitting phá vỡ sự phụ thuộc: các dự báo gây phiền của mỗi quan sát đến từ một mô hình được huấn luyện mà không có nó, và được ước lượng từ các thặng dư được gộp held-out. Cơ học là máy móc K-fold bình thường, được đề cập trong mô hình hóa spread với machine learning; điều quan trọng dưới đây là những folds bạn đưa cho nó.
Thuật Toán DML Từng Bước
Đầu vào: dữ liệu , phương pháp ML và , folds
Bước 1 — Phân chia: chia thành folds rời nhau.
Bước 2 — Cross-fit các mô hình gây phiền: cho , huấn luyện và trên phần bù của fold , sau đó tính và cho .
Bước 3 — Ước lượng:
Bước 4 — Suy luận:
với các khoảng .
Khoảng tin cậy hợp lệ cho chính xác một câu hỏi
Đây là điều cảnh báo quyết định xem kết quả DML có giá trị gì hay không, và là nơi hầu hết các sử dụng áp dụng của phương pháp âm thầm sụp đổ.
Sự bình thường tiệm cận ở trên là một tuyên bố về một can thiệp được chỉ định trước, một tập hợp các yếu tố gây nhiễu được chỉ định trước, một điểm được chỉ định trước. Khắc định chúng trước, chạy bộ ước lượng một lần, và khoảng có nghĩa là những gì nó nói. Thử ba can thiệp ứng viên, hoặc bốn tập hợp các yếu tố gây nhiễu, hoặc đổi learner cho đến khi p-value trông tốt hơn, và bạn không còn đang suy luận — bạn đang chạy một tìm kiếm, và p-value được báo cáo là p-value của một tối đa, không phải của một lần rút.
Blog đã đo điều này làm. Trong nghiên cứu tỷ lệ Sharpe giảm bớt, các tìm kiếm trên nhiễu thuần với lợi thế thực bằng không tạo ra tỷ lệ phát hiện sai naif là 1.000 — kiểm tra không điều chỉnh kích hoạt mỗi lần — trong khi p-value naif trung vị của người chiến thắng ngồi gần 0.0007. Không có gì về trực giao Neyman bảo vệ bạn khỏi điều này. Trực giao sửa chữa bias từ ước lượng gây phiền; nó không nói gì về bias từ tìm kiếm đặc tả. Một p-value DML của 1e-05 đạt được sau khi thử sáu đặc tả xứng đáng cùng một treatment Bonferroni/Holm/BHY như bất kỳ người chiến thắng nào khác được kéo ra từ một lưới, với được đặt thành số lượng đặc tả bạn thực sự chạy.
Điều này có một hậu quả thực tế trực tiếp cho các tính năng tiện lợi của công cụ. DoubleMLData chấp nhận một danh sách trong d_cols và sẽ vui vẻ trả về ba tác động can thiệp trong một bảng tóm tắt:
dml_data_multi = dml.DoubleMLData(
df, y_col='filled', d_cols=['queue_pos', 'toxicity', 'spread_at_post'],
x_cols=confounder_cols,
)
Ba hàng, ba p-values, và một vấn đề kiểm tra nhiều lần mà bảng tóm tắt không đề cập. Nếu bạn đọc cả ba, điều chỉnh cả ba. Nếu chỉ một là câu hỏi đã đăng ký trước, hãy nói như vậy, và coi hai cái còn lại một cách rõ ràng là thăm dò.
Cross-Fitting trên Chuỗi Thời Gian: Purge, Embargo, Folds Tùy Chỉnh

DML tiêu chuẩn giả định các quan sát i.i.d. Dữ liệu sổ không phải như vậy, và chế độ thất bại là chế độ mà blog đã ghi chép chi tiết: các hàng liền kề chia sẻ các cửa sổ phía trước chồng chéo, vì vậy một TimeSeriesSplit đơn giản vẫn rò rỉ câu trả lời qua ranh giới fold. Xem mô hình hóa spread với machine learning để thực hiện walk-forward đã được làm sạch và embargolý và lý do tại sao cần một khoảng ít nhất horizon hàng, và phân loại look-ahead bias để có danh mục đầy đủ các rò rỉ và độ lớn đo được của chúng.
Phần thực sự DML-đặc biệt là cách bạn đưa các folds đã được làm sạch cho bộ ước lượng, bởi vì set_sample_splitting có một hợp đồng khiến mọi người ngã:
import numpy as np
import doubleml as dml
def purged_folds(n: int, n_splits: int, horizon: int):
"""Các fold cửa sổ mở rộng với khoảng purge/embargo `horizon` hàng.
Cùng xây dựng như CV walk-forward đã được làm sạch trong bài viết
spread-modeling: khoảng loại bỏ sự chồng chéo giữa cửa sổ phía trước
của một hàng huấn luyện và một hàng xác nhận.
"""
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)
// tuple (train_idx, test_idx). Một lần lặp:
dml_plr.set_sample_splitting([folds])
dml_plr.fit()
Hai điều để nhận thức, không có điều nào rõ ràng từ tài liệu thư viện:
-
Các fold walk-forward đã được làm sạch không bao phủ mọi hàng. Các khoảng purge và khối huấn luyện ban đầu không bao giờ là fold kiểm tra của ai, vì vậy được ước lượng từ ít hơn thặng dư. Đó là hành vi đúng, không phải lỗi, nhưng điều đó có nghĩa là hiệu quả trong công thức phương sai là số lượng hàng kiểm tra được gộp — kiểm tra nó thay vì giả định.
-
Các lần lặp
n_repkhông miễn phí ở đây. Với K-fold ngẫu nhiên, lặp lại cross-fitting và trung bình là một sự giảm phương sai rẻ. Với một chia thời gian xác định có một chia duy nhất, vì vậyn_repkhông mua gì và không giấu gì; sự ổn định phải đến từ việc chạy lại trên các cửa sổ dữ liệu khác thay vào đó.
Đối với cấu trúc bảng (nhiều biểu tượng trong cùng một thời kỳ), DoubleML hỗ trợ các sai số chuẩn mạnh theo cụm — cụm trên biểu tượng, không phải trên thời gian, và xem xác thực đa biểu tượng để biết vị trí của blog về khi một kết quả cross-instrument thực sự được thiết lập.
Trường Hợp Được Đo: Vị Trí Hàng Đợi và Xác Suất Fill

Đây là câu hỏi nhân quả duy nhất trong bài viết mà dự án đã có dữ liệu, và nó nên được chạy thay vì được đề xuất. Phân tích vị trí hàng đợi đã đề cập đến ước lượng vị trí, cơ chế FIFO, tỷ lệ drain và thời gian để fill trên dữ liệu sổ thực; mô phỏng fill đề cập đến mô hình hóa xác suất fill và vòng calibrating so với fills trực tiếp. Cả hai tạo ra một mô hình dự báo của fills. DML chuyển đổi cùng một đầu vào thành một ước lượng nhân quả.
Đặc tả, đã đăng ký trước khi nhìn vào ước lượng:
- Kết quả : được fill trong
HORIZONsnapshots (nhị phân). - Can thiệp : vị trí hàng đợi được chuẩn hóa tại thời điểm đặt.
- Các yếu tố gây nhiễu : biến động đã thực hiện 1s, spread được báo giá bằng bps, mất cân bằng độ sâu, kích thước cấp độ tại post, khoảng cách từ mid bằng ticks, mã hóa thời gian trong ngày, nhãn chế độ.
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)
Kết quả để báo cáo là một so sánh bốn cột, không phải một hệ số duy nhất: ước lượng naif OLS của trên một mình, ước lượng kiểm soát tuyến tính của trên và , ước lượng DML với sai số chuẩn của nó, và giá trị mạnh mẽ từ phân tích độ nhạy — một yếu tố gây nhiễu không quan sát được sẽ phải mạnh như thế nào để vô hiệu hóa tác động. Khoảng giữa các cột naif và DML là lượng quan tâm thực: nó là bao nhiêu của giá trị rõ ràng của vị trí hàng đợi là trạng thái thị trường mặc một bộ trang phục.
Một null hoặc âm ở đây là một kết quả có thể xuất bản và phù hợp với blog này tốt hơn một cái tích cực sạch. Nếu tác động nhân quả của vị trí hàng đợi sụp đổ một khi biến động và kích thước cấp độ được partial out, đó là một phát hiện trực tiếp về chính sách đặt lệnh: vị trí không phải là thứ kiếm được fill, các điều kiện mà bạn nhận được vị trí là.
Phân Tích Yếu Tố Nhân Quả
Cách tiếp cận tiêu chuẩn để đầu tư yếu tố là kết hợp: sắp xếp theo một đặc điểm, hình thành danh mục long-short, quan sát rằng lợi nhuận khác nhau. DML cho phép một thử nghiệm khác — ước lượng tác động nhân quả trực tiếp của một đặc điểm trên lợi nhuận, loại bỏ các tác động gây nhiễu của các đặc điểm khác. Nếu tác động biến mất dưới DML, yếu tố không phải là nhân quả độc lập; nó là một đại lý.
Đây là thứ hai, hình thức hoài nghi yếu tố độc lập, và worth being explicit về cách nó liên quan đến thứ mà blog đã xuất bản. Tỷ lệ Sharpe giảm bớt tấn công sở bể yếu tố từ phía lựa chọn: với đủ thử nghiệm, một yếu tố có thể trông có ý nghĩa chỉ vì bạn nhìn nhiều lần. DML tấn công nó từ phía gây nhiễu: một yếu tố có thể trông có ý nghĩa trên một thử nghiệm trung thực duy nhất và vẫn là một đại lý cho cái gì đó trong tập hợp điều kiện. Một yếu tố phải tồn tại qua cả hai để thú vị, và hai chế độ thất bại là độc lập — vượt qua một không cho bạn biết gì về cái kia.
Những Gì DML Không Thể Làm
-
Nó yêu cầu các yếu tố gây nhiễu được quan sát. Nếu một biến không quan sát thúc đẩy cả can thiệp và kết quả, DML bị bias, và không có sự tinh tế ML nào sửa một vấn đề nhận dạng. Phân tích độ nhạy giới hạn rủi ro; nó không loại bỏ nó.
-
Nó ước lượng một tác động trung bình. Nếu tác động của vị trí hàng đợi thay đổi mạnh qua các chế độ, ước lượng điểm là trung bình trên hỗn hợp chế độ của mẫu của bạn. Để tính dị hình sử dụng Interactive Regression Model (
DoubleMLIRM) hoặc causal forest. -
Nó giả định một mô hình cấu trúc. Đặc tả tuyến tính một phần yêu cầu can thiệp đi vào phương trình kết quả theo một cách cụ thể. Nếu quá trình thực sự khác biệt về cơ bản, DML sai một cách tự tin.
-
Nó không khám phá cấu trúc nhân quả. DML ước lượng tác động của một can thiệp được chỉ định trước. Nó không cho bạn biết những biến nào là nguyên nhân.
-
Nó không miễn trừ bạn khỏi kiểm tra nhiều lần. Lặp lại điểm ở trên vì đó là điểm bị bỏ qua nhiều nhất: trực giao de-bias ước lượng gây phiền, không phải tìm kiếm đặc tả.
Ghi Chú Thực Tiễn
Kích thước mẫu. DML yêu cầu các mô hình gây phiền hội tụ tại , mà trong thực tế có nghĩa là đủ hàng để các mô hình ML xấp xỉ và bằng cách nào đó. Thay vì tin vào các ngưỡng số tròn, thiết lập sự đầy đủ một cách thực nghiệm theo cách xác thực đa biểu tượng làm — kiểm tra xem ước lượng tồn tại qua các công cụ và các giai đoạn phụ, và coi sự không ổn định là tín hiệu của nó.
Lựa chọn learner. Sự thật DML-đặc biệt là hẹp nhưng hữu ích: cho hội tụ , learner ảnh hưởng hiệu quả của (chiều rộng khoảng), không phải sự nhất quán của nó. Những learners nào worth tiếp cận trên dữ liệu thị trường dạng bảng, và tại sao gradient boosting là mặc định, đã được đề cập trong mô hình hóa spread với machine learning. Nếu di chuyển đáng kể qua các learner, đó không phải là menu để chọn — đó là bằng chứng rằng các hàm gây phiền được ước lượng kém, và theo phần trên, chọn cái thân thiện nhất biến bài tập thành một tìm kiếm.
Kết Luận
DML cung cấp cho blog một thứ nó chưa có: một cách để nói ra một yêu cầu vi cấu trúc thị trường như một tham số nhân quả với một sai số chuẩn có thể bảo vệ, thay vì như một dự báo với một điểm xác thực tốt.
Ba ý tưởng chịu lực là:
- Trực giao hóa điểm để các sai số giai đoạn đầu bù đắp đến thứ hai.
- Cross-fit, với các folds đã được làm sạch và embargolý trên dữ liệu chuỗi thời gian, để overfitting giai đoạn đầu không thể dịch chuyển .
- Chỉ định trước, để khoảng bạn báo cáo là khoảng bạn thực sự kiếm được.
Bộ ước lượng là phần dễ. Các phần khó vẫn không đổi: quyết định các yếu tố gây nhiễu nào quan trọng, lập luận rằng các giả định nhận dạng giữ, và chống lại urge để chạy đặc tả thêm một lần nữa.
Tài Liệu Tham Khảo
Dòng dõi của DML ngắn và worth một dòng: đó là mô hình tuyến tính một phần của Robinson (1988) với ML thay thế các bộ ước lượng hạt, đạt được giới hạn hiệu quả bán tham số, với một điều kiện trực giao truy về bài kiểm tra C() của Neyman và một anh em họ gần trong tài liệu học tập có mục tiêu (TMLE). Đóng góp của Chernozhukov et al. là cho thấy điều này có thể được operationalized với các learner ML tùy ý trong khi giữ lại suy luận -consistent, bình thường tiệm cận.
- 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.
Tác Giả
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.