피어슨 상관계수 - Pearson's product-moment correlation

개요

연속형 변수 2개의 상관 관계를 확인하기 위한 가장 기본적인 방법이다.

정확히 말해서 두개의 수치값들의 집합이 있을 때 이 두개의 수치값들은 각각의 순서쌍에 대해서 연결관계가 있다고 할 때 두 수치값이 서로 관련이 있는지를 확인하는 방법이다.

흔한 예로 있는 것이 고등학생 한 학급에 50명이 있다고 할 때 이 학생들의 수학과목의 성적과 물리과목의 성정이 관련이 있는지 확인하는 것이 있다. 즉 수학과목과 물리과목은 서로 수리적 또는 과학적 능력과 관련이 있어 두 과목은 서로 관련이 있을 것이라는 가설을 어느 정도 두고 있으며 실제로 그런지 확인한다.

피어슨의 상관계수는 그런 방법중에 가장 기본적인 방법이며 그 외에도 여러가지 상관방법이 있다.

피어슨 상관계수는 두 변수의 결합은 정규분포일 것이라는 가정이 포함되어 있으며 구조적으로 볼 때 이상치(outlier)에 매우 민감한 편이다.

주의할 것은 결과를 보고 상관관계가 인과관계와 관련이 있을 것이라는 확대해석을 하지 말아야하며 단순하게 두 변수가 연관성이 있다로만 결론을 내려야 한다는 것이다.

사용시 주의점

정규분포 문제

두 변량(변수, variable, variance)이 정규성(normality)을 따를 때 대해 최적화된 방법이므로 정규성 문제에서 자유롭지는 않다. 쉽게 예를 통해 말해보면 피어슨 상관계수는 두 변수가 정규분포여야 한다는 전제를 두지는 않지만 피어슨 상관계수는 정규분포에서 가장 잘 작동하도록 설계되었다고 한다. 위의 예에서 수학성적과 물리성적은 모두 정규분포여야 더 정확한 결과를 얻을 수 있다.

즉, 상관계수를 계산할 두 세트의 데이터가 각기 정규분포를 반드시 따를 필요는 없지만 두 데이터 세트의 데이터 포인트의 평균에서 편차의 곱은 정규분포를 따라야 한다고 알려져 있다.

오해석 문제

변량이 정규분포가 아닌 경우에도 사용할 수는 있으나 결과값이 달라질 가능성이 커서 오해석을 할 수 있다.

편차의 곱들이 정규분포를 따르지 않으면 오해석을 만드는 이상치(outlier)에 예민한 문제가 있다.

인과관계를 증명하지 않으므로 결과를 인과관계로 확대해석하는 것을 항상 경계해야한다.

가설검정을 수행해서 반드시 p-value를 확인해야 한다. 하지만, 그 결과를 무조건 신뢰하지는 않아야 한다.

이상치(outlier)에 매우 민감하므로 데이터를 트랜스폼 하거나 다른 기술을 보조방법으로 확인해야 할 수 있다.

20개 이상의 데이터 포인트에 대해서 수행한다면 데이터가 정규분포를 따르게 만들거나 아웃라이어를 확실하게 처리해야한다.

후속 작업(인과 관계 증명)이 필요하면 regression test를 수행해야 한다.

희박성(Intermittent) 문제에서 매우 자유롭지 않다. 즉, 데이터에 0이 많으면 쓸 수가 없다.

결측치가 많거나 0이 많은 데이터에 대해서는 바로 사용하기 어렵다.

결측치를 어떤 값으로 채워야하고 0인 값이 정말 0인지 찾아서 보정하는 문제를 해결해 주어야 하는데 그렇게 하기 어렵다면 사용하지 않아야 한다.

쉽게 사용할 수 있으나 쉽게 해석하지는 않아야 한다.

횡단면 데이터(cross-sectional) 또는 시계열 데이터(time-series)에 대해서 모두 사용할 수 있지만 시계열 데이터에는 해석을 매우 주의해야 하거나 사용하지 않아야 한다.

부연 설명

