使用Python进行RFM分析

news/2025/2/12 4:51:05/

RFM分析用于根据客户的购买行为来了解和细分客户。RFM代表最近一次消费 (Recency)、消费频率 (Frequency)和消费金额 (Monetary),这是三个关键指标,可提供有关客户参与度、忠诚度和企业价值的信息。本文将带您完成使用Python进行RFM分析的任务。

RFM分析:概述

RFM分析是数据科学专业人员使用的一个概念,特别是在营销领域,用于根据客户的购买行为来理解和细分客户。

使用RFM分析,企业可以评估客户的:

  • Recency(他们最后一次购买的日期)
  • Frequency(购买的频率)
  • Monetary(购买的金额)

这是提供有关客户参与度、忠诚度和对企业价值的信息的三个关键指标。

要使用Python执行RFM分析,我们需要一个包含客户ID、购买日期和交易金额的数据集。有了这些信息,我们可以计算每个客户的RFM值,并分析他们的模式和行为。

使用Python进行RFM分析

import pandas as pd
import plotly.express as px
import plotly.io as pio
import plotly.graph_objects as go
pio.templates.default = "plotly_white"data = pd.read_csv("rfm_data.csv")
print(data.head())

输出

   CustomerID PurchaseDate  TransactionAmount ProductInformation  OrderID  \
0        8814   2023-04-11             943.31          Product C   890075   
1        2188   2023-04-11             463.70          Product A   176819   
2        4608   2023-04-11              80.28          Product A   340062   
3        2559   2023-04-11             221.29          Product A   239145   
4        9482   2023-04-11             739.56          Product A   194545   Location  
0     Tokyo  
1    London  
2  New York  
3    London  
4     Paris  

计算RFM值

from datetime import datetime# Convert 'PurchaseDate' to datetime
data['PurchaseDate'] = pd.to_datetime(data['PurchaseDate'])# Calculate Recency
data['Recency'] = (datetime.now().date() - data['PurchaseDate'].dt.date).dt.days# Calculate Frequency
frequency_data = data.groupby('CustomerID')['OrderID'].count().reset_index()
frequency_data.rename(columns={'OrderID': 'Frequency'}, inplace=True)
data = data.merge(frequency_data, on='CustomerID', how='left')# Calculate Monetary Value
monetary_data = data.groupby('CustomerID')['TransactionAmount'].sum().reset_index()
monetary_data.rename(columns={'TransactionAmount': 'MonetaryValue'}, inplace=True)
data = data.merge(monetary_data, on='CustomerID', how='left')

为了计算最近时间,我们从当前日期中减去购买日期,并使用datetime.now().date()函数提取天数。它给出了自客户上次购买以来的天数,代表了他们的最近价值。

然后,我们计算了每个客户的频率。我们按“CustomerID”对数据进行分组,并计算唯一“OrderID”值的数量,以确定每个客户的购买次数。它给出了频率值,代表每个客户的购买总数。

最后,我们计算了每个客户的货币价值。我们按“CustomerID”对数据进行分组,并对“TransactionAmount”值进行求和,以计算每个客户的总支出。它为我们提供货币价值,代表每个客户的总货币贡献。

通过执行这些计算,我们现在为每个客户提供了必要的RFM值,这是了解RFM分析中客户行为和细分的重要指标。

在继续之前,让我们看看结果数据:

print(data.head())

输出

   CustomerID PurchaseDate  TransactionAmount ProductInformation  OrderID  \
0        8814   2023-04-11             943.31          Product C   890075   
1        2188   2023-04-11             463.70          Product A   176819   
2        4608   2023-04-11              80.28          Product A   340062   
3        2559   2023-04-11             221.29          Product A   239145   
4        9482   2023-04-11             739.56          Product A   194545   Location  Recency  Frequency  MonetaryValue  
0     Tokyo       62          1         943.31  
1    London       62          1         463.70  
2  New York       62          1          80.28  
3    London       62          1         221.29  
4     Paris       62          1         739.56  

计算RFM评分

