Py) 통계 - 상관분석

Py) 통계 - 상관분석

두 변수간의 선형관계. 즉, 선형성(linearity)을 알아보는 상관분석에 대해 알아보자.


Statistics

bike.csv 다운받기 [클릭]


개요

상관분석은 두 변수간 선형 관계(linear relationship, 직선적 관계)가 존재하는지, 존재하면 얼마나 강한지 알아보는 알아보는 분석 기법이다. 상관분석을 한다고 하면 보통 피어슨 상관계수(Pearson’s Correlation Coefficient)를 떠올린다. 하지만 피어슨 상관계수 말고도 어떤 속성의 자료간 비교가 이루어지는가에 따라서 알맞는 분석 기법을 선택해야 한다. 다음의 표를 참고하도록 하자.

Quantitiative Ordinal Nominal
Quantitiative Pearson's Biserial Point Biserial
Ordinal Biserial Spearman/Kendall Rank Biserial
Nominal Point Biserial Rank Biserial Phi, L, C Lambda

상관계수의 값에 따른 두 연속형 변수의 대략적인 분포는 다음과 같다. 모양이 직선에 가까울수록 1 또는 -1에 가까워짐을 알 수 있다.

상관계수 예시
※ 출처: https://en.wikipedia.org/wiki/Pearson_correlation_coefficient

※ 각 분포마다 상관계수가 적혀있지만 가운데에 상관계수가 적히지 않은 이유는 y의 변화가 0이기 때문에 피어슨 상관계수를 계산할 때 사용하는 공분산과 y표준편차가 0이기 때문이다.

Pearson’s Correlation

정식 명칭은 피어슨의 곱적률 상관(Pearson’s product-moment correlation)은 두 변수의 선형 관계가 존재할 경우 그 관계가 얼마나 강한지 알 수 있는 값이며 두 변수가 연속형 양적 변수일 경우에 사용가능한 방법이다. 상관계수는 공분산으로 부터 유도되며, 이를 제곱하는 경우 단순선형회귀의 결정계수와 같다. 그리고 상관계수의 값 범위는 -1 에서 1사이 이며 부호가 양수인 경우 “양의 상관 관계” 음수인 경우 “음의 상관 관계” 라고 한다.

이론

피어슨 상관계수는 다음과 같이 계산한다.

$$r = \frac{COV(X, Y)}{\sigma_x \times \sigma_y} = \frac{\sum{(x_i - \bar{x})(y_i - \bar{y})}}{\sqrt{\sum{(x_i - \bar{x})^2}} \times \sqrt{\sum{(y_i - \bar{y})^2}}}$$

검정통계량 t는 다음과 같이 계산한다.

$$t = \frac{r\sqrt{n - 2}}{\sqrt{1 - r^2}}$$

p-value는 $2 \times P(T>t)$로 계산하며 여기서 T는 자유도가 n – 2인 t 분포를 따른다.

가설

● 귀무가설($𝐻_0$): 두 변수간 선형관계가 존재하지 않는다. (r = 0)
● 대립가설($𝐻_1$): 두 변수간 선형관계가 존재한다. (r ≠ 0)


Spearman’s Correlation

스피어만 상관분석은 두 변수가 순서형 변수일 경우에 사용가능한 방법이며 두 변수가 정규성을 따르지 않는 경우에도 사용할 수 있는 비모수적 방법이다. 상관계수는 각 변수의 순위를 매긴 후 그 순위의 차를 활용하여 계산한다. 그리고 상관계수의 값 범위는 -1 에서 1사이 이며 부호가 양수인 경우 “양의 상관 관계” 음수인 경우 “음의 상관 관계” 라고 한다.

이론

스피어만 상관계수는 다음과 같이 계산한다.

$$\rho = 1 - \frac{6\sum{d_i ^2}}{n^3 - n}$$

검정통계량 t는 다음과 같이 계산한다.

$$t = \frac{\rho\sqrt{n - 2}}{\sqrt{1 - \rho^2}}$$

가설

● 귀무가설($𝐻_0$): 두 변수간 선형관계가 존재하지 않는다. (rho = 0)
● 대립가설($𝐻_1$): 두 변수간 선형관계가 존재한다. (rho ≠ 0)


Kendall Correlation

상관분석은 두 변수가 순서형 변수일 경우에 사용가능한 방법이며 두 변수가 정규성을 따르지 않는 경우에도 사용할 수 있는 비모수적 방법이다. 그리고 상관계수의 값 범위는 -1 에서 1사이 이며 부호가 양수인 경우 “양의 상관 관계” 음수인 경우 “음의 상관 관계” 라고 한다.

이론

켄달 상관계수는 다음과 같이 계산한다.

$$\tau_A = \frac{n_c - n_d}{n_0}, \, \tau_B = \frac{n_c - n_d}{\sqrt{(n_0 - n_1)(n_0 - n_2)}}$$
$$ \begin{align} n_0 &= n(n - 1)/2\\ n_1 &= \sum{t_i(t_i - 1)/2}\\ n_2 &= \sum{u_j(u_j - 1)/2}\\ n_c &= Number\,of\,concordant\,pairs\\ n_d &= Number\,of\,discordant\,pairs\\ t_i &= Number\,of\,tied\,values\,in\,the\,i^th\,group\,of\,ties\,for\,the\,first\,quantity\\ u_j &= Number\,of\,tied\,values\,in\,the\,j^th\,group\,of\,ties\,for\,the\,second\,quantity\\ \end{align} $$
$$\tau_C = \frac{2(n_c - n_d)}{n^2 \frac{m - 1}{m}}$$
$$ \begin{align} n_c &= Number\,of\,concordant\,pairs\\ n_d &= Number\,of\,discordant\,pairs\\ r &= Number\,of\,rows\\ c &= Number\,of\,columns\\ m &= min(r,c)\\ \end{align} $$

