農林漁牧網

您現在的位置是:首頁 > 林業

原理+程式碼|Python實現 kmeans 聚類分析

2022-04-08由 CDA資料分析師 發表于 林業

kmeans結果怎麼解釋

作者:蘿蔔

1。前言

聚類分析是研究分類問題的分析方法,是洞察使用者偏好和做使用者畫像的利器之一,也可作為其他資料分析任務的前置探索(如EDA)。上文的層次聚類演算法在資料探勘中其實並不常用,因為只是適用於小資料。所以我們引出了

K-Means

聚類法,這種方法計算量比較小。能夠理解

K-Means

的基本原理並將程式碼用於實際業務案例是本文的目標。下文將詳細介紹如何利用 Python 實現基於

K-Means

聚類的客戶分群,主要分為兩個部分:

詳細原理介紹

Python程式碼實戰

2。原理介紹

上一篇層次聚類的推文中提到「既然它們能被看成是一類的,所以要麼它們距離近,要麼它們或多或少有共同的特徵」。為了能夠更好地深入淺出,我們像上次那樣調整一下學習順序,將數學公式往後放,先從聚類過程與結果入手。注意,本文先以樣本之間的距離為聚類指標。

K-Means 聚類的目標就一句話「將 n 個觀測資料點按照一定標準劃分到 k 個聚類中」。至於這個標準怎麼定奪以及如何判斷聚類結果好壞等問題,文章後半段會提及。

K-Means

聚類的步驟用這一張圖就可以表達出來。(這裡的k為2,即分成兩類)

原理+程式碼|Python實現 kmeans 聚類分析

2.1關於kmeans的一些問題

問:在第二步的隨機指定每組的中心 這個步驟中,明擺著 ABC 為一類,DE 為一類 才是最正確的分類方式,畢竟肉眼就可以判斷距離了,為什麼指定每組的中心後反倒分類錯誤了呢?(第二步是將 AB 一類,CDE 一類)?

答:彆著急,

K-Means

演算法並不求一步就完全分類正確。第二步到第三步的過程被稱為“中心迭代“。一開始是隨機的指定每組的中心,這個中心可能是有偏頗的,所以第三步是用每個類的中心來代替第二步中隨即指定的中心。接下來再計算每個點到中心的距離,就會發現 C 這個點其實是離上面的中心更近(AB 一類,DE 一類本來就分類正確了,只是 C 出現了分類失誤)

問:圖中經過第四步後其實就已經劃分出了正確的分類,第五步還有什麼用呢?

答:第四步到第五步這個過程跟第二到第三步一樣,也叫 “ 中心迭代 ”,即將新分好的正確的類的中心作為群組的中心點。這樣才能為下一步的分類做準備,畢竟資料量並不只是圖中的五個點,這一套(五步)流程也不是隻執行一次就能完成分類,需要不斷重複,最終的結果便是不會再有點像 C 那樣更換分類的情況。

問:第一步要計算幾次距離?(k=2)

原理+程式碼|Python實現 kmeans 聚類分析

答:需要計算 10 次距離,隨即指定的兩個中心點到每一個已知點的距離:中心1,2 分別到點 ABCDE 的距離。其實也就是 n 個點,分成 k 類時,需要計算 n×k 次。

問:第一步用層次聚類法也是 10 次,為什麼還說 K-Means 是一個計算量較小的方法呢?

答:對第一步使用層次聚類法的計算次數為:

Cn2((C52 = (54)/2))

即計算兩兩點之間的距離,然後再比較篩選,即:

n(n-1) / 2 = 54 / 2 = 10

次,但這只是小的資料樣本,如果樣本量巨大呢(同樣還是k為2時)?那麼K-Means的n*k與層次聚類法的Cn2的複雜度圖比較便是:

資料量一旦開始增加,層級聚類法的計算複雜程度便呈指數級增長。

問:K-Means 的不足?

答:K-Means 最顯著的缺點便是 k 的個數不好確定,但在商業資料探勘上,這個缺點其實不一定難避免。因為商業資料探勘的 k-means 聚類方法中,k 大部分都在 2 ~ 12 這個範圍,所以只需要做 9 次,然後看哪種效果最好即可。

2.2K-Means 的要點

要點1:預先處理變數的缺失值、異常值要點2:變數標準化要點3:不同維度的變數,相關性儘量低要點4:如何決定合適的分群個數?·

主要推薦輪廓係數(Silhouette Coeficient),並結合以下注意事項:

分群結果的穩定性

重複多次分群,看結果是否穩定

分群結果是否有好解釋的商業意義

也有一種相對沒那麼嚴謹的分類方法,這種方法通常會分 5~8 類,這樣既能反映工作量(給領導看),又不至於太累(分出 12 類,還要對每一類的特徵進行探索,描述性統計分析等)

2.3輪廓係數