피어슨 상관관계의 기본은 두 확률 변수(variable)가 서로 독립인지 아닌지를 확인하는 것인데 각각의 변수의 평균에서의 분산의 방향과 양을 서로 곱하고 합산하여(product) 적률(moment)로 독립성을 검정하는 것이다. 아웃라이어에 굉장히 예민하며 계산에 대한 최적(optimum)이 정규분포를 가정으로 되어 있어 결국 두 변수가 정규분포가 아닌 경우 또는 두 변수의 편차의 곱이 정규분포를 따르지 않으면 제대로 해석을 할 수 없다고 알려져 있다. 가장 기본이 되는 유사도 검정 방법이긴 하지만 여러가지 위험성 때문에 최근에는 많은 데이터 사이언티스트들은 직접 사용하는 것을 기피하는 경향이 강해지고 있다.

상관관계를 확인하는 것 보다는 인과관계까지 바로 확인할 수 있게 회귀로 바로 진입하는 경우가 많아지고 있다.

관련 기법

  • Data Transformation: 정규분포로 변환
  • 0값 또는 NULL값에 대한 보정
  • Outlier reduction or Influential reduction: outlier 제거 또는 무력화, 0값 보정 및 무력화
  • Bootstrapping: 편추정에 대한 방지
  • Cook’s distance: outlier 무력화

참조 코드

비율 데이터와 양적 데이터에 대한 correlation의 반응 결과 시뮬레이션이다.

※ outlier의 존재 및 영향력에 따라 correlation의 결과가 크게 차이가 발생함을 확인한 것이다.

a <- rnorm(100, mean= 50, sd = 20)
b <- rnorm(100, mean= 2000, sd = 500)
c <- rnorm(100, mean= 120000, sd = 1500)
# 위의 세 변수는 정규분포에 의한 랜덤으로 서로 연관성이 없어야 함
 
paste(a, sep = "", collapse = ", ")
paste(b, sep = "", collapse = ", ")
paste(c, sep = "", collapse = ", ")
 
