DolphinDB 是新一代的高性能分布式时序数据库 (time-series database) ,同时具有丰富的数据分析和分布式计算功能。本教程使用 DolphinDB database 对淘宝 APP 的用户行为数据进行分析,进一步分析业务问题。
本教程中,我们把 DolphinDB 以及使用的数据集封装到 docker 中。 docker 中包含了 DolphinDB 的分布式数据库 dfs://user_behavior 。它包含一张表 user ,保存了 2017 年 11 月 25 日到 2017 年 12 月 3 日之间将近一百万淘宝 APP 用户的行为记录。我们采用组合分区方式,第一层按照日期分区,每天一个分区,第二层按照 userID 进行哈希分区,一共划分为 180 个分区。 user 表的结构如下所示:
各种用户行为类型的含义如下:
1. 下载docker部署包
本教程已经把 DolphinDB 以及用到的数据封装到 docker 容器中。使用前确保 docker 环境已经部署好。 docker 安装教程请参考。下载部署包,到部署包所在目录执行以下代码。
解压部署包:
gunzip bigdata.tar.gz
导入容器快照作为镜像:
cat bigdata.tar | docker import - my/bigdata:v1
获取镜像 my/bigdata:v1 的 ID:
docker images
启动容器(根据实际情况替换 images id ):
docker run -dt -p 8888:8848 --name test <image id> /bin/bash ./dolphindb/start.sh
在浏览器地址栏中输入本机 IP 地址 :8888 ,如 localhost:8888 ,进入 DolphinDB Notebook 。以下代码均在 DolphinDB Notebook 中执行。
该 docker 中的 DolphinDB license 有效期到 2019 年 9 月 1 日,如果 license 文件过期,只需要到官网下载社区版,用社区版的 license 替换 bigdata.tar/dolphindb/dolphindb.lic 即可。
2. 用户行为分析
查看数据量:
login("admin","123456")
user=loadTable("dfs://user_behavior","user")
select count(*) from user
98914533
user 表中一共有 98,914,533 条记录。
分析用户从浏览到最终购买商品整个过程的行为情况:
PV=exec count(*) from user where behavior="pv"
88596903
UV=count(exec distinct userID from user)
987984
在这 9 天中,淘宝 APP 的页面访问量为 88,596,903 ,独立访客为 987,984 。
上面使用到的 exec 是 DolphinDB 独有的功能,它与 select 类似。两者的区别是, select 语句总是返回一个表, exec 选择一列时会返回一个向量,与聚合函数一起使用时会返回一个标量,与 pivoy by 一起使用时会返回一个矩阵,方便后续对数据的计算。
统计只浏览一次页面的用户数量:
>
92
jumpRate=onceUserNum\UV*100
0.009312
只有 92 个用户只浏览过一个页面就离开了 APP ,占总用户数的 0.0093% ,几乎可以忽略不计,说明淘宝有足够的吸引力让用户停留在 APP 中。
统计各个用户行为的数量:
behaviors=select count(*) as num from user group by behavior
计算从有浏览到有意向购买的转化率:
将商品加入购物车和收藏商品都可以认为用户有意向购买。统计有意向购买的用户行为数量:
fav_cart=exec sum(num) from behaviors where behavior="fav" or behavior="cart"
8318654
intentRate=fav_cart\PV*100
9.389328
从浏览到有意向购买只有 9.38% 的转化率。
buy=(exec num from behaviors where behavior="buy")[0]
1998976
buyRate=buy\PV*100
2.256259
intent_buy=buy\fav_cart*100
24.030041
从浏览到最终购买只有 2.25% 的转化率,从有意向购买到最终购买的转化率为 24.03% ,说明大部分用户用户会把中意的商品收藏或加入购物车,但不一定会立即购买。
对各种用户行为的独立访客进行统计:
userNums=select count(userID) as num from (select count(*) from user group by behavior,userID) group by behavior
pay_user_rate=(exec num from userNums where behavior="buy")[0]\UV*100
67.852313
这 9 天中,使用淘宝 APP 的付费用户占 67.8% ,说明大部分用户会在淘宝 APP 上购物。
统计每天各种用户行为的用户数量:
dailyUserNums=select sum(iif(behavior=="pv",1,0)) as pageView, sum(iif(behavior=="fav",1,0)) as favorite, sum(iif(behavior=="cart",1,0)) as shoppingCart, sum(iif(behavior=="buy",1,0)) as payment from user group by date(behaveTime) as date
周五、周六和周日( 2017.11.25 、 2017.11.26 、 2017.12.02 、 2017.12.03 )淘宝 APP 的访问量明显增加。
iif 是 DolphinDB 的条件运算符,它的语法是 iif(cond, trueResult, falseResult) , cond 通常是布尔表达式,如果满足 cond ,则返回 trueResult ,如果不满足 cond ,则返回 falseResult 。
分别统计每天不同时间段下 站长交易 各种用户行为的数量。我们提供了以下两种方法:
第一种方法是分别统计各个时间段的数据,再把各个结果合并。例如,统计工作日 2017.11.29 (周三)不同时间段的用户行为数量。
re1=select first(behaveTime) as time, sum(iif(behavior=="pv",1,0)) as pageView, sum(iif(behavior=="fav",1,0)) as favorite, sum(iif(behavior=="cart",1,0)) as shoppingCart, sum(iif(behavior=="buy",1,0)) as payment from user where behaveTime between 2017.11.29T00:00:00 : 2017.11.29T05:59:59
re2=select first(behaveTime) as time, sum(iif(behavior=="pv",1,0)) as pageView, sum(iif(behavior=="fav",1,0)) as favorite, sum(iif(behavior=="cart",1,0)) as shoppingCart, sum(iif(behavior=="buy",1,0)) as payment from user where behaveTime between 2017.11.29T06:00:00 : 2017.11.29T08:59:59
re3=select first(behaveTime) as time, sum(iif(behavior=="pv",1,0)) as pageView, sum(iif(behavior=="fav",1,0)) as favorite, sum(iif(behavior=="cart",1,0)) as shoppingCart, sum(iif(behavior=="buy",1,0)) as payment from user where behaveTime between 2017.11.29T09:00:00 : 2017.11.29T11:59:59
re4=select first(behaveTime) as time, sum(iif(behavior=="pv",1,0)) as pageView, sum(iif(behavior=="fav",1,0)) as favorite, sum(iif(behavior=="cart",1,0)) as shoppingCart, sum(iif(behavior=="buy",1,0)) as payment from user where behaveTime between 2017.11.29T12:00:00 : 2017.11.29T13:59:59
re5=select first(behaveTime) as time, sum(iif(behavior=="pv",1,0)) as pageView, sum(iif(behavior=="fav",1,0)) as favorite, sum(iif(behavior=="cart",1,0)) as shoppingCart, sum(iif(behavior=="buy",1,0)) as payment from user where behaveTime between 2017.11.29T14:00:00 : 2017.11.29T17:59:59
re6=select first(behaveTime) as time, sum(iif(behavior=="pv",1,0)) as pageView, sum(iif(behavior=="fav",1,0)) as favorite, sum(iif(behavior=="cart",1,0)) as shoppingCart, sum(iif(behavior=="buy",1,0)) as payment from user where behaveTime between 2017.11.29T18:00:00 : 2017.11.29T21:59:59
re7=select first(behaveTime) as time, sum(iif(behavior=="pv",1,0)) as pageView, sum(iif(behavior=="fav",1,0)) as favorite, sum(iif(behavior=="cart",1,0)) as shoppingCart, sum(iif(behavior=="buy",1,0)) as payment from user where behaveTime between 2017.11.29T22:00:00 : 2017.11.29T23:59:59
re=unionAll([re1,re2,re3,re4,re5,re6,re7],false)
这种方法比较简单,但是需要编写大量重复代码。当然也可以把重复代码封装成函数。
def calculateBehavior(startTime,endTime){
return select first(behaveTime) as time, sum(iif(behavior=="pv",1,0)) as pageView, sum(iif(behavior=="fav",1,0)) as favorite, sum(iif(behavior=="cart",1,0)) as shoppingCart, sum(iif(behavior=="buy",1,0)) as payment from user where behaveTime between startTime : endTime
}
这样只需要指定时间段的起始时间即可。
另外一种方法是通过 DolphinDB 的 Map-Reduce 框架来完成。例如,统计工作日 2017.11.29 (周三)的用户行为。
def caculate(t){
return select first(behaveTime) as time, sum(iif(behavior=="pv",1,0)) as pageView, sum(iif(behavior=="fav",1,0)) as favorite, sum(iif(behavior=="cart",1,0)) as shoppingCart, sum(iif(behavior=="buy",1,0)) as payment from t
}
ds1 = repartitionDS(<select * from user>, `behaveTime, RANGE,2017.11.29T00:00:00 2017.11.29T06:00:000 2017.11.29T09:00:00 2017.11.29T12:00:00 2017.11.29T14:00:00 2017.11.29T18:00:00 2017.11.29T22:00:00 2017.11.29T23:59:59)
WedBehavior = mr(ds1, caculate, , unionAll{, false})
我们使用 repartitionDS 函数对 user 表重新按照时间范围来分区(不改变 user 表原来的分区方式),并生成多个数据源,然后通过 mr 函数,对数据源进行并行计算。 DolphinDB 会把 caculate 函数应用到各个数据源上,然后把各个结果合并。
工作日,凌晨( 0 点到 6 点)淘宝 APP 的使用率最高,其次是下午( 14 点到 16 点)。
统计周六( 2017.11.25 )和周日( 2017.11.26 )的用户行为:
ds2 = repartitionDS(<select * from user>, `behaveTime, RANGE,2017.11.25T00:00:00 2017.11.25T06:00:000 2017.11.25T09:00:00 2017.11.25T12:00:00 2017.11.25T14:00:00 2017.11.25T18:00:00 2017.11.25T22:00:00 2017.11.25T23:59:59)
SatBehavior = mr(ds2, caculate, , unionAll{, false})
ds3 = repartitionDS(<select * from user>, `behaveTime, RANGE,2017.11.26T00:00:00 2017.11.26T06:00:000 2017.11.26T09:00:00 2017.11.26T12:00:00 2017.11.26T14:00:00 2017.11.26T18:00:00 2017.11.26T22:00:00 2017.11.26T23:59:59)
SunBehavior = mr(ds3, caculate, , unionAll{, false})
周六和周日各个时间段淘宝 APP 的使用率都比工作日的使用率要高。同样地,周六日淘宝 APP 使用高峰是凌晨( 0 点到 6 点)。
3. 商品分析
allItems=select distinct(itemID) from user
4142583
在这 9 天中,一共涉及到 4,142,583 种商品。
统计每个商品的购买次数:
itemBuyTimes=select count(userID) as times from user where behavior="buy" group by itemID order by times desc
统计销量前 20 的商品:
salesTop=select top 20 * from itemBuyTimes order by times desc
ID 为 3122135 的商品销量最高,一共有 1,408 次购买。
统计各个购买次数下商品的数量:
buyTimesItemNum=select count(itemID) as itemNums from itemBuyTimes group by times order by itemNums desc
结果显示,绝大部分( 370,747 种)商品在这 9 天中都只被购买了一次,占所有商品的 8.94% 。购买次数越多,涉及到的商品数量越少。
统计所有商品的用户行为数量:
allItemsInfo=select sum(iif(behavior=="pv",1,0)) as pageView, sum(iif(behavior=="fav",1,0)) as favorite, sum(iif(behavior=="cart",1,0)) as shoppingCart, sum(iif(behavior=="buy",1,0)) as payment from user group by itemID
统计浏览量前 20 的商品:
pvTop=select top 20 itemID,pageView from allItemsInfo order by pageView desc
浏览量最高的商品 ID 为 812879 ,共有 29,720 次浏览,但是销量仅为 135 ,没有进入到销量前 20 。
统计销量前 20 的商品各个用户行为的数量:
select * from ej(salesTop,allItemsInfo,`itemID) order by times desc
销量最高的商品 3122135 的浏览量为 1777 ,没有进入浏览量前 20 ,从浏览到购买的转化率高达 79.2% ,该商品有可能是刚需用品,用户不需要太多浏览就决定购买。
扩展练习:
( 1 )计算 2017.11.25 每小时淘宝 APP 的购买率(购买率 = 购买次数 / 总行为次数 *100% )
( 2 )找出购买次数最多的用户以及他购买最多的商品
( 3 )计算商品 ID 为 3122135 的商品在各个时间段中的购买次数
( 4 )统计每个类别每个行为的次数
( 5 )计算每个类别中销量最高的商品
本教程仅供学习使用。
来自 “ ITPUB博客 ” ,链接:https://blog.itpub.net/69992959/viewspace-2753909/ ,如需转载,请注明出处,否则将追究法律责任。