原理+程式碼|Python實現 kmeans 聚類分析

圖片來自網路(相對好理解的一張解釋圖)

最好的分類結果:不同組之間的差距越大越好,同組內的樣本差距越小越好。這樣才能更好的體現物以類聚的思想(e。g: 同一類人的三觀非常一致,不同類的人之間三觀相差甚遠)。因為組內差異為零的話,a(i) 便無限接近於0,公式分子便為 b(i),分母

max{0, b(i)} = b(i),所以結果為b(i) / b(i) = 1,即越趨近於 1 代表組內聚類性和組間的分離度越好。

原理+程式碼|Python實現 kmeans 聚類分析

輪廓係數其實非常難求,組內的(a(i))好算,b(i) 非常難計算,而且還要每個點都要同不同組裡面的所有點進行計算,所以輪廓係數在實操的時候樣本量的大小需要控制,一般幾千就行了,幾萬的話就太難計算了;換言之,輪廓係數一般也是在探索的時候用,比如分層抽樣後對 k 的取值進行探索。這也再次呼應了前兩段提到的 K-Means 方法的 k 難以直接透過數學公式求得的的這一特點。

2.4K-Means 聚類的兩種用法

發現異常情況

:如果不對資料進行任何形式的轉換,只是經過中心標準化或級差標準化就進行快速聚類,會根據資料分佈特徵得到聚類結果。這種聚類會將極端資料聚為幾類。這種方法適用於統計分析之前的異常值剔除,對異常行為的挖掘,比如:監控銀行賬戶是否有洗錢行為、監控POS機是有從事套現、監控某個終端是否是電話卡養卡客戶等等。

將個案資料做劃分

:出於客戶細分目的的聚類分析一般希望聚類結果為大致平均的幾大類,因此需要將資料進行轉換比如使用原始變數的百分位秩、Turkey正態評分、對數轉換等等。在這類分析中資料的具體數值並沒有太多的意義,重要的是相對位置。這種方法適用場景包括客戶消費行為聚類、客戶積分使用行為聚類等等。

如果變數比較多比如 10 個左右,變數間的相關性又比較高,就應該做個因子分析或者稀疏主成分分析,因為 K-Means 要求不同維度的變數相關性儘量低。(本系列的推文:原理+程式碼|Python基於主成分分析的客戶信貸評級實戰)

那如果資料右偏嚴重,K-Means 聚類會出現什麼情況?

原理+程式碼|Python實現 kmeans 聚類分析

如果不經過任何處理,則聚類出來的結果便是如上圖那樣,出現”絕大部分客戶屬於一類,很少量客戶屬於另外一類“的情況,這就失去了客戶細分的意義(除非你是為了檢測異常值),因為有時候我們希望客戶能夠被均勻的分成幾類(許多領導和甲方的需求為均勻的聚類,這是出於管理的需求)

原理+程式碼|Python實現 kmeans 聚類分析

原始資料本來就是右偏的,幾種標準化方式之後其實也還是右偏的。。。,我們在學校學習統計學或聚類方法的時候,所用資料大多是來自自然科學的,所以分佈情況都比較“完美”,很少出現較強的偏態分佈。而現實生活與工作中的資料,如金融企業等,拿到的資料大多右偏嚴重。

原理+程式碼|Python實現 kmeans 聚類分析

上圖是能夠強迫將右偏資料轉換成均勻分佈的幾種方法。但通常回歸演算法時的右偏處理才會使用變數取自然對數的方法,聚類演算法常用Tukey正態分佈打分的方式來處理右偏資料。

2.5變數轉換小結

非對稱變數在聚類分析中選用百分位秩和Tukey正態分佈打分比較多;在迴歸分析中取對數比較多。因為商業上的聚類模型關心的客戶的排序情況,迴歸模型關心的是其具有經濟學意義,對數表達的是百分比的變化。

2.6使用決策樹做聚類後的客戶分析

聚類演算法還能與決策樹演算法一起用(期待臉(☆▽☆))?

原理+程式碼|Python實現 kmeans 聚類分析

輪廓係數可以為我們做K-Means聚類的時候提供一個k的參考值,而初步聚類後,我們便有了Y,即每個資料樣本所對應的類別。這時候我們畫棵決策樹(可以結合使用高階一些的決策樹視覺化方式),如果底端的葉子所呈現出的資料分類是某一類較多,其餘類偏少,這樣便表示這個k值是一個比較好的選擇。(每一類都相對較純,沒有雜質)

3。程式碼實戰

本次程式碼實戰我們將使用已經經過前文主成分分析處理過的有關銀行客戶的資料集:

CSC:counter service for customer —— 選擇櫃檯服務的客戶

ATM_POS: 使用 ATM 和 POS 服務的客戶

TBM:選擇有償服務的客戶

import pandas as pd

