利用Python进行电商网站用户行为分析
电商网站用户行为分析
项目需求
1.用户整体购物情况怎样?
- 统计数据集中总的用户数,商品数,商品类别数,用户行为数。
- 核心指标如PV,UV,跳出率,复购率,留存率等分别是多少?
2.用户的购物行为情况。
3.统计出每天各种行为的访问次数。
4.找出购买率最高的前二十个商品品类。
分析过程:获取业务方的需求->获取数据->分析数据->整理并清洗异常数据->实现需求
获取数据
import pandas as pd
import matplotlib.pyplot as plt
plt.rcParams['font.sans-serif'] = 'SimHei'
plt.rcParams['axes.unicode_minus'] = False
%matplotlib inline
# data = pd.read_csv('./UserBehavior.csv')
# 数据有3.7+ GB,比较大,全部读取耗费时间和内存,因此可以使用pandas的迭代读取方法,先获取前30万条数据,熟悉数据,并加入列名
user_behavior = pd.read_csv('./UserBehavior.csv',header=None,iterator=True)
head_data = user_behavior.get_chunk(300000)
head_data.head()
0 | 1 | 2 | 3 | 4 | |
---|---|---|---|---|---|
0 | 1 | 2268318 | 2520377 | pv | 1511544070 |
1 | 1 | 2333346 | 2520771 | pv | 1511561733 |
2 | 1 | 2576651 | 149192 | pv | 1511572885 |
3 | 1 | 3830808 | 4181361 | pv | 1511593493 |
4 | 1 | 4365585 | 2520377 | pv | 1511596146 |
# 加入列名
head_data.columns = ['user_id','goods_id','category_id','behaviour','timestamp']
head_data.head()
user_id | goods_id | category_id | behaviour | timestamp | |
---|---|---|---|---|---|
0 | 1 | 2268318 | 2520377 | pv | 1511544070 |
1 | 1 | 2333346 | 2520771 | pv | 1511561733 |
2 | 1 | 2576651 | 149192 | pv | 1511572885 |
3 | 1 | 3830808 | 4181361 | pv | 1511593493 |
4 | 1 | 4365585 | 2520377 | pv | 1511596146 |
数据集(UserBehavior.csv)来源于:阿里云天池数据集。包含了2017年11月25日至2017年12月3日之间,有行为的约一百万随机用户的所有行为(行为包括点击、购买、加购、喜欢)。数据集的每一行表示一条用户行为,由用户ID、商品ID、商品类目ID、行为类型和时间戳组成,并以逗号分隔。
- pv:商品详情页点击pv
- buy:商品购买
- cart:将商品加入购物车
- fav:收藏商品
head_data.info()
<class 'pandas.core.frame.DataFrame'>
RangeIndex: 300000 entries, 0 to 299999
Data columns (total 5 columns):
# Column Non-Null Count Dtype
--- ------ -------------- -----
0 user_id 300000 non-null int64
1 goods_id 300000 non-null int64
2 category_id 300000 non-null int64
3 behaviour 300000 non-null object
4 timestamp 300000 non-null int64
dtypes: int64(4), object(1)
memory usage: 11.4+ MB
从上可以看出,实验数据集没有缺失值。
- user_id 整数类型
- goods_id 整数类型
- category_id 整数类型
- behaviour 字符串,枚举类型,包含了pv、buy、cart和fav四种行为
- timestamp 时间戳,整数类型,需要转换为日期类型
数据清洗
(1)查看是否有缺失值
head_data.isnull().any()
user_id False
goods_id False
category_id False
behaviour False
timestamp False
dtype: bool
(2)将时间戳转为时间格式,并新加一列time
head_data['time'] = pd.to_datetime(head_data['timestamp'],unit='s')
(3)删除时间戳列
head_data.drop(['timestamp'],axis=1,inplace=True)
(4)将time设置为索引,目的是方便清除异常时间的数据
head_data.set_index('time',inplace=True)
(5)数据是2017年11月25日至2017年12月3日之间,将异常时间的数据清洗掉
head_data = head_data['2017-11-25':'2017-12-04']
head_data.head()
user_id | goods_id | category_id | behaviour | |
---|---|---|---|---|
time | ||||
2017-11-25 01:21:25 | 1 | 2576651 | 149192 | pv |
2017-11-25 07:04:53 | 1 | 3830808 | 4181361 | pv |
2017-11-25 07:49:06 | 1 | 4365585 | 2520377 | pv |
2017-11-25 13:28:01 | 1 | 4606018 | 2735466 | pv |
2017-11-25 21:22:22 | 1 | 230380 | 411153 | pv |
需求实现
(1)用户整体购物情况怎样?
- 统计数据集中总的用户数,商品数,商品类别数,用户行为数。
# 用户数、商品数、商品类别数
base_count = head_data[['user_id','goods_id','category_id']].nunique()
# 用户行为数
behaviour_count = head_data['behaviour'].count()
print(base_count,'\n','用户行为数:',behaviour_count)
user_id 2953
goods_id 161249
category_id 4494
dtype: int64
用户行为数: 296000
由以上的代码可以得到:用户数为2953、 商品数为161249、商品品类数为4494、用户行为数为296000
- 核心指标如PV,UV,跳出率,复购率,留存率等分别是多少?
behaviour_group = head_data.groupby(['behaviour']).count()
behaviour_group
time | user_id | goods_id | category_id | |
---|---|---|---|---|
behaviour | ||||
buy | 6247 | 6247 | 6247 | 6247 |
cart | 16603 | 16603 | 16603 | 16603 |
fav | 7429 | 7429 | 7429 | 7429 |
pv | 265721 | 265721 | 265721 | 265721 |
PV = behaviour_group[3:4]['user_id'].values[0]
UV = base_count[0:1].values[0]
PV/UV
89.98340670504571
页面总访问量(PV):265721、访问用户总数(UV):2953、平均每人每周访问量为90次页面
(2)统计用户的每个购买行为
思路:使用groupby进行分组统计
count_by_user_behav = head_data.groupby(['user_id','behaviour']).count()
count_by_user_behav.head()
goods_id | category_id | ||
---|---|---|---|
user_id | behaviour | ||
1 | pv | 53 | 53 |
100 | buy | 8 | 8 |
fav | 3 | 3 | |
pv | 72 | 72 | |
1000 | cart | 1 | 1 |
- 绘制折线图,展示用户的购买行为
count_by_userid_behav = count_by_user_behav['goods_id']
count_by_userid_behav[1:100].plot(kind='bar',figsize=(150,50))
plt.xlabel('用户及行为',fontsize=100)
plt.ylabel('用户购买行为次数',fontsize=100)
使用pandas自带的绘图功能进行绘制柱状图,因为用户有很多,我截取了部分用户数据及用户行为
(3)统计每天各行为的访问次数(绘制折线图)
# 根据行为类型进行分组统计
count_by_behav = head_data.groupby('behaviour')
# 设置画图尺寸大小
plt.figure(figsize=(12,6))
for group_name,group_data in count_by_behav:
# 对每天的行为进行统计,resample中的D表示天,也可以用H按小时统计
count_by_day = group_data.resample('D').count()['behaviour']
# 以日期作为X轴,以次数作为Y轴
x = count_by_day.index
y = count_by_day.values
# 设置x,y轴数据以及每条线的标签名
plt.plot(range(len(x)),y,label=group_name)
# 设置x轴的刻度以及对应的标签,rotation是设置标签的倾斜度
plt.xticks(range(len(x)),x,rotation=45)
# 对每条折线设置图例,自动选择最佳位置
plt.legend(loc='best')
# 设置x轴和y轴的标签
plt.xlabel('日期',fontsize=12)
plt.ylabel('行为次数',fontsize=12)
# 设置标题
plt.title('每天各行为的访问次数')
plt.show()
上图可以明显的看出,用户4中行为的走势,用户访问页面的次数是最多的,且在上图中,2017年12月02日出现了小高峰,通过查阅资料发现,这天为星期六,但12月03日的访问量并不是很高,如果不是数据准确性的问题,则可以说明这天可能做了活动,或APP改版等多种原因,导致这一天的访问量出现小高峰。
(4)找出购买率最高的前二十个商品品类(以柱状图展示)
- 购买率的计算时根据四种行为来进行计算的。
- 购买率=购买次数/(访问+加入购物车+收藏+购买)
- 思路:要根据商品品类进行分组
# 取消以时间为索引
head_data = head_data.reset_index()
# 按照商品的品类进行分组
count_by_category_id = head_data.groupby('category_id')
# 分组后每组数据的数量
count_by_category_id.size().head()
category_id
2171 12
2410 5
5064 67
7769 4
8109 1
dtype: int64
分组后的数据说明了,在上述的数据集***有4494个商品品类。
# 查看分组后的部分数据
for group_name,group_data in count_by_category_id:
print('组名:',group_name)
print('数据:\n',group_data)
print('数组的形状:\n',group_data.shape)
break
组名: 2171
数据:
time user_id goods_id category_id behaviour
24525 2017-11-27 11:12:34 1001120 1988565 2171 pv
24526 2017-11-27 11:19:35 1001120 536228 2171 pv
24541 2017-11-28 03:36:33 1001120 1988565 2171 pv
24543 2017-11-28 03:38:28 1001120 1988565 2171 fav
24570 2017-11-30 09:09:37 1001120 1988565 2171 pv
24571 2017-11-30 09:13:42 1001120 2898033 2171 pv
55473 2017-11-28 17:37:54 1002331 1981587 2171 pv
55474 2017-11-28 17:39:35 1002331 2786201 2171 pv
55475 2017-11-28 17:40:29 1002331 1981587 2171 pv
191651 2017-12-02 05:44:33 1008631 591563 2171 fav
191653 2017-12-02 05:44:58 1008631 591563 2171 pv
293787 2017-11-27 14:02:21 1013456 4767007 2171 pv
数组的形状:
(12, 5)
通过shape可以看出这组数据的形状为12行5列,一次可以直接用shape[0]作为购物的总次数使用,即取的是行数,如果是shape[1]则取的是列数,接下来在用behaviour进行分组,通过size属性,获取buy这一组的次数,最后将商品品类中购买率一一对应保存到字典中,使用内置函数sorted对字典进行排序。
con_dict = {
}
for group_name,group_data in count_by_category_id:
# 总次数
total = group_data.shape[0]
buy = 0
try:
# 有些商品没有购买行为,以buy作为索引获取时会出错,使用异常语句捕获一下异常
buy = group_data.groupby('behaviour').size()['buy']
except:
pass
# 购买转化率
buy_con = (buy/total)*100
# 类别名称对应转化率
con_dict[group_name] = buy_con
# 排序
sort_con = sorted(con_dict.items(),key=lambda item:item[1],reverse=True)
# 对排序后的列表取值
sort_con_20 = sort_con[: 20]
sort_con_20
[(324339, 100.0),
(589765, 100.0),
(654045, 100.0),
(665245, 100.0),
(848089, 100.0),
(910741, 100.0),
(1169371, 100.0),
(1340836, 100.0),
(1489467, 100.0),
(1516260, 100.0),
(1672287, 100.0),
(1712001, 100.0),
(1781126, 100.0),
(2464463, 100.0),
(2529139, 100.0),
(2555879, 100.0),
(2854994, 100.0),
(2923285, 100.0),
(3011375, 100.0),
(3428464, 100.0)]
得到前20个商品品类的购买转化率后,可以根据这个数据进行绘制图形
# 获取商品的品类
label = [i[0] for i in sort_con_20]
# 获取转化率
con = [i[1] for i in sort_con_20]
# 绘制图形
plt.figure(figsize=(20,6))
plt.bar(range(len(sort_con_20)),con,label=label)
plt.xticks(range(len(sort_con_20)),label)
plt.xlabel('商品的品类',fontsize=15)
plt.ylabel('商品品类的购买转化率',fontsize=15)
plt.title('各类商品的购买转化率')
plt.show()
总结:
通过使用Python来对电商网站用户行为进行简单的分析,其中涉及的分析点很多,在这里就不一一介绍,后续将会在MySQL数据库中使用SQL语句来对电商网站的用户行为进行分析。