炼数成金 门户 大数据 Python 查看内容

Python与RFM分析实战

2019-6-20 14:02| 发布者: 炼数成金_小数| 查看: 23345| 评论: 0|原作者: alitrack|来自: 数据思维

摘要: RFM是一种用于分析客户价值的方法。 它通常用于数据库营销和直接营销,并在零售和专业服务行业受到特别关注。InvoiceNo:发票编号。 定类数据,为每个事务唯一分配的6位整数。 如果此代码以字母'c'开头,则表示取消 ...

Python 数据库 Java Hadoop 培训

RFM是一种用于分析客户价值的方法。 它通常用于数据库营销和直接营销,并在零售和专业服务行业受到特别关注。
RFM 代表了三个纬度:
Recency – 最近一次消费
Frequency – 消费频率
Monetary Value – 消费金额

本次RFM实战所用数据来自一家英国在线零售商店2010年1月12日至2011年12月9的全部交易数据。下载地址,
https://archive.ics.uci.edu/ml/datasets/Online+Retail

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

代码,
加载所需包
import pandas as pd
import numpy as np
import matplotlib as plt
import seaborn as sn
%matplotlib inline

加载数据
Retail_df = pd.read_Excel("Online Retail.xlsx")
Retail_df.head(5)

Retail_df.dtypes
InvoiceNo              object
StockCode              object
Description            object
Quantity                int64
InvoiceDate    datetime64[ns]
UnitPrice             float64
CustomerID            float64
Country                object
dtype: object

把发票日期转为日期时间格式,并计算的属性数
#Convert the date in YYYY-mm-dd HH:MM format and store that date in 'Date' column
Retail_df['Date']=pd.to_datetime(Retail_df['InvoiceDate'], format = '%Y-%m-%d %H:%M:%S')
#Retail_df['Date']=Retail_df['Date'].apply(lambda x: x.strftime('%Y-%d-%m %H:%M'))

# Count the unique no of attributes in Retail data
def unique_counts(Retail_df):
   for i in Retail_df.columns:
       count = Retail_df[i].nunique()
       print(i, ": ", count)
unique_counts(Retail_df)
InvoiceNo :  25900
StockCode :  4070
Description :  4223
Quantity :  722
InvoiceDate :  23260
UnitPrice :  1630
CustomerID :  4372
Country :  38
Date :  23260

总价=数量*单件
Retail_df['Total_Price']=Retail_df['Quantity']\
*Retail_df['UnitPrice']
Retail_df.head(5)

剔除异常值
# 剔除空数据(NaN)
Online_retail_df = Retail_df[np.isfinite(Retail_df['CustomerID'])]
# 剔除数量小于等于0的数据
final_retail = Online_retail_df[Online_retail_df['Quantity'] > 0]
计算RFM
import datetime as dt
NOW = dt.datetime(2011,12,10)
rfmTable = final_retail.groupby('CustomerID').agg({'Date': lambda x: (NOW - x.max()).days, 'InvoiceNo': lambda x: len(x),'Total_Price': lambda x: x.sum()})
rfmTable['Date'] = rfmTable['Date'].astype(int)
rfmTable.rename(columns={'Date': 'recency', 
                         'InvoiceNo': 'frequency',
                       'Total_Price': 'monetary_value'}, inplace=True)
 
聚类
from sklearn.cluster import KMeans
from sklearn.preprocessing import StandardScaler
scaler = StandardScaler()
X_scaled = scaler.fit_transform( rfmTable )

clusters = KMeans(3)  # 3 clusters
clusters.fit( X_scaled )
KMeans(algorithm='auto', copy_x=True, init='k-means++', max_iter=300,
    n_clusters=3, n_init=10, n_jobs=None, precompute_distances='auto',
    random_state=None, tol=0.0001, verbose=0)

import random
random.seed(9008)
X_sample = np.array(random.sample(X_scaled.tolist(),20))
rfmTable["cluster_new"] = clusters.labels_
rfmTable.drop( 'cluster_new', axis = 1, inplace = True )
cmap = sn.cubehelix_palette(as_cmap=True, rot=-.3, light=1)
g = sn.clustermap(X_sample, cmap=cmap, linewidths=.5)


树形图显示有3-6个不同的簇。
我随机抽取了20-30个数据点来构建树状图
考虑使用肘方法来判断类数。

cluster_range = range( 1, 10 )
cluster_errors = []

for num_clusters in cluster_range:
  clusters = KMeans( num_clusters )
  clusters.fit( X_scaled )
  cluster_errors.append( clusters.inertia_ )
  
 clusters_df = pd.DataFrame( { "num_clusters":cluster_range, "cluster_errors": cluster_errors } )
 clusters_df.head(10)


import matplotlib.pyplot as plt
plt.figure(figsize=(12,6))
plt.plot( clusters_df.num_clusters
, clusters_df.cluster_errors, marker = "o" )

从上图看,分3组比较合适。
clusters = KMeans(3)  # 3 clusters
clusters.fit( X_scaled )
rfmTable["cluster_label"] = clusters.labels_
rfmTable.groupby('cluster_label').mean()

rfmTable_0 = rfmTable[rfmTable.cluster_label == 0]
rfmTable_0.head(10)

所有高Recency,低frequency,低monetary_value的都分到这组,这些对公司来说,是获得回报最少的客户。
rfmTable_1 = rfmTable[rfmTable.cluster_label == 1]
rfmTable_1.head(10)

低recency,高频次,高monetary,公司最有价值的客户。

参考
https://en.wikipedia.org/wiki/RFM_(customer_value)
https://baike.baidu.com/item/RFM%E6%A8%A1%E5%9E%8B
https://github.com/nikadeap/RFM-Analysis

声明:本文版权归原作者所有,文章收集于网络,为传播信息而发,如有侵权,请联系小编及时处理,谢谢!

欢迎加入本站公开兴趣群
软件开发技术群
兴趣范围包括:Java,C/C++,Python,PHP,Ruby,shell等各种语言开发经验交流,各种框架使用,外包项目机会,学习、培训、跳槽等交流
QQ群:26931708

Hadoop源代码研究群
兴趣范围包括:Hadoop源代码解读,改进,优化,分布式系统场景定制,与Hadoop有关的各种开源项目,总之就是玩转Hadoop
QQ群:288410967 

鲜花

握手

雷人

路过

鸡蛋

相关阅读

最新评论

热门频道

  • 大数据
  • 商业智能
  • 量化投资
  • 科学探索
  • 创业

即将开课

 

GMT+8, 2019-11-18 23:51 , Processed in 0.187526 second(s), 24 queries .