零售行业交易数据分析(2)——RFM模型分类及可视化(Python实现)

内容简介

接上一篇文章《客户终身价值(CLTV)计算和回归预测模型》,本文继续分析一年的零售交易数据,从用户的角度,使用RFM模型对用户进行打分归类,并对结果进行可视化展示。

数据集介绍

数据集包含一家在英国注册的在线零售公司于 01/12/2010 和 09/12/2011 之间发生的所有交易。该公司主要销售各种场合的礼品,公司的许多客户都是批发商。

数据集一共包含8列:

  • InvoiceNo:发票编号。标称,为每笔交易唯一分配的 6 位整数。如果此代码以字母“c”开头,则表示取消。
  • StockCode:商品(商品)代码。标称,为每个不同的产品唯一分配的 5 位整数。
  • Description: 描述。 产品(项目)名称。
  • Quantity:数量。每笔交易每个产品(项目)的数量。
  • InvoiceDate:发票日期和时间,每笔交易产生的日期和时间。
  • UnitPrice:单价,单位产品价格(以英镑为单位)。
  • CustomerID:客户编号,一个唯一分配给每个客户的 5 位整数。
  • Country:国名,每个客户所在国家/地区的名称。

数据预处理

1. 导入包和封装预处理过程

先导入要使用的包和封装好的预处理过程。

import os
import datetime
import squarify
import warnings
import pandas as pd 
import numpy as np
import datetime as dt
from operator import attrgetter
import seaborn as sns
import matplotlib.pyplot as plt
import matplotlib.colors as mcolors
import plotly.graph_objs as go
from plotly.offline import iplot
from sklearn.metrics import (silhouette_score,
                             calinski_harabasz_score,
                             davies_bouldin_score)
from lifetimes import BetaGeoFitter, GammaGammaFitter
from lifetimes.plotting import plot_period_transactions
%matplotlib inline
#%load_ext nb_black
warnings.filterwarnings('ignore')
sns.set_style('whitegrid')
palette = 'Set2'

def replace_with_thresholds(dataframe, variable, q1 = 0.25, q3 = 0.75):
    
    '''
    Detects outliers with IQR method and replaces with thresholds 
    
    '''
    
    df_ = dataframe.copy()
    quartile1 = df_[variable].quantile(q1)
    quartile3 = df_[variable].quantile(q3)
    iqr = quartile3 - quartile1
    
    up_limit = quartile3 + 1.5 * iqr
    low_limit = quartile1 - 1.5 * iqr
    df_.loc[(df_[variable] < low_limit), variable] = low_limit
    df_.loc[(df_[variable] > up_limit), variable] = up_limit
    
    return df_

def ecommerce_preprocess(dataframe):
    df_ = dataframe.copy()
    
    #Missing Values
    df_ = df_.dropna()
    
    #Cancelled Orders & Quantity
    df_ = df_[~df_['InvoiceNo'].str.contains('C', na = False)]
    df_ = df_[df_['Quantity'] > 0]
    
    #Replacing Outliers
    df_ = replace_with_thresholds(df_, "Quantity", q1 = 0.01, q3 = 0.99)
    df_ = replace_with_thresholds(df_, "UnitPrice", q1 = 0.01, q3 = 0.99)
    
    #Total Price
    df_["TotalPrice"] = df_["Quantity"] * df_["UnitPrice"]
    
    return df_

2. 数据导入

导入的同时指定好个列的数据格式,就可以直接使用上面封装好的函数对数据进行预处理。

预处理的过程这里直接跳过,具体的处理过程在《客户终身价值(CLTV)计算和回归预测模型》这篇文章中由比较详细的解释。

#数据导入
df=pd.read_csv("data.csv",encoding="utf-8",
                 dtype = {'CustomerID': str,
                          'InvoiceID': str},
                 parse_dates = ['InvoiceDate'], 
                 infer_datetime_format = True)
                 
df = ecommerce_preprocess(df)
df.describe()

RFM模型分析

RFM模型介绍

