利用 R 語言對使用者進行深度挖掘
作者簡介:謝佳標
樂逗遊戲高階資料分析師,負責大資料探勘及視覺化。資深 R 語言使用者,有九年以上資料探勘工作實戰經驗,多次在中國 R 語言大會上作主題演講。與張良均老師、楊坦老師合著的《R 語言與資料探勘》一書已在 2016 年 7 月出版,新書《R 語言遊戲資料分析》一書也即將於 2017 年初出版。
隨著遊戲市場競爭的日趨激烈,在如何獲得更大收益延長遊戲週期的問題上,越來越多的手機遊戲開發公司開始選擇藉助大資料,以便挖掘更多更細的使用者群、瞭解使用者習慣來進行精細化、個性化的運營。遊戲行業對使用者的深度挖掘一般從兩方面著手:
一方面是使用者遊戲行為的深度分析,如玩家在遊戲中的點選事件行為挖掘,譬如說新手教程中的點選事件,我們一般選擇最關心的點選事件(即關鍵路徑)進行轉化率的分析(統計每個關鍵路徑的點選人數或次數),通過漏斗圖的展現形式就可以直接看出每個關鍵路徑的流失和轉化情況。漏斗圖適合於單路徑轉化問題,如果涉及到多路徑(點選完一個按鈕後有多個按鈕同時提供選擇)情況時,可以使用路徑分析的方法,路徑分析更加基礎、更加全面、更加豐富、更能真實再現玩家在遊戲中的行為軌跡。
另一方面是對使用者付費行為的深度挖掘。付費使用者是直接給公司創造價值的核心使用者群,通過研究這批使用者的付費資料,把脈其付費特徵,可以實現精準推送,有效付費轉化率。
Part 1:路徑分析
總體來說,路徑分析有以下一些典型的應用場景:
可以根據不同的應用場景選擇不同的演算法實現,比如利用 sunburst 事件路徑圖對玩家典型的、頻繁的模式識別,利用基於時序的關聯規則發現前後路徑的關係。
最樸素遍歷法是直接對主要路徑的流向分析,因此最直觀和最容易讓人理解。
1)當用戶行為路徑比較複雜的時候,我們可以藉助當前最流行的資料視覺化 D3.js 庫中的 Sunburst Partition 來刻畫使用者群體的事件路徑點選狀況。從該圖的圓心出發,層層向外推進,代表了使用者從開始使用產品到離開的整個行為統計;sunburst 事件路徑圖可以快速定位使用者的主流使用路徑。靈活使用 sunburst 路徑統計圖,是我們在路徑分析中的一大法寶。
在 R 中,我們可以利用 sunburstR 包中的 sunburst 函式實現 sunburst 事件路徑圖,通過 install.packages(“sunburstR”) 命令完成安裝。
我們以 sunburstR 包中自帶的 visit-sequences.csv 資料集為例進行演示,用 sunburst 函式繪製 sunburst 事件路徑圖。
# sunburst事件路徑圖
# 載入sunburstR包
library(sunburstR)
# 匯入sequences資料
sequences <- read.csv(
system.file("examples/visit-sequences.csv" ,package="sunburstR")
,header = FALSE
,stringsAsFactors = FALSE
)
# 檢視前六行
head(sequences)
## V1 V2
## 1 account-account-account-account-account-account 22781
## 2 account-account-account-account-account-end 3311
## 3 account-account-account-account-account-home 906
## 4 account-account-account-account-account-other 1156
## 5 account-account-account-account-account-product 5969
## 6 account-account-account-account-account-search 692
# 繪製sunburst事件路徑圖
sunburst(sequences)
可見,當我們選中某條路徑時,其他路徑顏色變暗,圓圈中的數字表示選中路徑的人數(或次數)在總人數(或次數)的佔比。右上角是圖例,不同顏色代表不同的點選事件。左上角是我們選中的事件路徑流向。
2)我們可以利用基於時序的關聯規則來研究玩家的點選情況。目的是想找出玩家點選玩牌前一部分的點選情況。在 R 中,可以使用 arulesSequences 包中的核心函式 cspade 實現。此分析的關鍵是如何將普通資料集轉換成模型能識別的事務型資料集。
棋牌遊戲玩家從進入遊戲到玩牌的點選路徑是:歡迎介面操作,大廳介面點選操作,進入房間玩牌。
現在統計某個週期內該款棋牌遊戲的玩家點選事件資料,先檢視前六行情況:
## V1 V2 V3
## 1 1 1 11008
## 2 1 2 11001
## 3 1 3 11034
## 4 1 4 11002
## 5 2 1 11017
## 6 2 2 11004
第一列是玩家 id,第二列是玩家點選按鈕的順序,第三列是點選事件 ID(其中 11034 表示點選開始玩牌按鈕,其他 ID 表示點選 “個人資訊”、“房間列表”、“好友列表”、“halltool” 四大板塊的按鈕)。接下來,我們可以利用 as 函式將資料型別轉換成事務型資料,結果如下所示:
## transactions in sparse format with
## 24338 transactions (rows) and
## 250 items (columns)
## items transactionID sequenceID eventID
## [1] {click=11008} 1 1 1
## [2] {click=11001} 2 1 2
## [3] {click=11034} 3 1 3
## [4] {click=11002} 4 1 4
## [5] {click=11017} 5 2 1
## [6] {click=11004} 6 2 2
利用 arulesSequences 包中的 cspade 函式實現 cSPADE 演算法。由於要找出所有到達開始打牌的路徑,所以將支援度閾值 support 設定為 0,且欲返回點選開始打牌和前一次的點選事件,即返回序列的資料項數最大為 2,所以 maxlen 被設定為 2。
然後使用 sort 函式將 myrules 按照支援度的數值進行降序排序,並設定規則表示式,篩選出序列中最後一個數據項為 {click=11034} 的序列。
# 利用arulesSquences包中的cspade函式實現cSPADE演算法
myrules <- cspade(data_click_tran,parameter=list(support=0,maxlen=2),
control=list(verbose=TRUE))
##
## parameter specification:
## support : 0
## maxsize : 10
## maxlen : 2
##
## algorithmic control:
## bfstype : FALSE
## verbose : TRUE
## summary : FALSE
## tidLists : FALSE
##
## preprocessing ... 1 partition(s), 0.56 MB [0.08s]
## mining transactions ... 0.16 MB [0.13s]
## reading sequences ... [0.57s]
##
## total elapsed time: 0.78s
myrules <- sort(myrules,by="support") # 按照support進行排序
targetclick <- paste0(".*click=11034","[^\\}]*\\}>") # 設定規則表示式
finalrules <-myrules[grep(targetclick ,as(myrules,"data.frame")$sequence)]
inspect(finalrules[1:3]); # 檢視序列的前三條
## items support
## 1 <{click=11034}> 1.0000000
## 2 <{click=11008},
## {click=11034}> 0.6791511
## 3 <{click=11017},
## {click=11034}> 0.2769455
##
序列 2 中的 <{click=11008},{click=11034}> 表示點選行為順序是從 11008(從新手場進入玩牌房間)到 11034(開始玩牌), 支援度為 0.679。
最後,篩選關鍵點選按鈕,衡量其對 11034 的貢獻度。首先計算各點選事件支援度的百分比,並使用 cumsum()函式計算支援度 support 的累計百分比,並把累計百分比達到 75% 以上的點選事件作為引導使用者點選玩牌 11034 的重要事件觸發點。並利用 recharts 包的 echartr 函式繪製垂直的金字塔圖。
# 繪製支援度佔比的垂直金子塔圖
library(reshape)
md <- melt(result,id="click") # 對result資料進行重組
md$value[md$variable == "conf"] <- -md$value[md$variable == "conf"]/3
md <- md[order(md$variable,decreasing=T),] # 按照variable變數進行降序排序
# 繪製垂直金字塔圖
library(recharts)
echartr(md,click,value,variable,type="vbar",subtype="stack") %>%
setTitle("引導使用者進入開始打牌11034的重點事件id分析") %>%
setXAxis(axisLine=list(onZero=TRUE)) %>%
setYAxis(axisLabel=list(
formatter=JS('function (value) {return Math.abs(value);}')))
主要結論:11008 是為按鈕 11034 的點選貢獻最大的引流按鈕,support 佔比為 19.5%,接近全部引流按鈕的五分之一。
Part 2:付費使用者深度挖掘
針對遊戲付費使用者常用的深度挖掘手段如下圖所示:
LTV 預測法是根據玩家的前期付費能力預測未來一段時間的使用者生命週期價值,這在市場做廣告投放時候有很大的參考意義。玩家物品購買的關聯分析和社群發現,可以發現不同物品間的關係,從而可以進行物品捆綁銷售策略的建議。基於玩家物品的智慧推薦是利用物品的協同過濾方法對每一個玩家的購物可能進行推薦,從而實現個性化推薦,這個在現在的電商、網際網路是非常流行的做法。
從資料庫中匯出一份關於玩家物品購買資料,包括使用者 id、商品名稱和購買數量三個變數。前六行如下:
## player_id product_name qty
## 1 107204535 感恩大禮包 1
## 2 107204535 新手禮包 1
## 3 213666611 8條鑰匙 1
## 4 226500629 0.1元大禮包 1
## 5 226500629 8條鑰匙 1
## 6 226500629 限量版角色 1
1)現在,希望利用 arules 包中的 apriori 演算法對上面的資料進行關聯規則發現。此時,需要把資料轉化成事務型資料。程式碼如下:
# 利用cast函式對資料進行重組
library(reshape)
data_matrix <- cast(data,player_id~product_name)
## Using qty as value column. Use the value argument to cast to override this choice
# 檢視前三行五列資料
data_matrix[1:3,1:5]
## player_id 0.1元大禮包 10塊滑板 15000金幣 15元大禮包
## 1 107204535 NA NA NA NA
## 2 213666611 NA NA NA NA
## 3 226500629 1 NA NA NA
# 進行替換,將NA轉化為0,其他數字為1
data_matrix_new <- apply(data_matrix[,-1],2,function(x) {ifelse(is.na(x),0,1)})
# 對矩陣行名稱、列名稱進行賦值
data_matrix_new <- matrix(data_matrix_new,nrow=dim(data_matrix_new)[1],
ncol=dim(data_matrix_new)[2],
dimnames = list(data_matrix[,1],colnames(data_matrix)[-1]))
# 檢視前三行五列資料
data_matrix_new[1:3,1:5]
## 0.1元大禮包 10塊滑板 15000金幣 15元大禮包 1條鑰匙
## 107204535 0 0 0 0 0
## 213666611 0 0 0 0 0
## 226500629 1 0 0 0 0
# 利用as函式將矩陣轉換成事務型
library(arules)
data_class <- as(data_matrix_new,"transactions")
inspect(data_class[1:6]) # 檢視前六條交易記錄
## items transactionID
## [1] {感恩大禮包,新手禮包} 107204535
## [2] {8條鑰匙} 213666611
## [3] {0.1元大禮包,8條鑰匙,限量版角色} 226500629
## [4] {38000金幣,限量版角色,新手禮包} 230329140
## [5] {50條鑰匙} 264162836
## [6] {15000金幣,70000金幣,快速復活} 278620434
現在,可以利用 aurles 進行關聯規則分析和利用 aurlesViz 包進行規則視覺化。
# 建立關聯規則rules
library(arules)
rules <- apriori(data_class,parameter=list(support=0.005,confidence=0.1,minlen=2,target="rules"))
## Apriori
##
## Parameter specification:
## confidence minval smax arem aval originalSupport maxtime support minlen
## 0.1 0.1 1 none FALSE TRUE 5 0.005 2
## maxlen target ext
## 10 rules FALSE
##
## Algorithmic control:
## filter tree heap memopt load sort verbose
## 0.1 TRUE TRUE FALSE TRUE 2 TRUE
##
## Absolute minimum support count: 31
##
## set item appearances ...[0 item(s)] done [0.00s].
## set transactions ...[26 item(s), 6252 transaction(s)] done [0.00s].
## sorting and recoding items ... [21 item(s)] done [0.00s].
## creating transaction tree ... done [0.00s].
## checking subsets of size 1 2 3 done [0.00s].
## writing ... [48 rule(s)] done [0.00s].
## creating S4 object ... done [0.00s].
# 對關聯規則進行視覺化
rules_lift <- subset(rules,subset=lift>2)
library(arulesViz)
plot(rules_lift,method="grouped") #繪製分組矩陣
由圖可知,{超值大禮包} & {新手禮包} 說明這兩條規則的提升度最大;{解鎖滑板} & {限量版角色} 圓圈最大,說明這兩條規則的支援度最大。
2)最後,讓我們用 recommenderlab 對玩家購買道具進行智慧推薦。在構建模型之前,我們需要將資料轉換為評分矩陣。
library(recommenderlab)
# 將矩陣轉化為binaryRatingMatrix物件
data_class <- as(data_matrix_new,"binaryRatingMatrix")
as(data_class,"matrix")[1:3,1:5] #顯示部分物品購買情況
<pre><code>## 0.1元大禮包 10塊滑板 15000金幣 15元大禮包 1條鑰匙
## 107204535 FALSE FALSE FALSE FALSE FALSE
## 213666611 FALSE FALSE FALSE FALSE FALSE
## 226500629 TRUE FALSE FALSE FALSE FALSE</code></pre>
選擇 IBCF 建立推薦模型,對玩家進行 top3 推薦。
## 0.1元大禮包 10塊滑板 15000金幣 15元大禮包 1條鑰匙
## 107204535 FALSE FALSE FALSE FALSE FALSE
## 213666611 FALSE FALSE FALSE FALSE FALSE
## 226500629 TRUE FALSE FALSE FALSE FALSE
#選擇IBCF作為最優模型
model.best <- Recommender(data_class,method="IBCF")
# 使用precict函式,對玩家進行Top3推薦
data.predict <- predict(model.best,newdata=data_class,n=5)
recom3 <- bestN(data.predict,3)
as(recom3,"list")[1:5] #檢視前五個玩家的top3推薦
從上面的分享可知,我們在做資料分析建模之前,資料轉化處於非常重要的地位。如何把原始資料轉化成模型可以識別的資料,需要大家平時的經驗積累。以上內容是在第九屆中國 R 語言會議的分享內容。也是明年初將要出版的《R 語言遊戲資料分析》一書關於使用者分析的部分內容。