# Define scoring criteria for each RFM value
recency_scores = [5, 4, 3, 2, 1]  # Higher score for lower recency (more recent)
frequency_scores = [1, 2, 3, 4, 5]  # Higher score for higher frequency
monetary_scores = [1, 2, 3, 4, 5]  # Higher score for higher monetary value# Calculate RFM scores
data['RecencyScore'] = pd.cut(data['Recency'], bins=5, labels=recency_scores)
data['FrequencyScore'] = pd.cut(data['Frequency'], bins=5, labels=frequency_scores)
data['MonetaryScore'] = pd.cut(data['MonetaryValue'], bins=5, labels=monetary_scores)

分配从5到1的分数来计算recency分数,其中分数越高表示最近的购买。这意味着最近购买的客户将获得更高的recency分数。

分配从1到5的分数来计算frequency分数,其中较高的分数表示较高的购买频率。购买频率更高的客户将获得更高的频率分数。

为了计算monetary分数,分配从1到5的分数,其中较高的分数表示客户花费的金额较高。

为了计算RFM分数,我们使用pd.cut()函数将recency、frequency和monetary划分到bin中。我们为每个值定义5个bin,并为每个bin分配相应的分数。

一旦将分数添加到数据中,您将注意到它们是分类变量。您可以使用data.info()方法来确认这一点。因此,我们需要将它们的数据类型转换为整数,以进一步使用这些分数:

# Convert RFM scores to numeric type
data['RecencyScore'] = data['RecencyScore'].astype(int)
data['FrequencyScore'] = data['FrequencyScore'].astype(int)
data['MonetaryScore'] = data['MonetaryScore'].astype(int)

RFM值划分

现在,让我们根据分数计算最终RFM分数和价值段:

# Calculate RFM score by combining the individual scores
data['RFM_Score'] = data['RecencyScore'] + data['FrequencyScore'] + data['MonetaryScore']# Create RFM segments based on the RFM score
segment_labels = ['Low-Value', 'Mid-Value', 'High-Value']
data['Value Segment'] = pd.qcut(data['RFM_Score'], q=3, labels=segment_labels)

为了计算RFM分数,我们将Recency,Frequency和Monetary的分数相加。例如,如果客户的Recency得分为3,Frequency得分为4,Monetary得分为5,则其RFM得分将为12。

在计算RFM分数之后,我们基于分数创建RFM段。我们将RFM分数分为三个部分,即“低价值”、“中等价值”和“高价值”。分段是使用pd.qcut()函数完成的,该函数在分段之间均匀分布分数。

print(data.head())

输出

   CustomerID PurchaseDate  TransactionAmount ProductInformation  OrderID  \
0        8814   2023-04-11             943.31          Product C   890075   
1        2188   2023-04-11             463.70          Product A   176819   
2        4608   2023-04-11              80.28          Product A   340062   
3        2559   2023-04-11             221.29          Product A   239145   
4        9482   2023-04-11             739.56          Product A   194545   Location  Recency  Frequency  MonetaryValue  RecencyScore  FrequencyScore  \
0     Tokyo       62          1         943.31             1               1   
1    London       62          1         463.70             1               1   
2  New York       62          1          80.28             1               1   
3    London       62          1         221.29             1               1   
4     Paris       62          1         739.56             1               1   MonetaryScore  RFM_Score Value Segment  
0              2          4     Low-Value  
1              1          3     Low-Value  
2              1          3     Low-Value  
3              1          3     Low-Value  
4              2          4     Low-Value  

现在我们来看看分布情况:

# RFM Segment Distribution
segment_counts = data['Value Segment'].value_counts().reset_index()
segment_counts.columns = ['Value Segment', 'Count']pastel_colors = px.colors.qualitative.Pastel# Create the bar chart
fig_segment_dist = px.bar(segment_counts, x='Value Segment', y='Count', color='Value Segment', color_discrete_sequence=pastel_colors,title='RFM Value Segment Distribution')# Update the layout
fig_segment_dist.update_layout(xaxis_title='RFM Value Segment',yaxis_title='Count',showlegend=False)# Show the figure
fig_segment_dist.show()

在这里插入图片描述

RFM客户细分

我们计算的上述片段是RFM值片段。现在,我们将计算RFM客户细分。RFM价值段表示基于客户的RFM分数将客户分类为诸如“低价值”、“中等价值”和“高价值”的组。通过将RFM分数划分为不同的范围或组来确定这些分段,从而允许对总体客户RFM特征进行更细粒度的分析。RFM价值部分帮助我们了解客户在Recency,Frequency和Monetary方面的相对价值。

