Skip to article frontmatterSkip to article content
Site not loading correctly?

This may be due to an incorrect BASE_URL configuration. See the MyST Documentation for reference.

Chatterjee’s \xi

概要

Chatterjee (2021) によって提案された ξ(xi)相関係数 は、

  • あらゆる形の依存関係(線形・非線形)に対して感度が高い

  • ノンパラメトリックで順位に基づく

  • XX の分布に依存しない(一様性の仮定が不要)

  • 計算量が O(nlogn)O(n \log n) と高速(先行研究のMICは遅い)

という特徴を持つ新しい相関係数である。

目的は、「YYXX にどれだけ依存しているか」を測ることであり、特に回帰関係一般に対する依存度測定として利用できる。

アルゴリズム

(X,Y)(X, Y)を確率変数のペアとし、n2n\geq 2のiidな標本があるとする。

Step 1. データの並び替え

データ (X(1),Y(1)),,(X(n),Y(n))(X_{(1)}, Y_{(1)}), \ldots,(X_{(n)}, Y_{(n)})XX で昇順 X(1)X(n)X_{(1)} \leq \cdots \leq X_{(n)} に並べ替える。

同値がいれば一様にランダムに選ぶ。

Step 2. 相関係数ξn\xi_nを計算する

Y(j)Y(i)Y_{(j)} \leq Y_{(i)}jj、すなわちY(i)Y_{(i)}の順位をrir_iとする。
Y(j)Y(i)Y_{(j)} \geq Y_{(i)}jj、すなわちY(i)Y_{(i)}の逆順位をlil_iとする。

同順位がいない場合:

ξn(X,Y):=13i=1n1ri+1rin21\xi_n(X, Y):=1-\frac{3 \sum_{i=1}^{n-1}\left|r_{i+1}-r_i\right|}{n^2-1}

同順位がいる場合:

ξn(X,Y):=1ni=1n1ri+1ri2i=1nli(nli)\xi_n(X, Y):=1-\frac{n \sum_{i=1}^{n-1}\left|r_{i+1}-r_i\right|}{2 \sum_{i=1}^n l_i\left(n-l_i\right)}

性質

Y=f(X)Y = f(X) という関係のとき ξ(X,Y)=1\xi(X, Y) = 1 になる」という性質・コンセプトが他の相関係数とは異なる。

実装

scipyに実装されている

chatterjeexi — SciPy v1.16.2 Manual

from scipy.stats import chatterjee
xi = chatterjee(x, y)
import numpy as np
from scipy.stats import rankdata

def chatterjee_xi(x, y):
    """
    Compute Chatterjee (2021) xi correlation.
    """
    x = np.asarray(x)
    y = np.asarray(y)
    n = x.size

    # --- Step 1: Sort pairs by X (X(1),...,X(n)) ---
    idx = np.argsort(x)
    y_sorted = y[idx]

    # --- Step 2: r_i, l_i (rank and reverse rank of Y(i)) ---
    r = rankdata(y_sorted, method="max")      # r_i = rank(Y(i))
    l = rankdata(-y_sorted, method="max")     # l_i = reverse rank = rank(-Y(i))

    # --- Step 3: num = Σ|r_{i+1} - r_i| ---
    num = np.sum(np.abs(np.diff(r)))

    # --- Step 4: xi_n ---
    has_tie = all(x != np.unique(x)) or all(y != np.unique(y))
    if has_tie:
        den = np.sum((n - l) * l)
        xi = 1 - n * num / (2 * den)
    else:
        xi = 1 - 3 * num / (n**2 - 1)
    return xi
Source
import numpy as np
import matplotlib.pyplot as plt
fig, axes = plt.subplots(figsize=[10, 2.5], ncols=3)

true_r = 0
mu = np.array([0.0, 0.0])
Sigma = np.array([[1.0, true_r], [true_r, 1.0]])
samples = np.random.multivariate_normal(mu, Sigma, size=100)
x = samples[:, 0]
y = samples[:, 1]
axes[0].scatter(x, y)
axes[0].set_title(f"Chatterjee's xi = {chatterjee_xi(x, y):.3f}")

x = np.linspace(-10, 10, 15)
y = 1 / (1 + np.exp(-x))
axes[1].scatter(x, y)
axes[1].set_title(f"Chatterjee's xi = {chatterjee_xi(x, y):.3f}")

x = np.linspace(-3.14,3.14, 100)
y = x**2 + np.random.random(len(x))
axes[2].scatter(x, y)
axes[2].set_title(f"Chatterjee's xi = {chatterjee_xi(x, y):.3f}")

%matplotlib inline
<Figure size 1000x250 with 3 Axes>

参考

References
  1. Chatterjee, S. (2020). A New Coefficient of Correlation. Journal of the American Statistical Association, 116(536), 2009–2022. 10.1080/01621459.2020.1758115