内容
1.数据处理目标
对淘宝的用户行为数据做探索性分析,发现问题再具体分析。通过app用户行为的日志数据,包括用户、商品、行为、时间等信息,通过切片、钻孔、滚动、旋转、切块等数据分析方法,可以从不同的地方挖掘出其中蕴含的价值角度。这一次,我们从以下三个方向探索淘宝用户行为:
用户行为分析/销售品类分析/用户分类/漏斗分析;用户流失分析/用户复购分析产品销售分析2.了解数据2.1 获取数据
数据集来自阿里天池:淘宝用户行为数据,包含淘宝App从2017年11月25日到2017年12月3日9天的数据,约1000万随机用户有行为的全部数据。行为数据。
2.2 数据说明
数据列由用户ID(user_id)、商品ID(item_id)、商品类别ID(cate_id)、用户行为(type)和时间戳(time)组成。用户行为包括点击pv、购买buy、添加购物车、收藏收藏。由于原始数据集中数据量较大,本次随机抽取1000W+条记录进行数据分析。
3.数据清洗
数据清洗主要包括去除重复值、处理缺失值、处理异常值、生成派生变量等操作。数据预处理的顺序一般根据实际问题确定。
3.1 个缺失值
缺失值处理一般需要通过一定的方法找到缺失值,分析缺失值在整体样本中的分布比例,然后根据缺失值的比例和数据类型选择1丢弃列(类别变量,数值变量)。; 2 中位数、均值、众数等补全方法。
# 缺失值查看
dataframe.isnull().sum()
# 缺失值占比计算
dataframe.apply(lambda x: sum(x.isnull()) / len(x))
3.2 个重复值
重复值对一般模型影响不大,但会影响回归模型回归系数的准确性。重复值太多,需要从元数据中去除重复值。这个数据集中没有重复值,可以跳过。
# 剔除重复值
dataframe.drop_duplicates(inplace=True)
3.3 个异常值
处理异常值的常用方法有:直接删除、处理缺失值等;在本例中,数据集描述中写道,该数据集的日期范围为2017年11月25日至2017年12月3日有赞每日数据分析,即数据以外的部分数据为异常值,因此排除异常值。
# 保留2017.11.25-2017.12.3期间的数据
# 删除这段时间以外的数据
startTime = datetime.datetime.strptime("2017-11-25 00:00:00","%Y-%m-%d %H:%M:%S")
endTime = datetime.datetime.strptime("2017-12-03 23:59:59","%Y-%m-%d %H:%M:%S")
dataframe = dataframe[(dataframe.time>=startTime)&(dataframe.time<=endTime)]
dataframe = dataframe.reset_index(drop=True)
3.4 时间类型转换
# 保留2017.11.25-2017.12.3期间的数据
startTime = datetime.datetime.strptime("2017-11-25 00:00:00","%Y-%m-%d %H:%M:%S")
endTime = datetime.datetime.strptime("2017-12-03 23:59:59","%Y-%m-%d %H:%M:%S")
dataframe = dataframe[(dataframe.time>=startTime)&(dataframe.time<=endTime)]
# reset_index 重置索引,drop=True 把原来的索引index列去掉,重置index
dataframe = dataframe.reset_index(drop=True)
# 删除时间戳节约内存
dataframe.drop('timestamp', inplace=True, axis=1)
用户身份
97810
项目编号
1560525
类别ID
7966
类型
4
时间
755529
日期
9
4.用户行为分析4.1 用户消费行为
(1) 9 天内总用户 PV 和 UV
# 用户pv
dataframe.groupby(['type'])['userid'].count()
"""
type
buy 199147
cart 559132
fav 291657
pv 8944510
Name: userid, dtype: int64
"""
# 用户uv
dataframe.userid.nunique()
"""
97810
"""
总PV:8944150;紫外线:97810
(2)付费用户数,占比
# 付费用户数
user_bought_count = dataframe[dataframe['type']=='buy'].userid.nunique()
# 独立访客UV
total_unique_users = dataframe.userid.nunique()
# 付费用户占比
user_bought_count_rate = user_bought_count/total_unique_users
付费用户数:66452;付费用户占比:67.94%
(3)每日访问PV、UV
# 每日访问量PV
pv_day = dataframe[dataframe.type=='pv'].groupby('date').count()['userid'].reset_index().rename(columns={'userid':'pv'})
# 每日UV
uv_day = dataframe.groupby('date').nunique()['userid'].reset_index().rename(columns={'userid':'uv'})
(4)9天内各种用户行为(pv、fav、cart、buy)的总操作数、日均操作数、日均操作用户数
# 各类操作总数
type_series = dataframe.type.value_counts()
# 日平均操作数,日平均操作用户数
type_df = pd.DataFrame([type_series,type_series/9,type_series/total_unique_users],index=['total','avg_day','avg_user'])
(5)付费用户行为记录
# 付费用户的userid
buy_userid = dataframe[dataframe['type']=='buy']['userid'].drop_duplicates()
data_buy_userid = dataframe[dataframe['userid'].isin(buy_userid)]
# 付费用户的type分类统计
data_buy_userid_type = data_buy_userid.type.value_counts()
# 将付费用户记录补充到type_df中
type_df.loc['paying_user'] = data_buy_userid_type
(6)跳出率、回购率
# 只有点击行为的用户数
only_pv_user_count = len(user_type[user_type['pv']==user_type.sum(axis=1)])
# 总用户数
dataframe.userid.nunique()
# 跳失率
bounce_rate = only_pv_user_count/total_unique_users
"""
跳失率:5.74%
"""
# 购买两次以上的userid数
rebuy_user_count = len(user_type[user_type['buy']>=2])
# 复购率
rebuy_user_rate = rebuy_user_count/user_bought_count
"""
复购率:66.01%
"""
(7) 用户复购次数分布,人均购买次数
# 复购的userid具体复购次数分布
user_type[user_type['buy']>=2]['buy']
# 总购买次数
total_buy_time=dataframe[dataframe.type=='buy'].count()['userid']
# # 总购买用户数
total_paying_user=dataframe[dataframe.type=='buy']['userid'].nunique()
# 人均购买次数=总购买次数/总购买用户数
average_user_buy_time=total_buy_time/total_paying_user
"""
人均购买次数:2.996854872690062
"""
人均购买次数:2.996854872690062,计算方式以有购买行为的用户为准。下图为人均购买次数分布;
4.2 用户行为时间模型 用户行为、活动时间维度分析 用户量时间维度分析
(1)用户行为的变化
# 按日期date按统计用户行为type
behavior_type = list(dict(dataframe['type'].value_counts()).keys())
date_df = dataframe.groupby(['date']).type.value_counts().unstack()
# date_df 添加一列 weekday 将日期转换为星期
# datetime.datetime.isoweekday()返回的1-7代表周一到周日;
date_df['weekday'] = [datetime.datetime.isoweekday(x) for x in date_df.index]
(2)活跃用户数变化趋势(天)
# 每天操作次数超过5次的userid数
date_df['day_act_user'] = [(groupby_date.get_group(d).groupby(by='userid').size() > active_user_standard).value_counts()[True] for d in dates]
# 活跃用户比例
date_df['act_user_rate'] = date_df['day_act_user']/date_df['uv']
# 付费用户数(每天)
date_df['buyer'] = dataframe[dataframe['type']=='buy'].groupby(by=['date','userid']).size().count(level=0)
# 付费用户比例(每天)
date_df['buyer_rate'] = date_df['buyer']/date_df['uv']
# 人均购买量ARPU=总交易量/当日UV
date_df['ARPU'] = date_df['buy']/date_df['uv']
# 付费用户人均购买量ARPPU
date_df['ARPPU'] = date_df['buy']/date_df['buyer']
ARPU 评估应用变现效果:ARPU 越高,用户在此期间为应用带来的变现收入越多
ARPPU反映了付费用户为应用带来了多少收入,显示了忠诚的付费用户实际上愿意支付多少
(3)用户购买(buy)和点击(pv)行为的时间段分布
hour_df = dataframe.groupby('hour').type.value_counts().unstack()
uv_hour = pd.DataFrame(dataframe.groupby('hour')['userid'].nunique())
hour_df = hour_df.join(uv_hour,how='right')
hour_df.rename(columns={'userid':'uv'},inplace=True)
(4)用户累计活跃天数分布
# 每个user的活跃天数
tmp = dataframe[['userid','date','type']].groupby(by=['userid','date']).count()
user_active_days_df = tmp[tmp['type']>active_user_standard].count(level=0)
# 按活跃天数统计用户数
sorted_user_active_days_df = user_active_days_df['type'].value_counts().sort_index()
4.3 用户转化漏斗分析点击->收藏->购买点击->添加购买->购买
# 从pv到cart用户数
count_users_pv_cart = pv_cart_df[pv_cart_df.time_pv < pv_cart_df.time_cart].userid.nunique()
# 从cart到buy用户数
count_users_cart_buy = cart_buy_df[cart_buy_df.time_cart < cart_buy_df.time_buy].userid.nunique()
# 收藏加购转化率=(收藏数+加购数)/总用户数
fav_cart_ratio = (count_users_pv_fav + count_users_pv_cart)/total_unique_users
# 购买转化率(加购_购买数+收藏_购买数)/总用户数
buy_ratio=(count_users_fav_buy + count_users_cart_buy)/total_unique_users
这里我们使用pyecharts来绘制漏斗图
4.4 用户价值分析-RFM分析
RFM(Recency,Frequency,Monetary)模型通过三个指标来描述客户的价值:客户近期的购买行为、整体的购买频率、消费金额
# 先创建一个空的dataframe RF_df,存储RF
RF = pd.DataFrame(index=group_buy_userid.groups.keys(), # index=userid_buy_unique
columns=['R','F'])
# columns=计算出来每个userid的RF值
RF['F'] = group_buy_userid.type.count()
# 每个用户最近一次交易时间
RF['last_buy_time'] = group_buy_userid.time.max()
# 选择2017/12/04为对照日期,计算交易时间间隔
RF['R'] = (pd.to_datetime('2017-12-04')-RF['last_buy_time']).dt.days
最后一笔交易记录距离2017.12.04还有0天,即最后一笔交易发生在2017.12.03,
最长间隔9天,即2017.11.25天发生交易,人均交易间隔2.53天
# 对R划分等级
def R_score(x):
if 0 <= x <= 1:
return 4
elif 2 <= x<= 3:
return 3
elif 4<= x <= 6:
return 2
elif 7<= x <= 9:
return 1
else:
return 0
# 根据用户的R,F值进行评分
RF['R_score'] = RF.R.map(R_score) # 对RF_df的R列.map(函数)
RF['F_score'] = RF.F.map(F_score)
将R分为4个等级,0-1分4分;2-3得分3;4-6得分2,7-9得分1 交易间隔R越长,得分越低
# 判断每个用户的R_score\F_score是否大于均值
def R_mean(x):
if x > RF['R_score'].mean():
return 'yes'
else:
return 'no'
RF['R>mean?'] = RF.R_score.map(R_mean)
def user_classfication(tup): # 此处只能传入一个参数
x, y = tup
if x == 'no' and y == 'yes':
return '保持客户'
elif x == 'yes' and y == 'no':
return "发展客户"
elif x == 'yes' and y == 'yes':
return "价值客户"
elif x == 'no' and y == 'no':
return "挽留客户"
else:
return None
RF['user_classification'] = RF[['R>mean?','F>mean?']].apply(user_classfication, axis=1)
获取app各类用户占比
挽留客户 0.37 价值客户 0.26 发展客户 0.20 保持客户 0.17
根据RFM模型对用户进行分类后发现有赞每日数据分析,需要留存的客户占比最高(0.37),其次是重要价值用户。淘宝要注意需要留住客户,考虑通过促销、优惠券等方式促进发展,客户成为尊贵客户
5 商品交易量分析5.1 商品数量、品类数量、点击量、购买量
分析指标:销量前十品类的categoryid、销量前十产品的itemid
# 有交易操作的商品总数
total_unique_itemid = dataframe.itemid.nunique()
# 商品品类
total_unique_categoryid = dataframe.categoryid.nunique()
总商品数:1560525; 品类数:7966
# 按itemid分别统计其点击pv,购买,收藏,加购次数
item_type_df = dataframe.groupby('itemid').type.value_counts().unstack()
item_type_df.replace(to_replace=np.nan,value=0,inplace=True)
# 按购买量降序排列
item_type_df = item_type_df.sort_values(by='buy',ascending=False,axis=0)
5.2 产品购买转化率
# 点击pv到购买buy的转化率
item_type_df['buy_pv_conversion_rate'] = item_type_df['buy']/item_type_df['pv']
可以看出,购买转化率是无限的,或者转化率的异常值>1,所以需要剔除,然后再考虑产品转化率的分布区间分析。
# 筛掉异常值
category_type_df[category_type_df['buy_pv_conversion_rate']>1]
5.3 十大畅销产品和类别
6.结论和建议