알파트로스

[ML4AM] 3.Codependence (1) Correlation 본문

Machine Learning for Asset Managers

[ML4AM] 3.Codependence (1) Correlation

알파트로스 2024. 7. 1. 21:41

Pearson Correlation

가장 널리쓰이는 두 random variable 간의 선형적 연관성을 정량화하는 방법이다

 

\[\rho[X, Y] = \frac{\sigma[X, Y]}{\sigma[X]\sigma[Y]}\]

  • Requirements : \(\sigma[X, Y] = \rho[X, Y]\sigma[X]\sigma[Y]\)
    이 요구 조건은 두 변수 간의 공분산이 상관 계수와 두 변수의 표준 편차의 곱과 같아야 한다는 것을 의미한다. 이는 두 변수 간의 선형 관계를 나타내는 중요한 수식이다
  • 많은 금융 관계가 비선형적이기 때문에 상관관계가 이를 인식하지 못한다
  • 이상치에 크게 영향을 받아 결과가 왜곡될 수 있다.
  • 상관관계는 다변량 정규 분포를 벗어나면 의미가 없을 수 있다

 


NON-LINEAR generalization of Pearson's Correlation

  • Maximal Correlation
    \[
    \rho_{\text{max}}[X, Y] = \sup_{f:X \rightarrow \mathbb{R}, g:Y \rightarrow \mathbb{R}} \mathbb{E}[f(X)g(Y)]
    \]
    • \( 0 \leq \rho_{\text{max}}[X, Y] \leq 1\) : 상관관계 값은 0에서 1 사이\(\rho_{\text{max}}[X, Y] = 0\) 이면 \(X\)와 \(Y\)는 독립이다
    • \(\rho_{\text{max}}[X, Y] = 1\) 이면, \(f(X) = g(Y)\)를 만족하는 함수가 존재한다.
    • \(X\)와 \(Y\)가 가우시안일때 \(\rho_{\text{max}}[X, Y] = |\rho[X, Y]|\)이다  즉  피어슨 상관관계의 절대값 동일하다

이 방법의 단점은 계산 비용이 상대적으로 높다는 것이다. 최대 상관을 찾기 위해 Alternating Conditional Expectations (ACE) 알고리즘을 사용할 수 있다

import numpy as np
from ace import model  # https://pypi.org/project/ace/

def max_correlation(x: np.array, y: np.array) -> float:
    # Get max correlation using ace package
    # https://mlfinlab.readthedocs.io/en/latest/implementations/codependence.html
    ace_model = model.Model()
    ace_model.build_model_from_xy([x], y)
    return np.corrcoef(ace_model.ace.x_transforms[0], ace_model.ace.y_transform)[0][1]

 

  • Distance Correlation
    \[
    \rho_{\text{dist}}[X, Y] = \frac{dCov[X, Y]}{\sqrt{dCov[X, X] dCov[Y, Y]}}
    \]
    - \(dCov[X, Y]\) 는   \(X\)와 \(Y\)d의 doubly-centered Euclidean distance matrices의 average Hadamard product 다
    • \( 0 \leq \rho_{\text{dist}}[X, Y] \leq 1\) 상관관계 값은 0에서 1사이
    • \(\rho_{\text{dist}}[X, Y] = 0\) 이면 \(X\)와 \(Y\)는 독립이다

import numpy as np, copy
from scipy.spatial.distance import pdist, squareform

def distcorr(Xval, Yval, pval=True, nruns=500):
    # https://gist.github.com/wladston/c931b1495184fbb99bec
    X, Y = np.atleast_1d(Xval), np.atleast_1d(Yval)
    if np.prod(X.shape) == len(X): X = X[:, None]
    if np.prod(Y.shape) == len(Y): Y = Y[:, None]
    X, Y = np.atleast_2d(X), np.atleast_2d(Y)
    n = X.shape[0]
    if Y.shape[0] != X.shape[0]: raise ValueError('Number of samples must match')
    a, b = squareform(pdist(X)), squareform(pdist(Y))
    A = a - a.mean(axis=0)[None, :] - a.mean(axis=1)[:, None] + a.mean()
    B = b - b.mean(axis=0)[None, :] - b.mean(axis=1)[:, None] + b.mean()
    dcov2_xy = (A * B).sum() / float(n * n)
    dcov2_xx = (A * A).sum() / float(n * n)
    dcov2_yy = (B * B).sum() / float(n * n)
    dcor = np.sqrt(dcov2_xy) / np.sqrt(np.sqrt(dcov2_xx) * np.sqrt(dcov2_yy))
    if pval:
        greater = 0
        for i in range(nruns):
            Y_r = copy.copy(Yval)
            np.random.shuffle(Y_r)
            if distcorr(Xval, Y_r, pval=False) > dcor:
                greater += 1
        return (dcor, greater / float(nruns))
    else:
        return dcor

 

 

 

 

 

 

https://papers.ssrn.com/sol3/papers.cfm?abstract_id=3512994