본문 바로가기

Study/class note

R / 상관관계, 이원교차표(cross table)

ㅇ 자동화 코드 스크립트

text1 <- 'mycol0 <- rgb(1,1,1,seq(1,0,length=7)) \
car<- read.csv("c:\\data\\usedcars.csv")\
m<-sort(car$mileage)\

hist(m,col=mycol0,xlab="mileage",ylab="cnt",main="주행거리에 따른 중고차 분포")\
par(new=T)\
plot(m,dnorm(m,mean=mean(m),sd=sd(m)),type="l",axes=FALSE,ann=FALSE, col="red",\
     lwd=1.2)'

my_func <- function() {
  
  x1 <- menu( c('정규분포 그래프','상관관계 그래프') ,
              title='숫자를 선택하세요 ~' )  
  
  
  switch ( x1,  
           san1 = {  cat(text1)  } ,
           san2 = {   print('히스토그램 ~~ '  )  }
           
  )
  
}
my_func()

text1에 변수로 텍스트를 만들어 넣음.( 텍스트 안의 괄호는 모두 쌍따옴표로, 엔터마다 역슬래시(\) 붙여야함 )

function() 안에 switch에 넣을때 cat()을 사용해서  text1을 넣음.

getwd()  # 워킹디렉토리 확인

메모장에 코드를 붙여넣고 워킹디렉토리가 있는 위치에 저장함.(모든파일로 ANSI로 저장해야함)

source('my_func.R')
my_func()

R을 킬때마다 source('my_fun.R')로 함수를 호출하면 됨. 그 다음부턴 my_func()만 부르면 함수 바로 옴.

r <- function(){source('my_func.R')}

r()

코드를 간결하게 부르고 싶으면, 이 코드를 넣어 r()로 호출하면 됨.

 

+) 그래프에 색상넣는 방법 참고 사이트

http://sti.kostat.go.kr/window/2017b/html/2017_win_10.html

 

ㅁ 기계학습을 하기 전에 확인해야할 사항

1. 데이터 구조 확인

2. 이상치 확인

3. 결측치 확인

4. 수치형 데이터의 정규화 및 표준화

5. 수치형 데이터에 대해서 정규성을 띠는지 확인

6. 수치형 데이터에 대해서 상관관계를 보이는지 확인(회귀분석 시 사용)

 

 

36 수치형 데이터에 대해서 상관관계를 보이는지 확인(회귀분석 시 사용)

1. 산포도 그래프 : 두개의 수치형 데이터가 서로 연관성을 보이는지 확인할 때 유용한 그래프

2. 상관계수 확인 : 두개의 수치형 데이터가 서로 얼마나 상관관계를 보이는지를 -1 ~ 1 사이의 값으로 나타낸 값

 

예제. 중고차의 주행거리가 높으면 가격이 낮아지는지 산포도 그래프로 확인하기

car <- read.csv("c:\\data\\usedcars.csv")
plot(car$mileage, car$price, pch = 21, col = 'red', bg = 'red')
cor(car$mileage, car$price)

상관계수 : -0.8061494   > 높은 음의상관관계를 보이고 있어서 주행거리가 높을수록 중고차의 가격이 낮아짐을 보이고 있음.

 

문제201. 산포도 그래프와 상관계수를 확인하는 위의 3줄을 자동화 스크립트 2번에 추가하시오.

text1 <- 'mycol0 <- rgb(1,0,0,seq(1,0,length=7)) \
car<- read.csv("c:\\data\\usedcars.csv")\
m<-sort(car$mileage)\

hist(m,col=mycol0,xlab="mileage",ylab="cnt",main="주행거리에 따른 중고차 분포")\
par(new=T)\
plot(m,dnorm(m,mean=mean(m),sd=sd(m)),type="l",axes=FALSE,ann=FALSE, col="red",\
     lwd=1.2)'

text2 <- 'car <- read.csv("c:\\data\\usedcars.csv")\
plot(car$mileage, car$price, pch = 21, col = "red", bg = "red")\
cor(car$mileage, car$price)'