RFM模型是客户关系管理(CRM)中被广泛使用,是衡量客户价值的重要工具。通过客户的近期交易行为、交易频率和交易金额三项指标,将客户划分为不同类型:

  • R(Recency): 计算最近的一次消费时间距离2017年12月3日有多久。消费间隔越小,表示R值越小,价值越高。
  • F(Frequency):消费频率,在这个时间段里,用户消费的次数。
  • M(Monetary): 消费金额,用户消费的总金额。

SQL淘宝用户数据分析文章中,也使用到了RFM分析方法,是比较常用的用户分析模型。

1.分别计算R、F、M维度的值。

today_date = dt.datetime(2011,12,11)

rfm = df.groupby('CustomerID').agg({'InvoiceDate': lambda x: (today_date - x.max()).days,
                                    'InvoiceNo': lambda x: x.nunique(),
                                    'TotalPrice': lambda x: x.sum()})

rfm.columns = ['recency', 'frequency', 'monetary']
rfm= rfm[rfm['monetary'] > 0]
rfm = rfm.reset_index()

rfm.head()

在这里插入图片描述

2.汇总RFM分数并对用户分类

将计算好的RFM的值按照各自的分位数,分成1-5等分,然后组合成最终的RFM分数。
由于三个维度分别由5个等级,用户分数类别有555=125种不同的排列组合。为了简化过程,这里我们先使用R和F两个维度对用户进行简单的分类。

def get_rfm_scores(dataframe):
    
    df_ = dataframe.copy()
    df_['recency_score'] = pd.qcut(df_['recency'],5,labels = [5, 4, 3, 2, 1])
    df_['frequency_score'] = pd.qcut(df_['frequency'].rank(method = "first"), 5, labels = [1, 2, 3, 4, 5])
    df_['monetary_score'] = pd.qcut(df_['monetary'], 5, labels = [1, 2, 3, 4, 5])
    df_['RFM_SCORE'] = (df_['recency_score'].astype(str) + df_['frequency_score'].astype(str)+ df_['monetary_score'].astype(str))
    
    return df_

rfm = get_rfm_scores(rfm)

seg_map = {
    r'[1-2][1-2]': 'Hibernating',
    r'[1-2][3-4]': 'At Risk',
    r'[1-2]5': 'Can\'t Loose',
    r'3[1-2]': 'About to Sleep',
    r'33': 'Need Attention',
    r'[3-4][4-5]': 'Loyal Customers',
    r'41': 'Promising',
    r'51': 'New Customers',
    r'[4-5][2-3]': 'Potential Loyalists',
    r'5[4-5]': 'Champions'
}

rfm['segment'] = rfm['recency_score'].astype(str) +rfm['frequency_score'].astype(str)
rfm['segment'] = rfm['segment'].replace(seg_map, regex = True)

rfm.head()

在这里插入图片描述

3. RFM模型结果评估

#model evaluation
print(' RFM Model Evaluation '.center(70, '='))
X = rfm[['recency_score', 'frequency_score']]
labels = rfm['segment']
print(f'Number of Observations: {X.shape[0]}')
print(f'Number of Segments: {labels.nunique()}')
print(f'Silhouette Score: {round(silhouette_score(X, labels), 3)}')
print(f'Calinski Harabasz Score: {round(calinski_harabasz_score(X, labels), 3)}')
print(f'Davies Bouldin Score: {round(davies_bouldin_score(X, labels), 3)} \n{70*"="}')

在这里插入图片描述
对不同客户群体的RFM数值进行描述性分析

rfm[['recency','monetary','frequency','segment']]\
.groupby('segment')\
.agg({'mean','std','max','min'})

在这里插入图片描述

数据结果可视化

1.树状图

segments = rfm['segment'].value_counts().sort_values(ascending = False)
fig = plt.gcf()
ax = fig.add_subplot()
fig.set_size_inches(16, 10)
squarify.plot(sizes=segments,
              label=[label for label in seg_map.values()],
              pad = False,
              bar_kwargs = {'alpha': 1},
              text_kwargs = {'fontsize':15})
plt.title("Customer Segmentation Map", fontsize = 20)
plt.xlabel('Frequency', fontsize = 18)
plt.ylabel('Recency', fontsize = 18)
plt.show()

在这里插入图片描述

2.柱状图

