플레이어가 성장하는 도중 어디서 이탈을 많이 하는지 측정하기 위해, Stage 진행에 대한 Funnel 정보 (이하, Stage Funnel) 를 그려봤다.
대부분의 아이디어는 컨설팅을 받을 때 배운 것들이고, 그때 했던 것을 복기하는 차원에서 혼자서 해봤다.
우선 간단하게 데이터 정제를 DB 쿼리로 해봤고, 특정 스테이지 기준으로 더이상 정보가 없는 경우 해당 스테이지에 머물렀다고 간주했음
기간이 영향을 줄 수 있는데, 우선은 Funnel 을 그리는데에 집중했고, 이탈을 정의하는 방법에 따라 쿼리의 Where 절을 변경하면 되겠다.
  • 생각의 전개

    • 플레이어의 성장을 측정하기 위해 성장 기준을 무엇으로 삼을지 고민

    • “레벨", "스테이지 진행" 중 "스테이지 진행”을 선택

      • 레벨은 직관적이지만 후반 구간일수록 대변하는 플레이어 집단의 특성이 분산될 것으로 예상

        예를 들어, 특정 레벨 구간 N 의 플레이어 집단에 대해
        소유한 재화의 평균을 M(N), 표준편차를 D(N) 이라고 하고,
        3Lv과 50Lv 을 서로 비교해보면,
        M(3) 과 M(50) 의 관계는 예측하기 어렵겠지만, 적어도 D(3) < D(50) 일 가능성이 크다고 생각된다

        요약) 플레이를 많이 함 -> 재화 획득 / 소진을 여러번 경험함 -> 보유 재화의 분산이 큼

      • 스테이지 진행도 뒤로 갈수록 레벨과 비슷한 양상을 보이게 되나,
        레벨보다는 훨씬 덜 할 것으로 판단되는데,
        특정 스테이지를 플레이 해도 레벨이 오르지 않는 경우가 많은 것을 생각해보면 그저 당연한 일일 뿐..

    • 특정 스테이지에 머물러 있다는 정보도 중요하지만,
      사실 “왜” 머물러 있는지가 가장 중요할거라고 생각하고,
      “왜” 에 대한 가장 단순한 접근으로, 머물러 있기 직전에 해당 스테이지를 클리어 했는지 여부를 기준으로 그려봤음

    • 실패했는데 나가는것과 성공했는데 나가는 것이 어떤 의미를 갖고 있을지 고민중...

library(RMySQL)

# connect to db
conn <- dbConnect(MySQL(), user='', password='', dbname='', host='')