# 변수가 랜덤이므로 재현을 위해서 값을 기록해 둔다
# > paste(a, sep = "", collapse = ", ")
# [1] "43.5352862922437, 26.1142486253874, 83.0310075589865, 52.6120387834526, 79.0516784036759, 78.4067982054003, 49.062183315655, 33.9101133704574, 52.6453876117853, 22.5639577719374, 28.0566952588897, 58.3170898964112, 79.7531506969863, 16.4651442095427, 21.8266199445677, 84.7613164971811, 22.9314362586294, 57.2546573845694, 70.1072978856087, 69.5434626894672, 30.0281312105167, 51.331326846718, 37.7918517827927, 31.2858007434158, 16.1322596624448, 75.2985738809986, 12.5749486008556, 35.7921600656511, 64.806317406061, 62.977130791631, 47.3643715031428, 59.9356881188637, 21.6271869042728, 62.7203715153795, 65.4173808852516, 45.6678158936037, 65.4652627799009, 64.8256029810552, 59.5570284027551, 69.6764444112485, 58.5164575206365, 62.004266803614, 97.706433122476, 64.1470814021714, 41.8597076539052, 43.5156462394562, 14.5280461758878, 39.2917202512866, 80.7933545904295, 38.6129906668388, 40.3837831017038, 35.2616689131153, 34.003282142012, 68.7359333785656, 55.0633600450313, 54.1745798049531, 69.0118780703161, 53.4504373550242, 60.2301640760341, 9.7890658404699, 63.6178737287274, 29.5732275213378, 48.7588587666721, 40.5156753816904, 54.9906332676469, 32.4814706691121, 56.7982092746807, 55.1773169970468, 27.9953889016393, 35.4516456284645, 63.5454475487725, 75.9599618444786, 65.2507265886765, 33.9459834762341, 61.321763995156, 89.8059423687934, 84.6565172745663, 0.974251609395807, 35.1188518010291, 17.8961452288911, 84.213912723524, 33.9900156697055, 42.4386576418562, 59.4614633600509, 59.0355532878133, 51.9481361012289, 68.0797928653874, 72.1110911014688, 41.1499727814911, 75.2279481537229, 49.0997788926431, 63.3516617832293, 61.1487670634223, 27.6280479420989, 48.7997440672988, 82.448020715588, 65.9171002410758, 55.0521463374323, 68.8948953658392, 69.3871761692264"
# > paste(b, sep = "", collapse = ", ")
# [1] "1251.43332438274, 2342.37972353621, 2220.80372569032, 1895.67202861517, 2014.5484405777, 2376.00314439979, 2336.35697930541, 1654.00823520994, 1888.83098639829, 1181.60965560807, 1863.61920533526, 1481.15256643624, 1932.44372641792, 3055.92690257731, 1840.26793824745, 2208.60973931844, 1956.12542134589, 1631.76325719419, 2697.95727176067, 2429.20779820604, 2044.27327059926, 2371.31062184623, 2220.10184966659, 2139.39804535137, 1756.26740295561, 2259.86757217339, 1848.86774247112, 2463.81430642305, 2624.75885609224, 1778.54253932097, 1489.35179681014, 2891.55868135022, 1872.90871459947, 2399.44865358388, 2456.8524870807, 2741.75205825754, 3582.09350773464, 2900.74890621652, 2255.54297302259, 2667.33190357123, 1861.96324722154, 1884.02035899016, 3100.01143764508, 2022.4206226856, 2225.53778549019, 2635.82735842111, 1392.77415237051, 1305.97461470831, 1819.42159875603, 546.128677126583, 1457.97600776047, 2038.04094488796, 1652.43305615482, 1811.76409711056, 2611.6019475432, 2047.23886211447, 2202.41466500911, 1938.12732690756, 3018.09112950321, 2298.85390764845, 1371.98741043772, 1632.41914032878, 1512.07582044162, 2223.24185250764, 2823.81014669429, 1398.71033086321, 2440.25530481094, 1697.44725081322, 2529.9849209169, 1274.26673394536, 2538.96781338355, 2331.50749699991, 2531.01232864703, 2220.65705963555, 2436.36788346162, 2242.26168556345, 1684.61342059638, 2329.11879273551, 1794.99394056369, 1919.0816337302, 2063.6757595704, 3062.90035919268, 1754.96734557443, 1619.4821990434, 2726.76973077111, 2250.17607892164, 1864.44859264195, 2189.37654054184, 2512.62977050847, 1720.94990563809, 2088.27335020036, 2140.7877964509, 2210.3252937194, 1498.67647300586, 2900.34433448942, 2063.12406537933, 2567.97957458864, 1715.31375194128, 2962.83772029732, 2063.67912368279"
# > paste(c, sep = "", collapse = ", ")
# [1] "119251.740829297, 121454.749783168, 119322.863576464, 119625.053964249, 118777.133824213, 118886.263077579, 119452.106801154, 120852.422342105, 119878.777784741, 118744.994769308, 120485.993860488, 120900.993782886, 120029.694154418, 121873.759886909, 120103.095492903, 120464.566449077, 120413.950098949, 117675.521438293, 119369.593090079, 120240.848827266, 117719.926402129, 119937.608402987, 122204.395391432, 120046.437974128, 122030.752192869, 121758.319405922, 117695.944113387, 123573.943065106, 118291.406750377, 121223.526386357, 118517.552204085, 120807.901347187, 120621.001457778, 119475.47666331, 120242.292401057, 118921.238554979, 117521.086798667, 119578.721701939, 120911.304811968, 118703.778719702, 118788.362258785, 121556.481938474, 121028.947546723, 120985.485978974, 119249.785631828, 119058.080743588, 119660.567571029, 120534.219899411, 117111.884018716, 123267.794308878, 119786.970340605, 118413.811192198, 119009.253977222, 121819.638219391, 119700.137016435, 118591.023956261, 122084.292027088, 119312.936762931, 121054.04369525, 120441.609939599, 121026.397702518, 116540.245700406, 119952.566365456, 120310.313070646, 119499.52373053, 120397.564444098, 117148.951314992, 120480.029627339, 117264.617694825, 119973.696770688, 119083.964353884, 121199.805482649, 119799.284366371, 118761.546380338, 120774.208993894, 119938.635449809, 119953.469476303, 120705.658029756, 120433.900638267, 122404.092031616, 119370.262687362, 121592.496711847, 118925.505900191, 120272.407880099, 117654.657686838, 121295.025688249, 120741.271142659, 119270.308179925, 119029.993677834, 120957.591449431, 119201.571359284, 118571.767581187, 119661.859738992, 116945.538167552, 119312.891068774, 117398.409506805, 119068.847553957, 118553.244590584, 121318.583080948, 119410.618012882"
 
 
# 3번째 변수로 1번째, 2번째 변수를 나눠서 비율값으로 만든다.
# 분모가 같으므로 a와 b 그리고 a.rate와 b.rate는 상관계수가 거의 비슷해야 한다.
a.rate <- a/c
b.rate <- b/c
 
