当前位置:   article > 正文

kaggle 电商数据分析_适合做数据分析的kaggle数据集csdn

适合做数据分析的kaggle数据集csdn

项目背景

这个数据集是kaggle上面的一个电商数据集,其中包含2010年12月12日至2011年12月9日之间在英国注册的非商店在线零售的所有交易。该公司主要销售各种独特的礼品之类,其中许多客户该公司是批发商。因此本次数据分析将对客户进行分析,并对客户进行相关分层处理。

数据清洗

import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import os
import warnings
import missingno as msno
warnings.filterwarnings('ignore')

data = pd.read_csv('data.csv',encoding = 'utf-8', dtype = {'CustomerID' : str})
data.head()
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10

看到这个是数据的前五行
这就是data数据集的前五行。
接下来观看数据概况

data.describe()
  • 1

在这里插入图片描述
我们看到这里面Description和CustomerID字段都有相应的缺失,因此我们选择将这里面的数据进行处理。

首先我们选择将Description字段里面缺失的行删除,另外我们将CustinerID中确实字段填补为U。

data.dropna(axis = 0, subset = ['Description'], inplace = True)
data.CustomerID = data.CustomerID.fillna('U')
  • 1
  • 2

做好以上处理后我们看每个客户的每个订单的购买商品数量

temp = data.groupby(by=['CustomerID', 'InvoiceNo'], as_index=False)['StockCode'].count()
temp.rename(columns = {'StockCode': 'product numbers'})
  • 1
  • 2

在这里插入图片描述

退货情况分析

数据集标签InvioceNo里有一些编号包含’C’,这代表这些订单时退货订单,因此我们需要对这些退货订单进行处理。我们写一个函数,找出退货订单的原订单。这里面会有如下两种情况:

  1. 退货订单没有对应的原订单
  2. 退货订单存在一个或一个以上的原订单。
    因此我们创建一个quantity_canceled的标签,用来记录每一个订单退货量,方便我们之后计算相应的单笔订单真实消费额。
data_cleaned = data.copy(deep = True)
data_cleaned['quantity_canceled'] = 0
unpaired_invoice = []
paired_invoice = []
for index, col in data.iterrows():
   if col['Quantity'] > 0 or col['Description'] == 'Discount':
       continue
   #提取出和取消订单的商品配对的原订单    
   df_test = data[(data['CustomerID'] == col['CustomerID'])
                 &(data['StockCode'] == col['StockCode'])
                 &(data['InvoiceDate'] < col['InvoiceDate'])
                 &(data['Quantity']) > 0]
   
   if (len(df_test) == 0):
       unpaired_invoice.append(index)
   
   elif (len(df_test) == 1):
       index_order = df_test.index[0]
       data_cleaned.loc[index_order, 'quantity_canceled'] = -col['Quantity']
       paired_invoice.append(index)
       
   elif (len(df_test) > 1):
       df_test.sort_index(axis=0 ,ascending=False, inplace = True)
       for ind, val in df_test.iterrows():
           if val['Quantity'] < -col['Quantity']:
               continue
           data_cleaned.loc[ind, 'quantity_canceled'] = -col['Quantity']
           paired_invoice.append(index) 
           break 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29

经过上述代码处理后,我们就得到了两个列表,一个列表叫unpaired_invoice,这个里面记录了没有配对的订单。还有一个列表叫做paired_invoice,表示配对的订单。
我们查看列表长度,发现分别有7106和1994条。

我们接下来先探索相应的退货情况。

#分别提取数量为正的订单和数量为负的订单
data_canceled = data[data['Quantity'] <= 0]
data_all = data[(data['Quantity'] > 0)]

data_canceled['month'] = pd.to_datetime(data_canceled['InvoiceDate']).dt.month
data_all['month'] = pd.to_datetime(data_all['InvoiceDate']).dt.month

data_canceled['year'] = pd.to_datetime(data_canceled['InvoiceDate']).dt.year
data_all['year'] = pd.to_datetime(data_all['InvoiceDate']).dt.year

data_canceled['price'] = - data_canceled['Quantity'] * data_canceled['UnitPrice']
data_all['price'] = data_all['Quantity'] * data_all['UnitPrice']
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12

按照年月分别统计退货金额和退货率,tt这个表就是展示分月的退货总金额,pp代表所有订单数量为正的购物总金额,tt / pp 就代表退货率情况。

tt = data_canceled.groupby(['year','month'])['price'].sum().unstack()
pp = data_all.groupby(['year','month'])['price'].sum().unstack()

plt.figure(figsize = (8,6))
plt.title('各月份退货金额',fontsize = 16)
plt.bar(tt.loc[2011].index, tt.loc[2011].values)

plt.figure(figsize = (8,6))
plt.title('各月份退货比例',fontsize = 16)
plt.plot((tt / pp).loc[2011].index, (tt / pp).loc[2011].values,)
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10

在这里插入图片描述
在这里插入图片描述
我们看到在1月份和12月份相应的退货金额和退货比例都是上升的,这里的原因应该是在那个时候西方人可能会过圣诞节之类的节日,出现大批购物的次数变多,同时相应的退货次数也增多了,这和我们的双十一有没有点像啊,购买之后都是会有大批退货。

客户RFM分析

