pythonで相関関係と共分散を求めてみる。

数学

相関関係とは2種類のデータの関連性を示す指標であり、例えばAとBの間に何らかの関連性があるとき、AとBは相関関係にあるといえるでしょう。

例えば、Aが増加するときBも増加する場合はAとBの間に正の相関関係があり、Aが増加するときBが減少すればAとBの間には負の相関関係があるといえます。

この記事はこんな人におすすめ。

  • 共分散の求め方を知りたい。
  • 相関係数の求め方を知りたい。

プログラミング無料体験はこちら↓↓↓


Python で共分散を求めてみよう

あらかじめデータセットをexcelで用意しておきましたので、それを使って共分散を求めてみましょう。

ちなみに、共分散の公式は以下になります。

まず、分析用のライブラリpandasと数値計算モジュールnumpy をインポート。

次に、分析用のデータ読み込みを行います。

import pandas as pd #データ解析用ライブラリのインポート
import numpy as np # 数値計算モジュールのインポート
stats_work = pd.read_excel("stats_work.xlsx") # excelデータ読み込み
stats_work

読み込みました。

しかしこの表では、後々頭痛の種になるインデックス番号が入っているので「.set_index()」を使って、インデックスを新たに設定する必要があります。

stats_work_NID = stats_work.set_index("学生") # 学生をインデックスに使用
stats_work_NID

次に、データを分析しやすいように「.T」を使って、DataFrameを反転させます。

stats_work_t = stats_work_NID.T
stats_work_t

共分散の計算手順

共分散を求める手順は、

  1. 変数を定義する
  2. サンプルのサイズを求める
  3. 平均値を計算する
  4. 各データのxの偏差とyの偏差の積を求め、それをデータの総数で割る

という順番になります。

プログラムで書くと以下の通り。

# 変数を定義する
x = stats_work_t["数学"]
y = stats_work_t["英語"]

# サンプルサイズを求める
N = len(stats_work_t)

# 平均値の計算
mu_x = np.mean(x)
mu_y = np.mean(y)

# 各データのxの偏差とyの偏差の積を求め、それをデータの総数で割る
cov_stats_work = sum((x-mu_x)*(y-mu_y))/N

一つずつ分解してみていきます。

まずは x (数学)の変数を定義します。

x = stats_work_t["数学"]
x
1     53
2     74
3     60
4     67
5     53
6     53
7     40
8     53
9     60
10    87
Name: 数学, dtype: int64

次に y (英語)の変数を定義します。

y = stats_work_t["英語"]
y
1     79
2     95
3     69
4     79
5     61
6     89
7     52
8     55
9     73
10    88
Name: 英語, dtype: int64

つぎにデータの個数を数えます。

N = len(stats_work_t)
N
10

x (数学)の平均値を計算する。

mu_x = np.mean(x)
mu_x
60.0

y (英語)の平均値を計算する。

mu_x = np.mean(x)
mu_x
60.0

次に、各データのxの偏差とyの偏差の積を求め、それをデータの総数で割ると、共分散が求められます。

cov_stats_work = sum((x-mu_x)*(y-mu_y))/N
cov_stats_work
123.1

このデータの共分散は123.1。

共分散が正の値の場合、「xが大きいときyも大きい傾向」にあり、反対に負の値の場合は「xが大きいときyは小さい傾向にある」ことを意味します。

つまり、共分散が123.1の場合、数学の点数が高い場合英語の点数も高い傾向があるといえますね。

ついでに、不偏共分散を求めてみましょう。

自由度を1に設定し不偏共分散を求めると、値は122.1。

cov_stats_work_UB = sum((x-mu_x)*(y-mu_y))/N-1
cov_stats_work_UB
122.1

標本共分散よりは低い値になりました。

しかしこれでは、数学と英語の関係性はわかっても関係性の強さまではわかりません。

そこで登場するのが、相関関係です。

ピアソンの相関関係

相関関係は、xとyの直線的な相関関係の強さを示す値です。

共分散でも二つの値の関係性はわかりますが、共分散の値が大きいとき関係性が強いから値が大きいのか、または単純に単位の問題によって値が大きくなっているのかが判別できないのです。

そこで、二つのデータの関係性の強さを1から-1の間で表した値が相関係数といいます。

求め方はxとyの共分散をxとyの標準偏差の積で割ったで、公式は以下のようになっています。

では一行ずつ実装してみます。

まず、xの標準偏差を求めます。

sigma_2_x = np.std(x, ddof = 0)
sigma_2_x
12.529964086141668

つぎにyの標準偏差を求めます。

sigma_2_y = np.syd(y, ddof = 0)
sigma_2_y
13.971399357258385

xとyの共分散を、xの標準偏差とyの標準偏差の積で割ると相関係数が求められます。

rho = cov_stats_work / (sigma_2_x * sigma_2_y)
rho
0.7031829308273588

相関係数0.703なので、数学の成績と英語の成績の間には正の相関関係があると考えられます。

では、不偏共分散と不偏標準偏差を用いて、計算してみましょう。

sigma_2_UB_x = np.std(x, ddof = 1)
sigma_2_UB_y = np.std(y, ddof = 1)
rho = cov_stats_work_UB /(sigma_2_UB_x * sigma_2_UB_y)
rho
0.627723576511929

値は0.627と、標本共分散や標本標準偏差を使った場合よりは低い値になりましたが、それでも数学と英語に正の相関関係があることがわかります。

ではその相関関係をグラフで見てみましょう。

import matplotlib.pyplot as plt 
x = stats_work_t["数学"]
y = stats_work_t["英語"]
plt.scatter(x, y) # 散布図を描く
kijyunsen = np.polyfit(x,y,1) # 線形近似して切片と傾きを求める
func = np.poly1d(kijyunsen) # kijyunsenで求めた切片と傾きから一次式y=ax+bを求める
y2 = func(x) 
plt.plot(x, y2)
a = np.corrcoef(x, y)[0][1] # 一行目と2行目を取り出す

plt.show()

上のコードを実行することで、下のような散布図を描くことができます。

つまり数学が高得点であるほど、英語の点数も高いといえます。

プログラミング無料体験はこちら↓↓↓


コメント

タイトルとURLをコピーしました