99999久久久久久亚洲,欧美人与禽猛交狂配,高清日韩av在线影院,一个人在线高清免费观看,啦啦啦在线视频免费观看www

熱線電話:13121318867

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

CDA數(shù)據(jù)分析師 出品

作者:CDALevel Ⅰ持證人

崗位:數(shù)據(jù)分析師

行業(yè):大數(shù)據(jù)

背景

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

如今新基建大數(shù)據(jù)、人工智能行業(yè)在迅速的發(fā)展,而機器學(xué)習(xí)是其中不可或缺的一環(huán),機器學(xué)習(xí)強調(diào)的是利用人腦一般從歷史的數(shù)據(jù)中學(xué)習(xí)到經(jīng)驗并運用與未來的判斷中。而K-Means模型則是機器學(xué)習(xí)聚類算法中的一塊,本文結(jié)合Python實現(xiàn)K-Means聚類算法的編寫,同時應(yīng)用于客戶分群中。

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

本章分為三部分講解:

  1. K-Means聚類原理與算法步驟
  2. Python實現(xiàn)K-Means聚類算法
  3. 基于K-Means的RFM客戶分群構(gòu)建
  4. 對比與總結(jié)

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

  • 原理

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

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

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

Python實現(xiàn)基于<a href='/map/jiqixuexi/' style='color:#000;font-size:inherit;'>機器學(xué)習(xí)</a>的<a href='/map/rfmmoxing/' style='color:#000;font-size:inherit;'>RFM模型</a>

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

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

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

輸入:樣本集D,設(shè)定類別數(shù)目K

輸出:類劃分(K個類)

流程圖展現(xiàn)算法步驟,

Python實現(xiàn)基于<a href='/map/jiqixuexi/' style='color:#000;font-size:inherit;'>機器學(xué)習(xí)</a>的<a href='/map/rfmmoxing/' style='color:#000;font-size:inherit;'>RFM模型</a>

二、Python實現(xiàn)K-Means聚類算法

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

Python實現(xiàn)基于<a href='/map/jiqixuexi/' style='color:#000;font-size:inherit;'>機器學(xué)習(xí)</a>的<a href='/map/rfmmoxing/' style='color:#000;font-size:inherit;'>RFM模型</a>

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

上述樣本點的構(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)這三個點(類中心點)構(gòu)造樣本集。運用make_blobs()函數(shù)即可構(gòu)建樣本集,該函數(shù)中可以設(shè)定樣本集的數(shù)量n_samples方差cluster_std。最后以散點圖形式展現(xiàn)。

最后調(diào)用KMeans接口,將該樣本集進行聚類,用可視化的方式對聚類后結(jié)果進行展現(xiàn),結(jié)果如下圖

Python實現(xiàn)基于<a href='/map/jiqixuexi/' style='color:#000;font-size:inherit;'>機器學(xué)習(xí)</a>的<a href='/map/rfmmoxing/' style='color:#000;font-size:inherit;'>RFM模型</a>

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

Python實現(xiàn)基于<a href='/map/jiqixuexi/' style='color:#000;font-size:inherit;'>機器學(xué)習(xí)</a>的<a href='/map/rfmmoxing/' style='color:#000;font-size:inherit;'>RFM模型</a>

從上表可以看出,聚類中心點是存在微小差異的,這也說明KMeans接口時利用損失函數(shù)進行迭代的。相關(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)這段代碼即將估計器擬合上述的樣本集。其中,init參數(shù)即為上述所講KMeans++的初始化選擇方式。而后的參數(shù)為設(shè)定分成多少類。

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

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

三、基于K-Means的RFM客戶分群構(gòu)建

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

K-Means模型構(gòu)建(代碼)

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

# RMF實戰(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


## 機器幫助判斷(等深分箱)
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,'客戶類別'] = '重要價值用戶' 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)計')
plt.show()


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

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

Python實現(xiàn)基于<a href='/map/jiqixuexi/' style='color:#000;font-size:inherit;'>機器學(xué)習(xí)</a>的<a href='/map/rfmmoxing/' style='color:#000;font-size:inherit;'>RFM模型</a>

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

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