# plotting
par(mfrow=c(2, 1))
plot(a, b, pch=20)
plot(a.rate, b.rate, pch=20)
dev.off()
 
 
# install.packages("asbio")
library(asbio)
cor(a, b)  # correlation
cor(a.rate, b.rate)  # correlation with transformed variables
r.pb(a, b, beta = 0.2)  # percentage-bend correlation
r.pb(a.rate, b.rate, beta = 0.2)  # percentage-bend correlation with transformed variables
cor(a, b, method = "spearman")  # Spearman's correlation
 
# hypothesis test
cor.test(a, b)
cor.test(a.rate, b.rate)
cor.test(a, b, method = "spearman")  # hypothesis tset
 
# bootstrapping
library(boot)
cor.stat <- function(data, indices) {
  cor(data[indices, 1], data[indices, 2])
}
boot.output <- boot(data=cbind(a, b), cor.stat, R=100000)
(boot.output)
par(mfrow=c(1, 1))
hist(boot.output$t, nclass=32)
dev.off()
 
 
# responsibility test on outliers
# 정규분포에서의 랜덤으로 element가 10개인 변수 3개를 만들되 하나의 element는 outlier를 강제로 넣어준다.
# 첫번째 element에 outlier를 넣었으므로 outlier에 영향을 받는다면 상관계수가 매우 높게 나타날 것이다.
a1 <- c(100, rnorm(9, 5, 9))
b1 <- c(200, rnorm(9, 5, 9))
c1 <- c(500, rnorm(9, 50, 9))
paste(a1, sep = "", collapse = ", ")
# [1] "100, -17.8877517498719, 1.65010536316145, 10.8981253085614, -0.536608019252361, 0.368470776596632, 14.6682762969186, -10.6227685949784, 7.03189390859778, 14.9138302131459"
paste(b1, sep = "", collapse = ", ")
# [1] "200, -3.42021229405049, 0.877706007815157, -4.52919961063207, 19.5994542345915, 11.9415248662197, 10.7128587235155, 9.79371410533467, 22.8992163078861, -2.04341531240663"
paste(c1, sep = "", collapse = ", ")
# "200, -3.42021229405049, 0.877706007815157, -4.52919961063207, 19.5994542345915, 11.9415248662197, 10.7128587235155, 9.79371410533467, 22.8992163078861, -2.04341531240663"
 
cor(a1, b1)  # 상관계수가 클 것이다.
cor(a1/300, b1/300)  # 하나마나 한 짓이다.
cor(a1[2:10], b1[2:10]) # 상관계수가 낮을 것이다. outlier를 제거했으므로
cor(a1/c1, b1/c1)  # 상관계수가 작을 것이다. outlier를 무력화 했으므로
 
# 위의 결과를 각각 확인해 보면 비율인 경우 outlier의 영향을 줄이는 것을 볼 수 있지만 그렇지 않은 경우 outlier에 의해서 상관관계가 매우 높게 나타난다.
 
# Et cetera
cor(a1/b1, b1/b1)  # 하나마나한 것
cor(a1/(a1+b1), b1/(a1+b1))  # 하나마나한 것
 
# outlier checking with Cook's distance
library(MASS)
m1 <- lm(a ~ b)
plot(cooks.distance(m1))
# cook's distance로 outlier를 찾아낼 수 있다.
 
m1 <- lm(a1 ~ b1)
plot(cooks.distance(m1))

참고자료

https://ko.wikipedia.org/wiki/%EC%83%81%EA%B4%80%EB%B6%84%EC%84%9D