Python数模笔记-Sklearn(2)聚类分析
1、分類的分類
分類的分類?沒錯,分類也有不同的種類,而且在數(shù)學(xué)建模、機(jī)器學(xué)習(xí)領(lǐng)域常常被混淆。
首先我們談?wù)動斜O(jiān)督學(xué)習(xí)(Supervised learning)和無監(jiān)督學(xué)習(xí)(Unsupervised learning),是指有沒有老師,有沒有紀(jì)委嗎?差不多。有老師,就有正確解法,就有標(biāo)準(zhǔn)答案;有紀(jì)委,就會樹學(xué)習(xí)榜樣,還有反面教材。
有監(jiān)督學(xué)習(xí),是指樣本數(shù)據(jù)已經(jīng)給出了正確的分類,我們通過對正確分類的樣本數(shù)據(jù)進(jìn)行學(xué)習(xí),從中總結(jié)規(guī)律,獲取知識,付諸應(yīng)用。所以,監(jiān)督學(xué)習(xí)的樣本數(shù)據(jù),既提供了特征值又提供了目標(biāo)值,通過回歸(Regression)、分類(Classification)學(xué)習(xí)特征與目標(biāo)之間的關(guān)系。回歸是針對連續(xù)變量、連續(xù)數(shù)據(jù),分類是針對離散變量和布爾變量(0-1)。
無監(jiān)督學(xué)習(xí),是指樣本數(shù)據(jù)沒有提供確定的分類屬性,沒有老師,沒有標(biāo)準(zhǔn)答案,樣本數(shù)據(jù)中只有樣本的特征值而沒有目標(biāo)值,只能通過樣本數(shù)據(jù)自身的特征一邊摸索一邊自我學(xué)習(xí),通過聚類(Clustering)方法來尋找和認(rèn)識對象的相似性。
所以,我們說到分類時,其實有時是指分類(Classification),有時則是指聚類(Clustering)。
有監(jiān)督學(xué)習(xí)有老師,就有正確答案。雖然有時也會有模糊地帶,但總體說來還是有判定標(biāo)準(zhǔn)、有是非對錯的,只要與標(biāo)準(zhǔn)答案不一致就會被認(rèn)為判斷錯誤。
無監(jiān)督學(xué)習(xí)則不同,可以有不同的分類方法、不同的分類結(jié)果,通常只有相對的好壞而沒有絕對的對錯。甚至連分類結(jié)果的好壞也是相對的,要根據(jù)實際需要實際情況進(jìn)行綜合考慮,才能評價分類結(jié)果的好壞。誰能說人應(yīng)該分幾類,怎么分更合理呢?
歡迎關(guān)注 Youcans 原創(chuàng)系列,每周更新數(shù)模筆記
Python數(shù)模筆記-PuLP庫
Python數(shù)模筆記-StatsModels統(tǒng)計回歸
Python數(shù)模筆記-Sklearn
Python數(shù)模筆記-NetworkX
Python數(shù)模筆記-模擬退火算法
2、聚類分析
2.1 聚類的分類
聚類是從數(shù)據(jù)分析的角度,對大量的、多維的、無標(biāo)記的樣本數(shù)據(jù)集,按照樣本數(shù)據(jù)自身的相似性對數(shù)據(jù)集進(jìn)行分類。大量,是指樣本的數(shù)量大;多維,是指每個樣本都有很多特征值;無標(biāo)記,是指樣本數(shù)據(jù)對于每個樣本沒有指定的類別屬性。
需要說明的是,有時樣本數(shù)據(jù)帶有一個或多個分類屬性,但那并不是我們所要研究的類別屬性,才會被稱為無監(jiān)督學(xué)習(xí)。比如說,體能訓(xùn)練數(shù)據(jù)集中每個樣本都有很多特征數(shù)據(jù),包括性別、年齡,也包括體重、腰圍、心率和血壓。性別、年齡顯然都是樣本的屬性,我們也可以根據(jù)性別屬性把樣本集分為男性、女性兩類,這當(dāng)然是有監(jiān)督學(xué)習(xí);但是,如果我們是打算研究這些樣本的生理變化與鍛煉的關(guān)系,這是性別就不定是唯一的分類屬性,甚至不一定是相關(guān)的屬性了,從這個意義上說,樣本數(shù)據(jù)中并沒有給出我們所要進(jìn)行分類的類別屬性。
至于聚類的分類,是針對研究對象的不同來說的。把樣本集的行(rows)作為對象,考察樣本的相似度,將樣本集分成若干類,稱為 Q型聚類分析,屬于樣本分類。把樣本集的列(columns)作為對象,考察各個特征變量之間的關(guān)聯(lián)程度,按照變量的相關(guān)性聚合為若干類,稱為 R型聚類分析,屬于因子分析。
2.2 Q型聚類分析(樣本聚類)
Q 型聚類分析考察樣本的相似度,將樣本集分成若干類。我們需要綜合考慮樣本各種特征變量的數(shù)值或類型,找到一種分類方法將樣本集分為若干類,使每一類的樣本之間具有較大的相似性,又與其它類的樣本具有較大的差異性。通常是根據(jù)不同樣本之間的距離遠(yuǎn)近進(jìn)行劃分,距離近者分為一類,距離遠(yuǎn)者分成不同類,以達(dá)到“同類相似,異類相異”。
按照相似性分類,首先就要定義什么是相似。對于任意兩個樣本,很容易想到以樣本間的距離作為衡量相似性的指標(biāo)。在一維空間中兩點間的距離是絕對值:d(a,b)=abs[x(a)-x(b)];二維空間中兩點間的距離,我們最熟悉的是歐幾里德(Euclid)距離:d(a,b)=sqrt[(x1(a)-x1(b))**2+(x2(a)-x2(b))**2],歐式距離也可以拓展到多維空間。
除了歐式距離之外,還有其它度量樣本間距的方案,例如閔可夫斯基距離(Minkowski)、切比雪夫距離(Chebyshev)、馬氏距離(Mahalanobis)等。這些距離的定義、公式和使用條件,本文就不具體介紹了。世界是豐富多彩的,問題是多種多樣的,對于特殊問題有時就要針對其特點采用特殊的解決方案。
進(jìn)而,對于兩組樣本G1、G2,也需要度量類與類之間的相似性程度。常用的方法有最短距離法(Nearest Neighbor or Single Linkage Method)、最長距離法(Farthest Neighbor or Complete Linkage Method)、重心法(Centroid Method)、類均值法(Group Average Method)、離差平方和法(Sum of Squares Method)。
另外,處理實際問題時,在計算距離之前要對數(shù)據(jù)進(jìn)行標(biāo)準(zhǔn)化、歸一化,解決不同特征之間的統(tǒng)一量綱、均衡權(quán)重。
3、SKlearn 中的聚類方法
SKlearn 工具包提供了多種聚類分析算法:原型聚類方法(Prototype)、密度聚類方法(Density)、層次聚類方法(Hierarchical)、模型聚類(Model),等等,原型聚類方法又包括 k均值算法(K-Means)、學(xué)習(xí)向量量化算法(LVQ)、高斯混合算法(Gaussian Mixture)。詳見下表。
為什么會有這么多方法和算法呢?因為特殊問題需要針對其特點采用特殊的解決方案。看看下面這張圖,就能理解這句話了,也能理解各種算法都是針對哪種問題的。SKlearn 還提供了十多個聚類評價指標(biāo),本文就不再展開介紹了。
4、K-均值(K-Means)聚類算法
K-均值聚類算法,是最基礎(chǔ)的、應(yīng)用最廣泛的聚類算法,也是最快速的聚類算法之一。
4.1 原理和過程
K-均值聚類算法以最小化誤差函數(shù)為目標(biāo)將樣本數(shù)據(jù)集分為 K類。
K-均值聚類算法的計算過程如下:
- 設(shè)定 K 個類別的中心的初值;
- 計算每個樣本到 K個中心的距離,按最近距離進(jìn)行分類;
- 以每個類別中樣本的均值,更新該類別的中心;
- 重復(fù)迭代以上步驟,直到達(dá)到終止條件(迭代次數(shù)、最小平方誤差、簇中心點變化率)。
K-均值聚類算法的優(yōu)點是原理簡單、算法簡單,速度快,聚類效果極好,對大數(shù)據(jù)集具有很好的伸縮性。這些優(yōu)點特別有利于初學(xué)者、常見問題。其缺點是需要給定 K值,對一些特殊情況(如非凸簇、特殊值、簇的大小差別大)的性能不太好。怎么看這些缺點?需要給定 K值的問題是有解決方法的;至于特殊情況,已經(jīng)跟我們沒什么關(guān)系了。
4.2 SKlearn 中 K-均值算法的使用
sklearn.cluster.KMeans 類是 K-均值算法的具體實現(xiàn),官網(wǎng)介紹詳見:https://scikit-learn.org/stable/modules/generated/sklearn.cluster.KMeans.html#sklearn.cluster.KMeans
class sklearn.cluster.KMeans(n_clusters=8, *, init=‘k-means++’, n_init=10, max_iter=300, tol=0.0001, precompute_distances=‘deprecated’, verbose=0, random_state=None, copy_x=True, n_jobs=‘deprecated’, algorithm=‘a(chǎn)uto’)
KMeans 的主要參數(shù):
- n_clusters: int,default=8 K值,給定的分類數(shù)量,默認(rèn)值 8。
- init:{‘k-means++’, ‘random’} 初始中心的選擇方式,默認(rèn)’K-means++'是優(yōu)化值,也可以隨機(jī)選擇或自行指定。
- n_init:int, default=10 以不同的中心初值多次運行,以降低初值對算法的影響。默認(rèn)值 10。
- max_iter:int, default=300 最大迭代次數(shù)。默認(rèn)值 300。
- algorithm:{“auto”, “full”, “elkan”}, default=”auto” 算法選擇,"full"是經(jīng)典的 EM算法,“elkan"能快速處理定義良好的簇,默認(rèn)值 “auto"目前采用"elkan”。
KMeans 的主要屬性:
- **clustercenters:**每個聚類中心的坐標(biāo)
- labels_: 每個樣本的分類結(jié)果
- inertia_: 每個點到所屬聚類中心的距離之和。
4.3 sklearn.cluster.KMeans 用法實例
from sklearn.cluster import KMeans # 導(dǎo)入 sklearn.cluster.KMeans 類 import numpy as np X = np.array([[1,2], [1,4], [1,0], [10,2], [10,4], [10,0]]) kmCluster = KMeans(n_clusters=2).fit(X) # 建立模型并進(jìn)行聚類,設(shè)定 K=2 print(kmCluster.cluster_centers_) # 返回每個聚類中心的坐標(biāo) #[[10., 2.], [ 1., 2.]] # print 顯示聚類中心坐標(biāo) print(kmCluster.labels_) # 返回樣本集的分類結(jié)果 #[1, 1, 1, 0, 0, 0] # print 顯示分類結(jié)果 print(kmCluster.predict([[0, 0], [12, 3]])) # 根據(jù)模型聚類結(jié)果進(jìn)行預(yù)測判斷 #[1, 0] # print顯示判斷結(jié)果:樣本屬于哪個類別 # = 關(guān)注 Youcans,分享原創(chuàng)系列 https://blog.csdn.net/youcans =例程很簡單,又給了詳細(xì)注釋,就不再解讀了。核心程序就是下面這句:
kMeanModel = KMeans(n_clusters=2).fit(X)
4.4 針對大樣本集的改進(jìn)算法:Mini Batch K-Means
對于樣本集巨大的問題,例如樣本量大于 10萬、特征變量大于100,K-Means算法耗費的速度和內(nèi)存很大。SKlearn 提供了針對大樣本集的改進(jìn)算法 Mini Batch K-Means,并不使用全部樣本數(shù)據(jù),而是每次抽樣選取小樣本集進(jìn)行 K-Means聚類,進(jìn)行循環(huán)迭代。Mini Batch K-Means 雖然性能略有降低,但極大的提高了運行速度和內(nèi)存占用。
class sklearn.cluster.MiniBatchKMeans 類是算法的具體實現(xiàn),官網(wǎng)介紹詳見:https://scikit-learn.org/stable/modules/generated/sklearn.cluster.MiniBatchKMeans.html#sklearn.cluster.MiniBatchKMeans
class sklearn.cluster.MiniBatchKMeans(n_clusters=8, *, init=‘k-means++’, max_iter=100, batch_size=100, verbose=0, compute_labels=True, random_state=None, tol=0.0, max_no_improvement=10, init_size=None, n_init=3, reassignment_ratio=0.01)
MiniBatchKMeans 與 KMeans不同的主要參數(shù)是:
- batch_size: int, default=100 抽樣集的大小。默認(rèn)值 100。
Mini Batch K-Means 的用法實例如下:
from sklearn.cluster import MiniBatchKMeans # 導(dǎo)入 .MiniBatchKMeans 類 import numpy as np X = np.array([[1,2], [1,4], [1,0], [4,2], [4,0], [4,4],[4,5], [0,1], [2,2],[3,2], [5,5], [1,-1]]) # fit on the whole data mbkmCluster = MiniBatchKMeans(n_clusters=2,batch_size=6,max_iter=10).fit(X) print(mbkmCluster.cluster_centers_) # 返回每個聚類中心的坐標(biāo) # [[3.96,2.41], [1.12,1.39]] # print 顯示內(nèi)容 print(mbkmCluster.labels_) # 返回樣本集的分類結(jié)果 #[1 1 1 0 0 0 0 1 1 0 0 1] # print 顯示內(nèi)容 print(mbkmCluster.predict([[0,0], [4,5]])) # 根據(jù)模型聚類結(jié)果進(jìn)行預(yù)測判斷 #[1, 0] # 顯示判斷結(jié)果:樣本屬于哪個類別 # = 關(guān)注 Youcans,分享原創(chuàng)系列 https://blog.csdn.net/youcans =5、K-均值算法例程
5.1 問題描述
- 聚類分析案例—我國各地區(qū)普通高等教育發(fā)展?fàn)顩r分析,本問題及數(shù)據(jù)來自:司守奎、孫兆亮,數(shù)學(xué)建模算法與應(yīng)用(第2版),國防工業(yè)出版社。
問題的原始數(shù)據(jù)來自《中國統(tǒng)計年鑒,1995》和《中國教育統(tǒng)計年鑒,1995》,給出了各地區(qū)10 項教育發(fā)展數(shù)據(jù)。我國各地區(qū)普通高等教育的發(fā)展?fàn)顩r存在較大的差異,請根據(jù)數(shù)據(jù)對我國各地區(qū)普通高等教育的發(fā)展?fàn)顩r進(jìn)行聚類分析。
5.2 Python 程序
# Kmeans_sklearn_v1d.py # K-Means cluster by scikit-learn for problem "education2015" # v1.0d: K-Means 聚類算法(SKlearn)求解:各地區(qū)高等教育發(fā)展?fàn)顩r-2015 問題 # 日期:2021-05-10# -*- coding: utf-8 -*- import numpy as np import pandas as pd from sklearn.cluster import KMeans, MiniBatchKMeans# 主程序 = 關(guān)注 Youcans,分享原創(chuàng)系列 https://blog.csdn.net/youcans = def main():# 讀取數(shù)據(jù)文件readPath = "../data/education2015.xlsx" # 數(shù)據(jù)文件的地址和文件名dfFile = pd.read_excel(readPath, header=0) # 首行為標(biāo)題行dfFile = dfFile.dropna() # 刪除含有缺失值的數(shù)據(jù)# print(dfFile.dtypes) # 查看 df 各列的數(shù)據(jù)類型# print(dfFile.shape) # 查看 df 的行數(shù)和列數(shù)print(dfFile.head())# 數(shù)據(jù)準(zhǔn)備z_scaler = lambda x:(x-np.mean(x))/np.std(x) # 定義數(shù)據(jù)標(biāo)準(zhǔn)化函數(shù)dfScaler = dfFile[['x1','x2','x3','x4','x5','x6','x7','x8','x9','x10']].apply(z_scaler) # 數(shù)據(jù)歸一化dfData = pd.concat([dfFile[['地區(qū)']], dfScaler], axis=1) # 列級別合并df = dfData.loc[:,['x1','x2','x3','x4','x5','x6','x7','x8','x9','x10']] # 基于全部 10個特征聚類分析# df = dfData.loc[:,['x1','x2','x7','x8','x9','x10']] # 降維后選取 6個特征聚類分析X = np.array(df) # 準(zhǔn)備 sklearn.cluster.KMeans 模型數(shù)據(jù)print("Shape of cluster data:", X.shape)# KMeans 聚類分析(sklearn.cluster.KMeans)nCluster = 4kmCluster = KMeans(n_clusters=nCluster).fit(X) # 建立模型并進(jìn)行聚類,設(shè)定 K=2print("Cluster centers:\n", kmCluster.cluster_centers_) # 返回每個聚類中心的坐標(biāo)print("Cluster results:\n", kmCluster.labels_) # 返回樣本集的分類結(jié)果# 整理聚類結(jié)果listName = dfData['地區(qū)'].tolist() # 將 dfData 的首列 '地區(qū)' 轉(zhuǎn)換為 listNamedictCluster = dict(zip(listName,kmCluster.labels_)) # 將 listName 與聚類結(jié)果關(guān)聯(lián),組成字典listCluster = [[] for k in range(nCluster)]for v in range(0, len(dictCluster)):k = list(dictCluster.values())[v] # 第v個城市的分類是 klistCluster[k].append(list(dictCluster.keys())[v]) # 將第v個城市添加到 第k類print("\n聚類分析結(jié)果(分為{}類):".format(nCluster)) # 返回樣本集的分類結(jié)果for k in range(nCluster):print("第 {} 類:{}".format(k, listCluster[k])) # 顯示第 k 類的結(jié)果return # = 關(guān)注 Youcans,分享原創(chuàng)系列 https://blog.csdn.net/youcans = if __name__ == '__main__':main()5.3 程序運行結(jié)果
地區(qū) x1 x2 x3 x4 x5 x6 x7 x8 x9 x10 0 北京 5.96 310 461 1557 931 319 44.36 2615 2.20 13631 1 上海 3.39 234 308 1035 498 161 35.02 3052 0.90 12665 2 天津 2.35 157 229 713 295 109 38.40 3031 0.86 9385 3 陜西 1.35 81 111 364 150 58 30.45 2699 1.22 7881 4 遼寧 1.50 88 128 421 144 58 34.30 2808 0.54 7733 Shape of cluster data: (30, 10) Cluster centers:[[ 1.52987871 2.10479182 1.97836141 1.92037518 1.54974999 1.503441821.13526879 1.13595799 0.83939748 1.38149832][-0.32558635 -0.28230636 -0.28071191 -0.27988803 -0.28228409 -0.284940740.01965142 0.09458383 -0.26439737 -0.31101153][ 4.44318512 3.9725159 4.16079449 4.20994153 4.61768098 4.652966992.45321197 0.4021476 4.22779099 2.44672575][ 0.31835808 -0.56222029 -0.54985976 -0.52674552 -0.33003935 -0.26816609-2.60751756 -2.51932966 0.35167418 1.28278289]] Cluster results:[2 0 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 3 1 1 1 1 3]聚類分析結(jié)果(分為4類): 第 0 類:['上海', '天津'] 第 1 類:['陜西', '遼寧', '吉林', '黑龍江', '湖北', '江蘇', '廣東', '四川', '山東', '甘肅', '湖南', '浙江', '新疆', '福建', '山西', '河北', '安徽', '云南', '江西', '海南', '內(nèi)蒙古', '河南', '廣西', '寧夏', '貴州'] 第 2 類:['北京'] 第 3 類:['西藏', '青海']版權(quán)說明:
本文中案例問題來自:司守奎、孫兆亮,數(shù)學(xué)建模算法與應(yīng)用(第2版),國防工業(yè)出版社。
本文內(nèi)容及例程為作者原創(chuàng),并非轉(zhuǎn)載書籍或網(wǎng)絡(luò)內(nèi)容。
YouCans 原創(chuàng)作品
Copyright 2021 YouCans, XUPT
Crated:2021-05-09
歡迎關(guān)注 Youcans 原創(chuàng)系列,每周更新數(shù)模筆記
Python數(shù)模筆記-PuLP庫(1)線性規(guī)劃入門
Python數(shù)模筆記-PuLP庫(2)線性規(guī)劃進(jìn)階
Python數(shù)模筆記-PuLP庫(3)線性規(guī)劃實例
Python數(shù)模筆記-StatsModels 統(tǒng)計回歸(1)簡介
Python數(shù)模筆記-StatsModels 統(tǒng)計回歸(2)線性回歸
Python數(shù)模筆記-StatsModels 統(tǒng)計回歸(3)模型數(shù)據(jù)的準(zhǔn)備
Python數(shù)模筆記-StatsModels 統(tǒng)計回歸(4)可視化
Python數(shù)模筆記-Sklearn (1)介紹
Python數(shù)模筆記-Sklearn (2)聚類分析
Python數(shù)模筆記-Sklearn (3)主成分分析
Python數(shù)模筆記-Sklearn (4)線性回歸
Python數(shù)模筆記-Sklearn (5)支持向量機(jī)
Python數(shù)模筆記-模擬退火算法(1)多變量函數(shù)優(yōu)化
Python數(shù)模筆記-模擬退火算法(2)約束條件的處理
Python數(shù)模筆記-模擬退火算法(3)整數(shù)規(guī)劃問題
Python數(shù)模筆記-模擬退火算法(4)旅行商問題
總結(jié)
以上是生活随笔為你收集整理的Python数模笔记-Sklearn(2)聚类分析的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: C++文件操作与文件流
- 下一篇: 阶段项目:学生信息管理系统数据库设计