my_func <- function() {
  
  x1 <- menu( c('정규분포 그래프','산포도 그래프') ,
              title='숫자를 선택하세요 ~' )  
  
  
  switch ( x1,  
           san1 = {  cat(text1)  } ,
           san2 = {  cat(text2)  }
           
  )
  
}
my_func()

 

문제202. 코스피 등락율 데이터, 삼성전자 등락율 데이터, 현대자동차 등락율 데이터를 아래와 같이 데이터 프레임으로 생성하시오.

코스피 등락율 : K_index.csv, 삼성전자 등락율 : S_stock.csv, 현대자동차 등락율 : H_stock.csv

k <- read.csv("c:\\data\\K_index.csv")
s <- read.csv("c:\\data\\S_stock.csv")
h <- read.csv("c:\\data\\H_stock.csv")
head(h)

문제203. 위의 3개의 데이터 프레임을 전부 조인하시오.

x <- merge( merge(k,s, by = 'date'), h, by = 'date')
head(x)

문제204. 코스피 등락율(k_rate)와 삼성 주가 등락율(s_rate)를 가지고 산포도 그래프를 그리고 상관관계 계수를 출력하시오.

plot(x$k_rate, x$s_rate, pch = 21, col = "goldenrod", bg = "goldenrod")

x[is.na(x)] <- 0   # x데이터 프레임에서 NA값을 0으로 치환
cor(x$k_rate, x$s_rate)

0.5142456

문제205. 코스피 등락율(k_rate)와 현대자동차 주가 등락율(h_rate)를 가지고 산포도 그래프를 그리고 상관계수를 출력하시오.

plot(x$k_rate, x$h_rate, pch = 21, col = "dark salmon", bg = "dark salmon")

x[is.na(x)] <- 0   # x데이터 프레임에서 NA값을 0으로 치환
cor(x$k_rate, x$h_rate)

0.3262717

문제206. 위의 2개의 그래프를 하나의 화면에 같이 출력하시오.

par(mfrow = c(1,2)) # 1행 2열로 그래프 그리겠다
plot(x$k_rate, x$s_rate, pch = 21, col = "goldenrod", bg = "goldenrod",
     main = paste('삼성전자 : ',cor(x$k_rate, x$s_rate)))
plot(x$k_rate, x$h_rate, pch = 21, col = "cornflower blue", bg = "cornflower blue",
     main = paste('현대자동차 : ', cor(x$k_rate, x$h_rate)))

 

 

ㅁ 기계학습을 하기 전에 확인해야할 사항

1. 데이터 구조 확인

2. 이상치 확인

3. 결측치 확인

4. 수치형 데이터의 정규화 및 표준화

5. 수치형 데이터에 대해서 정규성을 띠는지 확인

6. 수치형 데이터에 대해서 상관관계를 보이는지 확인(회귀분석 시 사용)

7. 이원교차표( 기계가 잘 학습했는지 확인할 때 필요)

 

 

37  CrossTable(이원교차표) - p109

  두 명목 변수간의 관계를 관찰하고자 할 때 이원교차표를 사용

  교차표는 하나의 변수 값이 다른 변수값에 의해 어떻게 변하는지 관찰할 수 있다는 점에서 산포도 그래프와 유사함

install.packages("gmodels")  # 패키지 설치

library(gmodels)
emp <- read.csv("c:\\data\\emp3.csv")
CrossTable(x=emp$deptno, y=emp$job)

위와 비슷한 결과를 tapply 함수로 구현하면 아래와 같음

tapply(emp$empno, list(emp$deptno,emp$job), length)

CrossTable과 달리 taapply는 column total과 row total, 전체 total이 출력되지 않음.

 

문제207. 월급을 2500을 기준으로 직업별로 각각 월급이 2500이상인 사원들과 월급이 2500보다 작은 사원들의 분포를 이원교차표로 확인하시오.

emp$sal_2500 <- ifelse(emp$sal >= 2500, 1, 0)   # 0과 1이 담긴 파생변수 생성
emp