# df 為清洗好的資料

df = pd。read_csv(‘data_clean。csv’)

df。head()

這裡每個變數所在列的具體數值可先不做探究

這裡每個變數所在列的具體數值可先不做探究

原理+程式碼|Python實現 kmeans 聚類分析

3.1K-Means 聚類的第一種方式

不進行變數分佈的正太轉換——用於尋找異常值

# 使用k-means聚類

## 1。1 k-means聚類的第一種方式:不進行變數分佈的正態轉換——用於尋找異常值

# 1、檢視變數的偏度

var = [“ATM_POS”,“TBM”,“CSC”] # var: variable-變數

skew_var = {}

for i in var:

skew_var[i]=abs(df[i]。skew()) # 。skew() 求該變數的偏度

skew=pd。Series(skew_var)。sort_values(ascending=False)

skew

可以看出TBM這個變數的偏度已經超標,很可能會影響到後續的分類

原理+程式碼|Python實現 kmeans 聚類分析

進行k-means聚類

from sklearn。cluster import KMeans

kmeans = KMeans(n_clusters=3) # n_clusters=3 表示聚成3類

result = kmeans。fit(df)

result

與隨機森林,決策樹等演算法一樣,KMeans函式中的引數眾多,這裡不具體解釋了,可查閱官方文件

原理+程式碼|Python實現 kmeans 聚類分析

。join()

表示橫向拼接

# 對分類結果進行解讀

model_data_l = df。join(pd。DataFrame(result。labels_))

# 。labels_ 表示這一個資料點屬於什麼類

model_data_l = model_data_l。rename(columns={0: “clustor”})

model_data_l。sample(10)

原理+程式碼|Python實現 kmeans 聚類分析

繪製餅圖呈現每一類的比例

# 餅圖呈現

import matplotlib

get_ipython()。magic(‘matplotlib inline’)

model_data_l。clustor。value_counts()。plot(kind = ‘pie’)

# 自然就能發現出現分類很不平均的現象

原理+程式碼|Python實現 kmeans 聚類分析

3.2k-means聚類的第二種方式

進行變數分佈的正態轉換——用於客戶細分

# 進行變數分佈的正態轉換

import numpy as np

from sklearn import preprocessing

quantile_transformer = \

preprocessing。QuantileTransformer(output_distribution=‘normal’,

random_state=0) # 正態轉換

df_trans = quantile_transformer。fit_transform(df)

df_trans = pd。DataFrame(df_trans)

# 因為 。fit_transform 轉換出來的資料型別為 Series,

## 所以用 pandas 給 DataFrame 化一下

df_trans = df_trans。rename(columns={0: “ATM_POS”, 1: “TBM”, 2: “CSC”})

df_trans。head()

轉換的方式有很多種,每種都會涉及一些咋看起來比較晦澀的統計學公式,但請不要擔心,每種程式碼其實都是比較固定的,這裡使用QT轉換(每種轉換的原理和特點優劣等可參考網路資源)

原理+程式碼|Python實現 kmeans 聚類分析

檢驗一下偏度:發現幾乎都為 0 了

var = [“ATM_POS”,“TBM”,“CSC”]

skew_var = {}

迴圈計算偏度:發現都差不多等於 0 了。

for i in var:

skew_var[i] = abs(df_trans[i]。skew())

skew = pd。Series(skew_var)。sort_values(ascending=False)

skew # 字典顯示更方便

原理+程式碼|Python實現 kmeans 聚類分析

重複的聚類步驟,程式碼可直接貼上

kmeans = KMeans(n_clusters=4) # 這次聚成 4 類

result = kmeans。fit(df_trans)

model_data_l = df_trans。join(pd。DataFrame(result。labels_))

model_data_l = model_data_l。rename(columns={0: “clustor”})

model_data_l。head()

原理+程式碼|Python實現 kmeans 聚類分析

再次使用餅圖呈現結果,發現每類的比例開始平均了。

原理+程式碼|Python實現 kmeans 聚類分析

3.3結果分析

最後對結果進行分析如下表

原理+程式碼|Python實現 kmeans 聚類分析

4。小結

對於不同場景,我們的使用聚類的方法也有所不同:

一般場景下的聚類:

「變數歸一化 --> 分佈轉換 --> 主成分 --> 聚類」

發現異常境況的聚類:

「變數歸一化 --> 主成分 --> 聚類」

其實聚類模型對分析人員的業務修養要求較高,因為聚類結果好壞不是簡單的看統計指標就可得出明確的答案。統計指標是在所有的變數都符合某個假設條件才能表現良好的,而實際建模中很少能達到那種狀態;聚類的結果要做詳細的描述性統計,甚至作抽樣的客戶訪談,以瞭解客戶的真實情況,所以讓業務人員滿足客戶管理的目標,是聚類的終極目標。