<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          機(jī)器學(xué)習(xí) | KMeans聚類分析詳解

          共 20950字,需瀏覽 42分鐘

           ·

          2021-09-21 12:26

          大家好,我是老表,今天給大家分享一篇機(jī)器學(xué)習(xí)KMaens聚類分析算法文章,在后面的實(shí)戰(zhàn)中我們將用到該算法,希望大家認(rèn)真學(xué)習(xí)閱讀,覺(jué)得對(duì)自己學(xué)習(xí)有幫助的話,歡迎點(diǎn)贊、轉(zhuǎn)發(fā)、留言。


          首先需要你的電腦安裝好了Python環(huán)境,并且安裝好了Python開(kāi)發(fā)工具。

          如果你還沒(méi)有安裝,可以參考以下文章:
          如果僅用Python來(lái)處理數(shù)據(jù)、爬蟲(chóng)、數(shù)據(jù)分析或者自動(dòng)化腳本、機(jī)器學(xué)習(xí)等,建議使用Python基礎(chǔ)環(huán)境+jupyter即可,安裝使用參考Windows/Mac 安裝、使用Python環(huán)境+jupyter notebook

          如果想利用Python進(jìn)行web項(xiàng)目開(kāi)發(fā)等,建議使用Python基礎(chǔ)環(huán)境+Pycharm,安裝使用參考:Windows下安裝、使用Pycharm教程,這下全了 和 Mac下玩轉(zhuǎn)Python-安裝&使用Python/PyCharm 。


          大量數(shù)據(jù)中具有"相似"特征的數(shù)據(jù)點(diǎn)或樣本劃分為一個(gè)類別。聚類分析提供了樣本集在非監(jiān)督模式下的類別劃分。聚類的基本思想是"物以類聚、人以群分",將大量數(shù)據(jù)集中相似的數(shù)據(jù)樣本區(qū)分出來(lái),并發(fā)現(xiàn)不同類的特征。

          聚類模型可以建立在無(wú)類標(biāo)記的數(shù)據(jù)上,是一種非監(jiān)督的學(xué)習(xí)算法。盡管全球每日新增數(shù)據(jù)量以PB或EB級(jí)別增長(zhǎng),但是大部分?jǐn)?shù)據(jù)屬于無(wú)標(biāo)注甚至非結(jié)構(gòu)化。所以相對(duì)于監(jiān)督學(xué)習(xí),不需要標(biāo)注的無(wú)監(jiān)督學(xué)習(xí)蘊(yùn)含了巨大的潛力與價(jià)值。聚類根據(jù)數(shù)據(jù)自身的距離或相似度將他們劃分為若干組,劃分原則是組內(nèi)樣本最小化而組間距離最大化。

          常見(jiàn)聚類算法聚類效果對(duì)比圖

          聚類分析常用于數(shù)據(jù)探索或挖掘前期

          • 沒(méi)有先驗(yàn)經(jīng)驗(yàn)做探索性分析
          • 樣本量較大時(shí)做預(yù)處理

          常用于解決

          • 數(shù)據(jù)集可以分幾類;每個(gè)類別有多少樣本量
          • 不同類別中各個(gè)變量的強(qiáng)弱關(guān)系如何
          • 不同類型的典型特征是什么

          一般應(yīng)用場(chǎng)景

          • 群類別間的差異性特征分析
          • 群類別內(nèi)的關(guān)鍵特征提取
          • 圖像壓縮、分割、圖像理解
          • 異常檢測(cè)
          • 數(shù)據(jù)離散化

          當(dāng)然聚類分析也有其缺點(diǎn)

          • 無(wú)法提供明確的行動(dòng)指向
          • 數(shù)據(jù)異常對(duì)結(jié)果有影響


          本文將從算法原理、優(yōu)化目標(biāo)、sklearn聚類算法、算法優(yōu)缺點(diǎn)、算法優(yōu)化、算法重要參數(shù)、衡量指標(biāo)以及案例等方面詳細(xì)介紹KMeans算法。

          KMeans

          K均值(KMeans)是聚類中最常用的方法之一,基于點(diǎn)與點(diǎn)之間的距離的相似度來(lái)計(jì)算最佳類別歸屬。

          KMeans算法通過(guò)試著將樣本分離到 個(gè)方差相等的組中來(lái)對(duì)數(shù)據(jù)進(jìn)行聚類,從而最小化目標(biāo)函數(shù) (見(jiàn)下文)。該算法要求指定集群的數(shù)量。它可以很好地?cái)U(kuò)展到大量的樣本,并且已經(jīng)在許多不同領(lǐng)域的廣泛應(yīng)用領(lǐng)域中使用。

          被分在同一個(gè)簇中的數(shù)據(jù)是有相似性的,而不同簇中的數(shù)據(jù)是不同的,當(dāng)聚類完畢之后,我們就要分別去研究每個(gè)簇中的樣本都有什么樣的性質(zhì),從而根據(jù)業(yè)務(wù)需求制定不同的商業(yè)或者科技策略。常用于客戶分群、用戶畫像、精確營(yíng)銷、基于聚類的推薦系統(tǒng)。

          算法原理

          • 個(gè)樣本數(shù)據(jù)中隨機(jī)選取 個(gè)質(zhì)心作為初始的聚類中心。質(zhì)心記為

          • 定義優(yōu)化目標(biāo)

          • 開(kāi)始循環(huán),計(jì)算每個(gè)樣本點(diǎn)到那個(gè)質(zhì)心到距離,樣本離哪個(gè)近就將該樣本分配到哪個(gè)質(zhì)心,得到K個(gè)簇

          • 對(duì)于每個(gè)簇,計(jì)算所有被分到該簇的樣本點(diǎn)的平均距離作為新的質(zhì)心

          • 直到 收斂,即所有簇不再發(fā)生變化。

          KMeans迭代示意圖

          優(yōu)化目標(biāo)

          KMeans 在進(jìn)行類別劃分過(guò)程及最終結(jié)果,始終追求"簇內(nèi)差異小,簇間差異大",其中差異由樣本點(diǎn)到其所在簇的質(zhì)心的距離衡量。在KNN算法學(xué)習(xí)中,我們學(xué)習(xí)到多種常見(jiàn)的距離 ---- 歐幾里得距離、曼哈頓距離、余弦距離

          sklearn中的KMeans使用歐幾里得距離:

          則一個(gè)簇中所有樣本點(diǎn)到質(zhì)心的距離的平方和為:
          其中, 為一個(gè)簇中樣本的個(gè)數(shù), 是每個(gè)樣本的編號(hào)。這個(gè)公式被稱為簇內(nèi)平方和(cluster Sum of Square), 又叫做Inertia

          而將一個(gè)數(shù)據(jù)集中的所有簇的簇內(nèi)平方和相加,就得到了整體平方和(Total Cluster Sum of Square),又叫做Total InertiaTotal Inertia越小,代表著每個(gè)簇內(nèi)樣本越相似,聚類的效果就越好。因此 KMeans 追求的是,求解能夠讓Inertia最小化的質(zhì)心。

          KMeans有損失函數(shù)嗎?

          損失函數(shù)本質(zhì)是用來(lái)衡量模型的擬合效果的,只有有著求解參數(shù)需求的算法,才會(huì)有損失函數(shù)。KMeans不求解什么參數(shù),它的模型本質(zhì)也沒(méi)有在擬合數(shù)據(jù),而是在對(duì)數(shù)據(jù)進(jìn)行一 種探索。

          另外,在決策樹(shù)中有衡量分類效果的指標(biāo)準(zhǔn)確度accuracy,準(zhǔn)確度所對(duì)應(yīng)的損失叫做泛化誤差,但不能通過(guò)最小化泛化誤差來(lái)求解某個(gè)模型中需要的信息,我們只是希望模型的效果上表現(xiàn)出來(lái)的泛化誤差很小。因此決策樹(shù),KNN等算法,是絕對(duì)沒(méi)有損失函數(shù)的。

          雖然在sklearn中只能被動(dòng)選用歐式距離,但其他距離度量方式同樣可以用來(lái)衡量簇內(nèi)外差異。不同距離所對(duì)應(yīng)的質(zhì)心選擇方法和Inertia如下表所示, 在KMeans中,只要使用了正確的質(zhì)心和距離組合,無(wú)論使用什么樣的距離,都可以達(dá)到不錯(cuò)的聚類效果。

          距離度量質(zhì)心Inertia
          歐幾里得距離均值最小化每個(gè)樣本點(diǎn)到質(zhì)心的歐式距離之和
          曼哈頓距離中位數(shù)最小化每個(gè)樣本點(diǎn)到質(zhì)心的曼哈頓距離之和
          余弦距離均值最小化每個(gè)樣本點(diǎn)到質(zhì)心的余弦距離之和

          sklearn.cluster.KMeans

          語(yǔ)法:

          sklearn.cluster.KMeans(n_clusters=8, init='k-means++', n_init=10, max_iter=300, tol=0.0001, precompute_distances='auto', verbose=0, random_state=None, copy_x=True, n_jobs=None, algorithm='auto')

          參數(shù)與接口詳解見(jiàn)文末附錄

          例:

          >>> from sklearn.cluster import KMeans
          >>> import numpy as np
          >>> X = np.array([[12], [14], [10],
          ...               [102], [104], [100]])
          >>> kmeans = KMeans(n_clusters=2, random_state=0).fit(X)
          >>> kmeans.labels_
          array([111000], dtype=int32)
          >>> kmeans.predict([[00], [123]])
          array([10], dtype=int32)
          >>> kmeans.cluster_centers_
          array([[10.,  2.],
                 [ 1.,  2.]])

          KMeans算法優(yōu)缺點(diǎn)

          優(yōu)點(diǎn)

          • KMeans算法是解決聚類問(wèn)題的一種經(jīng)典算法, 算法簡(jiǎn)單、快速 。
          • 算法嘗試找出使平方誤差函數(shù)值最小的  個(gè)劃分。當(dāng)簇是密集的、球狀或團(tuán)狀的,且簇與簇之間區(qū)別明顯時(shí),聚類效果較好 。

          缺點(diǎn)

          • KMeans方法只有在簇的平均值被定義的情況下才能使用,且對(duì)有些分類屬性的數(shù)據(jù)不適合。
          • 要求用戶必須事先給出要生成的簇的數(shù)目  
          • 對(duì)初值敏感,對(duì)于不同的初始值,可能會(huì)導(dǎo)致不同的聚類結(jié)果。
          • 不適合于發(fā)現(xiàn)非凸面形狀的簇,或者大小差別很大的簇。
          • KMeans本質(zhì)上是一種基于歐式距離度量的數(shù)據(jù)劃分方法,均值和方差大的維度將對(duì)數(shù)據(jù)的聚類結(jié)果產(chǎn)生決定性影響。所以在聚類前對(duì)數(shù)據(jù)(具體的說(shuō)是每一個(gè)維度的特征)做歸一化(點(diǎn)擊查看歸一化詳解)和單位統(tǒng)一至關(guān)重要。此外,異常值會(huì)對(duì)均值計(jì)算產(chǎn)生較大影響,導(dǎo)致中心偏移,因此對(duì)于"噪聲"和孤立點(diǎn)數(shù)據(jù)最好能提前過(guò)濾 。

          KMeans算法優(yōu)化

          KMeans算法雖然效果不錯(cuò),但是每一次迭代都需要遍歷全量的數(shù)據(jù),一旦數(shù)據(jù)量過(guò)大,由于計(jì)算復(fù)雜度過(guò)大迭代的次數(shù)過(guò)多,會(huì)導(dǎo)致收斂速度非常慢。

          KMeans算法原來(lái)可知,KMeans在聚類之前首先需要初始化 個(gè)簇中心,因此 KMeans算法對(duì)初值敏感,對(duì)于不同的初始值,可能會(huì)導(dǎo)致不同的聚類結(jié)果。因初始化是個(gè)"隨機(jī)"過(guò)程,很有可能 個(gè)簇中心都在同一個(gè)簇中,這種情況 KMeans 聚類算法很大程度上都不會(huì)收斂到全局最小。

          想要優(yōu)化KMeans算法的效率問(wèn)題,可以從以下兩個(gè)思路優(yōu)化算法,一個(gè)是樣本數(shù)量太大,另一個(gè)是迭代次數(shù)過(guò)多

          MiniBatchKMeans 聚類算法

          mini batch 優(yōu)化思想非常樸素,既然全體樣本當(dāng)中數(shù)據(jù)量太大,會(huì)使得我們迭代的時(shí)間過(guò)長(zhǎng),那么隨機(jī)從整體當(dāng)中做一個(gè)抽樣,選取出一小部分?jǐn)?shù)據(jù)來(lái)代替整體以達(dá)到縮小數(shù)據(jù)規(guī)模的目的。

          mini batch 優(yōu)化非常重要,不僅重要而且在機(jī)器學(xué)習(xí)領(lǐng)域廣為使用。在大數(shù)據(jù)的場(chǎng)景下,幾乎所有模型都需要做mini batch優(yōu)化,而MiniBatchKMeans就是mini batch 優(yōu)化的一個(gè)應(yīng)用。直接上模型比較MiniBatchKMeansKMeans兩種算法計(jì)算速度(樣本量1,000,000)

          • KMeans用時(shí)接近 6 秒鐘,而MiniBatchKMeans 僅用時(shí)不到 1 秒鐘
          • 且聚類中心基本一致
          >>> KMeans.cluster_centers_
          array([[-2.50889102,  9.01143598],
                 [-6.88150415-6.88090477],
                 [ 4.63628843,  1.97271152],
                 [-8.83895916,  7.32493568]])

          >>> MiniBatchKMeans.cluster_centers_
          array([[-2.50141353,  8.97807161],
                 [-6.88418974-6.87048909],
                 [ 4.65410395,  1.99254911],
                 [-8.84903186,  7.33075289]])
          mini batch優(yōu)化方法是通過(guò)減少計(jì)算樣本量來(lái)達(dá)到縮短迭代時(shí)長(zhǎng),另一種方法是降低收斂需要的迭代次數(shù),從而達(dá)到快速收斂的目的。收斂的速度除了取決于每次迭代的變化率之外,另一個(gè)重要指標(biāo)就是迭代起始的位置

          2007年Arthur, David, and Sergei Vassilvitskii三人發(fā)表了論文"k-means++: The advantages of careful seeding"  http://ilpubs.stanford.edu:8090/778/1/2006-13.pdf,他們開(kāi)發(fā)了'k-means++'初始化方案,使得初始質(zhì)心(通常)彼此遠(yuǎn)離,以此來(lái)引導(dǎo)出比隨機(jī)初始化更可靠的結(jié)果。

          'k-means++' 聚類算法

          'k-means++'聚類算法是在KMeans算法基礎(chǔ)上,針對(duì)迭代次數(shù),優(yōu)化選擇初始質(zhì)心的方法。sklearn.cluster.KMeans 中默認(rèn)參數(shù)為 init='k-means++',其算法原理為在初始化簇中心時(shí),逐個(gè)選取 個(gè)簇中心,且離其他簇中心越遠(yuǎn)的樣本越有可能被選為下個(gè)簇中心。

          算法步驟:

          • 從數(shù)據(jù)即 中隨機(jī)(均勻分布)選取一個(gè)樣本點(diǎn)作為第一個(gè)初始聚類中心

          • 計(jì)算每個(gè)樣本與當(dāng)前已有聚類中心之間的最短距離;再計(jì)算每個(gè)樣本點(diǎn)被選為下個(gè)聚類中心的概率,最后選擇最大概率值所對(duì)應(yīng)的樣本點(diǎn)作為下一個(gè)簇中心

          • 重復(fù)上步驟,直到選擇個(gè)聚類中心

          'k-means++'算法初始化的簇中心彼此相距都十分的遠(yuǎn),從而不可能再發(fā)生初始簇中心在同一個(gè)簇中的情況。當(dāng)然'k-means++'本身也具有隨機(jī)性,并不一定每一次隨機(jī)得到的起始點(diǎn)都能有這么好的效果,但是通過(guò)策略,我們可以保證即使出現(xiàn)最壞的情況也不會(huì)太壞。

          'k-means++' code: 

          def InitialCentroid(x, K):
              c1_idx = int(np.random.uniform(0, len(x))) # Draw samples from a uniform distribution.
              centroid = x[c1_idx].reshape(1-1)  # choice the first center for cluster.
              k = 1
              n = x.shape[0# number of samples
              while k < K:
                  d2 = []
                  for i in range(n):
                      subs = centroid - x[i, :]  # D(x) = (x_1, y_1) - (x, y)
                      dimension2 = np.power(subs, 2# D(x)^2
                      dimension_s = np.sum(dimension2, axis=1)  # sum of each row
                      d2.append(np.min(dimension_s))
                  new_c_idx = np.argmax(d2)
                  centroid = np.vstack([centroid, x[new_c_idx]])
                  k += 1
              return centroid

          重要參數(shù)

          初始質(zhì)心

          KMeans算法的第一步"隨機(jī)"在樣本中抽取  個(gè)樣本作為初始質(zhì)心,因此并不符合"穩(wěn)定且更快"的需求。因此可通過(guò)random_state參數(shù)來(lái)指定隨機(jī)數(shù)種子,以控制每次生成的初始質(zhì)心都在相同位置。

          一個(gè)random_state對(duì)應(yīng)一個(gè)質(zhì)心隨機(jī)初始化的隨機(jī)數(shù)種子。如果不指定隨機(jī)數(shù)種子,則 sklearn中的KMeans并不會(huì)只選擇一個(gè)隨機(jī)模式扔出結(jié)果,而會(huì)在每個(gè)隨機(jī)數(shù)種子下運(yùn)行多次,并使用結(jié)果最好的一個(gè)隨機(jī)數(shù)種子來(lái)作為初始質(zhì)心。我們可以使用參數(shù)n_init來(lái)選擇,每個(gè)隨機(jī)數(shù)種子下運(yùn)行的次數(shù)。

          而以上兩種方法仍然避免不了基于隨機(jī)性選取  個(gè)質(zhì)心的本質(zhì)。在sklearn中,我們使用參數(shù)init ='k-means++'來(lái)選擇使用'k-means++'作為質(zhì)心初始化的方案。

          init : 可輸入"k-means++""random"或者一個(gè)n維數(shù)組。這是初始化質(zhì)心的方法,默認(rèn)"k-means++"。輸入"k- means++":一種為K均值聚類選擇初始聚類中心的聰明的辦法,以加速收斂。如果輸入了n維數(shù)組,數(shù)組的形狀應(yīng)該是(n_clusters,n_features)并給出初始質(zhì)心。

          random_state : 控制每次質(zhì)心隨機(jī)初始化的隨機(jī)數(shù)種子。

          n_init : 整數(shù),默認(rèn)10,使用不同的質(zhì)心隨機(jī)初始化的種子來(lái)運(yùn)行KMeans算法的次數(shù)。最終結(jié)果會(huì)是基于Inertia來(lái)計(jì)算的n_init次連續(xù)運(yùn)行后的最佳輸出。

          迭代停止

          max_iter : 整數(shù),默認(rèn)300,單次運(yùn)行的KMeans算法的最大迭代次數(shù)。

          tol : 浮點(diǎn)數(shù),默認(rèn)1e-4,兩次迭代間Inertia下降的量,如果兩次迭代之間Inertia下降的值小于tol所設(shè)定的值,迭代就會(huì)停下。

          衡量指標(biāo)

          聚類模型的結(jié)果不是某種標(biāo)簽輸出,并且聚類的結(jié)果是不確定的,其優(yōu)劣由業(yè)務(wù)需求或者算法需求來(lái)決定,并且沒(méi)有永遠(yuǎn)的正確答案。那么如何衡量聚類的效果呢?

          衡量簇內(nèi)差異來(lái)衡量聚類的效果

          內(nèi)平方和:Total_Inertia

          肘部法(手肘法)認(rèn)為圖上的拐點(diǎn)就是  的最佳值。

          # 應(yīng)用肘部法則確定 kmeans方法中的k
          from scipy.spatial.distance import cdist # 計(jì)算兩個(gè)輸入集合的每對(duì)之間的距離。
          from sklearn.cluster import KMeans
          import matplotlib.pyplot as plt
          import numpy as np
          import pandas as pd
          from sklearn.datasets import make_blobs
          plt.style.use('seaborn')
          plt.rcParams['font.sans-serif']=['Simhei'#顯示中文
          plt.rcParams['axes.unicode_minus']=False #顯示負(fù)號(hào)
          X, y = make_blobs(n_samples=5000, centers=4, cluster_std = 2.5, n_features=2,random_state=42)
          K=range(1,10)

          # 直接計(jì)算sse
          sse_result=[]
          for k in K:
              kmeans=KMeans(n_clusters=k, random_state=666)
              kmeans.fit(X)
              sse_result.append(sum(np.min(cdist(X,kmeans.cluster_centers_,'euclidean'),axis=1))/X.shape[0])
          plt.figure(figsize=(16,5))
          plt.subplot(1,2,1)
          plt.plot(K,sse_result,'gp-')
          plt.xlabel('k',fontsize=20)
          plt.ylabel(u'平均畸變程度')
          plt.title(u'肘部法則確定最佳的K值(1)',fontdict={'fontsize':15})

          # 第二種,使用inertia_
          L = []
          for k in K:
              kmeans = KMeans(n_clusters=k, random_state=666)
              kmeans.fit(X)
              L.append((k, kmeans.inertia_))
          a = pd.DataFrame(L)
          a.columns = ['k''inertia']
          plt.subplot(1,2,2)
          plt.plot(a.k, a.inertia,'gp-')
          plt.xlabel('k',fontsize=20)
          plt.ylabel('inertia')
          plt.title(u'肘部法則確定最佳的K值(2)',fontdict={'fontsize':15})
          plt.xticks(a.k)
          plt.show();

          輸出結(jié)果:

          但其有很大的局限:

          • 它的計(jì)算太容易受到特征數(shù)目的影響。
          • 它不是有界的,Inertia是越小越好,但并不知道合適達(dá)到模型的極限,能否繼續(xù)提高。
          • 它會(huì)受到超參數(shù)  的影響,隨著  越大,Inertia注定會(huì)越來(lái)越小,但并不代表模型效果越來(lái)越好。
          • Inertia對(duì)數(shù)據(jù)的分布有假設(shè),它假設(shè)數(shù)據(jù)滿足凸分布,并且它假設(shè)數(shù)據(jù)是各向同性的( isotropic),所以使用Inertia作為評(píng)估指標(biāo),會(huì)讓聚類算法在一些細(xì)長(zhǎng)簇,環(huán)形簇,或者不規(guī)則形狀的流形時(shí)表現(xiàn)不佳。

          其他衡量指標(biāo)

          1、真實(shí)標(biāo)簽已知時(shí)

          可以用聚類算法的結(jié)果和真實(shí)結(jié)果來(lái)衡量聚類的效果。但需要用到聚類分析的場(chǎng)景,大部分均屬于無(wú)真實(shí)標(biāo)簽的情況,因此以下模型評(píng)估指標(biāo)了解即可

          模型評(píng)估指標(biāo)說(shuō)明
          互信息分

          普通互信息分
          metrics.adjusted_mutual_info_score (y_pred, y_true)
          調(diào)整的互信息分
          metrics.mutual_info_score (y_pred, y_true)
          標(biāo)準(zhǔn)化互信息分
          metrics.normalized_mutual_info_score (y_pred, y_true)
          取值范圍在(0,1)之中越接近1,
          聚類效果越好在隨機(jī)均勻聚類下產(chǎn)生0分。
          V-measure:基于條件上分析的一系列直觀度量

          同質(zhì)性:是否每個(gè)簇僅包含單個(gè)類的樣本
          metrics.homogeneity_score(y_true, y_pred)
          完整性:是否給定類的所有樣本都被分配給同一個(gè)簇中
          metrics.completeness_score(y_true, y_pred) 
          同質(zhì)性和完整性的調(diào)和平均,叫做V-measure
          metrics.v_measure_score(labels_true, labels_pred)
          三者可以被一次性計(jì)算出來(lái):
          metrics.homogeneity_completeness_v_measure(labels_true, labels_pred)
          取值范圍在(0,1)之中越接近1,
          聚類效果越好由于分為同質(zhì)性和完整性兩種度量,可以更仔細(xì)地研究,模型到底哪個(gè)任務(wù)做得不夠好。對(duì)樣本分布沒(méi)有假設(shè),在任何分布上都可以有不錯(cuò)的表現(xiàn)在隨機(jī)均勻聚類下不會(huì)產(chǎn)生0分。
          調(diào)整蘭德系數(shù)
          metrics.adjusted_rand_score(y_true, y_pred)
          取值在(-1,1)之間,負(fù)值象征著簇內(nèi)的點(diǎn)差異巨大,甚至相互獨(dú)立,正類的 蘭德系數(shù)比較優(yōu)秀,
          越接近1越好對(duì)樣本分布沒(méi)有假設(shè),在任何分布上都可以有不錯(cuò)的表現(xiàn),尤其是在具有"折疊"形狀的數(shù)據(jù)上表現(xiàn)優(yōu)秀,在隨機(jī)均勻聚類下產(chǎn)生0分。
          2、真實(shí)標(biāo)簽未知時(shí)
          • 輪廓系數(shù)

          對(duì)沒(méi)有真實(shí)標(biāo)簽的數(shù)據(jù)進(jìn)行探索,常用輪廓系數(shù)評(píng)價(jià)聚類算法模型效果。

          • 樣本與其自身所在的簇中的其他樣本的相似度a,等于樣本與同一簇中所有其他點(diǎn)之間的平均距離 。

          • 樣本與其他簇中的樣本的相似度b,等于樣本與下一個(gè)最近的簇中的所有點(diǎn)之間的平均距離。

          根據(jù)聚類的要求"簇內(nèi)差異小,簇外差異大",我們希望b永遠(yuǎn)大于a,并且大得越多越好。單個(gè)樣本的輪廓系數(shù)計(jì)算為:
          取值范圍越大越好。
          • 越接近 1 表示樣本與自己所在的簇中的樣本很相似,并且與其他簇中的樣本不相似,當(dāng)樣本點(diǎn)與簇外的樣本更相似的時(shí)候,輪廓系數(shù)就為負(fù)。

          • 當(dāng)輪廓系數(shù)為 0 時(shí),則代表兩個(gè)簇中的樣本相似度一致,兩個(gè)簇本應(yīng)該是一個(gè)簇。

          語(yǔ)法:

          from sklearn.metrics import silhouette_score
          # 返回所有樣本的輪廓系數(shù)的均值
          from sklearn.metrics import silhouette_samples
          # 返回的是數(shù)據(jù)集中每個(gè)樣本自己的輪廓系數(shù)
          silhouette_score(X,y_pred)
          silhouette_score(X,cluster_.labels_)
          silhouette_samples(X,y_pred)

          例:

          L = []
          for i in range(220):
              k = i
              kmeans = KMeans(n_clusters=i)
              kmeans.fit(X)
              L.append([i, silhouette_score(X, kmeans.labels_)])
          a = pd.DataFrame(L)
          a.columns = ['k''輪廓系數(shù)']
          plt.figure(figsize=(85), dpi=70)
          plt.plot(a.k, a.輪廓系數(shù),'gp-')
          plt.xticks(a.k)
          plt.xlabel('k')
          plt.ylabel('輪廓系數(shù)')
          plt.title('輪廓系數(shù)確定最佳的K值',fontdict={'fontsize':15})

          輸出結(jié)果:

          輪廓系數(shù)看出,k=3時(shí)輪廓系數(shù)最大,肘部法的拐點(diǎn)亦是k=3,從數(shù)據(jù)集可視化圖(文末案例)中也能看出數(shù)據(jù)集可以清洗分割3個(gè)簇(雖然初始創(chuàng)建了四個(gè)簇,但上面兩個(gè)簇邊界并不清晰,幾乎連到一起)。

          輪廓系數(shù)有很多優(yōu)點(diǎn),它在有限空間中取值,使得我們對(duì)模型的聚類效果有一個(gè)"參考"。并且輪廓系數(shù)對(duì)數(shù)據(jù)的分布沒(méi)有假設(shè),因此在很多數(shù)據(jù)集上都表現(xiàn)良好。但它在每個(gè)簇的分割比較清洗時(shí)表現(xiàn)最好。

          • 其它評(píng)估指標(biāo)
          評(píng)估指標(biāo)sklearn.metrics
          卡林斯基-哈拉巴斯指數(shù)
          Calinski-Harabaz Index
          calinski_harabaz_score (X, y_pred)
          戴維斯-布爾丁指數(shù)
          Davies-Bouldin
          davies_bouldin_score (X, y_pred)
          權(quán)變矩陣
          Contingency
          cluster.contingency_matrix (X, y_pred)

          這里簡(jiǎn)單介紹卡林斯基-哈拉巴斯指數(shù),有 個(gè)簇的聚類而言, Calinski-Harabaz指數(shù)寫作如下公式:

          其中為數(shù)據(jù)集中的樣本量,為簇的個(gè)數(shù)(即類別的個(gè)數(shù)), 是組間離散矩陣,即不同簇之間的協(xié)方差矩陣, 是簇內(nèi)離散矩陣,即一個(gè)簇內(nèi)數(shù)據(jù)的協(xié)方差矩陣,而表示矩陣的跡。在線性代數(shù)中,一個(gè)矩陣的主對(duì)角線(從左上方至右下方的對(duì)角線)上各個(gè)元素的總和被稱為矩陣A的跡(或跡數(shù)),一般記作

          數(shù)據(jù)之間的離散程度越高,協(xié)方差矩陣的跡就會(huì)越大。組內(nèi)離散程度低,協(xié)方差的跡就會(huì)越小,也就越小,同時(shí),組間離散程度大,協(xié)方差的的跡也會(huì)越大,就越大,因此Calinski-harabaz指數(shù)越高越好。

          雖然calinski-Harabaz指數(shù)沒(méi)有界,在凸型的數(shù)據(jù)上的聚類也會(huì)表現(xiàn)虛高。但是比起輪廓系數(shù),其計(jì)算非常快速。

          案例

          from sklearn.cluster import KMeans
          from sklearn.metrics import silhouette_samples, silhouette_score
          import matplotlib.pyplot as plt
          import matplotlib.cm as cm
          import numpy as np
          import pandas as pd
          from sklearn.datasets import make_blobs
          X, y = make_blobs(n_samples=6000, centers=4, cluster_std = 2.5, n_features=2,center_box=(-12.012.0),
                            random_state=42)
          data = pd.DataFrame(X)
          fig, axes = plt.subplots(32)
          fig.set_size_inches(1827)
          n_clusters = 2
          for i in range(3):
              for j in range(2):
                  n_clusters = n_clusters
                  clusterer = KMeans(n_clusters=n_clusters, random_state=10).fit(X)
                  cluster_labels = clusterer.labels_
                  silhouette_avg = silhouette_score(X, cluster_labels)
                  print("For n_clusters =", n_clusters,
                        "The average silhouette_score is :", silhouette_avg)
                  sample_silhouette_values = silhouette_samples(X, cluster_labels)
                  colors = cm.nipy_spectral(cluster_labels.astype(float) / n_clusters)
                  axes[i,j].scatter(X[:, 0], X[:, 1]
                              ,marker='o'
                              ,s=8
                              ,c=colors
                             )
                  centers = clusterer.cluster_centers_
                  axes[i,j].scatter(centers[:, 0], centers[:, 1], marker='x',
                              c="red", alpha=1, s=200)
                  axes[i,j].set_title(f"The visualization of the clustered data when n_Clusters = {n_clusters}.")
                  axes[i,j].set_xlabel("Feature space for the 1st feature")
                  axes[i,j].set_ylabel("Feature space for the 2nd feature")
                  axes[i,j].text(0,-17,f"The average silhouette_score is :\n\n{silhouette_avg}",fontsize=10)
                  n_clusters += 1
          plt.show()

          輸出結(jié)果:

          擴(kuò)展--其他聚類算法

          DBSCAN

          從向量數(shù)組或距離矩陣執(zhí)行DBSCAN聚類。

          一種基于密度的帶有噪聲的空間聚類  。它將簇定義為密度相連的點(diǎn)的最大集合,能夠把具有足夠高密度的區(qū)域劃分為簇,并可在噪聲的空間數(shù)據(jù)集中發(fā)現(xiàn)任意形狀的聚類。

          基于密度的空間聚類與噪聲應(yīng)用。尋找高密度的核心樣本,并從中擴(kuò)展星團(tuán)。適用于包含相似密度的簇的數(shù)據(jù)。

          DBSCAN算法將聚類視為由低密度區(qū)域分隔的高密度區(qū)域。由于這種相當(dāng)通用的觀點(diǎn),DBSCAN發(fā)現(xiàn)的集群可以是任何形狀,而k-means假設(shè)集群是凸形的。DBSCAN的核心組件是核心樣本的概念,即位于高密度區(qū)域的樣本。因此,一個(gè)集群是一組彼此接近的核心樣本(通過(guò)一定的距離度量)和一組與核心樣本相近的非核心樣本(但它們本身不是核心樣本)。算法有兩個(gè)參數(shù),min_sampleseps,它們正式定義了我們所說(shuō)的密集。較高的min_samples或較低的eps表示較高的密度需要形成一個(gè)集群。

          根據(jù)定義,任何核心樣本都是集群的一部分。任何非核心樣本,且與核心樣本的距離至少為eps的樣本,都被算法認(rèn)為是離群值。

          而主要控制參數(shù)min_samples寬容的算法對(duì)噪聲(在嘈雜和大型數(shù)據(jù)集可能需要增加此參數(shù)),選擇適當(dāng)?shù)膮?shù)eps至關(guān)重要的數(shù)據(jù)集和距離函數(shù),通常不能在默認(rèn)值。它控制著點(diǎn)的局部鄰域。如果選擇的數(shù)據(jù)太小,大多數(shù)數(shù)據(jù)根本不會(huì)聚集在一起(并且標(biāo)記為-1表示"噪音")。如果選擇太大,則會(huì)導(dǎo)致關(guān)閉的集群合并為一個(gè)集群,并最終將整個(gè)數(shù)據(jù)集作為單個(gè)集群返回。

          例:

          >>> from sklearn.cluster import DBSCAN
          >>> import numpy as np
          >>> X = np.array([[12], [22], [23],
          ...               [87], [88], [2580]])
          >>> clustering = DBSCAN(eps=3, min_samples=2).fit(X)
          >>> clustering.labels_
          array([ 0,  0,  0,  1,  1-1])
          >>> clustering
          DBSCAN(eps=3, min_samples=2)

          eps float, default=0.5

          兩個(gè)樣本之間的最大距離,其中一個(gè)樣本被認(rèn)為是相鄰的。這不是集群內(nèi)點(diǎn)的距離的最大值,這是為您的數(shù)據(jù)集和距離函數(shù)選擇的最重要的DBSCAN參數(shù)。

          min_samples int, default=5

          被視為核心點(diǎn)的某一鄰域內(nèi)的樣本數(shù)(或總權(quán)重)。這包括點(diǎn)本身。

          更多DBSCAN聚類請(qǐng)參見(jiàn)

          https://scikit-learn.org/stable/modules/generated/sklearn.cluster.DBSCAN.html#sklearn.cluster.DBSCAN

          層次聚類

          層次聚類Hierarchical Clustering 通過(guò)計(jì)算不同類別數(shù)據(jù)點(diǎn)間的相似度來(lái)創(chuàng)建一棵有層次的嵌套聚類樹(shù)。在聚類樹(shù)中,不同類別的原始數(shù)據(jù)點(diǎn)是樹(shù)的最低層,樹(shù)的頂層是一個(gè)聚類的根節(jié)點(diǎn)。創(chuàng)建聚類樹(shù)有自下而上合并和自上而下分裂兩種方法。

          層次聚類的合并算法通過(guò)計(jì)算兩類數(shù)據(jù)點(diǎn)間的相似性,對(duì)所有數(shù)據(jù)點(diǎn)中最為相似的兩個(gè)數(shù)據(jù)點(diǎn)進(jìn)行組合,并反復(fù)迭代這一過(guò)程。

          簡(jiǎn)單來(lái)說(shuō)   通過(guò)計(jì)算每一個(gè)類別的數(shù)據(jù)點(diǎn)與所有數(shù)據(jù)點(diǎn)之間的歐式距離來(lái)確定它們之間的相似性,距離越小,相似度越高  。并將距離最近的兩個(gè)數(shù)據(jù)點(diǎn)或類別進(jìn)行組合,生成聚類樹(shù)。

          例:

          >>> from sklearn.cluster import AgglomerativeClustering
          >>> import numpy as np
          >>> X = np.array([[12], [14], [10],
          ...               [42], [44], [40]])
          >>> clustering = AgglomerativeClustering().fit(X)
          >>> clustering
          AgglomerativeClustering()
          >>> clustering.labels_
          array([111000])

          層次化聚類是一種通用的聚類算法,它通過(guò)合并或分割來(lái)構(gòu)建嵌套的聚類。集群的層次結(jié)構(gòu)表示為樹(shù)(或樹(shù)狀圖)。樹(shù)的根是收集所有樣本的唯一集群,葉子是只有一個(gè)樣本的集群。

          聚類對(duì)象使用自底向上的方法執(zhí)行分層聚類: 每個(gè)觀察從它自己的聚類開(kāi)始,然后聚類依次合并在一起。連接標(biāo)準(zhǔn)決定了用于合并策略的度量。

          • 最大或完全連接使簇對(duì)觀測(cè)之間的最大距離最小。
          • 平均連接使簇對(duì)的所有觀測(cè)值之間的平均距離最小化。
          • 單連接使簇對(duì)的最近觀測(cè)值之間的距離最小。
          • 當(dāng)與連通性矩陣聯(lián)合使用時(shí),團(tuán)聚向量聚合也可以擴(kuò)展到大量的樣本,但是當(dāng)樣本之間不加連通性約束時(shí),計(jì)算開(kāi)銷就大了:它在每一步都考慮所有可能的合并。

          更多層次聚類請(qǐng)參見(jiàn)

          https://scikit-learn.org/stable/modules/generated/sklearn.cluster.AgglomerativeClustering.html#sklearn.cluster.AgglomerativeClustering

          附錄

          KMeans參數(shù)

          • n_clusters int, default=8

            要聚成的簇?cái)?shù),以及要生成的質(zhì)心數(shù)。

          • init {‘k-means++’, ‘random’, ndarray, callable}, default=’k-means++’

            這是初始化質(zhì)心的方法,輸入"k- means++": 一種為K均值聚類選擇初始聚類中心的聰明的辦法,以加速收斂。如果輸入了n維數(shù)組,數(shù)組的形狀應(yīng)該是(n_clusters,n_features)并給出初始質(zhì)心。

          • n_init int, default=10

            使用不同的質(zhì)心隨機(jī)初始化的種子來(lái)運(yùn)行KMeans算法的次數(shù)。最終結(jié)果會(huì)是基于Inertia來(lái)計(jì)算的n_init次連續(xù)運(yùn)行后的最佳輸出。

          • max_iter int, default=300

            單次運(yùn)行的KMeans算法的最大迭代次數(shù)。

          • tol float, default=1e-4

            兩次迭代間Inertia下降的量,如果兩次迭代之間Inertia下降的值小于tol所設(shè)定的值,迭代就會(huì)停下。

          • precompute_distances {‘a(chǎn)uto’, True, False}, default=’auto’

            預(yù)計(jì)算距離(更快,但需要更多內(nèi)存)。

            'auto': 如果 n_samples * n_clusters > 1200萬(wàn),不要預(yù)先計(jì)算距離。這對(duì)應(yīng)于使用雙精度來(lái)學(xué)習(xí),每個(gè)作業(yè)大約100MB的內(nèi)存開(kāi)銷。

            True: 始終預(yù)先計(jì)算距離。False:從不預(yù)先計(jì)算距離。

          • verbose int, default=0

            計(jì)算中的詳細(xì)模式。

          • random_state int, RandomState instance, default=None

            確定質(zhì)心初始化的隨機(jī)數(shù)生成。使用int可以是隨機(jī)性更具有確定性。

          • copy_x bool, default=True

            在預(yù)計(jì)算距離時(shí),若先中心化數(shù)據(jù),距離的預(yù)計(jì)算會(huì)更加準(zhǔn)確。如果copy_xTrue(默認(rèn)值),則不會(huì)修改原始數(shù)據(jù),確保特征矩陣X是c-contiguous。如果為False,則對(duì)原始數(shù)據(jù)進(jìn)行修改,在函數(shù)返回之前放回原始數(shù)據(jù),但可以通過(guò)減去數(shù)據(jù)平均值,再加上數(shù)據(jù)平均值,引入較小的數(shù)值差異。注意,如果原始數(shù)據(jù)不是c -連續(xù)的,即使copy_xFalse,也會(huì)復(fù)制,這可能導(dǎo)致KMeans 計(jì)算量顯著變慢。如果原始數(shù)據(jù)是稀疏的,但不是CSR格式的,即使copy_xFalse的,也會(huì)復(fù)制一份。

          • n_jobs int, default=None

            用于計(jì)算的作業(yè)數(shù)。計(jì)算每個(gè)n_init時(shí)并行作業(yè)數(shù)。

            這個(gè)參數(shù)允許KMeans在多個(gè)作業(yè)線上并行運(yùn)行。給這個(gè)參數(shù)正值n_jobs,表示使用 n_jobs 條處理器中的線程。值-1表示使用所用可用的處理器。值-2表示使用所有可能的處理器-1個(gè)處理器,以此類推。并行化通常以內(nèi)存為代價(jià)增加計(jì)算(這種情況下,需要存儲(chǔ)多個(gè)質(zhì)心副本,每個(gè)作業(yè)一個(gè))

          • algorithm {“auto”, “full”, “elkan”}, default=”auto”

            使用KMeans算法。經(jīng)典的EM風(fēng)格的算法是"full"的。通過(guò)使用三角不等式,"elkan"變異在具有定義明確的集群的數(shù)據(jù)上更有效。然而,由于分配了額外的形狀數(shù)組(n_samples、n_clusters),它會(huì)占用更多的內(nèi)存。目前,"auto" 為密集數(shù)據(jù)選擇 "elkan" 為稀疏數(shù)據(jù)選擇"full"

          KMeans屬性

          • cluster_centers_ ndarray of shape (n_clusters, n_features)

            收斂到的質(zhì)心坐標(biāo)。如果算法在完全收斂之前已停止(受到'tol''max_iter'參數(shù)的控制),這些返回的內(nèi)容將與'labels_'中反應(yīng)出的聚類結(jié)果不一致。

          • labels_ ndarray of shape (n_samples,)

            每個(gè)樣本對(duì)應(yīng)的標(biāo)簽。

          • inertia_ float

            每個(gè)樣本點(diǎn)到它們最近的簇中心的距離的平方的和,又叫做"簇內(nèi)平方和"。

          • n_iter_ int

            實(shí)際迭代的次數(shù)。

          點(diǎn)贊+留言+轉(zhuǎn)發(fā),就是對(duì)我最大的支持啦~


          --End--


          文章點(diǎn)贊超過(guò)100+

          我將在個(gè)人視頻號(hào)直播(老表Max)

          帶大家一起進(jìn)行項(xiàng)目實(shí)戰(zhàn)復(fù)現(xiàn)



          掃碼即可加我微信

          老表朋友圈經(jīng)常有贈(zèng)書/紅包福利活動(dòng)

          點(diǎn)擊上方卡片關(guān)注公眾號(hào),回復(fù):1024
          領(lǐng)取最新Python學(xué)習(xí)資源

          學(xué)習(xí)更多:
          整理了我開(kāi)始分享學(xué)習(xí)筆記到現(xiàn)在超過(guò)250篇優(yōu)質(zhì)文章,涵蓋數(shù)據(jù)分析、爬蟲(chóng)、機(jī)器學(xué)習(xí)等方面,別再說(shuō)不知道該從哪開(kāi)始,實(shí)戰(zhàn)哪里找了
          點(diǎn)贊”就是對(duì)博主最大的支持 
          瀏覽 70
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          評(píng)論
          圖片
          表情
          推薦
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  毛片网站大全免费在线观看 | 欧美第一页福利 | 日本成人三级片在线观看 | 青青草人人操人人摸人人干 | 亚洲永久精品视频 |