library(gmodels)
CrossTable(emp$sal_2500, emp$job)

2500 이상은 1, 2500 이하는 0으로 값을 부여함.

이원교차표를 봤을 때 월급이 2500 이상인 직업은 ANALYST, PRESIDENT, MANAGER, 2500 이하인 직업은 CLERK, SALESMAN, MANAGER라는걸 확인할 수 있음.

 

ㅇ 이원교차표의 해석

1. 행 합계

2. 열 합계

3. 표 합계에 대한 대한 셀의 상대적 비율

4. 카이제곱 통계

 

(책 참고)

예제. 중고차의 모델(차종)과 색깔의 관계가 있는가? 보수적인 색깔이 더 많은 모델은?

문제208. 차 모델의 종류가 무엇인지 차 모델을 중복제거해서 출력하시오. 

car <- read.csv("c:\\data\\usedcars.csv")
unique(car$model)

# "SEL" "SE"  "SES"

문제209. 차 색깔의 종류는 무엇이 있는지 중복제거해서 출력하시오.

unique(car$color)

# "Yellow" "Gray"   "Silver" "White"  "Blue"   "Black"  "Green"  "Red"    "Gold"

보수적인 색 - black, white, grey, silver

보수적이지 않은 색 - yellow, blue, green, red, gold

 

문제210. 중고차의 색깔이 보수적이면 TRUE, 아니면 FALSE인 파생변수를 책 110페이지에 나온대로 conservative라는 이름으로 추가하시오.

car$conservative <- car$color %in% c("Black","Gray","Silver","White")
car

TRUE/FALSE 분포를 알고 싶다면, table()사용해서 건수를 출력하면 됨

table(car$conservative)

FALSE  TRUE 
   51    99

 

문제211. 차 모델별로도 보수적인 색깔이 더 많은지 CrossTable로 확인하시오.

library(gmodels)
CrossTable(car$model, car$conservative)

> 차 모델별로 보수적인 색깔이 더 많은 경향을 보이고 있음.

이것이 과연 우연히 일어난 일인지 아니면 연관이 있는 것인지 확인해볼 필요가 있음. = 카이제곱 검정

CrossTable()함수를 호출할 때 chisq = TRUE를 지정하면 카이제곱 검정의 결과를 얻을 수 있음.

library(gmodels)
CrossTable(car$model, car$conservative, chisq = TRUE)

Pearson's Chi-squared test 
------------------------------------------------------------
Chi^2 =  0.1539564     d.f. =  2     p =  0.92591 

(카이제곱 값)            (자유도)       (P-value 확률)

 

책에서 내린 결론 > P-value 확률이 매우 낮다면 두 변수가 연관이 있다는 강한 증거를 제공. 하지만 중고차 모델과 컬러에 관한 데이터는 P-value값이 0.9로 확률이 매우 높음. 따라서 중고차 모델과 컬러의 연관성은 우연이고 실제 연관이 있지 않을 가능성이 높음 (p.112)

 

ㅁ 카이제곱 검정

카이제곱 분포는 1900년 경에 칼 피어슨에 의해 개발되어 모집단에 대한 가설검정이나 교차분석에 유용하게 사용되는 분포

ex) 아래의 2x2 크로스 집계표를 보고 두 변수가 연관성이 있는지 살펴보시오.

관측빈도 당뇨 정상 전체
비만 10 10 20
정상체중 15 65 80
전체 25 75 100

귀무가설 : 당뇨와 비만은 연관성이 없다. (챔피언)

대립가설 : 당뇨와 비만은 연관성이 있다. (도전자)

 

참고 블로그) https://m.blog.naver.com/PostView.naver?isHttpsRedirect=true&blogId=kimyhkimyh&logNo=220987924942 

 

기대빈도 :  전체비율에 의한 예상 빈도(관측비율과 무관하다는 가정)

