티스토리 뷰

[R 독학중인 초보, 따라서 내용에 대한 품질은 보장 못함. 개인 공부 정리용으로 쓴 글임]



R을 쓰는 이유

R을 사용하는 가장 큰 목적은 데이터를 손쉽게 그래프로 그리는 것이다. Excel도 상당 수 유사한 기능을 제공해주고, 간편하지만 아쉽게도 다룰 수 있는 데이터 사이즈가 한정되어 있으며, 차트 기능도 제한적이다. 서비스를 하게 될 때 매일 천만건, 혹은 그 이상의 데이터가 쌓인다고 하면 이를 엑셀로 다루기란 불가능하다. 물론 R도 만능은 아니다. 사실 빅데이터를 다루려면 Hadoop을 이용하는 게 더 효과적일 수 있지만, Hadoop은 R처럼 툴이라기 보다는 프로그래머들을 위한 프레임워크 이므로, 현실적으로 '어느 정도 빅데이터'를 취급할 수 있는 통계툴은 R이 가장 적절하다.


데이터 - 분석하기 쉽게 편집해라!

실무에서 R을 이용해서 데이터 차트가 나오려면 3가지 과정을 거쳐야 한다. 첫째! 데이터를 수집해야 한다. 보통 혼자서는 할 수 없고 다른 부서의 협력, 개발자의 협력 등을 얻어야 하므로 가장 힘든 과정이다. 실제로 "이러저러해서 이런 데이터가 필요합니다." 라고 이해시키기 까지 1년이 걸릴 수 있다. 필요하다고 인정되더라도 다른 과제가 더 급하다는 피드백과 함께 영영 데이터를 얻지 못할 수도 있다. 데이터만 있으면 박사도 쉽게 된다는 소리가 괜히 나오는게 아니다. 뭐 여기서는 얻었다고 가정하고 진행하자. 둘째. 데이터를 어떻게 이용할지 (분석할지), 이 데이터로 어떤 값을 추출할지 고민해야 한다. 사실 이 과정을 먼저 거치고, 데이터를 요구하는 게 일반적인 과정이고 아주 중요한 부분이지만, 이것도 일단 여기서는 넘어가도록 하자. 셋째가, 데이터를 분석하고 이 데이터를 가지고 insight를 얻는 과정이다. 일단 R의 기본 테크닉 몇개를 예제와 함께 공부해보자. 



Example: Cohort Retention Data

서비스에서 많이 사용하는 Retention Data는, 가입고객이 재방문(혹은 재구매)하는지를 보여주는 통계이다. 월 단위로 Retention Data를 측정한다고 하면, 월별로 가입자 그룹을 Cohort + '월'과 같이 분류하고, 각각의 Client ID를 기준으로 방문 회수를 측정했다고 하자. 이를 데이터로 정리하면, 아래와 같이 될 것이다. X 축은 시간, Y축은 방문자 수 데이터이다. 그리고 테이블에서 low의 첫번째 줄인 Cohort가 범례가 될 것이다. 



위 데이터를 엑셀에서 그래프로 그려보면 아래와 같이 된다. 예를 들어, 맨 아래 Area가 1월 가입자의 월별 방문이다. 일반적으로 첫 월 방문자 수에서 점차로 줄어드는 것을 볼 수 있다. Retention Data는 전체 가입자 증가 추세와 함께 서비스가 이용자에게 잘 받아들여지고 있는지를 보여주는 중요한 지표이다. 만약 새로운 이용자가 계속 증가해서 전체적인 이용자 규모는 증가한다고 해도, 기존 이용자들이 서비스를 지속해서 이용하지 않고 중단하는 확률이 높다면, 서비스 품질에 큰 문제가 있다는 신호이기 때문이다. 새로 1명의 고객을 끌어들이는 것은 기존 고객 1명을 유지하는 것에 비해 훨씬 더 비용이 높기 때문에, Retention Rate가 낮다면, 이용자가 왜 서비스를 떠나는지 심각히 고민해야 한다. 




이런 식으로 Retention data를 분석하려고 할 때, 보기에는 참 쉬워보이지만 세상은 그리 만만하지 않다. 현실에서 데이터가 저렇게 차트를 그리기 쉽게 나와줄리가 없지 않은가? 당신이 담당하는 서비스가 무엇이던 간에, 당신이 개발자를 조르고 졸라서 얻을 수 있는 데이터는 아마 아래의 샘플 정도가 고작일 것이다. key인 user id와 접속한 시간, 그리고 접속해서 뭘 했는지에 관한 데이터가 Bla Bla나와 있을 것이다. 사실 어떤 데이터는 이런 식으로도 되어 있지 않고 log 형태로 Text Dummy에 묻혀 있을 수도 있다. '데이터가 없을 확률'이 가장 크고, 있더라도 이런 식으로도 얻기 조차 어렵다는 걸 알아두자. 데이터를 얻고자 하는 스타트업 서비스의 운영자라면 서비스의 DB구조와 Select로 시작하는 SQL문장을 작성할 능력, 그리고 DB에 대한 접근 권한 정도는 미리 확보하고 있어야 아쉬운 소리 하지 않고 데이터를 얻을 수 있다.