Python實現(xiàn)基于<a href='/map/jiqixuexi/' style='color:#000;font-size:inherit;'>機器學(xué)習(xí)</a>的<a href='/map/rfmmoxing/' style='color:#000;font-size:inherit;'>RFM模型</a>

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

Python實現(xiàn)基于<a href='/map/jiqixuexi/' style='color:#000;font-size:inherit;'>機器學(xué)習(xí)</a>的<a href='/map/rfmmoxing/' style='color:#000;font-size:inherit;'>RFM模型</a>

具體數(shù)值如下表:

Python實現(xiàn)基于<a href='/map/jiqixuexi/' style='color:#000;font-size:inherit;'>機器學(xué)習(xí)</a>的<a href='/map/rfmmoxing/' style='color:#000;font-size:inherit;'>RFM模型</a>

四、對比與總結(jié)

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

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

數(shù)據(jù)分析咨詢請掃描二維碼

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

數(shù)據(jù)分析師資訊
更多

OK
客服在線
立即咨詢
客服在線
立即咨詢
') } function initGt() { var handler = function (captchaObj) { captchaObj.appendTo('#captcha'); captchaObj.onReady(function () { $("#wait").hide(); }).onSuccess(function(){ $('.getcheckcode').removeClass('dis'); $('.getcheckcode').trigger('click'); }); window.captchaObj = captchaObj; }; $('#captcha').show(); $.ajax({ url: "/login/gtstart?t=" + (new Date()).getTime(), // 加隨機數(shù)防止緩存 type: "get", dataType: "json", success: function (data) { $('#text').hide(); $('#wait').show(); // 調(diào)用 initGeetest 進行初始化 // 參數(shù)1:配置參數(shù) // 參數(shù)2:回調(diào),回調(diào)的第一個參數(shù)驗證碼對象,之后可以使用它調(diào)用相應(yīng)的接口 initGeetest({ // 以下 4 個配置參數(shù)為必須,不能缺少 gt: data.gt, challenge: data.challenge, offline: !data.success, // 表示用戶后臺檢測極驗服務(wù)器是否宕機 new_captcha: data.new_captcha, // 用于宕機時表示是新驗證碼的宕機 product: "float", // 產(chǎn)品形式,包括:float,popup width: "280px", https: true // 更多配置參數(shù)說明請參見:http://docs.geetest.com/install/client/web-front/ }, handler); } }); } function codeCutdown() { if(_wait == 0){ //倒計時完成 $(".getcheckcode").removeClass('dis').html("重新獲取"); }else{ $(".getcheckcode").addClass('dis').html("重新獲取("+_wait+"s)"); _wait--; setTimeout(function () { codeCutdown(); },1000); } } function inputValidate(ele,telInput) { var oInput = ele; var inputVal = oInput.val(); var oType = ele.attr('data-type'); var oEtag = $('#etag').val(); var oErr = oInput.closest('.form_box').next('.err_txt'); var empTxt = '請輸入'+oInput.attr('placeholder')+'!'; var errTxt = '請輸入正確的'+oInput.attr('placeholder')+'!'; var pattern; if(inputVal==""){ if(!telInput){ errFun(oErr,empTxt); } return false; }else { switch (oType){ case 'login_mobile': pattern = /^1[3456789]\d{9}$/; if(inputVal.length==11) { $.ajax({ url: '/login/checkmobile', type: "post", dataType: "json", data: { mobile: inputVal, etag: oEtag, page_ur: window.location.href, page_referer: document.referrer }, success: function (data) { } }); } break; case 'login_yzm': pattern = /^\d{6}$/; break; } if(oType=='login_mobile'){ } if(!!validateFun(pattern,inputVal)){ errFun(oErr,'') if(telInput){ $('.getcheckcode').removeClass('dis'); } }else { if(!telInput) { errFun(oErr, errTxt); }else { $('.getcheckcode').addClass('dis'); } return false; } } return true; } function errFun(obj,msg) { obj.html(msg); if(msg==''){ $('.login_submit').removeClass('dis'); }else { $('.login_submit').addClass('dis'); } } function validateFun(pat,val) { return pat.test(val); }