?? 作者:韓信子@ShowMeAI
?? 資料分析實戰系列:https://www.showmeai.tech/tutorials/40
?? 機器學習實戰系列:https://www.showmeai.tech/tutorials/41
?? 本文地址:https://www.showmeai.tech/article-detail/325
?? 宣告:著作權所有,轉載請聯系平臺與作者并注明出處
?? 收藏ShowMeAI查看更多精彩內容
我們總會聽到很多公司的技術人員在做用戶畫像的作業,細分客戶/客戶分群是一個很有意義的作業,可以確保企業構建更個性化的消費者針對策略,同時優化產品和服務,
在機器學習的角度看,客戶分群通常會采用無監督學習的演算法完成,應用這些方法,我們會先收集整理客戶的基本資訊,例如地區、性別、年齡、偏好 等,再對其進行分群,
在本篇內容中,ShowMeAI將用一個案例講解基于客戶資訊做用戶分群的方法實作,
?? 核心步驟
整個客戶分群的程序包含一些核心的步驟:
- 資料收集
- 創建RFM表
- 探索資料&資料變換
- 應用聚類做用戶分群
- 解釋結果
?? 資料收集
下列資料操作處理與分析涉及的工具和技能,歡迎大家查閱ShowMeAI對應的教程和工具速查表,快學快用,
圖解資料分析:從入門到精通系列教程
資料科學工具庫速查表 | Pandas 速查表
資料科學工具庫速查表 | Seaborn 速查表
我們需要先結合業務場景收集資料,我們在本案例中使用的是 ??Online_Retail在線零售資料集,大家可以在ShowMeAI的百度網盤中下載獲取資料,
本份資料對應的是在線零售業務的交易資料,包含英國在線零售從 2010 年 12 月 1 日到 2011 年 12 月 9 日的交易,核心欄位包括產品名稱、數量、價格和其他表示 ID 的列,資料集包含 541909 條資料記錄,
?? 實戰資料集下載(百度網盤):公眾號『ShowMeAI研究中心』回復『實戰』,或者點擊 這里 獲取本文 [24]基于機器學習的用戶價值資料挖掘與客戶分群 『Online_Retail 在線零售資料集』
? ShowMeAI官方GitHub:https://github.com/ShowMeAI-Hub
為了快速演示客戶分群程序,我們不使用全部資料,我們從資料中采樣出 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.
- ?? Rade?i? D. Top 3 Methods for Handling Skewed Data (2020), Towards Data Science.
- ?? Elbow Method for optimal value of k in KMeans, Geeks For Geeks.
- ?? 圖解資料分析:從入門到精通系列教程:https://www.showmeai.tech/tutorials/33
- ?? 資料科學工具庫速查表 | Pandas 速查表:https://www.showmeai.tech/article-detail/101
- ?? 資料科學工具庫速查表 | Seaborn 速查表:https://www.showmeai.tech/article-detail/105
- ?? 機器學習實戰 | 機器學習特征工程最全解讀:https://www.showmeai.tech/article-detail/208
- ?? 圖解機器學習 | 聚類演算法詳解:https://www.showmeai.tech/article-detail/197
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/531488.html
標籤:其他