뭐, log에서 데이터를 추출하는 과정이나 이런건 python으로 하는 게 더 간편할 거 같지만 다 넘어가고, 여기서는 일단 위와 같은 데이터를 얻었다고 가정하고 이를 기반으로 Retention Rate를 그려보기로 하자. 사실 시간도 리눅스 서버면 시간 데이터도 저 포맷이 아닐테지만... 일단 어떻게 받았다 치고, 위 데이터에서 Retention Data를 월별로 얻는 방법을 생각해보자. 대략 아래와 같을 것이다.


0) 데이터를 R로 읽어온다. 

1) Daily Basis의 User ID 데이터에서 User ID를 중복되지 않게 취합한다. 

2) Daily Unique User ID를 Monthly로 합쳐서 Monthly로 중복되지 않게 User ID를 취합한다.

3) 월별로 Monthly Data를 만든다.

4) N월에 Unique ID에 대해서 N+1 ... N+n월의 Unique ID와 비교, 중복되는 개수를 추출한다.

5) Retention Data를 월별로 정리한다. 



이 과정을 상세히 다루려면, 무척 글이 길어질 것이므로 정리하는 내가 매우 짜증이 날 것이다. 따라서 저걸 다 할 수는 없고, 여기서는 Daily로 Retention Data를 정리하고 뽑는 경우를 설명하면서, 데이터를 다루는 조작법과 함수를 하나 써서 데이터를 재가공하는 예를 들어보겠다.


1) 먼저 데이터를 읽어온다. 데이터는 아래와 같다고 가정하자. 

DB에서 바로 가져오는 방법도 있는데, 여기서는 csv 파일 포맷으로 데이터가 Daily로 저장되어 있다고 가정하자. 여러개 파일을 처리하는 방법은 나도 아직 개노가다로 하고 있으니 (이글 쓴게 R배운지 첫주째 되는 날임) 누가 알려줬으면 좋겠다

data.df <-data.frame(read.csv(file="C:/AAA/R/study_sample.csv", header=TRUE, sep=","))

# data,frame / read.csv 용법은 따로 설명하지 않는다. 


2) Daily Basis의 User ID 데이터에서 User ID를 중복되지 않게 취합한다. 

특정 기준 (userid 열)을 기준으로 unique한 data 행만 뽑아낸다. 

xuser <- sample.df %>% distinct(userid)

xuser<- select(quser, userid, date)

뽑은 김에, unique한 날짜 데이터도 뽑아내자.

xdate<-unique(select(xuser,date))

# dplyr 패키지의 distinct를 이용하였다.


3) Retention Rate를 구하기 위해서는 매일 처음 방문한 이용자를 찾아야 한다. 10-11일에 방문한 ID는 aaa,bbb,ccc,ddd이고 10-12일에 방문한 이용자 ID는 aaa,bbb,ccc,ddd,eee,zzz이다. 12일 방문자 중에서 aaa,bbb,ccc,ddd는 11일의 재방문자이고 eee,zzz만 신규 방문자이다. 날짜별 신규 방문자를 구하는 방법은 날짜별로 중복없이 이용자를 구한다음, 교집합을 구하는 방식으로 진행하면 된다.


cohortA <-xuser %>% filter(date==xdate[i,1]) %>% select(userid) 

cohortB <-xdata %>% filter(date==xdate[j,1]) %>% select(userid) 

result[datenum*i-datenum+j,3] <-nrow(intersect(cohortA, cohortB))

# dplyr 패키지의 distinct를 이용하였다. 


4) 그럼 이제, 날짜별로 Retention한 회수를 구해보자. 가령 10-11일 방문자 aaa,bbb,ccc,ddd는 12일에도 aaa,bbb,ccc,ddd 모두 재방문 했고, 13일에는 aaa만 방문했다. 패키지 중에 이런 계산을 쉽게하는 놈이 분명히 있을텐데, 그런걸 모르니 그냥 함수를 하나 만들었다. 함수 이름은 retention, 변수는 csv를 읽어온 파일을 data.frame형태로 바꾼 놈이면 된다. 해당 데이터 프레임에 userid column, date column이 있어야 한다.


#함수를 선언합니다.