# select tidy data for stage funnel from stats log db
rs <- dbSendQuery(conn, "select cid, max(cd6) as field, 'lose' as result from _stats_log
     where ts > '2015-01-01 00:00:00'
          and ea like '%lose%'
          and el = 'player'
          and ec = 'combat'
     group by cid
union all
select cid, max(cd6), 'win' as result from _stats_log
     where ts > '2015-01-01 00:00:00'
          and ea like '%win%'
          and el = 'player'
          and ec = 'combat'
     group by cid;
")

# fetch result set
table <- fetch(rs, -1)

# clear db resources
dbClearResult(rs)
dbDisconnect(conn)

# result and field are factor
table$result <- as.factor(table$result)
table$field <- as.factor(table$field)

# show summary information
summary(table)

# draw result
library(ggplot2)

p <- ggplot(table, aes(field, fill=result))
p + geom_bar(position="dodge")



R 에서 의사결정나무 (Decision Tree) 를 간단하게 그려봤다

g1_grade, g1_type 의 값에 따라 succeeded 가 결정된다고 가정하고
이를 위한 예제용 데이터를 만들어봤다

의사결정 나무를 그리는 코드는 여기를 참고해서 만들어봤음 : http://www.statmethods.net/advstats/cart.html

코드 예제에서 rpart method=“anova” 로 되어있는데, 그렇게 그렸더니 원하는 결과가 나오지 않아서
박장시님 도움으로 rpart method=“class” 라고 써야한다는 것과 rattle package 에 대해 배움! - 장시님, 감사 (_ _)



# install prerequisite packages
# 이건 처음에 한번만 하면 됨
install.packages("rpart")
install.packages("rpart.plot")
install.packages("rattle")



# load library of rpart
library(rpart)
library(rpart.plot)
library(rattle)


# make sample data
df <- data.frame(g1_grade=3, g1_type=1, succeeded=1, seq=1:1000)
df <- rbind(df, data.frame(g1_grade=3, g1_type=3, succeeded=0, seq=1:800))
df <- rbind(df, data.frame(g1_grade=3, g1_type=2, succeeded=0, seq=1:900))
df <- rbind(df, data.frame(g1_grade=3, g1_type=1, succeeded=0, seq=1:100))
df <- rbind(df, data.frame(g1_grade=2, g1_type=1, succeeded=1, seq=1:100))
df <- rbind(df, data.frame(g1_grade=2, g1_type=1, succeeded=0, seq=1:800))
df <- rbind(df, data.frame(g1_grade=2, g1_type=2, succeeded=0, seq=1:800))
df <- rbind(df, data.frame(g1_grade=2, g1_type=2, succeeded=1, seq=1:100))
df <- rbind(df, data.frame(g1_grade=2, g1_type=3, succeeded=1, seq=1:200))
df <- rbind(df, data.frame(g1_grade=2, g1_type=3, succeeded=0, seq=1:900))

# show structure of df
str(df)
'data.frame': 5700 obs. of 4 variables:
$ g1_grade : num 3 3 3 3 3 3 3 3 3 3 ...
$ g1_type : num 1 1 1 1 1 1 1 1 1 1 ...
$ succeeded: num 1 1 1 1 1 1 1 1 1 1 ...
$ seq : int 1 2 3 4 5 6 7 8 9 10 ...

# make decision tree
tree <- rpart(succeeded ~ g1_type + g1_grade, data = df,
               method = "class", control = rpart.control(minsplit = 10))


# draw it with just simple plot!
plot(tree)
text(tree, use.n=TRUE, all=TRUE, cex=.8)

# check working directory
getwd()

# create post script file to export tree to pdf
post(tree, file = "tree.ps", title = "How to success")

# draw it with fancy tree!
fancyRpartPlot(tree)




그림들은 모두 같은 그림이고 포장만 좀 다르다.
fancyRpartPlot 이 가장 보기 좋다!

데이터를 해석해보자면,

* 전체 데이터 중 75% 는 succeeded = 0, 25% 는 succeeded = 1
     이게 조금 헛갈릴 수 있는데, 각 노드의 두번째 줄에 표시된 값이
     평가 대상 변수의 분포 비율이라고 보면 됨

* 1번 -> 2번 : 65% 가 넘어갔음. 이 데이터는 g1_type = {2, 3}.
     succeeded 분포는 0 이 92%, 1 이 8% 로,
     이를 통해 g1_type 이 2, 3 인 데이터는 succeeded = 1 이 될 확률이 8% 밖에 안된다고 볼 수 있음

* 1번 -> 3번 : 35% 가 넘어갔음. g1_type = 1
     succeeded 분포는 0 이 45%, 1 이 55% 로,
     g1_grade 기준으로 분기가 또 이루어짐

     * 3번 -> 6번 : 3번 조건인 데이터 중 (전체의 35%),
          전체의 16% 에 해당하는 데이터가 g1_grade < 2.5
          이를 통해 g1_type = 1 && g1_grade < 2.5 인 경우 succeeded = 1 이 될 확률이 11% 

     * 3번 -> 7번 : 3번 조건인 데이터 중 (전체의 35%),
          전체의 19% 에 해당하는 데이터가 g1_grade >= 2.5
          이를 통해 g1_type = 1 && g1_grade >= 2.5 인 경우 succeeded = 1 이 될 확률이 91% 

목적상 succeeded = 1 을 원한다면,
데이터의 g1_type = 1 로 만드는 것이 가장 큰 도움이 되고, 그 다음으로 g1_grade 를 2.5 이상으로 만들어야 함

의사결정 나무에 대해 살짝 알아봤는데,
코드 작성 없이 데이터 만으로 의사결정 나무를 만들어주고 시각화 해주는 R 이 매력적으로 느껴짐!



R 에서 MySQL 에 접속해서 SELECT 한 결과로 보고서를 그려보자

JOIN 이 가능하니, MySQL 에 로그를 넣어놓으면 가공하기 더 좋을 것 같다

참고로 아래 그래프는 우리 데이터에서 grade 별 count 에 대한 graph!



# load libraries for access and draw
library ("DBI")
library ("RMySQL")
library ("ggplot2")


# connect to database server
conn = dbConnect(MySQL(), user=’user', password=‘password', dbname=‘dbname', host=‘host')

# get table list
dbListTables(conn)

# query table content
rs = dbSendQuery(conn, "SELECT * FROM table")

# fetch and make data frame from ResultSet
table = fetch(rs)

# get column names
names(table)

# prepare plot for drawing
d = ggplot(table, aes(factor(column)))

# draw simple bar
d + geom_bar()

# release ResultSet resource
dbClearResult(rs)

# release DB Connection resource
dbDisconnect(conn)



문법 익힐겸, 무의미한 데이터를 만들어서 그림을 그려본다

단순히 랜덤 값으로 data frame 을 구성하고, y축 값을 sort 해서 step 을 그리는 구문이다



# load library
library ("ggplot2")

# set data frame with x and y
# y is random from 10 to 20
d = data.frame(x=1:100, y=runif(100, min=10, max=20))

# sort data of y
d$y = sort(d$y)

# draw step
p = ggplot(d, aes(x, y))
p + geom_step()



- Download & Install R

     R Homepage
          http://www.r-project.org/

     서울대 mirror
          http://healthstat.snu.ac.kr/CRAN/


- R Studio Download
     http://www.rstudio.com/products/rstudio/download/

     R Studio 가 참 훌륭한것 같음!


- 시각화 Plugin (ggplot)
     http://docs.ggplot2.org/current/

- install ggplot
     > install.packages("ggplot2")

     - 처음에 실행해서 ggplot2 를 설치하려고 하면
     > tar: Failed to set default locale

     뭐 이런 메시지 나오는데, Mac Terminal 에
     $ defaults write org.R-project.R force.LANG en_US.UTF-8

     http://davidprakash.blogspot.kr/2011/05/r-error-tar-failed-to-set-default.html
     이렇게 하고 재시작 하면 됨..



- 간단한 그래프 그려보기
     > x = 1:1000
     > y = x^2
     > plot(x, y)

+ Recent posts