plt.figure(figsize = (18, 8))
ax = sns.countplot(data = rfm,
                   x = 'segment',
                   palette = palette)
total = len(rfm.segment)
for patch in ax.patches:
    percentage = '{:.1f}%'.format(100 * patch.get_height()/total)
    x = patch.get_x() + patch.get_width() / 2 - 0.17
    y = patch.get_y() + patch.get_height() * 1.005
    ax.annotate(percentage, (x, y), size = 14)
plt.title('Number of Customers by Segments', size = 16)
plt.xlabel('Segment', size = 14)
plt.ylabel('Count', size = 14)
plt.xticks(size = 10)
plt.yticks(size = 10)
plt.show()

在这里插入图片描述

3.根据R、F、M三个维度查看客户分布情况

fig, axes = plt.subplots(3, 1, figsize=(16, 12))
fig.suptitle('RFM Segment Analysis', size = 14)
feature_list = ['recency', 'monetary', 'frequency']
for idx, col in enumerate(feature_list):
    sns.histplot(ax = axes[idx], data = rfm,
                 hue = 'segment', x = feature_list[idx],
                 palette= palette)
    if idx == 1:
        axes[idx].set_xlim([0, 400])
    if idx == 2:
        axes[idx].set_xlim([0, 30])
plt.tight_layout()
plt.show()

在这里插入图片描述

4. R、F、M分布情况

首先,分别查看三个维度分数的分布。

# plot the distribution of customers over R and F
fig, axes = plt.subplots(nrows=1, ncols=3, figsize=(15, 4))

for i, p in enumerate(['recency_score', 'recency_score', 'monetary_score']):
    parameters = {'recency_score':'recency', 'recency_score':'frequency','monetary_score':'monetary'}
    y = rfm[p].value_counts().sort_index()
    x = y.index
    ax = axes[i]
    bars = ax.bar(x, y, color='silver')
    ax.set_frame_on(False)
    ax.tick_params(left=False, labelleft=False, bottom=False)
    ax.set_title('Distribution of {}'.format(parameters[p]),
                fontsize=14)
    for bar in bars:
        value = bar.get_height()
        if value == y.max():
            bar.set_color('firebrick')
        ax.text(bar.get_x() + bar.get_width() / 2,
                value - 5,
                '{}\n({}%)'.format(int(value), int(value * 100 / y.sum())),
               ha='center',
               va='top',
               color='w')

plt.show()

在这里插入图片描述
结果显示,整体都是比较均匀地分布,都是在19%-20%。

接下来看对于不同的R和F,M的分布情况如何。

# plot the distribution of M for RF score
fig, axes = plt.subplots(nrows=5, ncols=5,
                         sharex=False, sharey=True,
                         figsize=(10, 10))

r_range = range(1, 6)
f_range = range(1, 6)
for r in r_range:
    for f in f_range:
        y = rfm[(rfm['recency_score'] == r) & (rfm['frequency_score'] == f)]['monetary_score'].value_counts().sort_index()
        x = y.index
        ax = axes[r - 1, f - 1]
        bars = ax.bar(x, y, color='silver')
        if r == 5:
            if f == 3:
                ax.set_xlabel('{}\nF'.format(f), va='top')
            else:
                ax.set_xlabel('{}\n'.format(f), va='top')
        if f == 1:
            if r == 3:
                ax.set_ylabel('R\n{}'.format(r))
            else:
                ax.set_ylabel(r)
        ax.set_frame_on(False)
        ax.tick_params(left=False, labelleft=False, bottom=False)
        ax.set_xticks(x)
        ax.set_xticklabels(x, fontsize=8)

        for bar in bars:
            value = bar.get_height()
            if value == y.max():
                bar.set_color('firebrick')
            ax.text(bar.get_x() + bar.get_width() / 2,
                    value,
                    int(value),
                    ha='center',
                    va='bottom',
                    color='k')
fig.suptitle('Distribution of M for each F and R',
             fontsize=14)
plt.tight_layout()
plt.show()

