首页 > 编程知识 正文

电商数据案例分析,电商如何分析数据

时间:2023-05-06 04:13:33 阅读:197986 作者:1898

kaggle电商零售数据分析案例 项目背景数据清洗退货情况分析客户RFM分析

项目背景

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

数据清洗 import pandas as pdimport numpy as npimport matplotlib.pyplot as pltimport osimport warningsimport missingno as msnowarnings.filterwarnings('ignore')data = pd.read_csv('data.csv',encoding = 'utf-8', dtype = {'CustomerID' : str})data.head()


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

data.describe()


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

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

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

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

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

退货情况分析

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

退货订单没有对应的原订单退货订单存在一个或一个以上的原订单。
因此我们创建一个quantity_canceled的标签,用来记录每一个订单退货量,方便我们之后计算相应的单笔订单真实消费额。 data_cleaned = data.copy(deep = True)data_cleaned['quantity_canceled'] = 0unpaired_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

经过上述代码处理后,我们就得到了两个列表,一个列表叫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.monthdata_all['month'] = pd.to_datetime(data_all['InvoiceDate']).dt.monthdata_canceled['year'] = pd.to_datetime(data_canceled['InvoiceDate']).dt.yeardata_all['year'] = pd.to_datetime(data_all['InvoiceDate']).dt.yeardata_canceled['price'] = - data_canceled['Quantity'] * data_canceled['UnitPrice']data_all['price'] = data_all['Quantity'] * data_all['UnitPrice']

按照年月分别统计退货金额和退货率,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月份和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)

为了计算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()


接下来我们就可以计算相应的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() #观察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)




接下来我们对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)

我们这里选取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


最后我们根据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()


最后我们用plotly这个包来进行展示分类

import plotly as pyimport plotly.graph_objs as gopyplot = py.offline.iplotpy.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五14八八95#扣扣.com 举报,一经查实,本站将立刻删除。