RFM分析主要包括三个维度,R代表客户最近一次购物消费的时间,F代表客户消费的频率, M代表客户消费总金额。为了进行这一分析,我们首先对数据进行以下处理,删除掉最近之前未配对的quantity为负的订单,由于配对订单已经包含在data_cleaned这一特征里面的quantity_canceled标签中,因此我们对配对的订单也予以删除

data_cleaned.drop(unpaired_invoice, axis = 0, inplace = True)
data_cleaned.drop(paired_invoice, axis = 0, inplace =True)
  • 1
  • 2

为了计算RFM,我们计算total_price,这包含了客户的退货订单,同时取每个客户每笔订单的时间

data_cleaned['TotalPrice'] = data_cleaned['UnitPrice'] * (data_cleaned['Quantity'] - data_cleaned['quantity_canceled'])
data_cleaned.sort_values('CustomerID')[:5]

invoice_price = data_cleaned.groupby(by = ['CustomerID','InvoiceNo'], as_index = False).agg({'TotalPrice': 'sum','InvoiceDate': 'first'})
invoice_price.rename(columns = {'TotalPrice': 'basket_price'}, inplace =True)
invoice_price = invoice_price.loc[invoice_price['basket_price'] > 0]
invoice_price.head()
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

在这里插入图片描述
接下来我们就可以计算相应的R_value, F_value, M_value了。

invoice_price['year'] = np.array([i.year for i in invoice_price['date']])
invoice_price['month'] = np.array([i.month for i in invoice_price['date']])
invoice_price['day'] = np.array([i.day for i in invoice_price['date']])

R_value = invoice_price['date'].max() - invoice_price.groupby('CustomerID')['date'].max()
F_value = invoice_price.groupby('CustomerID')['InvoiceNo'].count()
M_value = invoice_price.groupby('CustomerID')['basket_price'].sum()
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
#观察R_value的频数分布
plt.title('R_value分布直方图')
plt.hist(R_value.dt.days, bins = 20)

#观察F_value的频数分布
plt.title('F_value分布直方图')
plt.hist(F_value[F_value < 20], bins = 20)

#观察M_value的频数分布
plt.title('M_value分布直方图')
plt.hist(M_value[M_value < 4000], bins = 30)
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
接下来我们对R_value,F_value, M_value进行离散化分箱,便于我们对客户分类。

#分箱
R_bins = [0, 30, 60, 90, 360, 720]
F_bins = [1, 2,  5, 10, 20, 2000]
M_bins = [0, 500, 2000, 5000, 10000, 2000000]

R_score = pd.cut(R_value.dt.days, R_bins, labels = [5, 4, 3, 2, 1], right = False)
F_score = pd.cut(F_value, F_bins, labels = [1, 2, 3, 4, 5], right = False)
M_score = pd.cut(M_value, M_bins, labels = [1, 2, 3, 4, 5], right = False)

rfm = pd.concat([R_score, F_score, M_score], axis = 1)
rfm.rename(columns = {'date': 'R_score', 'InvoiceNo': 'F_score', "basket_price": 'M_score'}, inplace = True)
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11

我们这里选取R_value、F_value、M_value的均值作为相应的分割点,分为高低等级。

rfm['R'] = np.where(rfm['R_score'] > 3.57, '高', '低')
rfm['F'] = np.where(rfm['F_score'] > 2.03, '高', '低')
rfm['M'] = np.where(rfm['M_score'] > 1.89, '高', '低')

rfm['value'] = rfm['R'] + rfm['F'] + rfm['M']
rfm
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

在这里插入图片描述
最后我们根据value标签对客户进行分类

def trans_value(x):
    if x == '高高高':
        return '重要价值客户'
    
    elif x == '高低高':
        return '重要发展客户'
    elif x == '低高高':
        return '重要保持客户'
    elif x == '高高低':
        return '一般价值客户'
    elif x == '低低高':
        return '重要挽留客户'
    elif x == '高低低':
        return '一般发展客户'
    elif x == '低高低':
        return '一般客户'
    
    else:
        return '一般挽留客户'
        
rfm['用户等级'] = rfm['value'].apply(trans_value)
rfm['用户等级'].value_counts()      
        
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23

在这里插入图片描述
最后我们用plotly这个包来进行展示分类

import plotly as py
import plotly.graph_objs as go
pyplot = py.offline.iplot
py.offline.init_notebook_mode(connected=True)

trace_basic = [go.Bar(x = rfm['用户等级'].value_counts().index,
                     y = rfm['用户等级'].value_counts().values,
                     marker = dict(color = 'orange'), opacity = 0.5)]

layout = go.Layout(title = '用户等级情况', xaxis = dict(title = '用户重要度'))

figure_basic = go.Figure(data = trace_basic, layout = layout)
pyplot(figure_basic)

trace = [go.Pie(labels = rfm['用户等级'].value_counts().index,
                values = rfm['用户等级'].value_counts().values,
                textfont = dict(size = 12, color = 'white'), opacity = 0.5)]
layout = go.Layout(title = '用户等级比例')

figure = go.Figure(data = trace, layout = layout)
pyplot(figure)

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22

在这里插入图片描述
在这里插入图片描述

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/小小林熬夜学编程/article/detail/372649
推荐阅读
相关标签
  

闽ICP备14008679号