在这里插入图片描述
从上面图可以看出,数据主要集中在左上角和右下角:左上角是交易次数最少(F:1-2)并且交易金额也是集中在(M:1-2),表明有许多客户是一次性交易就离开了;右下角可见,这一年中花费最多的客户(M=5),大多是交易活动频繁的熟客(F和R都为4-5)。

  • 4
    点赞
  • 20
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: RFM模型是一种经典的客户价值评估模型,通过对客户的购买行为进行分析,对客户的价值和忠诚度进行评估和分类RFM模型包括三个维度:最近一次交易时间(Recency)、交易次数(Frequency)和交易金额(Monetary)。通过将客户分为不同的类别,可以更好地了解他们的消费习惯和购买行为,从而针对性地进行营活动。 在RFM模型中,Recency表示客户最近一次购买距今的时间,可以反映客户的忠诚度和活跃度;Frequency表示客户购买的频率,可以反映客户的稳定性和购买力;Monetary表示客户的购买金额,可以反映客户的消费水平和价值。通过对这三个指标进行综合分析,可以得到每个客户的RFM得分,并将客户按照得分分为不同的等级,如A类客户、B类客户等等。 在实际应用中,可以根据RFM模型的结果采取针对性的措施,如针对A类客户进行更多的关怀和奖励活动,提高他们的忠诚度和消费频率;针对B类客户进行促活动,鼓励他们增加购买次数和金额;针对C类客户进行回收和减少开,避免无效的损失。 总之,RFM模型是一种实用的客户价值评估模型,通过对客户的购买行为进行细致分析,可以更好地了解客户的消费趋势和行为习惯,从而制定更加精准的营策略,提高企业的售额和客户价值。 ### 回答2: Python中的RFM模型可以帮助企业进行顾客价值分析,以更好地了解顾客的特点和行为,便于提升营策略和增加企业收益。RFM的全称是Recency, Frequency, Monetary,即最近一次消费时间(Recency)、购买频率(Frequency)、消费金额(Monetary)。 在Python中,可以使用Pandas等数据处理库对顾客数据进行预处理,然后使用RFM模型进行分析。首先,需要对数据进行分组和计算,得到每个顾客的Recency、Frequency、Monetary值。Recency计算方法为最新日期减去该顾客最后一次购买日期;Frequency计算为该顾客购买的次数;Monetary计算为该顾客购买的总金额。 接下来,可以使用K-means聚类算法对顾客进行分类,根据不同的RFM值将顾客分成不同的群组,从而更好地了解不同群组的消费行为和价值。可以使用Python中的Scikit-learn等机器学习库实现聚类算法。 最后,可以根据不同群组的消费行为及价值,制定更好的营策略,比如针对高价值的顾客提供更加个性化的服务及优惠,针对低价值的顾客提供更具吸引力的促策略,从而提高企业的收益。 总之,Python中的RFM模型可以帮助企业更好地了解顾客特点和行为,提升营策略和收益。但是在实际使用中,需要注意数据清洗和预处理、算法选择和参数调节等问题,以确保模型结果的准确性和有效性。 ### 回答3: RFM模型是一种基于客户价值的分析模型,用于分析客户的"最近一次购买时间"(Recency)、"购买频率"(Frequency)和"平均购买金额"(Monetary)这三个维度的特征,根据这三个特征划分不同的客户群体,为客户分类和个性化营提供指导。Python一个功能强大的编程语言,可以利用Python实现RFM模型,使得RFM模型更加高效、精准。 首先,通过Python对需要分析的数据进行处理和清洗,然后计算每个客户的"最近一次购买时间"、"购买频率"和"平均购买金额"。接下来,计算每个客户的RFM得分,同时,确定每个维度的分值和权重。最后,将客户进行分组,根据分数高低细分为不同的客户群体,以便于执行不同的营策略。 在Python中,可以使用pandas和numpy等库来进行数据处理和计算,使用matplotlib和seaborn等库来进行数据可视化。通过RFM模型的应用,可以更好地适应客户市场的差异化需求,实现更个性化、效率化的营,增强客户忠诚度和满意度。 总之,Python RFM模型的应用可以实现对客户数据的高效处理和分析,更加方便地进行营策略的调整和迭代,提高客户的购买体验和满意度,为企业的可持续发展创造更大的价值。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值