retention <-function(xdata) {


#필요한 데이터를 뽑아냄

xuser <- xdata %>% distinct(userid)        # userid를 중복없이 뽑아냄

xuser<- select(xuser, userid, date)          # 다른 컬럼은 필요없으니 userid, date variable만 가져옴

xdate<-unique(select(xuser,date))          # 위의 값에서 unique한 날짜만 뽑아냄

datenum <- length(unique(xuser$date)) # 전체 데이터에 대해 돌리기 위해 분석할 날짜가 얼마나 되는지 구함


#결과데이터 들어갈 공간을 만둘어줌

#Cohort / Date / Count 3개의 Variable = 열 개수  #Chort * Date = 행 개수

result<- data.frame(matrix(0, nrow(xdate)*nrow(xdate) ))


# 반복문을 한 번 돌려보자  

for (i in 1:datenum) {   

              #해당 날짜의 방문자의 ID를 중복없이 뽑아냄

              cohortA <-xuser %>% filter(date==xdate[i,1]) %>% select(userid) 


              for (j in 1:datenum) {

 

                   # cohort 이름을 cohort variable에 추가한다.

                   result[datenum*i-datenum+j,1] <- paste("Cohort",xdate[i,1], sep=".")


                  # Date를 date variable에 추가한다.

                  result[datenum*i-datenum+j,2] <- paste(xdate[j,1])


                  ########### Count를 계산한다 ##############

                 # 일단 날짜별로 unique ID를 뽑아냄

                 cohortB <-xdata %>% filter(date==xdate[j,1]) %>% select(userid) 

                 #교집합을 뽑아내면, 해당 일자에 재방문한 unique한 회수가 됨

                 result[datenum*i-datenum+j,3] <-nrow(intersect(cohortA, cohortB))

               } # for

} # for


return (result)


} # function


이용할 때는 retention(xdata)와 같이 하면 된다. 결과값은 다음과 같다. 인수 이름은 마음대로 넣으면 된다. 


retention.data<-retention(data)


처음에 data.frame을 만들 때 column의 이름을 정해주지 않았다. 여기서 추가로 정해주면 된다.

names(retention.data)<-c("cohort", "date", "count")


Cohort Group별, 날짜별로 재방문한 ID 개수를 확인할 수 있다.




5) 이제 위의 데이터로 Area그래프를 그려보자. 남들 다 쓰는 ggplot2 패키지의 geom_area 를 활용하면 쉽게 그릴 수 있다.

colours 옵션은 colours<-c(rainbow(nrow(xdate)))와 같이 rainbow 함수를 쓰면 쉽게 설정할 수 있다.


ggplot(retention.data, aes(x=date, y=count, group=cohort)) + geom_area(aes(fill = cohort)) + scale_fill_manual(values=colours) + ggtitle('Retention by Cohort')

# ggplot2는 워낙 유명한 패키지니 자세한 설명은 생략한다.


 

차트가 그려졌다. 데이터가 3일분 밖에 없어서 모양은 좀 별로지만, 원하던 모양이 맞다. 


초보라, 간단히 데이터를 읽고 차트를 그리는 과정을 배우면서 몹시 기분이 좋았다. 아주 간단해 보이지만 R을 처음 배우는 나로서는 (책도 이제 반쯤 읽음) 여러가지 패키지를 쓰고, 기초를 익혀서 그래프를 그리고 나니 작은 거 하나라도 성취한 듯 하야 몹시 기뻐 글로 남기고자 한다. R의 전문가분들에게야 한없이 간단한 일이겠지만... 첫걸음을 떼는 초보에게는 "간단해 보이지만 자그만치 2개의 R패키지 기술이 합쳐진 컴비네이션 (에이. 하나 더 쓸걸) 이었단 말이다."




R 배우기 - 독학

1) R in action.pdf라고 쳐보면 Google에서 2011년 버전을 통째로 다운 받을 수 있음 (최신판 아니지만 기초 배우는 데는 상관없네요.)

2) Stackoverflow.com 실제 코드를 어떻게 활용하는지는 주로 여기하고, 구글 검색으로 배우고 있습니다.

3) Coresera에 동영상 강좌들: 보면 도움이 될 거 같은데, 일단 책이나 다 읽고 하려구요. 




Github에는 정말 어지간한 소스는 다 찾을 수 있다. 예를 들어 위의 문제에 대한 더 일반적인 해결책 소스는 아래 주소를 참고하자.  

https://github.com/mattm/retentioneer/blob/master/retentioneer.R



댓글
  • 프로필사진 BlogIcon 아이보스 내용 잘 읽었습니다. 제가 운영하고 있는 아이보스라는 곳도 커뮤니티(온라인마케팅 분야)의 성격을 지니고 있어 회원가입 후 유지되는 비율이 매우 중요합니다. 코호트 리텐션 분석을 통해 사이트의 현실을 보다 직관적으로 파악할 수 있는 것 같습니다. 2016.05.28 14:22
댓글쓰기 폼