熱線電話:13121318867

登錄
首頁精彩閱讀Python實現基于機器學習的RFM模型
Python實現基于機器學習的RFM模型
2022-01-27
收藏
Python實現基于<a href='/map/jiqixuexi/' style='color:#000;font-size:inherit;'>機器學習</a>的<a href='/map/rfmmoxing/' style='color:#000;font-size:inherit;'>RFM模型</a>

CDA數據分析師 出品

作者:CDALevel Ⅰ持證人

崗位:數據分析師

行業:大數據

背景

在前文(Python實現基于客觀事實的RFM模型)中闡述了如何運用分箱的技巧講客服進行分群,有興趣的讀者可以去回顧 一下。利用流行的編程語言---Python及分箱技巧進行RFM模型構建,結果發現,此方法有效了降低人工分群帶來的主觀性影響,然而,會出現類似偏態的現象。其原因是在于分箱的操作對R值、F值、M值都進行了一遍。因此,為解決這種類似偏態的問題,本文將利用機器學習中的K-Means聚類對客戶進行分群。

如今新基建大數據、人工智能行業在迅速的發展,而機器學習是其中不可或缺的一環,機器學習強調的是利用人腦一般從歷史的數據中學習到經驗并運用與未來的判斷中。而K-Means模型則是機器學習聚類算法中的一塊,本文結合Python實現K-Means聚類算法的編寫,同時應用于客戶分群中。

本文采用Anaconda進行Python編譯,主要涉及的Python模塊:

本章分為三部分講解:

  1. K-Means聚類原理與算法步驟
  2. Python實現K-Means聚類算法
  3. 基于K-Means的RFM客戶分群構建
  4. 對比與總結

一、K-Means聚類原理與算法步驟

  • 原理

"人以類聚,物以群分",這句話就是K-Means模型的思想點。其中,K代表類別數量(Tips:在機器學習中,自變量又叫預測變量,因變量又叫目標變量)。而Means代表每個類別中樣本的均值,因此這個Means也即均值的意思(Tips:這里的樣本通俗理解就是一個記錄行)。

K-Means聚類是以距離作為樣本間相似度的度量標準,將距離相近的樣本分配至同一個類別。樣本間的度量方式可以是歐氏距離,馬氏距離,余弦相似度等,K-Means聚類通常采用歐氏距離來度量各樣本間的距離。

歐式距離又稱歐幾里得度量,為常見的兩點之間或多點之間的距離表示法,如類別$x=(x{1},x{1},...,x{n})$與類別$y=(y{1},y{2},...,y{n})$間的距離如下式:

Python實現基于<a href='/map/jiqixuexi/' style='color:#000;font-size:inherit;'>機器學習</a>的<a href='/map/rfmmoxing/' style='color:#000;font-size:inherit;'>RFM模型</a>

馬氏距離同樣也是一種距離的度量,是由馬哈拉諾比斯(P. C. Mahalanobis)提出的,表示樣本間的協方差距離。它是一種有效的計算兩個未知樣本集的相似度的方法。這可以看作是歐式距離的修正,修正了歐式距離中各個維度尺度不一致且相關的問題。

對于一個均值為$mu=(mu{1},mu{2},...,mu_{p})^{T}$,協方差矩陣的S的多變量$x=(x^{1},x^{2},...,x^{p})^{T}$,其馬氏距離為下式

Python實現基于<a href='/map/jiqixuexi/' style='color:#000;font-size:inherit;'>機器學習</a>的<a href='/map/rfmmoxing/' style='color:#000;font-size:inherit;'>RFM模型</a>
  • 算法步驟

輸入:樣本集D,設定類別數目K

輸出:類劃分(K個類)

流程圖展現算法步驟,

Python實現基于<a href='/map/jiqixuexi/' style='color:#000;font-size:inherit;'>機器學習</a>的<a href='/map/rfmmoxing/' style='color:#000;font-size:inherit;'>RFM模型</a>

二、Python實現K-Means聚類算法

在上述原理和算法步驟可能有讀者不是很清楚,那么接下來將以例子的形式更加具體的展現K-Means是如何進行聚類的。首先利用scikit-learn庫中的datasets接口生成隨機樣本點作為我們的聚類輸入值,以可視化形式展現,如下圖:

Python實現基于<a href='/map/jiqixuexi/' style='color:#000;font-size:inherit;'>機器學習</a>的<a href='/map/rfmmoxing/' style='color:#000;font-size:inherit;'>RFM模型</a>

