python原理及代码_原理+代码|详解层次聚类及Python实现
前言
聚類分析是研究分類問題的分析方法,是洞察用戶偏好和做用戶畫像的利器之一。聚類分析的方法非常多,能夠理解經典又最基礎的聚類方法 ——?層次聚類法(系統聚類)?的基本原理并將代碼用于實際的業務案例是本文的目標,同時這也會為理解后續與聚類相關的推文如 K-Means 等打下基礎是。
本文將詳細介紹如何?利用 Python 實現基于層次聚類的客戶分群,主要分為兩個部分:層次聚類詳細原理介紹
Python 代碼實戰講解
原理部分
原理介紹
既然它們能被看成是一類的,所以要么它們距離近,要么它們或多或少有共同的特征。拿到數據集后,直接根據特征或指標來將樣本分類的做法其實更適合業務能力比較強的人或有了十分明確的指標如男女各一類等硬性要求,所以本文以樣本之間的距離為聚類指標。為了能夠更好地深入淺出,我們調整了一下學習順序,將小部分數學公式往后放,先從聚類結果的顯示與分析入手。
下面是有關層次聚類的幾個常見問題。
1、為什么都說層次樹是層次聚類法獨有的聚類結果圖?
因為樹形圖的橫坐標會將每一個樣本都標出來,并展示聚類的過程。幾十個樣本時候層次樹就已經 “無法” 查看了,更何況成百上千的數據樣本。
2、層次樹是怎么建立的?建立的基本步驟?
其實層次樹的建立過程表示的就是聚類的過程,只不過通過層次樹我們可以看出類之間的層次關系(這一類與那一類相差多遠),同時還可以通過層次樹決定最佳的聚類個數和看出聚類方式(聚類順序的先后)
基本步驟比較簡潔,只要短短的 3 步:計算每兩個觀測之間的距離
將最近的兩個觀測聚為一類,將其看作一個整體計算與其它觀測(類)之間的距離
一直重復上述過程,直至所有的觀測被聚為一類
建立層次樹的三個步驟雖然簡潔,但其實也有令人迷惑的地方,所以為了讓各位更好的從整體上去理解聚類過程而不是圄于細節,這里先直接放一個聚類過程圖和對應的層次樹
3、怎么從層次樹中看出聚類過程?
這一個簡短的問題中其實暗含不少門道,第一:**當兩個點被分為一類時,是從橫坐標出發向上延伸,后形成一條橫杠;當兩個類被分為一類時,是橫杠中點向上延伸。**這第一點中,橫杠的數量就表示當所有的點都被圈為一類的時候經過了多少次聚類。
同樣,橫杠距離橫坐標軸的高度也有玄機,畢竟每生成一個橫杠就表示又有一次聚類了,所以我們可以通過橫杠的高度判斷聚類的順序,結合上圖右半部分的圓圈和數字標號也可以看出。
所以聚類順序便如下表:
聚類次數被聚為一類的點第1次1和3 ? ? → ? ?1,3
第2次2和5 ? ? → ? ? 2,5
第3次2,5 和 4 ? → ? 2,5,4
第4次2,5,4 和 1,3 ? → ? 1,3,2,5,4
第5次1,3,2,5,4 和 6 ? → ? 1,3,2,5,4,6(所有點被聚為一類)
第二,整棵層次樹是由一棵棵小樹組成,每棵小樹代表了一個類,小樹的高度即是兩個點或兩個類之間的距離,所以兩個點之間的距離越近,這棵樹就越矮小。
下面這一段仔細閱讀的話對理解點與點,類與類,點與類之間的距離是如何在層次樹上體現很有幫助。先從最矮的高度只有?d1?小樹說起,這就是類 1,3 中兩個孤立的點 1 和 3 之間的距離;同理,d2 為類2,5 中點 2 和 5 之間的距離。
而至于 d3, d4, d5 這三個距離,他們并不像 d1 和 d2 那般表示的是一棵完整的樹的高度,而更像是 “?生長的枝干?”,因為從第一點中的 “ 當兩個類被分為一類時,是橫杠中點向上延伸。” 可以看出 d3 是從類 2,5 橫杠的中點往上延伸的,所以它表示會與另外的類聚成一起并形成一棵更大的樹,圖中即類 2,5 和點 4 被聚成一個新的類 2,5,4。
同理:d4 表示類 2,5,4 與類 1,3 聚成新類 1,3,2,5,4
d5 表示類 1,3,2,5,4 與點 6 聚成類 1,3,2,5,4,6
4、怎么從層次樹中看出聚類情況?可以通過決定縱軸分界線可決定這些數據到底是分成多少類
定好分界線后,只需要看距離這條線橫杠和單獨的豎線即可,上圖中距離紅線的橫杠有兩條(分別表示類1,2 和類2,5),單獨的豎線也有兩條,從橫坐標軸 4 和 6 上各延伸出的一條。同理可用到下圖
為什么最好不要分成 3 組:13,254,6 呢?
因為樹的高度表示兩個點之間的距離,所以 4 到 類25 的距離只比到 類13 的距離要多如下圖所示的一點點,所以硬是把 4 跟 25 分成一類就有點牽強了,正因為這種牽強的分類方式可能會讓我們忽略 4 這個點單獨的價值,所以我們不如直接將 4 看成單獨的一類。
推導與計算
接下來就是需要更加動腦的數學原理和公式部分了,我們需要知曉點與點,類與類,點與類這三種距離如何計算。
最包羅萬象的是明考斯基距離,因為 q 分別取 1 和 2 的時候就表示是絕對值距離和歐氏距離。點與點的距離很好求,我們一般用的都是歐氏距離,即初中學習的直角三角形三邊關系,上圖右上角點AC之間的距離(ab2 + bc2) 后再開根號
而至于類與類之間的距離求法,其實經過了一個演變,篇幅原因本文只會一筆帶過那些不常用的方法并將重心放在最常用和主流的方法上。
平均聯接和重心法都已經比較少用了,現大多采用較少受異常值影響且不知數據分布的情況下依然能有較好表現的 Ward 法。
其實 Ward 法的公式與方差分析相似,都是通過組間距離來定奪點點/點類/類類間的距離,Ward 法許多詳細的數學推導在網上有很多,這里我們直接展示最容易理解的一種:
上圖為已知的五個點和它們 x,y 軸坐標,SS 為 Ward 最小方差法的公式。
當兩個點被聚為一類時,這一類的組間差異 SS 便為其中一點的某一坐標與另外的所有坐標加加減減的一系列操作(通俗解釋,其實直接看上圖的 SS 計算過程已經可以理解。)
了解?Ward 最小方差法的基本求解公式后,我們可以從最簡單的聚類形式開始:5個點聚成4類。這意味著其中兩個點會被聚在一起,剩下三個點各自為一類,所以總共會出現 C52 = 10 中情況,每種情況的組內 SS 分別如下表:
同理,如果這 5 個點聚成 3/2/1 類的情況如下表:
需要注意的是:聚成兩類后計算出 AB 這兩個的利方差最小后,在后續聚成3類,2類的時候就直接把A和B兩個看成是同一個個體了,所以不會再出現A和B分開的局面。
結合兩個表,我們便可以得出如下結論:如果需要被聚成 4 類,AB為一類,剩下3個點各為一類最好(SS 最小)
如果需要被聚成 3 類,AB,DE為一類,剩下的 C 單獨為一類最好
如果需要被聚成 2 類,AB,CDE各位一類
如果需要被聚成 1 類,對不起,我覺得沒什么分析的必要
在進入代碼實戰前,我們簡單總結一下原理部分提到的知識點:層次樹的閱讀
兩個點之間的距離公式
Ward 法求類內的組間差異,用以決定聚出的類別個數
代碼實戰
在正式實戰前,需要注意以下幾點,首先原始數據通常需要經過處理才能用于分析:缺失值
異常值(極大或極小)
分類變量需要轉化為啞變量(0/1數值)
分類變量類別不宜過多
其次由于變量的量綱的不一樣引起計算距離的偏差,我們需要對數據進行標準化。同時不同的統計方法對數據有不同的要求:決策樹和隨機森林允許缺失值和異常值
聚類分析和回歸模型則不支持缺失值
在處理數據時,也有兩個問題值得關注,
1、聚類的時候,所有的 X 必須都是連續變量,為什么?
分類變量無法計算距離,如某個變量表示的是性別,男和女;教育程度為小學,初中,高中,大學,那該變量在各個個體之間的距離怎么計算?所以做聚類分析時盡可能用分類變量。
2、那這些分類變量的價值難道就無法利用了嗎?
可以先根據其他的連續變量聚類,而后對分出來的類做描述性統計分析,這時候就可以用上分類變量的價值了。另外一種方法是可以在第一步就把分類變量也用上的聚類方法,不過需要結合實際業務。
以市場客戶調研為例,屬于 “ 客戶的需求與態度 ” 這個分支,目的是依據調查問卷結果針對需求的數據分群,而調查分卷的問題中回答 “yes” 或者 “no” 類型的問題通常又會占一大部分,這時候我么可以通過合并多個問題回答的結果來將多個分類變量組合,生成一個連續變量,以電信客戶的使用和需求情況為例:
當然也還可以計算分類變量之間的?cos 相似度,即直接把分類變量設成距離。總之,分類變量在聚類當中是一定需要處理的。
現在終于到了正式的代碼階段,如果前面的原理都理解好了,代碼的理解則可不費吹灰之力。這里我們使用一份公開的城市經濟數據集,參數如下:AREA:城市名稱
Gross:總體經濟情況指數
Avg:平均經濟情況指數import?pandas?as?pd
import?numpy?as?np
import?matplotlib.pyplot?as?plt
plt.rc('font',?**{'family':?'Microsoft?YaHei,?SimHei'})??#?設置中文字體的支持
plt.rcParams['axes.unicode_minus']?=?False
#?解決保存圖像是負號'-'顯示為方塊的問題
df?=?pd.read_csv('城市經濟.csv')
df
這些城市的指標分布如下波士頓矩陣圖,篇幅原因繪圖代碼省略,后臺回復關鍵字獲取的源程序會一并提供。
sklearn 里面沒有層次聚類的函數,所以從 scipy 中導入import?scipy.cluster.hierarchy?as?sch
#?生成點與點之間的距離矩陣,?這里用的歐氏距離:?euclidean
## X:根據什么來聚類,這里結合總體情況 Gross 與平均情況 Avg 兩者
disMat?=?sch.distance.pdist(X=df[['Gross',?'Avg']],?metric='euclidean')
#?進行層次聚類:?計算距離的方法使用?ward?法
Z?=?sch.linkage(disMat,method='ward')
下面是層次聚類可視化:層次樹#?將層級聚類結果以樹狀圖表示出來并保存
#?需要手動添加標簽。
P?=?sch.dendrogram(Z,?labels=df.AREA.tolist())
plt.savefig('聚類結果.png')
最后說一下,未來還會有?K-Means?等聚類方法的推文。作為深入淺出聚類方法的開端,我們只需知道層次聚類相比 K-Means 的好處是它不用事先指定我們需要聚成幾類 (K-Means 算法代碼中的參數 k 指定)
這樣一來,我們只需要把計算全權交給程序,最終能得出一個比較精準的結果。但缺點是隨之而來的計算復雜度的增加。
所以層次聚類更適合小樣本;K-Means 更適合大樣本,在數據挖掘中也更常見,本文分享就到這里,我們下期決策樹見~
總結
以上是生活随笔為你收集整理的python原理及代码_原理+代码|详解层次聚类及Python实现的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 【视频】全天护眼,细节满满,荣耀100系
- 下一篇: 英语正能量语录收集