O2O优惠券数据分析
Posted Babyface Killer
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了O2O优惠券数据分析相关的知识,希望对你有一定的参考价值。
写在前面的话
本文中部分数据分析逻辑继承于O2O优惠券数据分析(一),如对文中部分数据处理和分析逻辑有问题,可先阅读前文。本文将主要负责分析线上用户行为及线上和线下共同用户的行为。
数据清理
# 读取线上数据集
online_df=pd.read_csv('/content/drive/MyDrive/o2o/ccf_online_stage1_train.csv')
online_df.head()
print('线下消费行为数据{}行'.format(online_df.shape[0]))
# 检查线上与线下数据是否可以通过User_id或者Merchant_id联系
offline_user=offline_df['User_id'].unique()
online_user=online_df['User_id'].unique()
offline_merchant=offline_df['Merchant_id'].unique()
online_merchant=online_df['Merchant_id'].unique()
common_user=list(set(offline_user)&set(online_user))
common_merchant=list(set(offline_merchant)&set(online_merchant))
print('共同用户{}人'.format(len(common_user)))
print('共同商家{}家'.format(len(common_merchant)))
# 检查缺失值
online_df.isnull().sum()
# 使用之前逻辑填补缺失值
online_df['Coupon_id'].fillna(0,inplace=True)
online_df['Discount_rate'].fillna(0,inplace=True)
# 查看数据类型
online_df.dtypes
# Coupon_id保留字符类型因为Coupon_id有‘fixed’取值
online_df['Date_received']=pd.to_datetime(online_df['Date_received'],format='%Y%m%d')
online_df['Date']=pd.to_datetime(online_df['Date'],format='%Y%m%d')
# 将没有消费的日期和没有领取优惠券的日期填充为dummy date
online_df['Date_received'].fillna('2021-01-01',inplace=True)
online_df['Date'].fillna('2021-01-01',inplace=True)
online_df['Date_received']=pd.to_datetime(online_df['Date_received'])
online_df['Date']=pd.to_datetime(online_df['Date'])
# 拆分discount_rate
discount_rate_string=online_df['Discount_rate']
purchase_amount=[]
discount_rate=[]
for r in discount_rate_string:
r=str(r)
if r=='fixed':
purchase_amount.append(99)
discount_rate.append(1)
elif ':' in r:
p=int(r.split(':')[0])
d=int(r.split(':')[1])
rate=d/p
purchase_amount.append(int(p))
discount_rate.append(round(rate,2))
elif float(r)==0.0:
purchase_amount.append(0)
discount_rate.append(0)
online_df['Purchase_amount']=purchase_amount
online_df['rate']=discount_rate
转化漏斗
因为线上数据中包含了用户的行为,所以我们可以利用这个信息来分析一下用户行为转换漏斗。
# 漏斗模型:点击->领取优惠券->使用优惠券
click_count=len(online_df[online_df['Action']==0])
receive_count=len(online_df[online_df['Action']==2])
use_count=len(online_df[(online_df['Action']==1)&(online_df['Date']<'2021-01-01')&(online_df['Date_received']<'2021-01-01')])
# 绘制漏斗模型
attrs=['Click','Receive','Use']
attr_value=[click_count,receive_count,use_count]
fig = go.Figure(go.Funnel(
y = attrs,
x = attr_value,
textposition = "inside",
textinfo = "value+percent initial",
opacity = 0.65, marker = {"color": ["deepskyblue", "lightsalmon", "tan", "teal", "silver"],
"line": {"width": [4, 2, 2, 3, 1, 1], "color": ["wheat", "wheat", "blue", "wheat", "wheat"]}},
connector = {"line": {"color": "royalblue", "dash": "dot", "width": 3}})
)
fig.show()
通过转化漏斗发现点击到领取优惠券转化率较低(7%),领取到使用转化率一般(33%)但和线下优惠券相比核销率更高。
线上消费行为中三种行为占比
# 提取所有使用优惠券的消费
useful_coupon_df=online_df.loc[(online_df['Date']<'2021-01-01') & (online_df['Date_received']<'2021-01-01')]
# 提取所有没有使用优惠券的消费
no_coupon_df=online_df.loc[(online_df['Coupon_id']==0)&online_df['Action']==1]
# 提取所有领取优惠券但没有使用的记录
useless_coupon_df=online_df.loc[(online_df['Date_received']<'2021-01-01')&(online_df['Date']=='2021-01-01')]
# 各种类型的记录占比
plt.figure(figsize=(8,5))
explode=[0.1,0.1,0.1]
plt.pie([len(useful_coupon_df),len(no_coupon_df),len(useless_coupon_df)],labels=['Used Coupon','No Coupon','Unused Coupon'],autopct='%1.1f%%',explode=explode,shadow=True)
plt.title('Coupon Usage')
和线下相比,线上使用优惠券的占比增加,未使用过的优惠券占比减少,说明线上优惠券对用户的吸引力更大。
影响线上优惠券核销率的因素分析
# 各个额度优惠券核销率
useful_coupon_count=pd.DataFrame(useful_coupon_df['Purchase_amount'].value_counts())
useless_coupon_count=pd.DataFrame(useless_coupon_df['Purchase_amount'].value_counts())
coupon_count=pd.merge(useful_coupon_count,useless_coupon_count,how='outer',left_index=True,right_index=True)
coupon_count.fillna(0,inplace=True)
coupon_count.sort_index(inplace=True)
label=coupon_count.index.astype(str)
value1=coupon_count['Purchase_amount_x']
value2=coupon_count['Purchase_amount_y']
plt.bar(x=label,height=value2,label='Unused Coupon',alpha=0.7)
plt.bar(x=label,height=value1,label='Used Coupon',bottom=value2,alpha=0.7)
plt.legend(loc='best')
plt.xlabel('Purchase Amount')
plt.ylabel('Amount')
axes2 = plt.twinx()
axes2.plot(label,value1/(value1+value2),color='red',marker='o')
axes2.set_ylabel('Usage rate')
通过以上分析可以看出满减额度(门槛)对于线上优惠券的核销率没有较大的影响因素但线上优惠券中限时低价折扣的发放次数和核销次数相等证明该优惠类型对线上客户有较大吸引力可以作为一种非常有效的营销手段。
# 各个折扣率优惠券的核销率
useful_coupon_count=pd.DataFrame(useful_coupon_df['rate'].value_counts())
useless_coupon_count=pd.DataFrame(useless_coupon_df['rate'].value_counts())
coupon_count=pd.merge(useful_coupon_count,useless_coupon_count,how='outer',left_index=True,right_index=True)
coupon_count.fillna(0,inplace=True)
coupon_count.sort_index(inplace=True)
label=coupon_count.index.astype(str)
value1=coupon_count['rate_x']
value2=coupon_count['rate_y']
plt.bar(x=label,height=value2,label='Unused Coupon',alpha=0.7)
plt.bar(x=label,height=value1,label='Used Coupon',bottom=value2,alpha=0.7)
plt.legend(loc='best')
plt.xlabel('Purchase Amount')
plt.ylabel('Amount')
plt.xticks(rotation='vertical')
axes2 = plt.twinx()
axes2.plot(label,value1/(value1+value2),color='red',marker='o')
axes2.set_ylabel('Usage rate')
通过对不同折扣率的核销率分析也可以证明线上用户对优惠券的折扣力度敏感度不高但对于限时低价折扣的反馈非常明显。
购买过的用户中对优惠券的敏感程度
# 提取所有线上购买的数据
online_purchased_df=online_df.loc[(online_df['Date']!='2021-01-01')&(online_df['Action']==1)]
# 每个用户使用优惠券的次数
use_coupon_count=pd.DataFrame(online_purchased_df[online_purchased_df['Date_received']!='2021-01-01'].groupby('User_id')['Date'].count())
# 所有购买过的消费者的购买次数
purchase_count=pd.DataFrame(online_purchased_df.groupby('User_id')['Date'].count())
coupon_analysis_df=pd.merge(purchase_count,use_coupon_count,how='outer',left_index=True,right_index=True)
coupon_analysis_df.fillna(0,inplace=True)
purchased_user_count=len(coupon_analysis_df)
no_coupon_only_count=len(coupon_analysis_df[coupon_analysis_df['Date_y']==0.0])
coupon_only_count=len(coupon_analysis_df[coupon_analysis_df['Date_x']==coupon_analysis_df['Date_y']])
plt.pie([no_coupon_only_count,coupon_only_count,purchased_user_count-no_coupon_only_count-coupon_only_count],labels=['No coupon only','Coupon only','Mixed'],autopct='%1.1f%%',explode=[0.1,0.1,0.1],shadow=True)
和线下优惠券相比,线上对优惠券敏感的用户更高(可能是限时低价优惠券带来的效应)但同时也有大部分用户对优惠券不敏感说明该品牌产品的价值是被用户认可的。
优惠券的拉新效果
# 优惠券的拉新效果
online_purchased_df=online_df.loc[(online_df['Date']!='2021-01-01')&(online_df['Action']==1)]
user_first_purchase_date=pd.DataFrame(online_purchased_df.groupby('User_id')['Date'].min())
user_first_coupon_date=pd.DataFrame(useful_coupon_df.groupby('User_id')['Date'].min())
coupon_acquisition_df=pd.merge(user_first_purchase_date,user_first_coupon_date,how='inner',left_index=True,right_index=True)
coupon_acquisition_df=coupon_acquisition_df[coupon_acquisition_df['Date_x']==coupon_acquisition_df['Date_y']]
coupon_acquisition_user=coupon_acquisition_df.index
new_user=len(coupon_acquisition_user)
all_user=len(online_df['User_id'].unique())
explode=[0.1,0.1]
plt.pie([new_user,all_user-new_user],labels=['New User with Coupon','Other'],autopct='%1.1f%%',explode=explode,shadow=True)
和线下优惠券相比线上优惠券的拉新效果更好,同时由于线上用户数较多,线上优惠券拉新用户数量也较为可观。
优惠券拉新质量
# 优惠券拉新的质量
new_user_coupon_df=online_purchased_df[online_purchased_df.User_id.isin(coupon_acquisition_user)]
all_user=online_purchased_df['User_id'].unique()
other_user=[i for i in all_user if i not in coupon_acquisition_user]
other_user_df=online_purchased_df[online_purchased_df.User_id.isin(other_user)]
new_user_frequency=new_user_coupon_df['User_id'].value_counts()
other_user_frequency=other_user_df['User_id'].value_counts()
plt.boxplot([new_user_frequency.values,other_user_frequency.values],showfliers=False,labels=['New user with coupon','Other user'],patch_artist=True)
plt.ylabel('Purchase Frequency')
从上图可知线上优惠券的拉新质量较高,由优惠券带来的新用户购买频次明显高于老用户。
结论
通过以上分析可以得出以下结论:
1.线上优惠券从点击到领取转化率较低,需要优化优惠券领取页面或优惠券类型来提高转化率
2.线上用户对限时低价优惠券反应非常强烈,但对满减门槛及折扣率不敏感,可以考虑使用限时低价优惠券作为促成用户完成消费行为的有效手段
3.和线下优惠券相比,对优惠券不敏感的用户同样占大多数,说明该商家的产品价值是被用户认可的,但仅使用优惠券完成消费的用户比例也同样增加说明和线下用户相比线上用户更喜欢”薅羊毛“
4.线上优惠券的拉新效果和拉新质量都要好于线下优惠券(极有可能为限时低价优惠券带来的效应),因此线上优惠券是非常有效的激活或者拉新的手段
线上线下共同用户行为分析
# 提取线上线下共同用户信息
offline_common_user_df=offline_df.loc[offline_df['User_id'].isin(common_user)]
online_common_user_df=online_df.loc[online_df['User_id'].isin(common_user)]
在线上线下同时有过购买的用户在线上线下各自的购买频率
# 比较线上线下共同用户购买频率
offline_common_user_frequency=offline_common_user_df[offline_common_user_df['Date']<'2021-01-01']['User_id'].value_counts()
online_common_user_frequency=online_common_user_df[(online_common_user_df['Date']<'2021-01-01')&(online_common_user_df['Action']==1)]['User_id'].value_counts()
plt.boxplot([offline_common_user_frequency.values,online_common_user_frequency.values],showfliers=False,labels=['Offline frequency','Online frequency'],patch_artist=True)
plt.ylabel('Purchase Frequency')
可以看到共同用户在线下购买频次的分布较广,说明有部分用户更倾向于在线下完成购买。
线上线下共同用户购买频次与纯线上或纯线下用户购买频次比较
# 比较线上线下共同用户和单独线上或单独线下用户购买频率
common_user_both_df=pd.merge(offline_common_user_frequency,online_common_user_frequency,how='inner',left_index=True,right_index=True)
common_frequency=common_user_both_df['User_id_x']+common_user_both_df['User_id_y']
pure_online_user=[x for x in online_purchased_df['User_id'] if x not in online_common_user_frequency.index]
pure_offline_user=[x for x in offline_purchased_df['User_id'] if x not in offline_common_user_frequency.index]
online_frequency=online_purchased_df[online_purchased_df['User_id'].isin(pure_online_user)]['User_id'].value_counts()
offline_frequency=offline_purchased_df[offline_purchased_df['User_id'].isin(pure_offline_user)]['User_id'].value_counts()
plt.boxplot([common_frequency,online_frequency,offline_frequency],showfliers=False,labels=['Common user','Online user','Offline user'],patch_artist=True)
从上图可以看出线上线下共同用户购买频次高于纯线上或纯线下用户,且纯线上和纯线下用户购买频次分布无较大差别。
线上线下共同用户占线上用户及线下用户总比重
# 线上线下共同用户占线上总用户和线下总用户的比重
fig,axs=plt.subplots(1,2)
explode=[0.1,0.1]
axs[0].pie([len(common_user),len(offline_user)-len(common_user)],explode=explode,labels=['Common user','Offline user'],autopct='%1.1f%%',shadow=True)
axs[1].pie([len(common_user),len(online_user)-len(common_user)],explode=explode,labels=['Common user','Online user'],autopct='%1.1f%%',shadow=True)
共同用户占线下用户比重较为均衡但大部分线上用户无线下购买体验。
线上线下共同用户转化漏斗
# 线上线下共同用户漏斗
click_count=len(online_common_user_df[online_common_user_df['Action']==0])
receive_count=len(online_common_user_df[online_common_user_df['Action']==2])
use_count=len(online_common_user_df[(online_common_user_df['Action']==1)&(online_common_user_df['Date']<'2021-01-01')&(online_common_user_df['Date_received']<'2021-01-01')])
# 绘制漏斗模型
attrs=['Click','Receive','Use']
attr_value=[click_count,receive_count,use_count]
fig = go.Figure(go.Funnel(
y = attrs,
x = attr_value,
textposition = "inside",
textinfo = "value+percent initial",
opacity = 0.65, marker = {"color": ["deepskyblue", "lightsalmon", "tan", "teal", "silver"],
"line": {"width": [4, 2, 2, 3, 1, 1], "color": ["wheat", "wheat", "blue", "wheat", "wheat"]}},
connector = {"line": {"color": "royalblue", "dash": "dot", "width": 3}})
)
fig.show()
与总体相比,线上线下共同用户在转化率方面均有提高。
首次在线上完成购买与首次在线下完成购买占整体的比例
# 首先在线上完成购买的用户占共同用户的比例
online_purchase=online_common_user_df[online_common_user_df['Action']==1]
offline_purchase=offline_common_user_df[offline_common_user_df['Date']!='2021-01-01']
online_first_purchase=pd.DataFrame(online_purchase.groupby('User_id')['Date'].min())
offline_first_purchase=pd.DataFrame(offline_purchase.groupby('User_id')['Date'].min())
common_df=pd.merge(online_first_purchase,offline_first_purchase,how='inner',left_index=True,right_index=True)
online_first=common_df[common_df['Date_x']<common_df['Date_y']]
plt.pie([len(online_first),len(common_df)-len(online_first)],labels=['Online purchase first','Offline purchase first'],autopct='%1.1f%%')
在有过购买体验的客户中首次购买体验完成与线上和线下的比例较为均衡,说明商家在线上与线下的资源分配上较为均衡没有顾此失彼。
结论
通过以上分析可以得出的有效结论:
1.线上线下共同用户中在线上线下的平均购买频次相当但线下购买频次的分布较广,可以考虑引导线上用户线下购买来增加用户粘性
2.线上线下共同用户购买频次与纯线上或纯线下用户相比更高,说明同时拥有两种购买体验的用户活跃度更高
3.线上线下共同用户在优惠券转化过程中转化率也更高,因此有过两种购物体验的客户被优惠券激活或被优惠券引导消费的可能性更高
写在最后的话
本文旨在提供一些数据分析的思路和数据处理的方法
请辩证地看待文中所有结论
如有错误请指出
转载请注明出处
以上是关于O2O优惠券数据分析的主要内容,如果未能解决你的问题,请参考以下文章