출처 : https://www.youtube.com/watch?v=RymrCV3K5J8 ← 상당히 좋음
양의 상관 → 두 변수가 동시에 커질때 (양의 연관성)
음의 상관 → 두 변수가 반대로 움직일 때 (음의 연관성)
무상관 → 상관이 없다 → 무상관이면 0에 가깝다
양의상관에서는 + + 또는 - - 이므로 양의값을 가짐
음의 상관에서는 + - 또는 - + 이므로 음의 값을 가짐
Cov값의 차이가 나타나는 이유 : 1번이 X의범위와 Y의 범위가 더 크기때문!
표준화 해줘서 나오는게 상관계수야
모상관계수 X,Y의 공분산을 각각의 편차로 나눠준다.
모상관계수를 우리가 직접적으로 구할 수 없으니 표본에 대한 상관계수를 구하는것이 피어슨상관계수이고, 이때 자유도는 n-2 이다.
그 이유는 표본이 X그룹과 Y그룹 2개라서 그렇다.
수학적 관계이지, 속성의 관계는 아니다. 이는 선형관계의 측도이다. (곡선관계는 찾아내지 못한다)
연관성의 측도로 공분산을 사용 (Covariance == Cov)
X의 분산은 ? → X가 얼마나 퍼져있는가
Var(x) =
Y의 분산은 ? → Y가 얼마나 퍼져있는가
Var(Y) =
X,Y의 공분산은? → X,Y가 어떠한 방향성을 갖고있는가? → 이 공분산은 데이터가 얼마나 퍼져있냐에 따라 값의 차이가 있다
COV(X,Y) =
X, Y 의 상관계수는? → 공분산의 표준화를 통하여, 얼마나 퍼져있든, 상관성을 볼수있다. 그러나 곡선관계는 해석이 불가하다.
Corr(X,Y) = = →
import numpy as np
data=[243,278,184,249,207]
def mean(data):
tmp=0
n=0
for i in data:
tmp+=i
n+=1
return tmp/n
def var(data,df=0):#df = 1 :: 자유도 n-1 , df=0 : 자유도 n으로
m=mean(data)
n=0
tmp = 0
for i in data:
tmp+=(i-m)**2
n+=1
return tmp/(n-df)
def std(data,df=0):
variance=var(data)
return variance**0.5
print('내가만든함수\t\t Numpy함수')
print(mean(data),'\t\t\t', np.mean(data))
print(var(data),'\t\t', np.var(data))
print(std(data),'\t', np.std(data))
"""
내가만든함수 Numpy함수
232.2 232.2
1090.96 1090.96
33.02968361943541 33.02968361943541
"""
# data
new=[88,89,83,112,104]
def cov(X,Y):
muX=mean(X)
muY=mean(Y)
n=0
up=0
for x,y in zip(X,Y):
n+=1
up+=(x-muX)*(y-muY)
return up/(n-1)
print(cov(data,new),'\n', np.cov(data,new)[0][1])
'''
71.69999999999999 , 71.7 '''
def covv(X,Y): #sum, list, map, lambda , zip 이용해보기
muX, muY = mean(X), mean(Y)
return sum(list(map(lambda x : (x[0]-muX)*(x[1]-muY), zip(X,Y)))) / (len(X)-1)
covv(data,new) , cov(data,new) , np.cov(data,new)[0][1]
''' (71.69999999999999, 71.69999999999999, 71.7) '''
def corr(X,Y):
muX, muY = mean(X), mean(Y)
Sxx=sum(list(map(lambda x : (x-muX)**2, X)))
Syy=sum(list(map(lambda y : (y-muY)**2, Y)))
Sxy=sum(list(map(lambda x : (x[0]-muX)*(x[1]-muY), zip(X,Y))))
return Sxy / ((Sxx**0.5)*(Syy**0.5))
corr(data,new),np.corrcoef(data,new)
'''
0.15868973512570766
array([[1. , 0.15868974],
[0.15868974, 1. ]])
'''
R을 이용한 데이터 처리 & 분석 실무: 스피어만 상관 계수
스피어만 상관계수 (Spearman's Rank Correlation Codfficient)
두 데이터의 실제 값 대신, 두 값의 순위(rank)를 사용해 상관계수를 계산하는 방식이다. 피어슨상관계수와 마찬가지로 범위는 [-1,1]이며, 양의상관—음의상관을 나타낸다.
스피어만상관계수는 비선형관계의 연관성을 파악할 수 있다는 장점이 있다.
또한, 데이터의 순위만 매길 수 있다면 적용 가능하므로 연속형(Continuous) 데이터에 적합한 피어슨상관계수와 달리 이산형(Discrete)데이터, 순서형(Ordinal)데이터에 적용이 가능하다.
Ex. 국어점수와 영어점수의 상관계수 → 피어슨 , 국어석차와 영어석차의 상관계수 → 스피어만
→ ,
는 변수 x에서 i 번째 데이터의 순위
는 변수 y에서 i 번째 데이터의 순위
는 각각 x,y의 평균
여기서 라고 하면, 식이 굉장히 간단해지는데,
from scipy import stats
data=[243,278,184,249,207]
new=[88,89,83,112,104]
def getRank(X): #주어진 list의 각각 랭크값을 반환 (동일값도 랭크증가)
tmp=[]
xrank=sorted(X, reverse=True)
for x in X:
tmp.append(xrank.index(x)+1)
return tmp
def spearmanR(X,Y):
xrank, yrank=getRank(X), getRank(Y)
up = 6 * sum(list(map(lambda x : (x[0]-x[1])**2 , zip(xrank,yrank) ) ) )
down=len(X) * (len(X)**2-1)
return 1 - (up/down)
spearmanR(data,new), stats.spearmanr(data,new)
# (0.5 , SpearmanrResult(correlation=0.49999999999999994, pvalue=0.39100221895577053))