數據背景
- 來源:阿里移動推薦算法
- 背景:2014年是阿里巴巴集團移動電商業務快速發展的一年,例如2014雙11大促中移動端成交占比達到42.6%,超過240億元。相比PC時代,移動端網絡的訪問是隨時隨地的,具有更豐富的場景數據,比如用戶的位置信息、用戶訪問的時間規律等。
- 這個比賽的目的是:要使用訓練數據(2014年11月18日至2014年12月18日)建立推薦模型,并輸出用戶在接下來一天(2014年12月19日)對商品子集購買行為的預測結果。
- 而我的目標則是從該數據進行隨機抽樣,并用mysql進行分析,提高自己對電商指標體系的認識。
數據詳情
tianchi_mobile_recommend_train_user命名為USER表:
- user_id, 用戶標識, 抽樣&字段脫敏
- item_id, 商品標識, 字段脫敏
- behavior_type, 用戶對商品的行為類型, 包括瀏覽(1)、收藏(2)、加購物車(3)、購買(4)
- user_geohash, 用戶位置的空間標識,可以為空, 由經緯度通過保密的算法生成
- item_category, 商品分類標識, 字段脫敏
- time, 行為時間, 精確到小時級別
提出問題
- 分析用戶使用APP過程中的常用電商指標,了解運營現狀,查看各個環節的流失率,并找到需要改進的環節。
- 研究用戶在不同維度下的行為規律,了解用戶行為特征,優化運營策略。
- 研究用戶的價值、針對不同價值的用戶進行精細化運營
- 研究用戶生命周期,針對不同周期的用戶采取不同的策略
電商指標
我對電商指標的理解,是基于六個維度的:
- 用戶
- 商品
- 商品類別
- 用戶行為
- 行為地址
- 時間
基于用戶和商品、商品類別可以分析用戶整體的購買偏好。
基于用戶和用戶行為可以分析PV、UV、PV/UV、跳失率、總訂單量、用戶行為之間的轉化率等。
基于用戶和時間可以分析用戶購買的時間偏好。
基于商品類別和用戶行為可以分析不同商品類別的轉化率的差異。
基于商品類別和時間可以分析不同商品類別的熱銷時間段。
基于用戶行為和時間可以分析用戶的行為特征。
基于時間和別的字段,結合RFM模型可以給用戶價值打標簽。
基于AARRR模型,可以分析用戶的生命周期,劃分不同用戶所處的周期階段。
數據的導入及清洗
將csv導入mysql的方法:
- 命令行:關于如何使用命令提示符將CSV文件導入MySQL
- python:將大csv文件導入mysql數據庫
下面的實例用python抽取100000條數據,并導入mysql的數據庫:taobao。
from sqlalchemy import create_engine
import pandas as pd
import pymysql
import numpy as np
#讀取數據
data = pd.read_csv('user.csv',encoding = 'gbk')
data = data.sample(n=1000000)
#創建連接數據庫對象
engine = create_engine('mysql+pymysql://用戶名:密碼@localhost/數據庫名?charset=utf8')
#存入數據庫
data.to_sql('數據庫表名字',engine)
清除空值
數據介紹中說明只有user_geohash中存在空值(非空比例在35%左右)且經過加密處理,無法對該字段進行分析,因此,直接刪除處理。
#查看user_geohash字段的非空比例
SELECT COUNT(u.`user_geohash`)/(SELECT COUNT(*) FROM USER) AS 'user_geohash字段的非空比例'
FROM USER AS u
WHERE u.`user_geohash` IS NOT NULL;
#由于這列存在大量的空值且經過加密處理,故刪除此列
ALTER TABLE USER DROP COLUMN user_geohash;
查找重復數據
這里的數據有重復值也是可以理解的,因為記錄行為的最小粒度為小時,同一用戶同一個行為在同一小時內是可能存在多次的,因此這里不去重處理。
SELECT *, COUNT(*)
FROM USER AS u
GROUP BY u.`user_id`, u.`item_id`, u.`behavior_type`, u.`time`
HAVING COUNT(*) > 1;
查看數據是否存在異常
檢查數據的時間范圍和行為數據的類別是否為4個即可。
# 檢查時間是否異常
SELECT MIN(u.`time`) AS '時間起點', MAX(u.`time`) AS '時間終點'
FROM USER AS u;
# 檢查用戶行為類別是否異常
SELECT DISTINCT u.`behavior_type`
FROM USER AS u;
缺失值檢查
# 檢查缺失值
SELECT COUNT(u.`user_id`),
COUNT(u.`item_id`),
COUNT(u.`item_category`),
COUNT(u.`behavior_type`),
COUNT(u.`time`)
FROM USER AS u
進一步處理
- 將日期和時間進行分離
#添加列:alter table 表名 add column 列名 varchar(30);
ALTER TABLE USER ADD COLUMN `date` VARCHAR(20) NOT NULL AFTER `time`;
#更新列:UPDATE table_name SET field1=new-value1, field2=new-value2 [WHERE Clause]
UPDATE USER
SET DATE = TIME;
#將date轉為年月日
UPDATE USER
SET DATE = DATE_FORMAT(DATE, '%Y-%m-%d');
#將time轉為小時
UPDATE USER
SET TIME = DATE_FORMAT(TIME, '%H');
#檢查一下轉化結果
SELECT *
FROM USER AS u
- 將用戶行為數據進行替換: 1:pv 2:fav 3:cart 4:buy
UPDATE USER
SET `behavior_type` = (CASE behavior_type
WHEN 1 THEN "pv"
WHEN 2 THEN "fav"
WHEN 3 THEN "cart"
WHEN 4 THEN "buy"
ELSE "other"
END);
感覺寫的沒問題但是一直報錯,查了一下stackoverflow發現原來py導入,各字段的格式并不是我們想要的格式,需要進行修改。注意:字段的類型一般不要修改,一定要謹慎。
DESC USER;
#alter table 表名 modify column 字段名 類型;
ALTER TABLE USER MODIFY COLUMN behavior_type VARCHAR(20);
驗證結果
SELECT *
FROM USER AS u;
指標的構建
1. 總體運營指標
① 流量指標
- 計算頁面訪客數(pv)、獨立訪客數(uv)、人均點擊數(uv/pv)
# uv pv pv\uv
SELECT COUNT(u.`user_id`) AS 'pv',
COUNT(DISTINCT u.`user_id`) AS 'uv',
COUNT(u.`user_id`)/COUNT(DISTINCT u.`user_id`) AS 'pv\uv',
COUNT(u.`user_id`)/(COUNT(DISTINCT u.`user_id`)*30) AS '日人均點擊次數'
FROM USER AS u
WHERE u.`behavior_type` = 'pv';
- 頁面訪客:942253次、獨立訪客數:9922位、人均點擊次數95次。
95/30≈3.2次,日人均點擊次數大概為3次/人/天
②每日流量指標變化趨勢
# 計算每天的uv pv pv\uv
SELECT u.date AS '日期',
COUNT(u.`user_id`) AS 'pv',
COUNT(DISTINCT u.`user_id`) AS 'uv',
COUNT(u.`user_id`)/COUNT(DISTINCT u.`user_id`) AS '人均頁面訪問數'
FROM USER AS u
WHERE u.`behavior_type` = 'pv'
GROUP BY u.date
ORDER BY u.date ASC;
導出數據
# 后邊加
INTO OUTFILE '/daily_uvpv.csv'
FIELDS TERMINATED BY ','
OPTIONALLY ENCLOSED BY '"'
LINES TERMINATED BY '\n';
需要更改配置什么的,一般情況下是不會存在導出數據的,因此,直接用sqluog的導出功能了。
-
可視化分析趨勢
pv、uv指標呈正相關性;
三個指標在大部分時間走勢是穩定的,從2014-12-11開始上升,到2014-12-12達到峰值,2014-12-13結束回到正常水平。
雙十二活動的影響無疑是明顯的。
- AARRR漏斗轉化率
①計算每個用戶行為的pv
# 用戶行為的pv
SELECT u.`behavior_type`, COUNT(u.`behavior_type`) AS 'behavior_count'
FROM USER AS u
GROUP BY u.`behavior_type`
ORDER BY behavior_count DESC;
由于在購物環節中,收藏和加入購物車是沒有先后之分的,這兩個環節可以放在一起,因此轉化率只有瀏覽-加入購物車/收藏、 收藏-購買。
從轉化率來看:瀏覽-收藏/加入購物車的轉化率僅為5%、收藏\加入購物車-購買的轉化率也只有20%,也不是太高,說明有非常多的用戶在收藏和加入購物車之后并沒有真正的購買。
從占比來看:總體收藏的占比為2.11%,總體加入購物車的占比為2.98%,總體購買的占比僅有1%,說明有非常多的用戶在瀏覽后沒有進行下一步操作,有非常多的無效點擊;
② 按照獨立訪客計算漏斗轉化率
# 用戶行為的uv
SELECT u.`behavior_type`, COUNT(DISTINCT u.`user_id`) AS 'behavior_count'
FROM USER AS u
GROUP BY u.`behavior_type`
ORDER BY behavior_count DESC;
用戶從瀏覽到收藏/加入購物車的轉化率很高,為94.15%,說明用戶有瀏覽后收藏/加入購物車的習慣。但是從收藏/加入購物車到購買的轉化率僅為38.45%,是用戶流失發生的主要環節。
- 訂單指標
① 成交量
- 總體成交量與人均購買次數
# 總體成交量與人均購買次數
SELECT COUNT(u.`behavior_type`) AS 成交總量
FROM USER AS u
WHERE u.`behavior_type` = 'buy';
- 每日成交量與人均購買次數走勢
# 每日成交量與人均購買次數走勢
SELECT u.`date`,
COUNT(u.`user_id`) AS '日成交量',
COUNT(DISTINCT u.`user_id`) AS '日用戶數',
COUNT(u.`behavior_type`)/COUNT(DISTINCT u.`user_id`) AS '人均日購買次數'
FROM USER AS u
WHERE u.`behavior_type` = 'buy'
GROUP BY u.`date`
ORDER BY u.`date` ASC;
訂單在大部分時間是保持平穩的,而在2014-12-12這天有爆發的增長,造成這一現象的原因是雙十二電商大促活動,與前面的流量走勢相結合進行分析,可以得到互相印證。
而且這一個月內,平均一個用戶購買了2.1次,每天的訂單量和流量指標是一致的。
② 復購率
- 總體的復購率
# 復購人數
SELECT COUNT(t.cnt) AS '復購人數'
FROM (SELECT u.`user_id`, COUNT(u.`user_id`) AS cnt
FROM USER AS u
WHERE u.`behavior_type` = 'buy'
GROUP BY u.`user_id`
HAVING cnt > 1) AS t;
#復購率
SELECT SUM(IF(t.cnt = 1, 0, 1))/SUM(IF(t.cnt IS NULL, 0, 1)) AS '復購率'
FROM (SELECT u.`user_id`, COUNT(u.`user_id`) AS cnt
FROM USER AS u
WHERE u.`behavior_type` = 'buy'
GROUP BY u.`user_id`) AS t;
復購人數為2268人,復購率為49.51%。
- 商品品類復購排行榜
SELECT u.`item_category`, COUNT(*) AS '購買次數'
FROM USER AS u
WHERE u.`behavior_type` = 'buy'
GROUP BY u.`item_category`
ORDER BY 購買次數 DESC
LIMIT 10;
可惜這里的商品類別是經過脫敏的,否則可以進行研究和下鉆,優化商品結構。
- 用戶復購排行
SELECT u.`user_id`, COUNT(*) AS '購買次數'
FROM USER AS u
WHERE u.`behavior_type` = 'buy'
GROUP BY u.`user_id`
ORDER BY 購買次數 DESC
LIMIT 10;
這些用戶對于平臺的忠誠度是比較高的,對于平臺的價值也是比較高的,可以開發用戶信息庫、收集詳實的用戶資料,追蹤記錄顧客的交易情況,收集用戶畫像,或者線上組織客戶VIP微信群,微信通知系統等,針對這些用戶的購買偏好進行更精準的運營。
2. 用戶行為特征分析
- 用戶行為時間的特征
① 按日期粒度:
SELECT u.`date`,
COUNT(*) AS '行為總數',
SUM(IF(u.`behavior_type` = 'pv', 1, 0)) AS '點擊次數',
SUM(IF(u.`behavior_type` = 'fav', 1, 0)) AS '收藏次數',
SUM(IF(u.`behavior_type` = 'fav', 1, 0)) AS '加入購物車次數',
SUM(IF(u.`behavior_type` = 'buy', 1, 0)) AS '購買次數',
COUNT(DISTINCT u.`user_id`) AS '用戶總數',
COUNT(*)/COUNT(DISTINCT u.`user_id`) AS '人均行為次數',
CONCAT(ROUND(SUM(IF(u.`behavior_type` = 'pv', 1, 0))/COUNT(*)*100, 2), '%') AS '點擊數占比',
CONCAT(ROUND(SUM(IF(u.`behavior_type` = 'buy', 1, 0))/COUNT(*)*100, 2), '%') AS '成交數占比'
FROM USER AS u
GROUP BY u.`date`
ORDER BY u.`date` ASC;
按如期粒度來看,用戶或活躍度與總體行為數是正相關的,走勢平穩,雙十二電商大促這天各項指標暴增,且當天點擊數占比有所下降(用戶的點擊更有針對性), 成交數占比大幅上升。
② 按周的粒度
查詢數據發現2014-11-18到2014-11-23,2014-12-15到2014-12-18均不滿一周,因此,只取完整的三周進行分析:
SELECT DATE_FORMAT(u.`date`, '%W') AS '星期',
COUNT(*) AS '行為總數',
SUM(IF(u.`behavior_type` = 'pv', 1, 0)) AS '點擊次數',
SUM(IF(u.`behavior_type` = 'fav', 1, 0)) AS '收藏次數',
SUM(IF(u.`behavior_type` = 'fav', 1, 0)) AS '加入購物車次數',
SUM(IF(u.`behavior_type` = 'buy', 1, 0)) AS '購買次數',
COUNT(DISTINCT u.`user_id`) AS '用戶總數',
COUNT(*)/COUNT(DISTINCT u.`user_id`) AS '人均行為次數',
CONCAT(ROUND(SUM(IF(u.`behavior_type` = 'pv', 1, 0))/COUNT(*)*100, 2), '%') AS '點擊數占比',
CONCAT(ROUND(SUM(IF(u.`behavior_type` = 'buy', 1, 0))/COUNT(*)*100, 2), '%') AS '成交數占比'
FROM USER AS u
WHERE u.date BETWEEN '2014-11-24' AND '2014-12-14'
GROUP BY DATE_FORMAT(u.`date`, '%W')
ORDER BY DATE_FORMAT(u.`date`, '%W') ASC;
一周中的大部分時間用戶活躍度都比較平穩,周五比較特殊,出現了增長。 查看數據發現雙十二正好是周五,因此是可以理解的。
③ 小時粒度
SELECT u.`time`,
COUNT(*) AS '行為總數',
SUM(IF(u.`behavior_type` = 'pv', 1, 0)) AS '點擊次數',
SUM(IF(u.`behavior_type` = 'fav', 1, 0)) AS '收藏次數',
SUM(IF(u.`behavior_type` = 'fav', 1, 0)) AS '加入購物車次數',
SUM(IF(u.`behavior_type` = 'buy', 1, 0)) AS '購買次數',
COUNT(DISTINCT u.`user_id`) AS '用戶總數',
COUNT(*)/COUNT(DISTINCT u.`user_id`) AS '人均行為次數',
CONCAT(ROUND(SUM(IF(u.`behavior_type` = 'pv', 1, 0))/COUNT(*)*100, 2), '%') AS '點擊數占比',
CONCAT(ROUND(SUM(IF(u.`behavior_type` = 'buy', 1, 0))/COUNT(*)*100, 2), '%') AS '成交數占比'
FROM USER AS u
GROUP BY u.`time`
ORDER BY u.`time` ASC;
各項指標呈正相關關系,每天0-5點用戶的活躍率快速降低,講到一天活躍量的最低值,6-10點用戶活躍度快速上升,10-18點用戶活躍度較為平穩,18-23點用戶活躍度快速上升,達到一天的峰值。
結論:晚間用戶最為活躍,但用戶行為傾向于瀏覽;白天時段,用戶的購買比率為一天內最高的,此時購買的目的性最強。
- 用戶商品偏好特征
SELECT u.`item_category`,
SUM(IF(u.`behavior_type` = 'pv', 1, 0)) AS '點擊次數',
SUM(IF(u.`behavior_type` = 'fav', 1, 0)) AS '收藏次數',
SUM(IF(u.`behavior_type` = 'fav', 1, 0)) AS '加入購物車次數',
SUM(IF(u.`behavior_type` = 'buy', 1, 0)) AS '購買次數',
CONCAT(ROUND(SUM(IF(u.`behavior_type` = 'pv', 1, 0))/COUNT(u.`behavior_type`)*100, 2), '%') AS '點擊數占比',
CONCAT(ROUND(SUM(IF(u.`behavior_type` = 'buy', 1, 0))/COUNT(u.`behavior_type`)*100, 2), '%') AS '成交數占比'
FROM USER AS u
GROUP BY u.`item_category`
ORDER BY 點擊次數 DESC;
可以建立 點擊數-購買數的二維圖像 選擇合適的中心點,將產品分為四個類別:
- 點擊數高,購買數高。說明此類產品剛需比較強,品牌多且種類豐富,用戶在較高的需求下有很多的選擇;
- 點擊數低購買數高。用戶的購買決策十分果斷,且對于該類產品的需求量也是很大的,說明該類產品選擇性比較小,可能形成幾個品牌壟斷的情況,或者產品的差異性較小,用戶不愿花費過多的精力去挑選。
- 點擊數低購買數低,絕大多數產品都集中在這個象限,這種產品存在很多的替代品,用戶很難集中在某個子類進行大量購買,而是跳躍式選購。
- 點擊數高購買數低,這類產品的需求彈性較大,用戶購買存在隨機性。
- 用戶行為路徑上的特征
用戶購買商品分為以下幾類過程:
- 瀏覽后購買
- 瀏覽后加入購物車購買
- 瀏覽后收藏購買
- 瀏覽后收藏并加入購物車購買
CREATE VIEW 用戶行為 AS
SELECT u.`user_id`,
SUM(IF(u.`behavior_type` = 'pv', 1, 0)) AS '點擊次數',
SUM(IF(u.`behavior_type` = 'fav', 1, 0)) AS '收藏次數',
SUM(IF(u.`behavior_type` = 'fav', 1, 0)) AS '加入購物車次數',
SUM(IF(u.`behavior_type` = 'buy', 1, 0)) AS '購買次數'
FROM USER AS u
GROUP BY u.`user_id`,
u.`item_id`,
u.`date`;
CREATE VIEW 標準化指標表 AS
SELECT uh.`user_id`,
CONCAT(IF(uh.`點擊次數`>=1,1,0),
IF(uh.`收藏次數`>=1,1,0),
IF(uh.`加入購物車次數`>=1,1,0),
IF(uh.`購買次數`>=1,1,0)) AS '行為路徑'
FROM 用戶行為 AS uh
WHERE uh.`購買次數` >= 1 AND uh.`點擊次數` <> 0;
SELECT a.`行為路徑`,
COUNT(DISTINCT a.`user_id`) AS '用戶數'
FROM 標準化指標表 AS a
GROUP BY a.`行為路徑`
由于數據是抽取的,這個所得的結果誤差較大。但這個結果顯示,直接夠買的用戶遠遠多于瀏覽后加購或者收藏再購買的用戶。說明,大部分購買者都是喜歡直接購買商品的,而非仔細挑選商品。
- 用戶復購率特征
#先計算每個用戶的購買次數
#然后對購買次數進行統計
SELECT tmp.購買次數, COUNT(tmp.購買次數) AS '用戶數'
FROM (SELECT u.`user_id`, COUNT(u.`user_id`) AS '購買次數'
FROM USER AS u
WHERE u.`behavior_type` = 'buy'
GROUP BY u.`user_id`
ORDER BY 購買次數 DESC) AS tmp
GROUP BY tmp.購買次數
ORDER BY tmp.購買次數 ASC
這一個月內,用戶的購買次數大部分集中在5次以內,開發空間較大。
3.基于RFM模型分析用戶的價值
根據數據的情況,這里只能計算R和F
R(Recently): 最近一天的購買時間差(以2014-12-18為基準)
F(Frequency): 近期的購買頻率
DROP VIEW IF EXISTS RF的統計視圖;
# 創建RF的統計視圖
CREATE VIEW RF的統計視圖 AS
SELECT u.`user_id`,
DATEDIFF('2014-12-18', MAX(u.`date`)) AS R,
COUNT(u.`user_id`) AS F
FROM USER AS u
WHERE u.`behavior_type` = 'buy'
GROUP BY u.`user_id`;
SELECT *
FROM RF的統計視圖
根據直方圖的情況:
將R/F分為四組:
- 0-5、5-12、12-23,、23-30分別對應4、3、2、1分
- F值1-3、3-5、5-7、7以上分別對應1、2、3、4分
DROP VIEW IF EXISTS 用戶價值打分;
CREATE VIEW 用戶價值打分 AS
SELECT rf.`user_id`,
(CASE
WHEN rf.R BETWEEN 0 AND 5 THEN 4
WHEN rf.R BETWEEN 5 AND 12 THEN 3
WHEN rf.R BETWEEN 12 AND 23 THEN 2
WHEN rf.R BETWEEN 23 AND 30 THEN 1
END) AS R_score,
(CASE
WHEN rf.F BETWEEN 1 AND 3 THEN 1
WHEN rf.F BETWEEN 3 AND 5 THEN 2
WHEN rf.F BETWEEN 5 AND 7 THEN 3
WHEN rf.F BETWEEN 7 AND 81 THEN 4
END) AS F_score
FROM RF的統計視圖 AS rf;
SELECT *
FROM 用戶價值打分;
計算R、F的平均值,確定評分標準
給用戶貼上價值標簽
重要價值客戶:R、F得分都高
重要保持客戶:R得分比較高,F得分比較低
重要發展客戶:R得分比較低,F得分比較高
一般價值客戶:R、F得分都比較低
DROP VIEW IF EXISTS 用戶標簽表;
CREATE VIEW 用戶標簽表 AS
SELECT s.`user_id`,
(CASE
WHEN s.R_score >= 2.78 AND s.F_score >= 1.21 THEN '重要價值客戶'
WHEN s.R_score >= 2.78 AND s.F_score <= 1.21 THEN '重要保持客戶'
WHEN s.R_score <= 2.78 AND s.F_score >= 1.21 THEN '重要發展客戶'
WHEN s.R_score <= 2.78 AND s.F_score <= 1.21 THEN '一般價值客戶'
END) AS 客戶類型
FROM 用戶價值打分 AS s;
SELECT *
FROM 用戶標簽表;
SELECT l.`客戶類型`, COUNT(l.`客戶類型`) AS 'cnt'
FROM 用戶標簽表 AS l
GROUP BY l.`客戶類型`;