现在,让我们创建并分析RFM客户细分,这些细分是基于RFM分数的更广泛的分类。在Recency,Frequency和Monetary方面,以下是如何创建RFM客户细分:

# Create a new column for RFM Customer Segments
data['RFM Customer Segments'] = ''# Assign RFM segments based on the RFM score
data.loc[data['RFM_Score'] >= 9, 'RFM Customer Segments'] = 'Champions'
data.loc[(data['RFM_Score'] >= 6) & (data['RFM_Score'] < 9), 'RFM Customer Segments'] = 'Potential Loyalists'
data.loc[(data['RFM_Score'] >= 5) & (data['RFM_Score'] < 6), 'RFM Customer Segments'] = 'At Risk Customers'
data.loc[(data['RFM_Score'] >= 4) & (data['RFM_Score'] < 5), 'RFM Customer Segments'] = "Can't Lose"
data.loc[(data['RFM_Score'] >= 3) & (data['RFM_Score'] < 4), 'RFM Customer Segments'] = "Lost"# Print the updated data with RFM segments
print(data[['CustomerID', 'RFM Customer Segments']])

在上面的代码中,我们根据RFM分数将RFM细分给客户,然后在数据中创建一个名为“RFM Customer Segments”的新列。

RFM分析

现在,让我们分析每个价值细分中不同RFM客户细分的客户分布:

segment_product_counts = data.groupby(['Value Segment', 'RFM Customer Segments']).size().reset_index(name='Count')segment_product_counts = segment_product_counts.sort_values('Count', ascending=False)fig_treemap_segment_product = px.treemap(segment_product_counts, path=['Value Segment', 'RFM Customer Segments'], values='Count',color='Value Segment', color_discrete_sequence=px.colors.qualitative.Pastel,title='RFM Customer Segments by Value')
fig_treemap_segment_product.show()

在这里插入图片描述
现在让我们分析Champions细分市场中RFM值的分布:

# Filter the data to include only the customers in the Champions segment
champions_segment = data[data['RFM Customer Segments'] == 'Champions']fig = go.Figure()
fig.add_trace(go.Box(y=champions_segment['RecencyScore'], name='Recency'))
fig.add_trace(go.Box(y=champions_segment['FrequencyScore'], name='Frequency'))
fig.add_trace(go.Box(y=champions_segment['MonetaryScore'], name='Monetary'))fig.update_layout(title='Distribution of RFM Values within Champions Segment',yaxis_title='RFM Value',showlegend=True)fig.show()

在这里插入图片描述
现在,让我们分析Champions细分市场中的RFM之间的相关性:

correlation_matrix = champions_segment[['RecencyScore', 'FrequencyScore', 'MonetaryScore']].corr()# Visualize the correlation matrix using a heatmap
fig_heatmap = go.Figure(data=go.Heatmap(z=correlation_matrix.values,x=correlation_matrix.columns,y=correlation_matrix.columns,colorscale='RdBu',colorbar=dict(title='Correlation')))fig_heatmap.update_layout(title='Correlation Matrix of RFM Values within Champions Segment')fig_heatmap.show()

在这里插入图片描述
现在让我们来看看所有细分市场的客户数量:

import plotly.colorspastel_colors = plotly.colors.qualitative.Pastelsegment_counts = data['RFM Customer Segments'].value_counts()# Create a bar chart to compare segment counts
fig = go.Figure(data=[go.Bar(x=segment_counts.index, y=segment_counts.values,marker=dict(color=pastel_colors))])# Set the color of the Champions segment as a different color
champions_color = 'rgb(158, 202, 225)'
fig.update_traces(marker_color=[champions_color if segment == 'Champions' else pastel_colors[i]for i, segment in enumerate(segment_counts.index)],marker_line_color='rgb(8, 48, 107)',marker_line_width=1.5, opacity=0.6)# Update the layout
fig.update_layout(title='Comparison of RFM Segments',xaxis_title='RFM Segments',yaxis_title='Number of Customers',showlegend=False)fig.show()

在这里插入图片描述
现在让我们来看看所有细分市场的Recency,Frequency和Monetary分数:

