두 변수간에 어떤 선형적 관계를 가지는지 분석하는 기법.
#두 자료의 공분산 / 상관계수 구하기
x = [8,3,6,6,5,9,3,9,3,4]
y=[60,20,40,60,90,50,10,80,40,50]
공분산
np.cov(x,y)
data.cov()
상관계수
np.corrcoef(x,y)
data.corr(method='pearson')
두 자료의 단위가 다르면 공분산은 함께 변한다.
하지만 상관계수는 변하지 않고 일정하다
상관계수는 1,-1에 가까울수록 깊은 상관관계를 가진다.
이상적인 수치는 ±0.3~±1 이다.
주의
: 공분산 / 상관계수는 선형적인 데이터에 대해서만 유의하다.
data.corr(method='pearson')
Pearson(피어슨)
Kendall(켄달)
Spearman(스피어만)
data.go.kr의 자료를 사용
국내 유료 관광지에 대해 외국인(일본,중국,미국) 관광객이 선호하는 관광지 관계분석
사용된 데이터 : 관광지 입장정보.json / 중국인방문객.json / 일본인방문객.json / 미국인 방문객.json
fname = '../testdata/서울특별시_관광지입장정보_2011_2016.json'
#stirng -> dict (decode)
jsonTP = json.loads(open(fname,'r',encoding='utf-8').read())
#연월 / 관광지명 / 입장객수
tour_table = pd.DataFrame(jsonTP,columns=('yyyymm','resNm','ForNum'))
tour_table = tour_table.set_index('yyyymm')
resNm = tour_table.resNm.unique() #관광지명 5개 얻음
print(resNm[:5])
#중국인
cdf = '../testdata/중국인방문객.json'
jdata = json.loads(open(cdf,'r',encoding='utf-8').read())
china_table = pd.DataFrame(jdata)
print(china_table.head())
#일본인
jdf = '../testdata/일본인방문객.json'
jdata = json.loads(open(jdf,'r',encoding='utf-8').read())
japan_table = pd.DataFrame(jdata,columns=('yyyymm','visit_cnt'))
japan_table.rename(columns={'visit_cnt':'japan'},inplace=True)
japan_table.set_index('yyyymm',inplace=True)
#미국인
udf = '../testdata/미국인방문객.json'
jdata = json.loads(open(udf,'r',encoding='utf-8').read())
usa_table = pd.DataFrame(jdata,columns=('yyyymm','visit_cnt'))
usa_table.rename(columns={'visit_cnt':'USA'},inplace=True)
usa_table.set_index('yyyymm',inplace=True)
#full join
all_table = pd.merge(china_table,japan_table, \
left_index=True, right_index=True)
all_table = pd.merge(all_table,usa_table,left_index=True,right_index=True)
r_list = []
#사용자정의 그래프함수. 5개 관광지별 방문객수
for tp in resNm[:5]:
r_list.append(setScatterChart(tour_table,all_table,tp))
r_df = pd.DataFrame(r_list,columns=('고궁명','중국','일본','미국'))
r_df = r_df.set_index('고궁명')
print(r_df)
r_df.plot(kind='bar',rot=50)
plt.show()
# china japan USA
# yyyymm
# 201101 91252 209184 43065
# 201102 140571 230362 41077
# 201103 141457 306126 54610
tp
: for 루프로 인해 관광지명이 순차적으로 전달된다.사용자정의 함수 setScatterChart
에서 그래프를 그린다.
def setScatterChart(tour_table,all_table,tourpoint):
# 순차적으로 전달되어 오는 각 관광지 5개를 필터링
tour = tour_table[tour_table['resNm']==tourpoint]
# 필터링된 관광지DF와 해외방문객수 데이터DF를 날짜기준 merge
merge_table = pd.merge(tour,all_table,left_index=True,right_index=True)
#상관관계 분석
fig = plt.figure()
fig.suptitle(tourpoint + ' 관광지의 상관관계 분석')
plt.subplot(1,3,1)
plt.xlabel('중국인 입장객수')
plt.ylabel(('외국인 입장객수'))
lamb1 = lambda p:merge_table['china'].corr(merge_table['ForNum'])
r1 = lamb1(merge_table)
print('r1 :',r1)
plt.title('r={:.5f}'.format(r1))
plt.scatter(merge_table['china'],merge_table['ForNum'],s=6)
#이후 2개국 반복
plt.show()
subplot
으로 구획을 나누었다..corr()
을 이용하여 분석했다.분석시 상관분석에서 가장 많이하는 실수가
상관분석 그림을 보며 원인-결과로 설명하는 것이다.
A와 B가 positive correlation이란 사실은
A가 증가하는게 원인이 되서 B가 증가하는지,
B가 증가하는게 원인이 되서 A가 증가하는지 알 수 없다.
ex)
날씨가 더워질수록 아이스크림이 잘 팔린다.
날씨가 더워질수록 날파리가 늘어난다.
"아이스크림 판매가 늘어나니 날파리도 증가한다" 라고 판단할 수는 없다.
원인-결과 분석을 하고싶다면, 상관분석이 아니라
Y(결과)=aX(원인)+b의 회귀분석 을 수행하자.