© Bản quyền thuộc về Quantopian Inc.
© Bản quyền sửa đổi thuộc về AI Cafe¹
Giấy phép Creative Commons Attribution 4.0.
Khuyến cáo
¶
Tương quan tuyến tính¶
By Evgenia "Jenny" Nitishinskaya and Delaney Granizo-Mackenzie with example algorithms by David Edwards
Edited by AI Cafe¹
Hệ số tương quan đo lường mức độ mà mối quan hệ giữa hai biến là tuyến tính. Giá trị của nó luôn nằm trong khoảng từ -1 đến 1. Một hệ số dương cho thấy các biến có mối quan hệ trực tiếp, tức là khi một biến tăng, biến kia cũng tăng theo. Một hệ số âm cho thấy các biến có mối quan hệ ngược chiều, nghĩa là khi một biến tăng, biến kia sẽ giảm. Càng gần 0, hệ số tương quan càng cho thấy mối quan hệ giữa các biến yếu hơn.
Hệ số tương quan của hai chuỗi $X$ và $Y$ được định nghĩa là $$r = \frac{Cov(X,Y)}{std(X)std(Y)}$$ trong đó $Cov$ là hiệp phương sai và $std$ là độ lệch chuẩn.
Hai tập dữ liệu ngẫu nhiên sẽ có hệ số tương quan gần 0.
Tương quan vs. hiệp phương sai¶
Tương quan chỉ là một hình thức chuẩn hóa của hiệp phương sai. Về bản chất, chúng giống nhau và thường được sử dụng một cách tương đối thay thế cho nhau trong các cuộc trò chuyện hàng ngày. Rõ ràng là việc sử dụng ngôn ngữ chính xác khi thảo luận về hai khái niệm này là rất quan trọng, nhưng về mặt khái niệm, chúng gần như tương đương.
Hiệp phương sai không có nhiều ý nghĩa khi đứng một mình¶
Giả sử chúng ta có hai biến $X$ và $Y$ và chúng ta lấy hiệp phương sai của hai biến này.
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
X = np.random.rand(50)
Y = 2 * X + np.random.normal(0, 0.1, 50)
np.cov(X, Y)[0, 1]
np.float64(0.1441919014697786)
Điều này có nghĩa là gì? Hệ số tương quan sử dụng thông tin về phương sai của X và Y để chuẩn hóa chỉ số này. Khi chúng ta đã chuẩn hóa chỉ số vào thang -1 đến 1, chúng ta có thể đưa ra những nhận định có ý nghĩa và so sánh các hệ số tương quan.
Để thấy điều này được thực hiện như thế nào, hãy xem công thức.
$$\frac{Cov(X, Y)}{std(X)std(Y)}$$
$$= \frac{Cov(X, Y)}{\sqrt{var(X)}\sqrt{var(Y)}}$$
$$= \frac{Cov(X, Y)}{\sqrt{Cov(X, X)}\sqrt{Cov(Y, Y)}}$$
Để minh họa điều này, hãy so sánh hệ số tương quan và hiệp phương sai của hai chuỗi.
X = np.random.rand(50)
Y = 2 * X + 4
print('Covariance of X and Y: \n' + str(np.cov(X, Y)))
print('Correlation of X and Y: \n' + str(np.corrcoef(X, Y)))
Covariance of X and Y: [[0.10601576 0.21203153] [0.21203153 0.42406305]] Correlation of X and Y: [[1. 1.] [1. 1.]]
Tại sao cả np.cov
và np.corrcoef
đều trả về ma trận?¶
Ma trận hiệp phương sai là một khái niệm quan trọng trong thống kê. Thông thường, mọi người sẽ nói đến hiệp phương sai của hai biến $X$ và $Y$, nhưng thực tế đó chỉ là một phần tử trong ma trận hiệp phương sai của $X$ và $Y$. Đối với mỗi biến đầu vào, chúng ta có một hàng và một cột. Đường chéo chính chỉ là phương sai của biến đó, hay $Cov(X, X)$, các phần tử ngoài đường chéo là các hiệp phương sai giữa các biến khác nhau. Ma trận này đối xứng qua đường chéo. Hãy kiểm tra xem điều này có đúng không.
cov_matrix = np.cov(X, Y)
# We need to manually set the degrees of freedom on X to 1, as numpy defaults to 0 for variance
# This is usually fine, but will result in a slight mismatch as np.cov defaults to 1
error = cov_matrix[0, 0] - X.var(ddof=1)
print('error: ' + str(error))
error: 1.3877787807814457e-17
X = np.random.rand(50)
Y = np.random.rand(50)
plt.scatter(X,Y)
plt.xlabel('X Value')
plt.ylabel('Y Value')
# taking the relevant value from the matrix returned by np.cov
print('Correlation: ' + str(np.cov(X,Y)[0,1]/(np.std(X)*np.std(Y))))
# Let's also use the builtin correlation function
print('Built-in Correlation: ' + str(np.corrcoef(X, Y)[0, 1]))
Correlation: 0.44273422806935 Built-in Correlation: 0.4338795435079629
Bây giờ hãy xem hai tập dữ liệu có tương quan sẽ trông như thế nào.
X = np.random.rand(50)
Y = X + np.random.normal(0, 0.1, 50)
plt.scatter(X,Y)
plt.xlabel('X Value')
plt.ylabel('Y Value')
print('Correlation: ' + str(np.corrcoef(X, Y)[0, 1]))
Correlation: 0.9257852499729657
Hãy giảm bớt mối quan hệ bằng cách thêm nhiều nhiễu hơn.
X = np.random.rand(50)
Y = X + np.random.normal(0, .2, 50)
plt.scatter(X,Y)
plt.xlabel('X Value')
plt.ylabel('Y Value')
print('Correlation: ' + str(np.corrcoef(X, Y)[0, 1]))
Correlation: 0.8311971598791154
Cuối cùng, hãy xem mối quan hệ nghịch đảo trông như thế nào.
X = np.random.rand(50)
Y = -X + np.random.normal(0, .1, 50)
plt.scatter(X,Y)
plt.xlabel('X Value')
plt.ylabel('Y Value')
print('Correlation: ' + str(np.corrcoef(X, Y)[0, 1]))
Correlation: -0.9403653209019381
Chúng ta thấy một chút sai số làm tròn, nhưng rõ ràng chúng là cùng một giá trị.
# Cài thư viện lấy dữ liệu miễn phí
!curl -fsSLO https://raw.githubusercontent.com/algo-stocks/data/master/data.py
from data import get_prices
start = '2023-01-01'
end = '2025-01-01'
closes = get_prices('VHM', 'VIC', start_date=start, end_date=end)
plt.scatter(closes['VHM'], closes['VIC'])
plt.xlabel('VHM')
plt.ylabel('VIC')
plt.title('Stock prices from ' + start + ' to ' + end)
print("Correlation coefficient:", np.corrcoef(closes['VHM'], closes['VIC'])[0,1])
Correlation coefficient: 0.826685415220237
Xây dựng danh mục gồm các tài sản không tương quan với nhau¶
Một lý do nữa mà hệ số tương quan hữu ích trong tài chính là những tài sản không tương quan với nhau tạo ra những danh mục đầu tư tốt nhất. Cảm nhận cho điều này là nếu các tài sản không tương quan, một sự sụt giảm ở một tài sản sẽ không tương ứng với sự sụt giảm ở một tài sản khác. Điều này dẫn đến một dòng lợi nhuận rất ổn định khi nhiều tài sản không tương quan được kết hợp lại với nhau.
Hạn chế¶
Ý nghĩa¶
Thật khó để xác định một cách chính xác liệu một mối tương quan có ý nghĩa hay không, đặc biệt như ở đây, các biến không được phân phối theo phân phối chuẩn. Hệ số tương quan của chúng gần bằng 1, vì vậy có thể nói rằng hai giá cổ phiếu này có tương quan trong khoảng thời gian chúng ta sử dụng, nhưng điều này có chỉ ra mối tương quan trong tương lai hay không?
Một vấn đề cơ bản là rất dễ dàng để khai thác dữ liệu tìm kiếm mối tương quan bằng cách chọn khoảng thời gian phù hợp. Để tránh điều này, người ta nên tính toán mối tương quan của hai đại lượng qua nhiều khoảng thời gian lịch sử và xem xét phân phối của hệ số tương quan.
Lấy một ví dụ, hãy nhớ rằng mối tương quan của VIC và VHM từ ngày 01 tháng 01 năm 2023 đến ngày 01 tháng 01 năm 2025 là 0.82. Hãy xem xét mối tương quan động 60 ngày giữa hai cổ phiếu này để xem nó thay đổi như thế nào.
rolling_correlation = closes['VIC'].rolling(60).corr(closes['VHM'])
ax = rolling_correlation.plot()
ax.set_xlabel('Day')
ax.set_ylabel('60-day Rolling Correlation')
Text(0, 0.5, '60-day Rolling Correlation')
Mối Quan Hệ Phi Tuyến¶
Hệ số tương quan có thể hữu ích trong việc kiểm tra độ mạnh của mối quan hệ giữa hai biến. Tuy nhiên, điều quan trọng là phải nhớ rằng hai biến có thể liên kết theo những cách khác nhau và có thể dự đoán được mà phân tích này không thể phát hiện. Ví dụ, một biến có thể hoàn toàn theo dõi hành vi của một biến khác, nhưng với một độ trễ. Có những kỹ thuật để xử lý sự tương quan trễ này. Ngoài ra, một biến có thể liên quan đến tỷ lệ thay đổi của một biến khác. Không có mối quan hệ nào trong số này là tuyến tính, nhưng có thể rất hữu ích nếu được phát hiện.
Ngoài ra, hệ số tương quan có thể rất nhạy cảm với các điểm ngoại lệ. Điều này có nghĩa là việc bao gồm hoặc loại trừ ngay cả một vài điểm dữ liệu cũng có thể thay đổi kết quả của bạn, và không phải lúc nào cũng rõ ràng liệu những điểm này chứa thông tin hay chỉ là nhiễu.
Ví dụ, hãy làm cho phân phối nhiễu trở thành phân phối Poisson thay vì phân phối chuẩn và xem điều gì sẽ xảy ra.
X = np.random.rand(100)
Y = X + np.random.poisson(size=100)
plt.scatter(X, Y)
np.corrcoef(X, Y)[0, 1]
np.float64(0.31075874029838185)
Kết luận, tương quan là một kỹ thuật mạnh mẽ, nhưng như các kỹ thuật thống kê khác, chúng ta nên cẩn thận để không suy diễn kết quả trong khi thực tế là không có gì cả.
Lưu ý: Tài liệu này mang tính chất chia sẻ kiến thức khoa học dữ liệu. Các mã chứng khoán xuất hiện trong tài liệu chỉ mang tính chất minh hoạ, không khuyến nghị đầu tư. Chúng tôi không chịu trách nhiệm trước mọi rủi ro nào do sử dụng tài liệu này.