( 두 집단의 비만 비율이 통계적으로 차이가 전혀 없다면 당뇨 환자 25명 중에서 20%(5명)가 비만이고, 정상인 75명 중에서도 20%(15명)가 비만일 것으로 기대할 수 있을 것이다. 이렇듯 두 변수 사이에 연관성이 없다는 가정 하에 예상되는 빈도를 기대빈도라고 한다. )

관측빈도 당뇨 정상 전체 기대빈도 당뇨 정상 전체
비만 10 10 20   5 15 20
정상체중 15 65 80   20 60 80
전체 25 75 100   25 75  

카이제곱값 = 관측빈도와 기대빈도의 차이의 제곱을 기대빈도로 나눈 값들의 합

               = (10-5)^2 / 5 + (10 - 15) ^2 / 15 + (15-20)^2/20 + (65-60)^2/60 = 8.33333

R x C의 자료는 (R-1)x(C-1)의 자유도를 따름 = (2-1)*(2-1)

카이제곱값 : 8.333333, 자유도 : 1일때 p-value확률은?  = 0.003899566

1 - pchisq(q = 8.33, df = 1, lower.tail = TRUE)

> 0.004의 확률이므로 유의수준이 5%(0.05) 미만이므로 귀무가설을 기각하고 당뇨와 비만 사이에 연관성이 있다는 대립가설을 채택할 수 있다. 즉, 비만과 당뇨는 연관성이 있다고 볼 수 있음.

 

> 카이제곱값이 높을수록 p-value값이 낮아짐 ---> 두 변수의 연관성이 많다

   카이제곱값이 낮을수록 p-value값이 높아짐 ---> 두 변수의 연관성이 적다

 

문제212. 사원 테이블의 직업과 커미션을 받는 유무가 서로 연관성이 있는지 CrossTable의 카이제곱검정값으로 확인하시오.

귀무가설 : 커미션을 받는 유무는 직업과 연관성이 없다

대립가설 : 커미션을 받는 유무는 직업과 연관성이 있다

 

유의수준 5% 미만의 확률이 나오면 귀무가설을 기각하고 대립가설을 채택하면 됨

emp <- read.csv("c:\\data\\emp2.csv")
emp$comm_accept <- ifelse(is.na(emp$comm), 0, 1)  # comm은 안받으면 0, 받으면 1
emp$cnt <- 1


result <- xtabs(cnt ~ comm_accept + job, emp)
result

chisq.test(result)  # 카이제곱 검정 실행

Pearson's Chi-squared test

data:  result
X-squared = 14, df = 4, p-value = 0.007295

 

> p-value가 0.05보다 작으므로 커미션을 받는 유무는 직업과 연관성이 있다라고 할 수 있음.

 

문제213. 위의 결과를 파이썬으로 구현하시오.

# python
import pandas as pd
import scipy.stats as stats

emp = pd.read_csv("c:\\data\\emp2.csv")
emp['comm'] = emp['comm'].fillna(999)  # 커미션을 받는 사람중에 0이 있음. 전혀 없을만한 값을 넣음
emp['comm_accept'] = emp['comm'].apply(lambda x: x!= 999)

result = pd.crosstab(emp['comm_accept'], emp['job'])  # R의 xtabs와 같은 것
result

result가 이원교차표인데 이 표를 가지고 카이제곱 값과 확률을 구함.

# python
stats.chi2_contingency(observed=result)

14.0,    <- 카이제곱 값
 0.007295055724436127,      <- p-value값
 4    <- 자유도(df)

 

+) 카이제곱 파이썬 메뉴얼

https://docs.scipy.org/doc/scipy/reference/generated/scipy.stats.chi2_contingency.html

 

 

문제214. 위에서 구현한 파이썬 코드 2줄을 아래의 R코드 처럼 구현해서 한번에 comm_accept에 커미션을 받으면 1 아니면 0이 들어가게 하시오

# R
emp$comm_accept <- ifelse(is.na(emp$comm), 0, 1)
# python
emp['comm_r'] = emp['comm'].apply(lambda x: 1 if x >= 0 else 0)
반응형