# Calculate the average Recency, Frequency, and Monetary scores for each segment
segment_scores = data.groupby('RFM Customer Segments')['RecencyScore', 'FrequencyScore', 'MonetaryScore'].mean().reset_index()# Create a grouped bar chart to compare segment scores
fig = go.Figure()# Add bars for Recency score
fig.add_trace(go.Bar(x=segment_scores['RFM Customer Segments'],y=segment_scores['RecencyScore'],name='Recency Score',marker_color='rgb(158,202,225)'
))# Add bars for Frequency score
fig.add_trace(go.Bar(x=segment_scores['RFM Customer Segments'],y=segment_scores['FrequencyScore'],name='Frequency Score',marker_color='rgb(94,158,217)'
))# Add bars for Monetary score
fig.add_trace(go.Bar(x=segment_scores['RFM Customer Segments'],y=segment_scores['MonetaryScore'],name='Monetary Score',marker_color='rgb(32,102,148)'
))# Update the layout
fig.update_layout(title='Comparison of RFM Segments based on Recency, Frequency, and Monetary Scores',xaxis_title='RFM Segments',yaxis_title='Score',barmode='group',showlegend=True
)fig.show()

在这里插入图片描述

总结

RFM分析用于根据客户的购买行为来了解和细分客户。RFM代表Recency,Frequency和Monetary,这是三个关键指标,可提供有关客户参与度、忠诚度和企业价值的信息。


http://www.ppmy.cn/news/1116081.html

相关文章

王道考研操作系统

王道考研操作系统 计算机系统概述操作系统的概念操作系统的特征操作系统的发展历程操作系统内核中断和异常![在这里插入图片描述](https://img-blog.csdnimg.cn/162452b4c60144e0bd500e180127c447.png)系统调用操作系统结构虚拟机错题 进程与线程进程控制进程通信线程和多线程模…

使用patch-package保存node_modules包修改

遇到情况&#xff0c;第三方包存在bug或者缺少文件时候&#xff0c;我们手动修改了某个包时候&#xff0c;下次npm安装时候会导致原来的修改呗覆盖 安装 这时候可以用到npm工具包patch-package&#xff0c;项目更目录命令行安装 npm i -D patch-package修改文件 修改好nod…

mysql知识大全

MySQL知识大全&#xff08;2&#xff09; MySqL 基础为1—7&#xff08;增删改查基础语法&#xff09;&#xff0c;MySQL进阶知识为8—11&#xff08;约束、数据库设计、多表查询、事务&#xff09; 1、数据库相关概念 以前我们做系统&#xff0c;数据持久化的存储采用的是文件…

升级:远程桌面软件玩游戏指南

你有没有遇到过这样的场景&#xff1a;你想玩一款特定的游戏&#xff0c;但却受到设备功能的限制&#xff1f;这就是游戏远程桌面的概念变得非常宝贵的地方。从本质上讲&#xff0c;它允许您远程利用高端游戏计算机的功能&#xff0c;使您能够在自己的设备上玩游戏。 可以考虑…

全网最全Kettle教程-Kettle概述

文章目录 第一章 Kettle概述1.1 Kettle发展历程1.2 Kettle简介1.3 Kettle相关俗语1.4 Kettle设计与组成1.5 Kettle功能模块1.6 Kettle的执行Transformation&#xff08;转换&#xff09;1.7 Kettle商业和社区版区别1.8 数据集成与ETL1.9 ETL工具比较 第一章 Kettle概述 1.1 Ke…

SpringBoot连接MySql主从配置 读写分离

SpringBoot连接MySql主从配置 主从读写分享 1、添加maven依赖 <dependency><groupId>org.apache.shardingsphere</groupId><artifactId>sharding-jdbc-spring-boot-starter</artifactId><version>4.1.1</version> </dependency…

Python150题day06

1.4字典练习题 ①字典基本操作 dic { python: 95, java: 99, c: 100 } 用程序解答以下题目 1.字典的长度是多少 2.请修改java这个key对应的value值为98 3.删除 c 这个key 4.增加一个key-value对&#xff0c;key值为 php,value是90 5.获取所有的key值&#xff0c;存储在列表里…

diffusers中DDPMScheduler/AutoencoderKL/UNet2DConditionModel/CLIPTextModel代码详解

扩散模型的训练时比较简单的 上图可见&#xff0c;unet是epsθ是unet。noise和预测出来的noise做个mse loss。 训练的常规过程&#xff1a; latents vae.encode(batch["pixel_values"].to(weight_dtype)).latent_dist_sample() latents latents*vae.config.scali…