美文网首页
使用MySQL 对淘宝用户进行数据分析 实战学习

使用MySQL 对淘宝用户进行数据分析 实战学习

作者: 秦_Eric | 来源:发表于2019-03-18 21:08 被阅读0次

    案例来源: 知乎《使用 MySQL 对淘宝用户行为进行分析》 by StarLau

    总结:

    MySQL编码问题需要重新学习,配置环境也要重新学习

    原作者对数据类型没有合理设置,MySQL数据类型的选择对检索性能影响较大。

    学习到的几点:

    1.日期和时间格式拆分

    2.从日转为周date_format()函数,同时,group by 可以使用select 中的字段(别名)(group by 后的字段一定要是select中的字段,不然你怎么分组显示呢?)

    3.描述性分析

    4.用MySQL做RFM模型的语法

    5.case when 的用法

    没有涉及的知识点:表的关联

    1.背景

    数据为淘宝APP 2014年11月-2014年12月的用户行为数据

    包含字段:

    数据已做脱敏处理,地理位置大多为NULL,且加密处理过无法分析。

    2数据加载

    下载的数据是CSV格式,102万条记录,500M,初步尝试导入出现了几个问题。

    问题1:数据编码不符

    文件原始编码为ASCII,需要转为utf8,常见方法为用记事本的方法打开CSV文件,另存的时候修改保存编码。

    另存为-修改编码方式

    但第二问题就出现了:文件太大,电脑打不开。使用分块读取,并直接保存为utf8格式,利用的Python中的pandas,代码如下

    import pandas as pd 

    f = open('路径')

    reader = pd.read_csv(f, sep=',', iterator=True)

    loop =True

    chunkSize =100000

    chunks = []

    while loop:

                   try:        

                           chunk = reader.get_chunk(chunkSize)        

                           chunks.append(chunk)

                   exceptStopIteration:        

                            loop =False

                           print("Iteration is stopped.")

    df = pd.concat(chunks, ignore_index=True)

    df.to_csv('路径',encoding=utf8,ignore_index=false)

    问题3:成功转为utf8格式的文件后,使用load导入MySQL时,数据量出错。

    原文件只有102万条记录,导入数据库后,select count(*) 后发现返回了1200万条记录。查看前1000条记录,没有发现数据格式有问题,那就只可能是重复导入了。但导入代码是没有问题,不知道问题在哪。

    load导入语言

    load data infile '路径' into table user_behavior fields terminated by',' optionally enclosed by '"' lines terminated by '\r\n' ignore 1 lines

    最后放弃全部导入,只读取了前10万条数据,导入MySQL,成功导入。

    导入小结:

    MySQL导入可以使用一些图形化界面的软件,比如Navicat。但作为新手,如果使用图形化软件,可能就不会遇到这些问题了,也就不能了解导入存在的问题。常见问题:编码,导入语句,路径书写(使用反斜杠)

    3.数据一致化处理:

    1.字段behavior_type 原值标签为1234,对应为pv(浏览量)、fav(收藏)、cart(加入购物车)、buy(支付)。为了便于分析,修改为对应行为。

    UPDATE user SET behavior_type = REPLACE(behavior_type, 1, 'pv');

    UPDATE user SET behavior_type = REPLACE(behavior_type, 2, 'fav');

    UPDATE user SET behavior_type = REPLACE(behavior_type, 3, 'cart');

    UPDATE user SET behavior_type = REPLACE(behavior_type, 4, 'buy');

    2.将date-time字段拆分为date和time

    -- 重命名 time 字段名称为 date    ALTER TABLE user CHANGE time date VARCHAR(255);

    -- 添加 time 列    ALTER TABLE user ADD time VARCHAR(20);

    -- 复制 date 列到 time 列   UPDATE user SET time = date;

    -- 在 date 列截取(年-月-日)信息UPDATE user SET date = REPLACE(date, date, SUBSTRING_INDEX(date,' ',1));

    -- 在 time 列截取小时信息UPDATE user SET time = REPLACE(time, time, SUBSTRING_INDEX(time,' ',-1));

    4.数据分析

    1.整体用户访问情况

    对应指标:pv(浏览量)  两种都可以计算出

    ①SELECT COUNT(behavior_type) AS '总访问量' FROM user GROUP BY behavior_type HAVING behavior_type='pv';

    ②select count(*) from user_behavior where behavior_type='pv'

    2.日均访问量

    对应指标:每日pv

    ①SELECT date,COUNT(behavior_type) AS '日均访问量' FROM user WHERE behavior_type='pv' GROUP BY date ORDER BY date;

    3.访客数

    对应指标:uv

    ①SELECT COUNT( DISTINCT user_id) AS '用户总数' FROM user;

    错误:select count(user_id) from user_behavior group by user_id

    想法:每个用户id都是独立的,那将id分组,然后统计有多少个分组也可以实现。问题出在上面的一段SQL返回的是明细,每个user_id的重复次数

    ②正确: select count(*) from (select count(user_id) from user_behavior group by user_id) as t

    要点:使用了临时表,要注意必须为临时表指定名称,不然报错。

    4.用户中有购买行为的人数

    SELECT COUNT( DISTINCT user_id) AS '购买用户数量' FROM user WHERE behavior_type='buy';

    5.用户的购物情况

    作者建立了视图。相对于临时表,视图可以保存在数据库中,当下次使用时,可以直接引用,同时视图可以随着数据的更新而更新,比较方便。

    原数据是以单条用户行为为记录,视图是汇总单个用户的行为数

    CREATE VIEW user_behaviorASSELECT

    user_id, count(behavior_type),

    SUM(CASE WHEN behavior_type='pv' THEN 1 ELSE 0 END) AS 'pv',

    SUM(CASE WHEN behavior_type='fav' THEN 1 ELSE 0 END) AS 'fav',

    SUM(CASE WHEN behavior_type='cart' THEN 1 ELSE 0 END) AS 'cart',

    SUM(CASE WHEN behavior_type='buy' THEN 1 ELSE 0 END) AS 'buy'

    FROM userGROUP BY user_idORDER BY COUNT(behavior_type) DESC;

    问题:初次建立视图,字段的别名都是汉字,比如(访问量),在后期使用的时候又报出编码错误,无法识别。没有找到解决办法,使用英文单词代替。

    6.复购率

    对应指标:re_purchases 购买>2/购买人群

    SELECT CONCAT(ROUND(SUM(case when 购买次数>=2 then 1 else 0 end)/SUM(case when 购买次数 >0 then 1 else 0 end)*100),'%') AS '复购率' FROM user_behavior;

    问题:自己当时想的是直接select count两种人群数,然后做除法。事实上既费劲,运行时间又长

    select (select count(user_id) from user_behavior_details where buy>=2)/(select count(*) from user_behavior_detail where buy>0) as  percentage

    7.转化漏斗

    从访问——>加购物车——>购买三个环节用户流失的情况分析

    计算各个环节与上个环节的比值

     SELECT

    CONCAT(ROUND(SUM(点击次数)/SUM(点击次数)*100,2),'%') AS 'pv',

    CONCAT(ROUND((SUM(加购数)+SUM(收藏次数))/SUM(点击次数)*100,2),'%') AS 'pv_to_favCart',

    CONCAT(ROUND(SUM(购买次数)/SUM(点击次数)*100,2),'%') AS 'pv_to_buy'

    FROM user_behavior;

    8.查看购买率高和购买率低的用户在其他行为上有何区别

    SELECT user_id,点击次数,收藏次数,加购数,购买次数,ROUND(购买次数/点击次数*100,2) AS '购买率' FROM user_behavior GROUP BY user_id ORDER BY 购买率 DESC;

    9.一天中用户行为特征

    SELECT time, COUNT(behavior_type),

    SUM(CASE WHEN behavior_type='pv' THEN 1 ELSE 0 END) AS '点击次数',

    SUM(CASE WHEN behavior_type='fav' THEN 1 ELSE 0 END) AS '收藏次数',

    SUM(CASE WHEN behavior_type='cart' THEN 1 ELSE 0 END) AS '加购数',

    SUM(CASE WHEN behavior_type='buy' THEN 1 ELSE 0 END) AS '购买次数'

    FROM user  GROUP BY time  ORDER BY time;

    10.一周内用户行为特征

    我第一想法:除了case then 外可以使用其他吗?比如  count(pv) from behavior_type where behavior_type='pv' 只显示pv的,然后用uion联合fav,cart,buy。因为select的字段是一致的,所以应该可以

    select  data_format(time,'%W') as week ,

    sum(case when behavior_type='pv' then 1 eles 0 end) as 'pv'

    sum(case when behavior_type='fav' then 1 else 0) as 'fav'

    sum(case when behavior_type='cart' then 1 else 0) as 'cart'

    sum(case then behavior_type='buy' then 1 else 0) as 'buy'

    from behavior_type 

    group by week

    order by date_format(time,'%W')#order by 不可以使用别名?

    11.基于FRM 模型用户细分

    从来没有用过MySQL做用户细分,语句如下

    SELECT r.user_id,f.frequency,recent_rank,freq_rank,

    CONCAT(CASE WHEN recent_rank<=(4330)/4 THEN '4'

    WHEN recent_rank>(4330)/4 AND recent_rank<=(4330)/2 THEN '3'

    WHEN recent_rank>(4330)/2 AND recent_rank<=4330/4*3 THEN '2' ELSE '1' END,

    CASE WHEN freq_rank<=(4330)/4 THEN '4'

    WHEN freq_rank>(4330)/4 AND freq_rank<=(4330)/2 THEN '3'

    WHEN freq_rank>(4330)/2 AND freq_rank<=4330/4*3 THEN '2' ELSE '1' END)

    AS user_value

    FROM (

    SELECT a.*,(@rank:=@rank+1) AS recent_rank FROM(SELECT user_id,DATEDIFF('2014-12-19',max(date)) AS recent

    FROM user AS t1 WHERE behavior_type='buy' GROUP BY user_id ORDER BY recent)AS a,

    (SELECT @rank:=0) AS b) AS r,(SELECT *,(@rank2:=@rank2+1) AS freq_rank

    FROM(SELECT user_id,count(*) AS frequency FROM user WHERE behavior_type='buy' GROUP BY user_id ORDER BY frequency DESC)AS a,(SELECT @rank2:=0)AS b) AS f WHERE r.user_id=f.user_id;

    相关文章

      网友评论

          本文标题:使用MySQL 对淘宝用户进行数据分析 实战学习

          本文链接:https://www.haomeiwen.com/subject/ypwtmqtx.html