오늘은 기초 통계 시간에 단골 손님인 상관계수에 대한 개념을 완벽하게 정리해보도록 하겠습니다. 이번 포스팅에서는 상관계수란 무엇인지, 상관계수와 공분산의 관계, 상관계수 계산 공식과 숨어있는 의미를 이해해 보겠습니다.
상관계수 (Correlation coefficient) 란?
상관 계수correlation coefficient란 통계학에서 자주 등장하는 개념으로, 두 변수 간의 선형 관계의 강도와 방향을 나타내는 값입니다. 보통 그리스 기호 \rho을 사용하여 나타내며, 값은 -1에서 1 사이의 값을 가지며, -1에 가까울 수록 두 변수가 음의 상관관계를, 1에 가까울 수록 두 변수가 양의 상관관계를 갖는다는 것을 의미합니다. 0은 두 변수 간에 선형 관계가 없음을 의미합니다.
상관계수의 정의
상관계수는 여러가지 종류가 있지만, 보통 다음과 같이 피어슨(Pearson)이 정의한 상관계수를 의미합니다. 두 확률 변수 X와 Y에 대하여 상관계수 \rho_{X,Y} 는 다음과 같이 정의합니다.
위 식의 각 기호는 다음과 같은 의미를 가지고 있습니다.
- \rho_{X,Y} 는 두 변수 X와 Y 사이의 피어슨 상관계수를 의미합니다.
- \text{corr}(X,Y)는 X와 Y의 상관계수를 의미합니다.
- \text{cov}(X,Y)는 X와 Y의 공분산을 의미합니다.
- \sigma_X 와 \sigma_Y 는 각각 X와 Y의 표준편차를 의미합니다.
- \mu_X 와 \mu_Y 는 X와 Y의 평균을 의미합니다.
- E는 기대값(평균)을 의미합니다.
즉, 상관계수라고 하는 것은 기초 통계 시간에 배우는 모평균, 모분산과 같이 굳이 붙이자면, 모상관계수라고 부를 수 있겠습니다. 이 값은 보통 알 수 없죠. 그래서 우리는 주어진 표본들을 사용해서 이 값을 추정합니다.
(표본) 피어슨 상관계수 공식
두 쌍으로 이루어진 표본 n개를 사용해서 상관계수 \rho_{X,Y}를 추정 할 때 사용되는 표본 상관계수의 공식은 다음과 같습니다.
위 식의 각 기호는 다음과 같은 의미를 가지고 있습니다.
- x_i와 y_i는 각각의 관측값입니다.
- \bar{x}와 \bar{y}는 각 변수의 평균값입니다.
- s_x와 s_y는 각각 x와 y의 표준편차입니다.
- n은 관측값의 총 수입니다.
첫번째 줄 수식에서 분자는 두 변수의 표본 공분산을 나타내며, 분모는 두 변수의 표본 표준편차의 곱을 나타내고 있습니다.
공분산과 상관계수의 관계
앞에서 살펴본 식에서도 알 수 있듯, 공분산과 상관계수는 밀접한 관계가 있습니다. 고려대학교 통계학과 송성주 교수님이 쓴 수리통계학 책에 두 통계량 사이의 관계가 잘 나와있습니다.
즉, 상관계수는 공분산의 단점을 보완한 두 확률변수의 퍼짐 관계를 측정하는 지표인 것이죠.
피어슨 상관계수 해석과 의미
상관계수는 -1에서 1 사이의 값을 가집니다. -1과 1사이의 값을 사용해서 두 변수의 퍼짐에 대한 선형적인 강도와 뱡향을 나타내죠. 선형성을 나타내는 선형적인 강도와 뱡향은 상관계수의 절대값과 부호를 사용해서 알아낼 수 있습니다.
- 강도: 상관계수 절대값
- 방향: 상관계수 부호
다음의 그림은 두 변수에서 관찰된 순서쌍 표본들의 분포와 이것들을 사용하여 계산한 표본 상관계수 값을 나타낸 그림입니다.
두 변수 X와 Y가 상관계수 값이 -0.99에서 0.99로 변해감에 따라서 선형적인 관계가 강해졌다가 약해졌다가 다시 강해집니다. 상관계수 r 값에 따라서 다음과 같은 패턴을 보입니다.
- r이 0에 가까우면: 두 변수 사이에는 거의 선형 발생 패턴이 없습니다. 즉, 한 변수의 값이 큰 값이 나오거나 작은 값이 나와도, 다른 변수의 값에는 영향을 주지 않습니다.
- 양의 r 값: 두 변수가 함께 큰 값이 나오는 경향이 있습니다. 예를 들어, r이 0.7이면 한 변수의 값이 크게 나온다면 다른 변수의 값도 크게나오는 경향이 있다는 것을 의미합니다.
- 음의 r 값: 한 변수의 값이 크게 나왔을 때 다른 변수의 값은 작게 나오는 경향이 있습니다. 예를 들어, r이 -0.7이면 한 변수가 큰 값을 가진다면 다른 변수의 값은 작은 값을 경향이 있습니다.
- r 값이 1 또는 -1일 때: 이는 “완벽한” 상관관계를 의미합니다. 두 변수는 일정한 비율로 함께 증가하거나 감소합니다. 그래프에 그렸을 때 모든 데이터 포인트가 직선 위에 위치하게 됩니다.
정리하면, 상관계수의 절대값이 나타내는 상관정도는 ‘두 변수의 관계가 얼마나 직선에 가까운가?’를 나타냅니다. 또한, 상관계수의 부호가 나타내는 방향은 상관된 방향이 우하향 (부호 음수)인지, 우상향 (부호 양수)인지를 나타내는 것이죠. 이러한 것은 다음의 그림을 보면 좀 더 명확하게 이해가 될 것입니다.
피어슨 상관계수 계산 예제
예제 데이터 다운받기
먼저 examscore.csv 파일을 다운로드합니다. 주어진 데이터에는 다음과 같은 30명 학생의 중간고사 기말고사 점수가 들어있습니다.
이 데이터를 사용해서 R과 파이썬에서 각각 피어슨 상관계수 구하는 방법에 대하여 알아보도록 하겠습니다.
상관계수 R에서 계산하기
다음의 코드를 통하여 데이터를 불러옵니다.
library(tidyverse)
mydata <- read_csv("examscore.csv")
위 코드를 실행하면 mydata
라는 데이터 프레임이 생성되고, head()
함수를 통해 데이터의 첫 부분을 확인할 수 있습니다.
head(mydata)
>> # A tibble: 6 × 4
>> student_id gender midterm final
>> <dbl> <chr> <dbl> <dbl>
>> 1 1 F 38 46
>> 2 2 M 42 67
>> 3 3 F 53 56
>> 4 4 M 48 54
>> 5 5 M 46 39
>> 6 6 M 51 74
R에서 상관계수는 cor() 함수를 사용하면 쉽게 계산 할 수 있습니다. 두 변수 midterm과 final 벡터를 선택하여 cor() 함수에 넣어줍니다.
cor(mydatafinal)
>> [1] 0.6770075
상관계수 파이썬에서 계산하기
파이썬에서 피어슨 상관계수를 구하기 위해 pandas
와 scipy.stats
라이브러리를 활용할 수 있습니다.
import pandas as pd
from scipy.stats import pearsonr
# 데이터 불러오기
mydata = pd.read_csv("examscore.csv")
# 피어슨 상관계수 구하기
correlation_coefficient, _ = pearsonr(mydata['midterm'], mydata['final'])
print(correlation_coefficient)
>> 0.6770074859224257
pearsonr
함수는 피어슨 상관계수와 이에 대한 p-값 두 가지 결과값을 반환합니다. 예를 들어,
correlation_coefficient, p_value = pearsonr(mydata['midterm'], mydata['final'])
같이 사용하면, 첫 번째 변수에는 상관계수가, 두 번째 변수에는 p-값이 할당됩니다.
피어슨 상관계수의 직관적 이해
피어슨 상관계수 손으로 직접 계산하기
표본 상관계수 수식을 직관적으로 이해하기 위해서 앞에서 배운 공식을 살짝 다르게 써보도록 하겠습니다.
r_{xy}= \frac{1}{n-1} \sum_{i=1}^{n} \left( \frac{x_i - \bar{x}}{s_x} \right) \left( \frac{y_i - \bar{y}}{s_y} \right)
앞에서 다운받은 중간고사 기말고사 데이터를 사용해서 위의 수식을 그대로 계산해보면 다음과 같이 동일한 상관계수 값이 나오는 것을 확인 할 수 있습니다.
n <- length(mydatamidterm)
y_bar <- mean(mydatamidterm)
s_y <- sd(mydatamidterm - x_bar) / s_x
z_y <- (mydatamidterm, mydata$final, asp = 1,
xlab = "중간고사",
ylab = "기말고사",
main = "시험점수 산점도")
title(sub = paste("상관계수: ", round(my_corr, 4)), adj = 1, col.sub = "red")
abline(v = x_bar)
abline(h = y_bar)
위에서 살펴본 상관계수 식을 뜯어보면, 상관계수는 두 표준화된 점수를 곱한 값을 더해서 나줘주는 것을 알 수 있습니다. 1, 2, 3, 4 사분면에 위치한 점들의 x, y 값을 곱한 값을 생각했을 경우, 1, 3 사분면에 위치한 점들은 양수가, 2, 4 사분면에 위치한 점들은 음수가 나오게 됩니다.
z_x * z_y
>> [1] 0.055356131 0.049164984 0.224095213 0.079635135 -0.207706885
>> [6] 0.830827538 -0.368312500 0.048072429 1.237136681 -0.094566723
>> [11] -0.347432556 0.301302447 1.331096429 0.429010012 0.168374897
>> [16] 0.307979174 -0.139240092 0.619600198 0.274595542 2.085202312
>> [21] 3.577389937 3.697449615 2.083259992 -0.201394343 0.205400379
>> [26] 0.003641851 -0.137540561 0.599691414 2.360890410 0.560238032
sign
함수를 이용하여 이 수들의 부호만 따로 정리를 해보도록 하겠습니다.
sign(z_x * z_y)
>> [1] 1 1 1 1 -1 1 -1 1 1 -1 -1 1 1 1 1 1 -1 1 1 1 1 1 1 -1 1
>> [26] 1 -1 1 1 1
이 부호를 이용하면 다음과 같은 그래프가 완성됩니다.
plot(z_x, z_y, asp = 1,
xlab = "표준 중간고사 점수",
ylab = "표준 기말고사 점수",
main = "중간, 기말고사 표준점수 분포",
col = c("blue", "red")[as.factor(sign(z_x * z_y))])
title(sub = paste("상관계수: ", round(my_corr, 4)), adj = 1, col.sub = "red")
abline(v = 0)
abline(h = 0)
즉, 위의 그래프에서 빨간 점들은 양의 상관관계가 나오는데 기여하는 데이터들이고, 파란 점들은 음의 상관관계가 나오도록 기여하는 점들이라고 생각할 수 있습니다. 하지만, 부호만이 이렇게 상관관계에 영향을 미칠까요? 아닙니다. 한가지 요소가 더 있습니다. 바로 표준 점수들의 곱의 절대값 크기죠!
abs(z_x * z_y)
>> [1] 0.055356131 0.049164984 0.224095213 0.079635135 0.207706885 0.830827538
>> [7] 0.368312500 0.048072429 1.237136681 0.094566723 0.347432556 0.301302447
>> [13] 1.331096429 0.429010012 0.168374897 0.307979174 0.139240092 0.619600198
>> [19] 0.274595542 2.085202312 3.577389937 3.697449615 2.083259992 0.201394343
>> [25] 0.205400379 0.003641851 0.137540561 0.599691414 2.360890410 0.560238032
이 값을 점의 크기로 대체하여 봅시다.
plot(z_x, z_y, asp = 1,
xlab = "표준 중간고사 점수",
ylab = "표준 기말고사 점수",
main = "중간, 기말고사 표준점수 분포",
col = c("blue", "red")[as.factor(sign(z_x * z_y))],
cex = abs(z_x * z_y))
title(sub = paste("상관계수: ", round(my_corr, 4)), adj = 1, col.sub = "red")
abline(v = 0)
abline(h = 0)
위의 그래프는 상관계수의 계산 과정을 시각화 한 그래프라고 생각 할 수 있겠죠? 상관계수는 그래프의 모든 점들을 더 한 후 n-1로 나눠준 값이 됩니다. 값을 보면, 빨간 큰 점들이 많이 보이니, 당연히 작은 파란색 점들의 상관계수에 대한 영향력은 줄어들 것이고, 상관계수는 양의 값인 0.677 값이 나오는 게 되는 것이죠.