目次
1. 実験の紹介
この実験では主に相関分析用のカスタム ピアソン相関係数を実装します。
相関分析は、2 つ以上の変数間の関連度を 評価するために使用される一般的な統計手法です。この実験では、ピアソン相関係数とスピアマン相関係数という 2 つの一般的な相関指標を使用しました。ピアソン相関係数は 2 つの連続変数間の線形関係を測定するために使用されますが、スピアマン相関係数は、線形であるかどうかに関係なく、2 つの変数間の単調な関係を評価するのに適しています。
2. 実験環境
この一連の実験では PyTorch 深層学習フレームワークを使用し、関連する操作は次のとおりです (深層学習シリーズの記事の環境に基づく)。
1. 仮想環境を構成する
ディープラーニング連載記事の環境
conda create -n DL python=3.7
conda activate DL
pip install torch==1.8.1+cu102 torchvision==0.9.1+cu102 torchaudio==0.8.1 -f https://download.pytorch.org/whl/torch_stable.html
conda install matplotlib
conda install scikit-learn
新規追加
conda install pandas
conda install seaborn
conda install networkx
conda install statsmodels
pip install pyHSICLasso
注:私の実験環境では上記の順番で各種ライブラリをインストールしていますので、まとめてインストールしてみたい方は試してみてください(問題が起こるかどうかは神のみぞ知る)
2. ライブラリバージョンの紹介
ソフトウェアパッケージ | 今回の実験版は | 現在の最新バージョン |
マットプロットライブラリ | 3.5.3 | 3.8.0 |
しこり | 1.21.6 | 1.26.0 |
パイソン | 3.7.16 | |
scikit-learn | 0.22.1 | 1.3.0 |
松明 | 1.8.1+cu102 | 2.0.1 |
トーショーディオ | 0.8.1 | 2.0.2 |
トーチビジョン | 0.9.1+cu102 | 0.15.2 |
新しい
ネットワークx | 2.6.3 | 3.1 |
パンダ | 1.2.3 | 2.1.1 |
pyHSICLase | 1.4.2 | 1.4.2 |
シーボーン | 0.12.2 | 0.13.0 |
状態モデル | 0.13.5 | 0.14.0 |
3.IDE
Pycharmの使用を推奨します(中でもpyHSICLassoライブラリはVScodeでエラーが発生しており、解決策はまだ見つかっていません...)
3. 実験内容
0. 必要なツールをインポートする
import numpy as np
from scipy import stats
import matplotlib.pyplot as plt
1. cal_pearson (ピアソン相関係数を計算)
def cal_pearson(x, y):
n = len(x)
mean_x = np.mean(x)
mean_y = np.mean(y)
x_ = x - mean_x
y_ = y - mean_y
s_x = np.sqrt(np.sum(x_ * x_))
s_y = np.sqrt(np.sum(y_ * y_))
r = np.sum((x_ / s_x) * (y_ / s_y))
t = r / np.sqrt((1 - r * r) / (n - 2)) # p值需要对t值进行查表获得
return r
-
変数 x の長さ、つまりサンプル数を計算します。
-
変数 x と y の平均を計算します。
-
変数 x、y の標準偏差を計算します。
-
x_ と y_ の対応する位置の値を除算し、乗算して合計することにより、ピアソン相関係数 r を計算します。
-
r の値を sqrt((1 - r^2) / (n - 2)) で割ることにより、t 値を計算します。ここで、n - 2 は、t 値に対するサンプル サイズの影響を補正するために使用される補正係数です。
-
計算されたピアソン相関係数 r を返します。
2. メインプログラム
a. 実験 1 (強い正の相関):
x1 = np.random.random(100)
y1 = np.random.random(100) + x1
plt.scatter(x1, y1, marker='.')
plt.show()
pearson1, p1 = stats.pearsonr(x1, y1)
r1 = cal_pearson(x1, y1)
print(pearson1)
print(r1)
print()
- 長さ 100 の 2 つのランダム配列 x1 および y1 を生成します。ここで、y1 は x1 にランダム ノイズを加えたものに基づいています。
- x1 と y1 の散布図を描きます。
scipy.stats.pearsonr
x1 と y1 のピアソン相関係数と p 値は、次の関数を使用して計算されました。- カスタム関数を使用して
cal_pearson
同じ相関係数を計算しました。
0.6991720710419989
0.6991720710419991
b. 実験 2 (線形相関はほとんどなし):
x2 = np.random.random(100)
y2 = np.random.random(100)
plt.scatter(x2, y2, marker='.')
plt.show()
pearson2, p2 = stats.pearsonr(x2, y2)
r2 = cal_pearson(x2, y2)
print(pearson2)
print(r2)
print()
長さ 100 の 2 つのランダム配列 x2 と y2 が、ノイズを追加せずに生成されました。散布図もプロットされ、ピアソン相関係数が個別に計算されました。
-0.11511730616773974
-0.11511730616773967
c. 実験 3 (非常に強い正の相関):
長さ 100 の 2 つのランダム配列 x3 と y3 が生成されます。ここで、y3 には、x3 に基づいてより大きなランダム ノイズが追加されます。散布図もプロットされ、ピアソン相関係数が個別に計算されました。
x3 = np.random.random(100)
y3 = np.random.random(100) + x3 * 50
plt.scatter(x3, y3, marker='.')
plt.show()
pearson3, p3 = stats.pearsonr(x3, y3)
r3 = cal_pearson(x3, y3)
print(pearson3)
print(r3)
print()
d. 実験 4 (スピアマン相関係数行列):
(10, 10) の形状を持つランダム配列データを生成し、scipy.stats.spearmanr
関数を使用してデータの各列間のスピアマン相関係数と p 値を計算し、結果を出力しました。
data = np.random.random((10, 10))
spearman_np, p_np = stats.spearmanr(data)
print(spearman_np, p_np)
3. コードの統合
import numpy as np
from scipy import stats
import matplotlib.pyplot as plt
def cal_pearson(x, y):
n = len(x)
mean_x = np.mean(x)
mean_y = np.mean(y)
x_ = x - mean_x
y_ = y - mean_y
s_x = np.sqrt(np.sum(x_ * x_))
s_y = np.sqrt(np.sum(y_ * y_))
r = np.sum((x_ / s_x) * (y_ / s_y))
t = r / np.sqrt((1 - r * r) / (n - 2)) # p值需要对t值进行查表获得
return r
if __name__ == '__main__':
np.random.seed(0)
x1 = np.random.random(100)
y1 = np.random.random(100) + x1
plt.scatter(x1, y1, marker='.')
plt.show()
pearson1, p1 = stats.pearsonr(x1, y1)
r1 = cal_pearson(x1, y1)
print(pearson1)
print(r1)
print()
x2 = np.random.random(100)
y2 = np.random.random(100)
plt.scatter(x2, y2, marker='.')
plt.show()
pearson2, p2 = stats.pearsonr(x2, y2)
r2 = cal_pearson(x2, y2)
print(pearson2)
print(r2)
print()
x3 = np.random.random(100)
y3 = np.random.random(100) + x3 * 50
plt.scatter(x3, y3, marker='.')
plt.show()
pearson3, p3 = stats.pearsonr(x3, y3)
r3 = cal_pearson(x3, y3)
print(pearson3)
print(r3)
print()
data = np.random.random((10, 10))
spearman_np, p_np = stats.spearmanr(data)
print(spearman_np, p_np)