
CDA數(shù)據(jù)分析師 出品
作者:CDALevel Ⅰ持證人
崗位:數(shù)據(jù)分析師
行業(yè):大數(shù)據(jù)
背景
在前文(Python實(shí)現(xiàn)基于客觀事實(shí)的RFM模型)中闡述了如何運(yùn)用分箱的技巧講客服進(jìn)行分群,有興趣的讀者可以去回顧 一下。利用流行的編程語言---Python及分箱技巧進(jìn)行RFM模型構(gòu)建,結(jié)果發(fā)現(xiàn),此方法有效了降低人工分群帶來的主觀性影響,然而,會出現(xiàn)類似偏態(tài)的現(xiàn)象。其原因是在于分箱的操作對R值、F值、M值都進(jìn)行了一遍。因此,為解決這種類似偏態(tài)的問題,本文將利用機(jī)器學(xué)習(xí)中的K-Means聚類對客戶進(jìn)行分群。
如今新基建大數(shù)據(jù)、人工智能行業(yè)在迅速的發(fā)展,而機(jī)器學(xué)習(xí)是其中不可或缺的一環(huán),機(jī)器學(xué)習(xí)強(qiáng)調(diào)的是利用人腦一般從歷史的數(shù)據(jù)中學(xué)習(xí)到經(jīng)驗(yàn)并運(yùn)用與未來的判斷中。而K-Means模型則是機(jī)器學(xué)習(xí)中聚類算法中的一塊,本文結(jié)合Python實(shí)現(xiàn)K-Means聚類算法的編寫,同時應(yīng)用于客戶分群中。
本文采用Anaconda進(jìn)行Python編譯,主要涉及的Python模塊:
本章分為三部分講解:
"人以類聚,物以群分",這句話就是K-Means模型的思想點(diǎn)。其中,K代表類別數(shù)量(Tips:在機(jī)器學(xué)習(xí)中,自變量又叫預(yù)測變量,因變量又叫目標(biāo)變量)。而Means代表每個類別中樣本的均值,因此這個Means也即均值的意思(Tips:這里的樣本通俗理解就是一個記錄行)。
K-Means聚類是以距離作為樣本間相似度的度量標(biāo)準(zhǔn),將距離相近的樣本分配至同一個類別。樣本間的度量方式可以是歐氏距離,馬氏距離,余弦相似度等,K-Means聚類通常采用歐氏距離來度量各樣本間的距離。
歐式距離又稱歐幾里得度量,為常見的兩點(diǎn)之間或多點(diǎn)之間的距離表示法,如類別$x=(x{1},x{1},...,x{n})$與類別$y=(y{1},y{2},...,y{n})$間的距離如下式:
馬氏距離同樣也是一種距離的度量,是由馬哈拉諾比斯(P. C. Mahalanobis)提出的,表示樣本間的協(xié)方差距離。它是一種有效的計(jì)算兩個未知樣本集的相似度的方法。這可以看作是歐式距離的修正,修正了歐式距離中各個維度尺度不一致且相關(guān)的問題。
對于一個均值為$mu=(mu{1},mu{2},...,mu_{p})^{T}$,協(xié)方差矩陣的S的多變量$x=(x^{1},x^{2},...,x^{p})^{T}$,其馬氏距離為下式
輸入:樣本集D,設(shè)定類別數(shù)目K
輸出:類劃分(K個類)
以流程圖展現(xiàn)算法步驟,
在上述原理和算法步驟可能有讀者不是很清楚,那么接下來將以例子的形式更加具體的展現(xiàn)K-Means是如何進(jìn)行聚類的。首先利用scikit-learn庫中的datasets接口生成隨機(jī)樣本點(diǎn)作為我們的聚類輸入值,以可視化形式展現(xiàn),如下圖:
從上圖可以看出輸入的樣本點(diǎn)肉眼可見可以分成3類,那么怎么用K-Means將此樣本集識別出3類呢。這里用到scikit-learn庫中的KMeans接口,該接口的訓(xùn)練算法與上述算法是大同小異的。其中稍有差別的是,初始的類中心點(diǎn)的選擇并不是隨機(jī)的,而是選擇k-means++的初始化方案,將類中心化為彼此原理的點(diǎn)。具體而言將在代碼體現(xiàn)。其次不同的是,結(jié)束條件,上述算法步驟的結(jié)束條件時判斷各類別中的樣本是否發(fā)生改變,而KMeans接口中的結(jié)束條件是類似于利用損失函數(shù):$||Means{old}-Means{new}||$,該式子的意思是計(jì)算舊類中心點(diǎn)于新類中心點(diǎn)的距離,如果該距離小于給定的值$epsilon$,則結(jié)束,輸出類別。
上述樣本點(diǎn)的構(gòu)建及可視化的代碼如下
import numpy as np import matplotlib.pyplot as plt import seaborn as sns from sklearn.datasets import make_blobs
sns.set_style('darkgrid') # 中文顯示問題解決 plt.rcParams['font.sans-serif'] = ["SimHei"]
plt.rcParams["axes.unicode_minus"] = False # 生成例子數(shù)據(jù) np.random.seed(123)
centers = [[2, 1], [6, 5], [10, 3]]
n_clusters = len(centers)
X, labels_true = make_blobs(n_samples=300, centers=centers, cluster_std=0.7)
plt.scatter(X[:,0],X[:,1],c='red',marker='o',
label='樣本')
plt.legend()
plt.savefig('example.jpg',dpi=200)
plt.show()
代碼解讀:
首先設(shè)置可視化的主題為seaborn下的黑格子狀態(tài),其次選擇圍繞(2,1),(6,5),(10,3)這三個點(diǎn)(類中心點(diǎn))構(gòu)造樣本集。運(yùn)用make_blobs()函數(shù)即可構(gòu)建樣本集,該函數(shù)中可以設(shè)定樣本集的數(shù)量n_samples和方差cluster_std。最后以散點(diǎn)圖形式展現(xiàn)。
最后調(diào)用KMeans接口,將該樣本集進(jìn)行聚類,用可視化的方式對聚類后結(jié)果進(jìn)行展現(xiàn),結(jié)果如下圖
可以明確看到,聚類結(jié)果為3類,和我們預(yù)期的是一致的,接下來看類別中心點(diǎn)于原設(shè)計(jì)的中心點(diǎn)對比,如下表。
從上表可以看出,聚類中心點(diǎn)是存在微小差異的,這也說明KMeans接口時利用損失函數(shù)進(jìn)行迭代的。相關(guān)代碼如下
# K-Means聚類 from sklearn.cluster import KMeans
sns.set_style('darkgrid') # 中文顯示問題解決 plt.rcParams['font.sans-serif'] = ["SimHei"]
plt.rcParams["axes.unicode_minus"] = False # 模型擬合 k_means = KMeans(init="k-means++", n_clusters=3)
k_means.fit(X) # 可視化結(jié)果 fig = plt.figure(figsize=(15,8))
colors = ["#4EACC5", "#FF9C34", "#4E9A06"]
k_means_cluster_centers = k_means.cluster_centers_
k_means_labels = k_means.labels_
ax = fig.add_subplot()
for k, col in zip(range(n_clusters), colors):
my_members = k_means_labels == k
cluster_center = k_means_cluster_centers[k]
ax.plot(X[my_members, 0], X[my_members, 1], "w", markerfacecolor=col, marker="*")
ax.plot(
cluster_center[0],
cluster_center[1], "o",
markerfacecolor=col,
markeredgecolor="k",
markersize=6,
)
ax.set_title("KMeans聚類結(jié)果") #ax.set_xticks() #ax.set_yticks() plt.savefig('例子結(jié)果.jpg',dpi=200)
代碼解讀:
KMeans(init="k-means++", n_clusters=3)這段代碼即將估計(jì)器擬合上述的樣本集。其中,init參數(shù)即為上述所講KMeans++的初始化選擇方式。而后的參數(shù)為設(shè)定分成多少類。
擬合后的KMeans估計(jì)器是可以進(jìn)行調(diào)用的,這里我們調(diào)用類中心點(diǎn)(k_means.cluster_centers_)和樣本所屬類別(k_means.labels_)。
最后一段代碼是結(jié)合類中心點(diǎn)和樣本所屬類別進(jìn)行可視化展示,可以非常明確的看到聚類后的結(jié)果。(TIps:最后保存圖片的dpi是調(diào)整像素的,在Python編譯器里面默認(rèn)保存的圖像像素普遍都不高,讀者可以適當(dāng)?shù)脑O(shè)置。)
K-Means模型構(gòu)建(代碼)
有了數(shù)據(jù)和scikit-learn庫中的KMmeans接口的了解,那么接下來先上完整代碼和解釋,模型構(gòu)建的代碼如下
# RMF實(shí)戰(zhàn) import pandas as pd import seaborn as sns
sns.set_style('darkgrid')
# 中文顯示問題解決
plt.rcParams['font.sans-serif'] = ["SimHei"]
plt.rcParams["axes.unicode_minus"] = False
## 數(shù)據(jù)讀取 data = pd.read_excel('rfm.xlsx')
X = data.drop(columns = 'user_id')
## KMeans模型構(gòu)建
k_means = KMeans(init="k-means++", n_clusters=8,random_state=123)
k_means.fit(X)
## 類別查看 data['categories'] = k_means.labels_
## 相關(guān)屬性查看
k_means.cluster_centers_
k_means.verbose
## 機(jī)器幫助判斷(等深分箱)
result = k_means.cluster_centers_
reuslt = pd.DataFrame(result)
reuslt['R_label'] = pd.qcut(reuslt[2],2,labels = range(1,3)).astype('int')
reuslt['F_label'] = pd.qcut(reuslt[0],2,labels = range(1,3)).astype('int')
reuslt['M_label'] = pd.qcut(reuslt[1],2,labels = range(1,3)).astype('int')
## 客戶分類打標(biāo)簽 for i,j in data.iterrows(): if j['categories'] == 0 or j['categories'] == 2: data.loc[i,'客戶類別'] = '一般發(fā)展用戶' if j['categories'] == 1 or j['categories'] == 5: data.loc[i,'客戶類別'] = '重要價(jià)值用戶' if j['categories'] == 3 or j['categories'] == 7: data.loc[i,'客戶類別'] = '重要保持客戶' if j['categories'] == 4 or j['categories'] == 6: data.loc[i,'客戶類別'] = '一般挽留客戶' # 可視化
cate_sta = data['客戶類別'].value_counts()
cate_sta = pd.DataFrame(cate_sta)
sns.barplot(y='客戶類別', x=cate_sta.index, data=cate_sta)
plt.title('用戶類別統(tǒng)計(jì)')
plt.show()
從上圖可以看到,利用KMeans的估計(jì)器,我們已經(jīng)得到了每個id所屬的類別,那么現(xiàn)在的問題是,該怎么判斷用戶是哪種客戶類別呢(Tips:用戶類別分為8種,不清楚的讀者可以回顧前文),這時候就需要用到類中心點(diǎn),通過判斷類中心點(diǎn)來給每種分類一個判斷,下表為每個類別對應(yīng)的類中心點(diǎn)。
有了每個類別的類中心點(diǎn),我們就需要對每個類賦予RFM模型中的客戶類別,本文在這方面選擇分箱的技巧進(jìn)行分類。
對類中心點(diǎn)實(shí)現(xiàn)等深分箱,與前文運(yùn)用等距分箱不同,這里采取的是指定每個類別種的個數(shù)是一致的,這也符合RFM模型中的每個值都有4個高,4個低。在Python中利用pd.qcut()函數(shù)進(jìn)行分箱,其參數(shù)與等距分箱大同小異,有興趣的讀者可以研究。最后以"2"代表高,"1"代表低。并按照RFM的規(guī)則將每種類別賦予一個客戶類別,結(jié)果如下表:
最后,以柱狀圖的形式展示該份數(shù)據(jù)集中的客戶類別總數(shù)
具體數(shù)值如下表:
與前文(Python實(shí)現(xiàn)基于客觀事實(shí)的RFM模型)對比,本文將該份數(shù)據(jù)集中的用戶分為4類(一般發(fā)展用戶、重要保持客戶、一般挽留客戶、重要價(jià)值用戶),而前文將用戶分為5類(一般發(fā)展用戶、一般挽留用戶、重要挽留客戶、一般保持用戶、重要發(fā)展用戶)。可以看出,兩者都識別出了一般發(fā)展用戶的信息,且其所占比例也是最多的。不同之處在于,基于KMeans聚類模型的RFM模型可以挖掘出重要保持客戶、重要價(jià)值用戶的信息,而基于客觀事實(shí)的RFM模型對一般挽留用戶較為敏感。
因此,對于決策者而言,每個模型得到的RFM模型是不一致的,而決策者應(yīng)該從模型結(jié)果的相同點(diǎn)入手,如該份數(shù)據(jù),兩個模型都發(fā)現(xiàn)了一般發(fā)展用戶所占比例是最大的,代表其解釋性強(qiáng)。而對于模型間的不同點(diǎn),則需要更深入的探討如何取舍的問題。
數(shù)據(jù)分析咨詢請掃描二維碼
若不方便掃碼,搜微信號:CDAshujufenxi
SQL Server 中 CONVERT 函數(shù)的日期轉(zhuǎn)換:從基礎(chǔ)用法到實(shí)戰(zhàn)優(yōu)化 在 SQL Server 的數(shù)據(jù)處理中,日期格式轉(zhuǎn)換是高頻需求 —— 無論 ...
2025-09-18MySQL 大表拆分與關(guān)聯(lián)查詢效率:打破 “拆分必慢” 的認(rèn)知誤區(qū) 在 MySQL 數(shù)據(jù)庫管理中,“大表” 始終是性能優(yōu)化繞不開的話題。 ...
2025-09-18CDA 數(shù)據(jù)分析師:表結(jié)構(gòu)數(shù)據(jù) “獲取 - 加工 - 使用” 全流程的賦能者 表結(jié)構(gòu)數(shù)據(jù)(如數(shù)據(jù)庫表、Excel 表、CSV 文件)是企業(yè)數(shù)字 ...
2025-09-18DSGE 模型中的 Et:理性預(yù)期算子的內(nèi)涵、作用與應(yīng)用解析 動態(tài)隨機(jī)一般均衡(Dynamic Stochastic General Equilibrium, DSGE)模 ...
2025-09-17Python 提取 TIF 中地名的完整指南 一、先明確:TIF 中的地名有哪兩種存在形式? 在開始提取前,需先判斷 TIF 文件的類型 —— ...
2025-09-17CDA 數(shù)據(jù)分析師:解鎖表結(jié)構(gòu)數(shù)據(jù)特征價(jià)值的專業(yè)核心 表結(jié)構(gòu)數(shù)據(jù)(以 “行 - 列” 規(guī)范存儲的結(jié)構(gòu)化數(shù)據(jù),如數(shù)據(jù)庫表、Excel 表、 ...
2025-09-17Excel 導(dǎo)入數(shù)據(jù)含缺失值?詳解 dropna 函數(shù)的功能與實(shí)戰(zhàn)應(yīng)用 在用 Python(如 pandas 庫)處理 Excel 數(shù)據(jù)時,“缺失值” 是高頻 ...
2025-09-16深入解析卡方檢驗(yàn)與 t 檢驗(yàn):差異、適用場景與實(shí)踐應(yīng)用 在數(shù)據(jù)分析與統(tǒng)計(jì)學(xué)領(lǐng)域,假設(shè)檢驗(yàn)是驗(yàn)證研究假設(shè)、判斷數(shù)據(jù)差異是否 “ ...
2025-09-16CDA 數(shù)據(jù)分析師:掌控表格結(jié)構(gòu)數(shù)據(jù)全功能周期的專業(yè)操盤手 表格結(jié)構(gòu)數(shù)據(jù)(以 “行 - 列” 存儲的結(jié)構(gòu)化數(shù)據(jù),如 Excel 表、數(shù)據(jù) ...
2025-09-16MySQL 執(zhí)行計(jì)劃中 rows 數(shù)量的準(zhǔn)確性解析:原理、影響因素與優(yōu)化 在 MySQL SQL 調(diào)優(yōu)中,EXPLAIN執(zhí)行計(jì)劃是核心工具,而其中的row ...
2025-09-15解析 Python 中 Response 對象的 text 與 content:區(qū)別、場景與實(shí)踐指南 在 Python 進(jìn)行 HTTP 網(wǎng)絡(luò)請求開發(fā)時(如使用requests ...
2025-09-15CDA 數(shù)據(jù)分析師:激活表格結(jié)構(gòu)數(shù)據(jù)價(jià)值的核心操盤手 表格結(jié)構(gòu)數(shù)據(jù)(如 Excel 表格、數(shù)據(jù)庫表)是企業(yè)最基礎(chǔ)、最核心的數(shù)據(jù)形態(tài) ...
2025-09-15Python HTTP 請求工具對比:urllib.request 與 requests 的核心差異與選擇指南 在 Python 處理 HTTP 請求(如接口調(diào)用、數(shù)據(jù)爬取 ...
2025-09-12解決 pd.read_csv 讀取長浮點(diǎn)數(shù)據(jù)的科學(xué)計(jì)數(shù)法問題 為幫助 Python 數(shù)據(jù)從業(yè)者解決pd.read_csv讀取長浮點(diǎn)數(shù)據(jù)時的科學(xué)計(jì)數(shù)法問題 ...
2025-09-12CDA 數(shù)據(jù)分析師:業(yè)務(wù)數(shù)據(jù)分析步驟的落地者與價(jià)值優(yōu)化者 業(yè)務(wù)數(shù)據(jù)分析是企業(yè)解決日常運(yùn)營問題、提升執(zhí)行效率的核心手段,其價(jià)值 ...
2025-09-12用 SQL 驗(yàn)證業(yè)務(wù)邏輯:從規(guī)則拆解到數(shù)據(jù)把關(guān)的實(shí)戰(zhàn)指南 在業(yè)務(wù)系統(tǒng)落地過程中,“業(yè)務(wù)邏輯” 是連接 “需求設(shè)計(jì)” 與 “用戶體驗(yàn) ...
2025-09-11塔吉特百貨孕婦營銷案例:數(shù)據(jù)驅(qū)動下的精準(zhǔn)零售革命與啟示 在零售行業(yè) “流量紅利見頂” 的當(dāng)下,精準(zhǔn)營銷成為企業(yè)突圍的核心方 ...
2025-09-11CDA 數(shù)據(jù)分析師與戰(zhàn)略 / 業(yè)務(wù)數(shù)據(jù)分析:概念辨析與協(xié)同價(jià)值 在數(shù)據(jù)驅(qū)動決策的體系中,“戰(zhàn)略數(shù)據(jù)分析”“業(yè)務(wù)數(shù)據(jù)分析” 是企業(yè) ...
2025-09-11Excel 數(shù)據(jù)聚類分析:從操作實(shí)踐到業(yè)務(wù)價(jià)值挖掘 在數(shù)據(jù)分析場景中,聚類分析作為 “無監(jiān)督分組” 的核心工具,能從雜亂數(shù)據(jù)中挖 ...
2025-09-10統(tǒng)計(jì)模型的核心目的:從數(shù)據(jù)解讀到?jīng)Q策支撐的價(jià)值導(dǎo)向 統(tǒng)計(jì)模型作為數(shù)據(jù)分析的核心工具,并非簡單的 “公式堆砌”,而是圍繞特定 ...
2025-09-10