我报名参与金石方案1期应战——分割10万奖池,这是我的第2篇文章,点击检查活动详情
- 作者:韩信子@ShowMeAI
- 数据剖析实战系列:www.showmeai.tech/tutorials/4…
- 机器学习实战系列:www.showmeai.tech/tutorials/4…
- 本文地址:www.showmeai.tech/article-det…
- 声明:版权一切,转载请联系渠道与作者并注明出处
- 收藏ShowMeAI检查更多精彩内容
咱们总会听到许多公司的技术人员在做用户画像的作业,细分客户/客户分群是一个很有含义的作业,能够保证企业构建更个性化的消费者针对战略,一起优化产品和服务。
在机器学习的视点看,客户分群通常会选用无监督学习的算法完结。运用这些方法,咱们会先搜集整理客户的根本信息,例如区域、性别、年龄、偏好 等,再对其进行分群。
在本篇内容中,ShowMeAI将用一个案例讲解根据客户信息做用户分群的方法完结。
中心进程
整个客户分群的进程包含一些中心的进程:
- 数据搜集
- 创立RFM表
- 探究数据&数据改换
- 运用聚类做用户分群
- 解说成果
数据搜集
下列数据操作处理与剖析涉及的东西和技能,欢迎大家查阅ShowMeAI对应的教程和东西速查表,快学快用。
图解数据剖析:从入门到通晓系列教程
数据科学东西库速查表 | Pandas 速查表
数据科学东西库速查表 | Seaborn 速查表
咱们需求先结合事务场景搜集数据,咱们在本案例中运用的是 Online_Retail在线零售数据集,大家能够在ShowMeAI的百度网盘中下载获取数据。
本份数据对应的是在线零售事务的买卖数据,包含英国在线零售从 2010 年 12 月 1 日到 2011 年 12 月 9 日的买卖。中心字段包含产品名称、数量、价格和其他表明 ID 的列。数据集包含 541909 条数据记载。
实战数据集下载(百度网盘):公众号『ShowMeAI研究中心』回复『实战』,或者点击 这儿 获取本文 [24]根据机器学习的用户价值数据挖掘与客户分群 『Online_Retail 在线零售数据集』
⭐ ShowMeAI官方GitHub:github.com/ShowMeAI-Hu…
为了快速演示客户分群进程,咱们不运用悉数数据,咱们从数据中采样出 10000 条演示整个进程,对应的数据读取与采样代码如下:
# 导入东西库
import pandas as pd
import matplotlib.pyplot as plt
import numpy as np
# 读取数据
df = pd.read_excel('Online_Retail.xlsx')
df = df[df['CustomerID'].notna()]
# 数据采样
df_fix = df.sample(10000, random_state = 42)
采样出来的数据如下
创立 RFM 表
数据准备好之后,为了细分客户,咱们会对数据做处理,拿到一些中心指标,比方客户前次购买产品的时刻,客户购买产品的频率以及客户为产品付出的费用。
也就是咱们说的制作 RFM 表的进程,咱们创立对应的字段,包含 Recency(最近一次消费)、Frequency(消费频率)和 Monetary Value(消费金额列),它们的构建方式别离如下:
- 能够用事务发生的日期减去快照日期,来代表最近消费时刻点。
- 能够核算每个客户的买卖量,作为频度信息。
- 能够汇总每个客户的一切买卖金额,作为消费金额列。
处理进程的代码如下:
# 只保存日期
from datetime import datetime
df_fix["InvoiceDate"] = df_fix["InvoiceDate"].dt.date
# 总金额
df_fix["TotalSum"] = df_fix["Quantity"] * df_fix["UnitPrice"]
# 最近消费时刻点快照
import datetime
snapshot_date = max(df_fix.InvoiceDate) + datetime.timedelta(days=1)
# 统计聚合
customers = df_fix.groupby(['CustomerID']).agg({
'InvoiceDate': lambda x: (snapshot_date - x.max()).days,
'InvoiceNo': 'count',
'TotalSum': 'sum'})
# 重命名字段
customers.rename(columns = {'InvoiceDate': 'Recency',
'InvoiceNo': 'Frequency',
'TotalSum': 'MonetaryValue'}, inplace=True)
得到成果如下
探究数据&数据改换
下列数据预处理涉及的常识,欢迎大家查阅ShowMeAI对应的常识详解文章。
- 机器学习实战 | 机器学习特征工程最全解读
咱们的许多典型的模型算法,关于数据散布都有一些前提假设,比方咱们会认为连续值字段是根本符合正态散布的,咱们对不同的字段进行可视化处理,以检查其散布:
fig, ax = plt.subplots(1, 3, figsize=(15,3))
sns.distplot(customers['Recency'], ax=ax[0])
sns.distplot(customers['Frequency'], ax=ax[1])
sns.distplot(customers['MonetaryValue'], ax=ax[2])
plt.tight_layout()
plt.show()
咱们会发现,数据并不是完全正态散布的,准确地说,它们都是有偏的,咱们通常会经过一些数据改换手法来对数据做一些整理,常见的数据改换方式包含:
- 对数转化
- 平方根改换
- box-cox 改换
咱们能够对原始数据,别离运用『对数改换』、『平方根改换』和『box-cox 改换处理』,把散布制作如下:
from scipy import stats
def analyze_skewness(x):
fig, ax = plt.subplots(2, 2, figsize=(5,5))
sns.distplot(customers[x], ax=ax[0,0])
sns.distplot(np.log(customers[x]), ax=ax[0,1])
sns.distplot(np.sqrt(customers[x]), ax=ax[1,0])
sns.distplot(stats.boxcox(customers[x])[0], ax=ax[1,1])
plt.tight_layout()
plt.show()
print(customers[x].skew().round(2))
print(np.log(customers[x]).skew().round(2))
print(np.sqrt(customers[x]).skew().round(2))
print(pd.Series(stats.boxcox(customers[x])[0]).skew().round(2))
analyze_skewness('Recency')
analyze_skewness('Frequency')
fig, ax = plt.subplots(1, 2, figsize=(10,3))
sns.distplot(customers['MonetaryValue'], ax=ax[0])
sns.distplot(np.cbrt(customers['MonetaryValue']), ax=ax[1])
plt.show()
print(customers['MonetaryValue'].skew().round(2))
print(np.cbrt(customers['MonetaryValue']).skew().round(2))
依据图像可视化,咱们别离对Recency、Frequency、MonetaryValue挑选box-cox改换,box-cox改换和三次方根(cbrt)改换。
from scipy import stats
customers_fix = pd.DataFrame()
customers_fix["Recency"] = stats.boxcox(customers['Recency'])[0]
customers_fix["Frequency"] = stats.boxcox(customers['Frequency'])[0]
customers_fix["MonetaryValue"] = pd.Series(np.cbrt(customers['MonetaryValue'])).values
customers_fix.tail()
处理过后的数据是这样的
咱们一瞬间运用到的模型算法(K-Means 聚类),关于不同字段的幅度巨细是敏感的,咱们会再做进一步的数据处理,把数据幅度规范化,这儿咱们能够直接运用 Scikit-Learn 的
# 导入库
from sklearn.preprocessing import StandardScaler
# 初始化对象
scaler = StandardScaler()
# 拟合和转化数据
scaler.fit(customers_fix)
customers_normalized = scaler.transform(customers_fix)
# 均值为 0,方差为 1
print(customers_normalized.mean(axis = 0).round(2)) # [0. -0。 0.]
print(customers_normalized.std(axis = 0).round(2)) # [1. 1. 1.]
得到成果如下:
建模与分群
数据处理完结,咱们能够进一步运用算法模型完结客户分群了,这儿咱们运用聚类算法 K-Means 来对数据分组。
K-Means 算法是一种无监督学习算法,它经过迭代和聚合来依据数据散布确认数据属于哪个簇。关于 K-Means 的具体常识欢迎大家检查ShowMeAI的教程文章:
- 图解机器学习 | 聚类算法详解
实践运用 K-Means 算法是很简单的,咱们直接运用 Scikit-Learn 来完结。但是 K-Means 算法中有一个很重要的超参数『簇数k』。下面咱们运用『肘点法』来定位最好的超参数:
from sklearn.cluster import KMeans
sse = {}
for k in range(1, 11):
kmeans = KMeans(n_clusters=k, random_state=42)
kmeans.fit(customers_normalized)
sse[k] = kmeans.inertia_
plt.title('The Elbow Method')plt.xlabel('k')
plt.ylabel('SSE')
sns.pointplot(x=list(sse.keys()), y=list(sse.values()))
plt.show()
这是成果,
依据上图的成果,咱们选定 k 取值为 3(因为大于3的k取值下,SSE的成果并不再急剧下降,而是呈现近线性)。咱们设定n_clusters
为3,再重新聚类:
model = KMeans(n_clusters=3, random_state=42)
model.fit(customers_normalized)
model.labels_.shape
模型解说&事务了解
咱们根据聚类成果来对用户群做一些解读和事务了解,这儿咱们将聚类得到的 3 个 cluster 的聚类中心信息输出,代码如下:
customers["Cluster"] = model.labels_
customers.groupby('Cluster').agg({
'Recency':'mean',
'Frequency':'mean',
'MonetaryValue':['mean', 'count']}).round(2)
结合上述成果,对3类聚类得到的用户群解读如下:
- 用户群0:频频消费,消费数额大,且最近有购买行为。能够视作『忠诚客户群』。
- 用户群1: 消费频率较低,消费数额小,但最近有购买行为。能够视作『新客户群』。
- 用户群2:消费频率较低,消费数额小,上一次购买的时刻较早。能够视作『流失客户群』。
参考资料
- Daqing C., Sai L.S, and Kun G. Data mining for the online retail industry: A case study of RFM model-based customer segmentation using data mining (2012), Journal of Database Marketing and Customer Strategy Management.
- Millman K. J, Aivazis M. Python for Scientists and Engineers (2011), Computing in Science & Engineering.
- Radei D. Top 3 Methods for Handling Skewed Data (2020), Towards Data Science.
- Elbow Method for optimal value of k in KMeans, Geeks For Geeks.
- 图解数据剖析:从入门到通晓系列教程:www.showmeai.tech/tutorials/3…
- 数据科学东西库速查表 | Pandas 速查表:www.showmeai.tech/article-det…
- 数据科学东西库速查表 | Seaborn 速查表:www.showmeai.tech/article-det…
- 机器学习实战 | 机器学习特征工程最全解读:www.showmeai.tech/article-det…
- 图解机器学习 | 聚类算法详解:www.showmeai.tech/article-det…