從上圖可以看出輸入的樣本點肉眼可見可以分成3類,那么怎么用K-Means將此樣本集識別出3類呢。這里用到scikit-learn庫中的KMeans接口,該接口的訓練算法與上述算法是大同小異的。其中稍有差別的是,初始的類中心點的選擇并不是隨機的,而是選擇k-means++的初始化方案,將類中心化為彼此原理的點。具體而言將在代碼體現。其次不同的是,結束條件,上述算法步驟的結束條件時判斷各類別中的樣本是否發生改變,而KMeans接口中的結束條件是類似于利用損失函數:$||Means{old}-Means{new}||$,該式子的意思是計算舊類中心點于新類中心點的距離,如果該距離小于給定的值$epsilon$,則結束,輸出類別。

上述樣本點的構建及可視化的代碼如下

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 # 生成例子數據 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()

代碼解讀:

首先設置可視化的主題為seaborn下的黑格子狀態,其次選擇圍繞(2,1),(6,5),(10,3)這三個點(類中心點)構造樣本集。運用make_blobs()函數即可構建樣本集,該函數中可以設定樣本集的數量n_samples方差cluster_std。最后以散點圖形式展現。

最后調用KMeans接口,將該樣本集進行聚類,用可視化的方式對聚類后結果進行展現,結果如下圖

Python實現基于<a href='/map/jiqixuexi/' style='color:#000;font-size:inherit;'>機器學習</a>的<a href='/map/rfmmoxing/' style='color:#000;font-size:inherit;'>RFM模型</a>

可以明確看到,聚類結果為3類,和我們預期的是一致的,接下來看類別中心點于原設計的中心點對比,如下表。

Python實現基于<a href='/map/jiqixuexi/' style='color:#000;font-size:inherit;'>機器學習</a>的<a href='/map/rfmmoxing/' style='color:#000;font-size:inherit;'>RFM模型</a>

從上表可以看出,聚類中心點是存在微小差異的,這也說明KMeans接口時利用損失函數進行迭代的。相關代碼如下

# 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) # 可視化結果 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聚類結果") #ax.set_xticks() #ax.set_yticks() plt.savefig('例子結果.jpg',dpi=200)

代碼解讀:

KMeans(init="k-means++", n_clusters=3)這段代碼即將估計器擬合上述的樣本集。其中,init參數即為上述所講KMeans++的初始化選擇方式。而后的參數為設定分成多少類。

擬合后的KMeans估計器是可以進行調用的,這里我們調用類中心點(k_means.cluster_centers_)和樣本所屬類別(k_means.labels_)。

最后一段代碼是結合類中心點和樣本所屬類別進行可視化展示,可以非常明確的看到聚類后的結果。(TIps:最后保存圖片的dpi是調整像素的,在Python編譯器里面默認保存的圖像像素普遍都不高,讀者可以適當的設置。)

三、基于K-Means的RFM客戶分群構建

  • 數據來源首先數據的來源依舊是在前文(Python實現基于客觀事實的RFM模型)所用到的已經處理好的數據,即有user_id、R、F、M4個字段的數據,數據展示如下,如有讀者不清楚該數據是如何處理,可以回顧前文。
Python實現基于<a href='/map/jiqixuexi/' style='color:#000;font-size:inherit;'>機器學習</a>的<a href='/map/rfmmoxing/' style='color:#000;font-size:inherit;'>RFM模型</a>

K-Means模型構建(代碼)

有了數據和scikit-learn庫中的KMmeans接口的了解,那么接下來先上完整代碼和解釋,模型構建的代碼如下

# RMF實戰 import pandas as pd import seaborn as sns
sns.set_style('darkgrid')
# 中文顯示問題解決
plt.rcParams['font.sans-serif'] = ["SimHei"]
plt.rcParams["axes.unicode_minus"] = False


## 數據讀取 data = pd.read_excel('rfm.xlsx')
X = data.drop(columns = 'user_id')


## KMeans模型構建
k_means = KMeans(init="k-means++", n_clusters=8,random_state=123)
k_means.fit(X)


## 類別查看 data['categories'] = k_means.labels_


## 相關屬性查看
k_means.cluster_centers_
k_means.verbose


## 機器幫助判斷(等深分箱)
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')




