Python数模笔记-Sklearn(2)聚类分析
1、分類的分類
分類的分類?沒錯,分類也有不同的種類,而且在數學建模、機器學習領域常常被混淆。
首先我們談談有監督學習(Supervised learning)和無監督學習(Unsupervised learning),是指有沒有老師,有沒有紀委嗎?差不多。有老師,就有正確解法,就有標準答案;有紀委,就會樹學習榜樣,還有反面教材。
有監督學習,是指樣本數據已經給出了正確的分類,我們通過對正確分類的樣本數據進行學習,從中總結規律,獲取知識,付諸應用。所以,監督學習的樣本數據,既提供了特征值又提供了目標值,通過回歸(Regression)、分類(Classification)學習特征與目標之間的關系?;貧w是針對連續變量、連續數據,分類是針對離散變量和布爾變量(0-1)。
無監督學習,是指樣本數據沒有提供確定的分類屬性,沒有老師,沒有標準答案,樣本數據中只有樣本的特征值而沒有目標值,只能通過樣本數據自身的特征一邊摸索一邊自我學習,通過聚類(Clustering)方法來尋找和認識對象的相似性。
所以,我們說到分類時,其實有時是指分類(Classification),有時則是指聚類(Clustering)。
有監督學習有老師,就有正確答案。雖然有時也會有模糊地帶,但總體說來還是有判定標準、有是非對錯的,只要與標準答案不一致就會被認為判斷錯誤。
無監督學習則不同,可以有不同的分類方法、不同的分類結果,通常只有相對的好壞而沒有絕對的對錯。甚至連分類結果的好壞也是相對的,要根據實際需要實際情況進行綜合考慮,才能評價分類結果的好壞。誰能說人應該分幾類,怎么分更合理呢?
歡迎關注 Youcans 原創系列,每周更新數模筆記
Python數模筆記-PuLP庫
Python數模筆記-StatsModels統計回歸
Python數模筆記-Sklearn
Python數模筆記-NetworkX
Python數模筆記-模擬退火算法
2、聚類分析
2.1 聚類的分類
聚類是從數據分析的角度,對大量的、多維的、無標記的樣本數據集,按照樣本數據自身的相似性對數據集進行分類。大量,是指樣本的數量大;多維,是指每個樣本都有很多特征值;無標記,是指樣本數據對于每個樣本沒有指定的類別屬性。
需要說明的是,有時樣本數據帶有一個或多個分類屬性,但那并不是我們所要研究的類別屬性,才會被稱為無監督學習。比如說,體能訓練數據集中每個樣本都有很多特征數據,包括性別、年齡,也包括體重、腰圍、心率和血壓。性別、年齡顯然都是樣本的屬性,我們也可以根據性別屬性把樣本集分為男性、女性兩類,這當然是有監督學習;但是,如果我們是打算研究這些樣本的生理變化與鍛煉的關系,這是性別就不定是唯一的分類屬性,甚至不一定是相關的屬性了,從這個意義上說,樣本數據中并沒有給出我們所要進行分類的類別屬性。
至于聚類的分類,是針對研究對象的不同來說的。把樣本集的行(rows)作為對象,考察樣本的相似度,將樣本集分成若干類,稱為 Q型聚類分析,屬于樣本分類。把樣本集的列(columns)作為對象,考察各個特征變量之間的關聯程度,按照變量的相關性聚合為若干類,稱為 R型聚類分析,屬于因子分析。
2.2 Q型聚類分析(樣本聚類)
Q 型聚類分析考察樣本的相似度,將樣本集分成若干類。我們需要綜合考慮樣本各種特征變量的數值或類型,找到一種分類方法將樣本集分為若干類,使每一類的樣本之間具有較大的相似性,又與其它類的樣本具有較大的差異性。通常是根據不同樣本之間的距離遠近進行劃分,距離近者分為一類,距離遠者分成不同類,以達到“同類相似,異類相異”。
按照相似性分類,首先就要定義什么是相似。對于任意兩個樣本,很容易想到以樣本間的距離作為衡量相似性的指標。在一維空間中兩點間的距離是絕對值: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)等。這些距離的定義、公式和使用條件,本文就不具體介紹了。世界是豐富多彩的,問題是多種多樣的,對于特殊問題有時就要針對其特點采用特殊的解決方案。
進而,對于兩組樣本G1、G2,也需要度量類與類之間的相似性程度。常用的方法有最短距離法(Nearest Neighbor or Single Linkage Method)、最長距離法(Farthest Neighbor or Complete Linkage Method)、重心法(Centroid Method)、類均值法(Group Average Method)、離差平方和法(Sum of Squares Method)。
另外,處理實際問題時,在計算距離之前要對數據進行標準化、歸一化,解決不同特征之間的統一量綱、均衡權重。
3、SKlearn 中的聚類方法
SKlearn 工具包提供了多種聚類分析算法:原型聚類方法(Prototype)、密度聚類方法(Density)、層次聚類方法(Hierarchical)、模型聚類(Model),等等,原型聚類方法又包括 k均值算法(K-Means)、學習向量量化算法(LVQ)、高斯混合算法(Gaussian Mixture)。詳見下表。
為什么會有這么多方法和算法呢?因為特殊問題需要針對其特點采用特殊的解決方案。看看下面這張圖,就能理解這句話了,也能理解各種算法都是針對哪種問題的。SKlearn 還提供了十多個聚類評價指標,本文就不再展開介紹了。
4、K-均值(K-Means)聚類算法
K-均值聚類算法,是最基礎的、應用最廣泛的聚類算法,也是最快速的聚類算法之一。
4.1 原理和過程
K-均值聚類算法以最小化誤差函數為目標將樣本數據集分為 K類。
K-均值聚類算法的計算過程如下:
- 設定 K 個類別的中心的初值;
- 計算每個樣本到 K個中心的距離,按最近距離進行分類;
- 以每個類別中樣本的均值,更新該類別的中心;
- 重復迭代以上步驟,直到達到終止條件(迭代次數、最小平方誤差、簇中心點變化率)。
K-均值聚類算法的優點是原理簡單、算法簡單,速度快,聚類效果極好,對大數據集具有很好的伸縮性。這些優點特別有利于初學者、常見問題。其缺點是需要給定 K值,對一些特殊情況(如非凸簇、特殊值、簇的大小差別大)的性能不太好。怎么看這些缺點?需要給定 K值的問題是有解決方法的;至于特殊情況,已經跟我們沒什么關系了。
4.2 SKlearn 中 K-均值算法的使用
sklearn.cluster.KMeans 類是 K-均值算法的具體實現,官網介紹詳見: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=‘auto’)
KMeans 的主要參數:
- n_clusters: int,default=8 K值,給定的分類數量,默認值 8。
- init:{‘k-means++’, ‘random’} 初始中心的選擇方式,默認’K-means++'是優化值,也可以隨機選擇或自行指定。
- n_init:int, default=10 以不同的中心初值多次運行,以降低初值對算法的影響。默認值 10。
- max_iter:int, default=300 最大迭代次數。默認值 300。
- algorithm:{“auto”, “full”, “elkan”}, default=”auto” 算法選擇,"full"是經典的 EM算法,“elkan"能快速處理定義良好的簇,默認值 “auto"目前采用"elkan”。
KMeans 的主要屬性:
- **clustercenters:**每個聚類中心的坐標
- labels_: 每個樣本的分類結果
- inertia_: 每個點到所屬聚類中心的距離之和。
4.3 sklearn.cluster.KMeans 用法實例
from sklearn.cluster import KMeans # 導入 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) # 建立模型并進行聚類,設定 K=2 print(kmCluster.cluster_centers_) # 返回每個聚類中心的坐標 #[[10., 2.], [ 1., 2.]] # print 顯示聚類中心坐標 print(kmCluster.labels_) # 返回樣本集的分類結果 #[1, 1, 1, 0, 0, 0] # print 顯示分類結果 print(kmCluster.predict([[0, 0], [12, 3]])) # 根據模型聚類結果進行預測判斷 #[1, 0] # print顯示判斷結果:樣本屬于哪個類別 # = 關注 Youcans,分享原創系列 https://blog.csdn.net/youcans =例程很簡單,又給了詳細注釋,就不再解讀了。核心程序就是下面這句:
kMeanModel = KMeans(n_clusters=2).fit(X)
4.4 針對大樣本集的改進算法:Mini Batch K-Means
對于樣本集巨大的問題,例如樣本量大于 10萬、特征變量大于100,K-Means算法耗費的速度和內存很大。SKlearn 提供了針對大樣本集的改進算法 Mini Batch K-Means,并不使用全部樣本數據,而是每次抽樣選取小樣本集進行 K-Means聚類,進行循環迭代。Mini Batch K-Means 雖然性能略有降低,但極大的提高了運行速度和內存占用?! ?br /> class sklearn.cluster.MiniBatchKMeans 類是算法的具體實現,官網介紹詳見: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不同的主要參數是:
- batch_size: int, default=100 抽樣集的大小。默認值 100。
Mini Batch K-Means 的用法實例如下:
from sklearn.cluster import MiniBatchKMeans # 導入 .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_) # 返回每個聚類中心的坐標 # [[3.96,2.41], [1.12,1.39]] # print 顯示內容 print(mbkmCluster.labels_) # 返回樣本集的分類結果 #[1 1 1 0 0 0 0 1 1 0 0 1] # print 顯示內容 print(mbkmCluster.predict([[0,0], [4,5]])) # 根據模型聚類結果進行預測判斷 #[1, 0] # 顯示判斷結果:樣本屬于哪個類別 # = 關注 Youcans,分享原創系列 https://blog.csdn.net/youcans =5、K-均值算法例程
5.1 問題描述
- 聚類分析案例—我國各地區普通高等教育發展狀況分析,本問題及數據來自:司守奎、孫兆亮,數學建模算法與應用(第2版),國防工業出版社。
問題的原始數據來自《中國統計年鑒,1995》和《中國教育統計年鑒,1995》,給出了各地區10 項教育發展數據。我國各地區普通高等教育的發展狀況存在較大的差異,請根據數據對我國各地區普通高等教育的發展狀況進行聚類分析。
5.2 Python 程序
# Kmeans_sklearn_v1d.py # K-Means cluster by scikit-learn for problem "education2015" # v1.0d: K-Means 聚類算法(SKlearn)求解:各地區高等教育發展狀況-2015 問題 # 日期:2021-05-10# -*- coding: utf-8 -*- import numpy as np import pandas as pd from sklearn.cluster import KMeans, MiniBatchKMeans# 主程序 = 關注 Youcans,分享原創系列 https://blog.csdn.net/youcans = def main():# 讀取數據文件readPath = "../data/education2015.xlsx" # 數據文件的地址和文件名dfFile = pd.read_excel(readPath, header=0) # 首行為標題行dfFile = dfFile.dropna() # 刪除含有缺失值的數據# print(dfFile.dtypes) # 查看 df 各列的數據類型# print(dfFile.shape) # 查看 df 的行數和列數print(dfFile.head())# 數據準備z_scaler = lambda x:(x-np.mean(x))/np.std(x) # 定義數據標準化函數dfScaler = dfFile[['x1','x2','x3','x4','x5','x6','x7','x8','x9','x10']].apply(z_scaler) # 數據歸一化dfData = pd.concat([dfFile[['地區']], 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) # 準備 sklearn.cluster.KMeans 模型數據print("Shape of cluster data:", X.shape)# KMeans 聚類分析(sklearn.cluster.KMeans)nCluster = 4kmCluster = KMeans(n_clusters=nCluster).fit(X) # 建立模型并進行聚類,設定 K=2print("Cluster centers:\n", kmCluster.cluster_centers_) # 返回每個聚類中心的坐標print("Cluster results:\n", kmCluster.labels_) # 返回樣本集的分類結果# 整理聚類結果listName = dfData['地區'].tolist() # 將 dfData 的首列 '地區' 轉換為 listNamedictCluster = dict(zip(listName,kmCluster.labels_)) # 將 listName 與聚類結果關聯,組成字典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聚類分析結果(分為{}類):".format(nCluster)) # 返回樣本集的分類結果for k in range(nCluster):print("第 {} 類:{}".format(k, listCluster[k])) # 顯示第 k 類的結果return # = 關注 Youcans,分享原創系列 https://blog.csdn.net/youcans = if __name__ == '__main__':main()5.3 程序運行結果
地區 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]聚類分析結果(分為4類): 第 0 類:['上海', '天津'] 第 1 類:['陜西', '遼寧', '吉林', '黑龍江', '湖北', '江蘇', '廣東', '四川', '山東', '甘肅', '湖南', '浙江', '新疆', '福建', '山西', '河北', '安徽', '云南', '江西', '海南', '內蒙古', '河南', '廣西', '寧夏', '貴州'] 第 2 類:['北京'] 第 3 類:['西藏', '青海']版權說明:
本文中案例問題來自:司守奎、孫兆亮,數學建模算法與應用(第2版),國防工業出版社。
本文內容及例程為作者原創,并非轉載書籍或網絡內容。
YouCans 原創作品
Copyright 2021 YouCans, XUPT
Crated:2021-05-09
歡迎關注 Youcans 原創系列,每周更新數模筆記
Python數模筆記-PuLP庫(1)線性規劃入門
Python數模筆記-PuLP庫(2)線性規劃進階
Python數模筆記-PuLP庫(3)線性規劃實例
Python數模筆記-StatsModels 統計回歸(1)簡介
Python數模筆記-StatsModels 統計回歸(2)線性回歸
Python數模筆記-StatsModels 統計回歸(3)模型數據的準備
Python數模筆記-StatsModels 統計回歸(4)可視化
Python數模筆記-Sklearn (1)介紹
Python數模筆記-Sklearn (2)聚類分析
Python數模筆記-Sklearn (3)主成分分析
Python數模筆記-Sklearn (4)線性回歸
Python數模筆記-Sklearn (5)支持向量機
Python數模筆記-模擬退火算法(1)多變量函數優化
Python數模筆記-模擬退火算法(2)約束條件的處理
Python數模筆記-模擬退火算法(3)整數規劃問題
Python數模筆記-模擬退火算法(4)旅行商問題
總結
以上是生活随笔為你收集整理的Python数模笔记-Sklearn(2)聚类分析的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: C++文件操作与文件流
- 下一篇: 阶段项目:学生信息管理系统数据库设计