实验背景:

这是从2010/01/12-2011/12/09一家在英国的网络电商的真实数据,所以数据类型和值都具有很强的随机性,实践性较强。

该电商的主营业务是卖一些订制礼物。所以本次分析的目的是对该电商的客户进行分类,以让业务部门可以对不同的顾客有不一样的促销方式(marketing initiatives or offer),以增大销量。

实验内容:

数据预处理:

1.导入观察数据:

#import all necessary package
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import seaborn as sns
import warnings
warnings.filterwarnings("ignore")

数据源:https://www.kaggle.com/carrie1/ecommerce-data

#load data
df=pd.read_csv(r'E:\test\ecommerce-data\data.csv',encoding='ISO-8859-1')
df.head()


观察数据一共有8列,根据已经显示的前5列,发现数据特点是同一个顾客ID可能在同一个INVOCE中购买了多项商品,并且逐行显示。

2.清理数据:

#观察数据
df.info()


重点关注InvoiceDate 是object格式,为了之后方便计算,我们最好将其变换为Datetime的格式。

#利用Datetime函数,加入指定格式,识别参数
df['InvoiceDate']=pd.to_datetime(df.InvoiceDate,format='%m/%d/%Y %H:%M')

3.检查空值

df.isnull().sum()


可以看到CID有相当多的空值,由于刚刚没有显示空值行的属性,现在单独将其列出进行分析:

Nan_rows=df[df.isnull().T.any()]
Nan_rows.tail(5)


因为我们无法通过别的列进行推断或者根据已有数据进行插值法补全CID,所以将其归类为脏数据删除

df=df.dropna(subset=['CustomerID'])
df.isnull().sum()


当我们删除CID之后,Description也为0。说明之前的那些CID为NaN的行里有一部分的Description也为NaN

4.重复值检查

df.duplicated().sum()


重复值只有5000多行,影响不大,我们选择删除

df.drop_duplicates(inplace=True)

在数据已经被清理干净之后,我们可以对其特征进行观察

数据分析与观察

1:找出Country一共有几种:

df.Country.unique()


顾客来自很多国家,那具体的下单数量和国家有很大的关联吗?我们可以将每个国家的下单数量进行排序并且可视化进行分析:

#先要将重复的CID去除,保证一个顾客只被计算了一次
order_unique_cus=df.drop_duplicates(['CustomerID'], keep='first', inplace=False)
order_sum=order_unique_cus.groupby(by='Country').UnitPrice.count()
order_sum=order_sum.sort_values(ascending=False).head(5)
plt.figure(figsize=(20,5))
sns.barplot(order_sum.index,order_sum.values,palette="Greens_r")
plt.ylabel('Counts')
plt.title('Num of orders in different country',fontsize=15,color='r',fontweight='bold')
plt.xticks(rotation=45)


明显的可以观察等到英国的购买人数占主要消费,计算出占比为:

order_unique_cus.loc[order_unique_cut.Country=='United Kingdom'].shape[0]/order_unique_cut.shape[0


综上,由于主要消费群体为英国,并且每个国家的用户购买习惯也不一样,之后的RFM分析将只会针对英国的顾客进行分析

df.describe()

我们可以看到QUANTITY和Unitprice都有极大值的影响,图像应该是严重的长尾状态。
并且发现QUANTITY里竟然有负数的出现,将这些负数取出进行观察:

#option1:
df[df['Quantity']<0].head(5)
#option2:
df1=df.query("Quantity<0").head(5)


发现Q为负数的时候,InvoiceNo前面都有C的出现,经过确认C开头意味着取消的订单。

还有一种情况就是Stockcode为D的时候,后面都注释该商品为打折商品

这些数据对我们造成了很大的困扰, 因为被取消,造成的原因很多,例如拍错或者不想要等原因, 这个可以之后在关注流失的时候重点分析,我们现在可以将他们先行取消。

#用DROP,删除掉<0的行(以Index为索引)
df.drop(df[ df.Quantity<0].index, inplace=True)
df.describe()

现在数据已经基本上彻底“干净”,我们可以开始进行RFM分析:

英国顾客的RFM分析

首先我们选择以天数为最小时间单位,创建新的一列date:

import datetime
df['date']=df['InvoiceDate'].apply(lambda x: x.date)


DATE一列已经被创造出来,且我们保存了原来的InvoiceDate 方便之后进行对照,RFM的定义不再赘述,下面是针对该实验的每个参数的实现方法:

R:最近的一次的消费。我们采用最后一天(max)作为“今天”减去每位顾客最后一次消费的时间

F: 每位顾客购买的频次

M:每位顾客购买的销量总额: unitprice*quantity

#创建消费总额列
df['M']=df['UnitPrice']*df['Quantity']
#将需要分析的列提出,创建一个RFM数据透视表
rfm=pivot_table(index='CustmerID',values=['date','InvoiceNo','M'],aggfunc=['date':'max','InvoiceNo':'count','M':'sum'])
#将Invoice的列名修改成F
rfm.rename(columns={'Invoice':'F'},inplace=True)
#计算最近一次消费,并且将结果类型换算成可计算的数据类型
rfm['R']=(rfm.date.max()-rfm.date)/np.timedelta64(1,'D')
#再次取出需要分析的3列
rfm1=rfm[['R','F','M']]
rfm1


接下来,我们用**聚类(KMEANS)**进行RFM分析:

聚类里有一个重要的参数是K,也就是我们将数据分为几类是最合适的。这个会有欠拟合和过拟合的问题,所以K的选择至关重要。本次选用手肘法进行评测:

手肘法的核心就是观察SSE(误差平方和),当你分类越多,样本划分就越来越精细,SSE自然会逐渐减小,但当K增大到一定程度时,对结果的影响就不会很大。所以我们画出分类从1至10,看SSE的变化趋势,选出拐点处对应的类数。

#我们选择1-10 ,对每一个都进行评估
SSE=[]
for k in range(1,10):estimator=Kmeans(n_cluster=k)estimator.fit(rfm1)SSE.append(estimator.inertia_)
x=range(1,10)
plt.plot(x,SSE,'x-')
plt.show()


当K=3的时候,会获得最好的分类,接下来我们就可以使用kmeans包进行计算

#选用3作为合适的簇,进行拟合
kmeans=KMeans(n=cluster=3,random_state=0.fit(rfm1)
#获取每个点的label
rfm1['cluster']=kmeans.labels_
rfm1.sort_values(by='cluster')

看到所有顾客已经被分为3类,我们接着探究一下每类的特性

R & Cluster

sns.boxyplot(rfm1.cluaster,rfm.R)
plt.title('boxplot across R and Cluster',fontsize=15,color='r',fontweight='bold')
plt.savefig(r'E:\test\ecommerce-data\boxplot across R and cluster.png')


首先因为R代表的最近的一次消费,所以需要R越小越好,根据箱线分布图:

  1. 第一类的客户分布较广,极值过高,为“最差”表现
  2. 第三类除了一些异常值的出现,它的极大值相比于第二类也比较高。
  3. 第二类的表现最好,极值中位数平均数全部都是最低水平,属于我们的“黄金VIP”

从R分析顾客的等极度为: 2>3>1

F & Cluster

sns.boxplot(rfm1.cluster,rfm1.F)
plt.title('boxplot across F and Cluster',fontsize=15,color='r',fontweight='bold')
plt.savefig(r'E:\test\ecommerce-data\boxplot across F and cluster.png')


由于F代表频数,我们希望F越大越好,说明买的次数多,根据箱线分布图:

  1. 第一类的客户虽有个别极值,但是普遍中位数包括平均数都较低,表现依旧不太乐观。
  2. 第二类属于中间水平,表现中等。
  3. 第三类的表现最好,不仅极大值多,中位数平均数全部都是最高水平,说以他们依然占据着“黄金VIP”席位

从F分析顾客的等极度为: 3>2>1

M & Cluster

sns.boxplot(rfm1.cluster,rfm1.M)
plt.title('boxplot across M and Cluster',fontsize=15,color='r',fontweight='bold')
plt.savefig(r'E:\test\ecommerce-data\boxplot across M and cluster.png')


最后M也是商家最在乎的消费总金额,越高买的金额数越大,商家就越获利,根据箱线分布图:

  1. 第一类的客户依旧最低值。
  2. 第三类属于中间水平,消费普遍在5万至10万之间。
  3. 第二类的表现是最惊人的,他也应该是在之前我们分析数据时,极值的所在处,中位数都已经快接近20万

从M分析顾客的等极度为: 2>3>1

综上: 可以得到第二类是最需要保值的顾客,我们可以将他们列为我们的“黄金VIP”提高留存。第三类其次,第一类则为相对逊色的普通用户。

然而,在聚类中,我们只分了三大类。

根据业务要求,如果想参照经典的RFM将每个指标都分类划分,目的也是能根据更精细划分来增强营销的精准性,则会采用另外一种编程方法实现。

当然,具体对于每一个指标划分点在现实工作中要和业务进行讨论,如果在没有经验数据的基础上,用分位数函数进行分组就是最科学的。

我的方法是先定义2个不同的函数,因为3个参数的中需要R越低越好,而F和M则是最高越好。

#在每一次新的计算,我偏向于创建一个变量,这样保证原始文件的完整性。
rfm2=rfm[['R','F','M']]
#将原始的RFM数据分为4等分
quantile=rfm2.quantile(q=[0.25,0.5,0.75])
def Rscore(x,col):if x<=quantile[col][0.25]:return 1elif x<=quantile[col][0.5]:return 2elif x<=quantile[col][0.75]:return 3else:return 4def FMScore(x.col):if x<=quantile[col][0.25]:return 4elif x<=quantile[col][0.5]:return 3elif x<=quantile[col][0.75]:return 2else:return 1

接下来,将函数运用在rfm中:

rfm2['Rscore']=rfm2['R'].apply(Rscore,args=('R'))
rfm2['f_score']=rfm2['F'].apply(FMscore,args=('F'))
rfm2['m_score']=rfm2['M'].apply(FMscore,args=('M'))

这时,有2种方法:

第一种为直接合并法:1+1+1=111 然后确定分类

第二种是将每组的得分利用权重相加:

本次分析采用第二种,但是将第一种的实现写在下面:

#直接合并法:因为rfm为数值型变量,我们需要将他们变为字符串相加
rfm2['str_score']=rfm2['r_score'].apply(str)+rfm2['f_score'].apply(str)+rfm2['m_score'].apply(str)#或者用map直接对每一列的数值一一映射成为STRrfm2['rfmscore']=rfm2['r_score'].map(str)+rfm2['f_score'].map(str)+rfm2['m_score'].map(str)

第二种的权重法:

#我将M的权重设为0.5为最重要,R设为0.2,F设为0.3
rfm2['rfm_total_score']=rfm2['r_score']*0.2+rfm2['f_score']*0.3+rfm2['m_score']*0.5

得到下图:

得到得分后,我们对每一个等级的顾客进行贴标签化:

bins=rfm2['rfm_total_score'].quantile(q=[0,0.125,0.25,0.375,0.5,0.625,0.75,0.875,1])
bins[0] =0
labels =  ['流失客户','一般维持客户','一般发展客户','潜力客户','重要挽留客户','重要保持客户','重要发展客户','重要价值客户']
rfm2['level'] = pd.cut(rfm2.rfm_total_score,bins,labels=labels)


可视化:

#这块是为保证可视化输出 中文不是小方块的问题
import matplotlib.pyplot as plt
plt.rcParams['font.sans-serif'] = [u'SimHei']
plt.rcParams['axes.unicode_minus'] = False
plt.figure(figsize=(15,8))
#准备好要可视化的表格
cus=rfm2.groupby('level').count().sort_values('R')
x=cus.index
y=cus.R
#画图修饰
plt.bar(x,y,alpha=0.9, facecolor = 'lightskyblue', edgecolor = 'white')
plt.xticks(x,rotation=60,fontsize=15)
plt.title('The Number Of Customer \n In Different Type',fontsize=20,color='r',fontweight='bold')
plt.ylabel('Num of Customer',fontsize=15)
plt.xlabel('Level',fontsize=15)
plt.savefig(r'E:\test\ecommerce-data\The number of customer in different type.png')


从这个可以看到重要发展客户占绝大多数,说明该电商的前景还是很乐观的,可以在保证重要价值客户依旧留存的基础上,加大营销力度等,将更多的重要发展客户变为忠诚客户,扩展业务。

实验结果

我们分别利用了聚类和分箱的方式,实现了RFM顾客分层,结合业务后,提出了对于营销的一些意见。并且由于此数据量的类型非常全面,之后我们也可以去从不同的维度分析该公司情况,包括用更多的算法来测试哪一个参数对总销售额的影响最大,以更完备的提供一些可实用性建议和意见。

PS:这是我写的第二篇数据分析的报告,如果大家发现有错误欢迎评论区留言,这样可以互相进步!如果没有欢迎大家点赞给个鼓励!嘿嘿

下面的链接是我第一篇处女座数据分析报告,主要是针对2019年airbnb纽约的房源进行的可视化一些练习,也欢迎大家移步去看看。(十二卖瓜,自卖自夸,哈哈):
https://blog.csdn.net/MRmaand12/article/details/105788430

RFM分析英国电商购物顾客群体(KAGGLE)相关推荐

  1. 电商 竞品分析_电商平台竞品分析报告.docx

    Planning scheme 电商平台竞品分析报告 电商平台竞品分析报告 电商平台竞品分析报告 V1.0 2018-3-18 状态 : [ √ ] 草稿 [ ] 修改中 [ ] 定稿 文件标签: 竞 ...

  2. 直播电商购物消费者满意度在线调查报告(三)

    三.直播电商购物消费满意度调查主要结果 为了进一步进行直播电商购物消费满意度调查,并总结出影响消费者满意度(https://www.manyibar.com/news/labels/xiaofeizh ...

  3. 共享可写节包含重定位_艾瑞咨询:2020年数说双11电商购物节报告

    回复"2020数说双11电商购物节"获取完整版报告 <2020年数说双11电商购物节报告>基于艾瑞十八年对互联网流量研究的研究经验.数据积累以及艾瑞数据监测工具多平台网 ...

  4. 直播电商购物消费者满意度在线调查报告(四)

    四.总结与建议 随着"互联网+"经济特别是电子商务经济的持续快速发展,直播电商作为一种新型营销模式越来越被广大消费者接受和认可.为了更好的服务消费者,电商领域一直在不断变化进步,预 ...

  5. 电商购物网站开发需要注意这些问题

    在当下的网络营销市场中,电商购物网站之间的竞争还是很激烈的,各行各业的企业纷纷掺入其中,这势必会为当下的营销市场带来混乱且持久的战役.而在如此激烈的购物网站市场竞争中,如果想要做出改变就要懂得购物网站 ...

  6. 第八章 交互技术,8.1 VR电商购物(作者:宋五)

    8.1 VR电商购物 前言 GM LAB在2016年3月成立,是一个旨在探索最新电商购物体验的实验室.在探索VR购物的过程中,有两个需要核心解决的问题:一个是VR购物的产品形态是什么,另一个是VR环境 ...

  7. 揭秘阿里VR电商购物

    GM LAB在2016年3月成立,是一个旨在探索最新电商购物体验的实验室.在探索VR购物的过程中,有两个需要核心解决的问题:一个是VR购物的产品形态是什么,另一个是VR环境下的店铺和商品怎么来.对于这 ...

  8. 基于MVC模式的电商购物系统

    该平台的整体设计使用了MVC模式,实现了分层的设计.本电商购物系统主要包含了二个部分:前台客户可以直接通过电脑或客户端网站进行登录,进行商品的购买.后台管理人员可以查看所有客户的基本信息:也可以对店铺 ...

  9. 2021年中国智能仓储行业情况分析:电商快速发展,促进智能物流及仓储快速发展[图]

    一. 智能仓储行业产业链 近几年来,随着信息技术和互联网在商品物流领域的应用,极大地促进了基于"互联网+"的商品物流行业的发展,有物流就有仓储,智能仓储系统在商品物流中的不断应用, ...

最新文章

  1. cocos2d中CCAnimation的使用(cocos2d 1.0以上版本)
  2. neuroph轻量级神经网络框架
  3. 面试无忧之Zookeeper总结心得
  4. 向mysql 插入中文数值报错
  5. 你真的了解.NET中的String吗?
  6. spark sql读取hive底层_[大数据]spark sql读写Hive数据不一致
  7. 创建局域网内远程git仓库,并将本地仓库push推到远程仓库中
  8. 【html+css3】在一张jpg图片上,显示多张透明的png图片
  9. 光照强度曲线图android,有关光合作用的曲线图的分析(一) - xyz的日志 - 网易博客...
  10. 面试官必问的信号量与生产者消费者问题
  11. 咋做数据分析,张口就来RFM模型,结果用错了
  12. 神奇的分形艺术: Mandelbrot集和Julia集
  13. 一小时学会使用SpringBoot整合阿里云SMS短信服务
  14. 重写equals()方法
  15. 我家的三个犹太小富豪(转)
  16. 数字图像处理9--尺度空间
  17. 【服务器数据恢复】重装系统导致分区无法访问的数据恢复案例
  18. 收藏|Java程序员必看的几本基础书籍和常用工具
  19. 推荐一款webstorm的主题,类似vscode的黑色主题,习惯vscode的用户可以试试
  20. scrapy爬虫使用简明教程

热门文章

  1. 【车载以太网】【AVB/TSN】概述
  2. 共享车位停车数据 共享停车管理平台,共享车位解决停车问题!
  3. 基于tutk方案的p2p源码_搭建p2p穿透服务器
  4. xtrabackup备份报错:Error : failed to fetch query result SELECT server _ uuid , local , replication
  5. 计算机毕业设计SSM爱音乐网站【附源码数据库】
  6. 如何与“外包”公司做好合作?我有几点建议
  7. html打印不弹出对话框,在C#带或不带Web浏览器控制和打印对话框打印的HTML
  8. java flowlayout 左对齐_java – FlowLayout的顶部对齐
  9. 华为OD机试 - 内存池(C 语言解题)【独家】
  10. java转换中文日期(二零一七年四月二十日、○九年四月三十日)