## 客戶分類打標簽 for i,j in data.iterrows(): if j['categories'] == 0 or j['categories'] == 2: data.loc[i,'客戶類別'] = '一般發展用戶' if j['categories'] == 1 or j['categories'] == 5: data.loc[i,'客戶類別'] = '重要價值用戶' 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('用戶類別統計')
plt.show()


  • 代碼解釋:首先,明確我們的模型構建目標。對于一份客戶行為價值數據而言,我們是不知道這其中到底包括幾種類別的客戶的,有可能包含了8類,也有可能包含3類等。而這個類別的確定就需要通過KMeans模型自動的去識別。因此,首先我們設定聚類的簇(類別數目)為RFM中的總類別數量8種,初始化的類中心點依舊使用KMeans++的方式。這段內容在上面注釋為KMeans模型構建部分。有了擬合后的模型后,我們就需要查看擬合后的相關屬性結果,k_means.cluster_centers_,k_means.labels_這兩個函數分別查看8個類中心點和對于每個id所屬的類別。接著,有了類中心點之后,我們就需要對類中心點進行等深分箱。最后賦予每個用戶相應的客戶類別并進行可視化直觀展示,下面將詳細對結果進行闡述。
  • K-Means模型結果計息利用在第二部分所學知識,即可對這份數據進行一個KMeans聚類,得到的結果如下表:
Python實現基于<a href='/map/jiqixuexi/' style='color:#000;font-size:inherit;'>機器學習</a>的<a href='/map/rfmmoxing/' style='color:#000;font-size:inherit;'>RFM模型</a>

從上圖可以看到,利用KMeans的估計器,我們已經得到了每個id所屬的類別,那么現在的問題是,該怎么判斷用戶是哪種客戶類別呢(Tips:用戶類別分為8種,不清楚的讀者可以回顧前文),這時候就需要用到類中心點,通過判斷類中心點來給每種分類一個判斷,下表為每個類別對應的類中心點。

Python實現基于<a href='/map/jiqixuexi/' style='color:#000;font-size:inherit;'>機器學習</a>的<a href='/map/rfmmoxing/' style='color:#000;font-size:inherit;'>RFM模型</a>

有了每個類別的類中心點,我們就需要對每個類賦予RFM模型中的客戶類別,本文在這方面選擇分箱的技巧進行分類。

對類中心點實現等深分箱,與前文運用等距分箱不同,這里采取的是指定每個類別種的個數是一致的,這也符合RFM模型中的每個值都有4個高,4個低。在Python中利用pd.qcut()函數進行分箱,其參數與等距分箱大同小異,有興趣的讀者可以研究。最后以"2"代表高,"1"代表低。并按照RFM的規則將每種類別賦予一個客戶類別,結果如下表:

Python實現基于<a href='/map/jiqixuexi/' style='color:#000;font-size:inherit;'>機器學習</a>的<a href='/map/rfmmoxing/' style='color:#000;font-size:inherit;'>RFM模型</a>

最后,以柱狀圖的形式展示該份數據集中的客戶類別總數

Python實現基于<a href='/map/jiqixuexi/' style='color:#000;font-size:inherit;'>機器學習</a>的<a href='/map/rfmmoxing/' style='color:#000;font-size:inherit;'>RFM模型</a>

具體數值如下表:

Python實現基于<a href='/map/jiqixuexi/' style='color:#000;font-size:inherit;'>機器學習</a>的<a href='/map/rfmmoxing/' style='color:#000;font-size:inherit;'>RFM模型</a>

四、對比與總結

與前文(Python實現基于客觀事實的RFM模型)對比,本文將該份數據集中的用戶分為4類(一般發展用戶、重要保持客戶、一般挽留客戶、重要價值用戶),而前文將用戶分為5類(一般發展用戶、一般挽留用戶、重要挽留客戶、一般保持用戶、重要發展用戶)??梢钥闯?,兩者都識別出了一般發展用戶的信息,且其所占比例也是最多的。不同之處在于,基于KMeans聚類模型的RFM模型可以挖掘出重要保持客戶、重要價值用戶的信息,而基于客觀事實的RFM模型對一般挽留用戶較為敏感。

因此,對于決策者而言,每個模型得到的RFM模型是不一致的,而決策者應該從模型結果的相同點入手,如該份數據,兩個模型都發現了一般發展用戶所占比例是最大的,代表其解釋性強。而對于模型間的不同點,則需要更深入的探討如何取舍的問題。

數據分析咨詢請掃描二維碼

若不方便掃碼,搜微信號:CDAshujufenxi

數據分析師資訊
更多

OK
客服在線
立即咨詢
日韩人妻系列无码专区视频,先锋高清无码,无码免费视欧非,国精产品一区一区三区无码
客服在線
立即咨詢