검정통계량 z는 다음과 같이 계산한다.

$$z_A = \frac{3(n_c - n_d)}{\sqrt{n(n - 1)(2n + 5) / 2}}, \, z_B = \frac{n_c - n_d}{\sqrt{v }}$$
$$ \begin{align} v &= (v_0 - v_t - v_u)/18 + v_1 + v_2\\ v_0 &= n(n - 1)(2n + 5)\\ v_t &= \sum{t_i(t_i - 1)(2t_i + 5)}\\ v_u &= \sum{u_j(u_j - 1)(2u_j + 5)}\\ v_1 &= \sum{t_i(t_i - 1)}\sum{u_j(u_j - 1)/2n(n - 1)}\\ v_2 &= \sum{t_i(t_i - 1)(t_i - 2)}\sum{u_j(u_j - 1)(u_j - 2)}/(9n(n - 1)(n - 2))\\ \end{align} $$

가설

● 귀무가설($𝐻_0$): 두 변수간 선형관계가 존재하지 않는다. (tau = 0)
● 대립가설($𝐻_1$): 두 변수간 선형관계가 존재한다. (tau ≠ 0)


실습

데이터 준비

“bike.csv” 데이터를 읽어오자
※ 게시물 상단에서 다운로드 받을 수 있다.

1
2
3
df = pd.read_csv("bike.csv")
df = df.iloc[:, 4:].copy()
df.head(2)
weather temp atemp humidity windspeed casual registered count
0 1 9.84 14.395 81 0.0 3 13 16
1 1 9.02 13.635 80 0.0 8 32 40

Pandas

간단하게 상관계수를 확인하려면 데이터프레임 객체의 .corr() 메서드를 쓸 수 있다.

1
df[["temp", "atemp"]].corr()
temp atemp
temp 1.000000 0.984948
atemp 0.984948 1.000000

기온(temp)과 체감온도(atemp)는 매우 높은 양의 상관관계가 있다는 것을 알 수 있다. 그리고 기본적으로 계산되는 상관계수는 피어슨 상관계수이다. .corr() 메서드는 총 세 종류의 상관분석을 지원하는데 피어슨 상관계수가 기본값이며 “Kendall” 또는 “Spearman”을 “method” 인자에 할당하면 캔달 또는 스피어만 상관분석을 실시할 수 있다.
순서형 데이터로 간주할 수 있는 날씨(weather) 변수와 상대습도(humidity) 변수를 대상으로 순위 상관분석을 실시하고 그 상관계수를 확인하는 코드는 다음과 같다.

1
df[["weather", "humidity"]].corr(method = "kendall")
weather humidity
weather 1.000000 0.324066
humidity 0.324066 1.000000
1
df[["weather", "humidity"]].corr(method = "spearman")
weather humidity
weather 1.000000 0.399492
humidity 0.399492 1.000000

그리고 여러 변수를 한 번에 넣게되면 상기 결과와 마찬가지로 상관계수 행렬을 데이터프레임 객체로 산출해주며 이 결과를 활용하여 향후 상관계수행렬도(correlation coefficient plot)를 그리는데 활용할 수 있다.

1
df.corr().round(2)
weather temp atemp humidity windspeed casual registered count
weather 1.00 -0.06 -0.06 0.41 0.01 -0.14 -0.11 -0.13
temp -0.06 1.00 0.98 -0.06 -0.02 0.47 0.32 0.39
atemp -0.06 0.98 1.00 -0.04 -0.06 0.46 0.31 0.39
humidity 0.41 -0.06 -0.04 1.00 -0.32 -0.35 -0.27 -0.32
windspeed 0.01 -0.02 -0.06 -0.32 1.00 0.09 0.09 0.10
casual -0.14 0.47 0.46 -0.35 0.09 1.00 0.50 0.69
registered -0.11 0.32 0.31 -0.27 0.09 0.50 1.00 0.97
count -0.13 0.39 0.39 -0.32 0.10 0.69 0.97 1.00

그런데 두 변수만 상관분석을 실시하는 경우 필요한 값은 하나인데 데이터프레임으로 반환되는게 번거롭고 불편하다면 다음과 같이 시리즈 객체와 .corr() 함수의 “other” 인자를 사용할 수 있다.

1
2
df["temp"].corr(other = df["atemp"])
## 0.9849481104817077

scipy

단순히 상관계수를 산출하는 것이 아닌 가설검정을 하여 제대로 p-value까지 확인하고싶다면 scipy 라이브러리의 함수를 사용할 수 있다. 피어슨, 스피어만, 켄달 상관분석을 실시하고 싶다면 다음과 같이 pearsonr(), spearmanr(), kendalltau() 함수를 불러와 사용할 수 있다.

1
2
3
from scipy.stats import pearsonr
from scipy.stats import spearmanr
from scipy.stats import kendalltau

각 함수의 사용법은 같으니 pearsonr() 함수만 알아보도록 한다.

1
2
pearsonr(df["temp"], df["atemp"])
## PearsonRResult(statistic=0.9849481104817074, pvalue=0.0)

여기서 p-value가 매우 작아 0으로 표기되었다. 이는 유의수준 5%로 검정할 경우 귀무가설을 기각하고 대립가설을 채택하여 산출된 피어슨 상관계수 0.9849481이 유의미하다고 할 수 있다.

만약 상관계수와 p-value를 별도의 객체로 저장하고자 한다면 다음과 같이 코드를 작성할 수 있다.

1
2
3
stat, p = pearsonr(df["temp"], df["atemp"])
stat, p
## (0.9849481104817074, 0.0)
Your browser is out-of-date!

Update your browser to view this website correctly. Update my browser now

×