日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 编程语言 > python >内容正文

python

以《简单易懂》的语言带你搞懂无监督学习算法【附Python代码详解】机器学习系列之K-Means篇

發(fā)布時(shí)間:2023/12/18 python 27 豆豆
生活随笔 收集整理的這篇文章主要介紹了 以《简单易懂》的语言带你搞懂无监督学习算法【附Python代码详解】机器学习系列之K-Means篇 小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

大家早上好,本人姓吳,如果覺(jué)得文章寫(xiě)得還行的話也可以叫我吳老師。歡迎大家跟我一起走進(jìn)數(shù)據(jù)分析的世界,一起學(xué)習(xí)!

感興趣的朋友可以關(guān)注我或者我的數(shù)據(jù)分析專(zhuān)欄,里面有許多優(yōu)質(zhì)的文章跟大家分享哦。


目錄

  • 必看前言
  • 無(wú)監(jiān)督學(xué)習(xí)算法
    • 1 聚類(lèi)與分類(lèi)
    • 2 K-Means算法
      • 2.1 K-Means的基本原理
        • 2.1.1 K-Means 是如何工作的?
        • 2.1.2 簇內(nèi)誤差平方和的定義
      • 2.2 K-Means算法的python實(shí)現(xiàn)
        • 2.2.1 導(dǎo)入數(shù)據(jù)集
        • 2.2.2 編寫(xiě)距離計(jì)算函數(shù)
        • 2.2.3 編寫(xiě)隨機(jī)生成質(zhì)心函數(shù)
        • 2.2.4 編寫(xiě) K-Means 聚類(lèi)函數(shù)
        • 2.2.5 算法驗(yàn)證
  • 結(jié)束語(yǔ)

必看前言

今天這一篇文章,將跟大家分享一下無(wú)監(jiān)督學(xué)習(xí)算法。

而本文將試圖用簡(jiǎn)單易懂的語(yǔ)言來(lái)講說(shuō)到底什么是無(wú)監(jiān)督學(xué)習(xí)算法,同時(shí)主要會(huì)以KMeans算法為例,跟大家詳細(xì)地說(shuō)明。

無(wú)監(jiān)督學(xué)習(xí)算法

決策樹(shù)、線性和邏輯回歸都是比較常用的機(jī)器學(xué)習(xí)算法,他們雖然有著不同的功能,但卻都屬于“有監(jiān)督學(xué)習(xí)” 的?部分,即是說(shuō),模型在訓(xùn)練的時(shí)候,即需要特征矩陣X,也需要真實(shí)標(biāo)簽y。機(jī)器學(xué)習(xí)當(dāng)中,還有相當(dāng)?部分算法屬于 “無(wú)監(jiān)督學(xué)習(xí)” ,無(wú)監(jiān)督的算法在訓(xùn)練的時(shí)候只需要特征矩陣X,不需要標(biāo)簽。無(wú)監(jiān)督學(xué)習(xí)的代表算法有聚類(lèi)算法、降維算法。

聚類(lèi)算法又叫做“無(wú)監(jiān)督分類(lèi)”,其目的是將數(shù)據(jù)劃分成有意義或有用的組(或簇)。這種劃分可以基于我們的業(yè)務(wù)需求或建模需求來(lái)完成,也可以單純地幫助我們探索數(shù)據(jù)的自然結(jié)構(gòu)和分布。

比如在商業(yè)中,如果我們手頭有大量的當(dāng)前和潛在客戶的信息,我們可以使用聚類(lèi)將客戶劃分為若干組,以便進(jìn)一步分析和開(kāi)展?fàn)I銷(xiāo)活動(dòng),最有名的客戶價(jià)值判斷模型RFM(Recency Frequency Monetary),就常常和聚類(lèi)分析共同使用。再比如,聚類(lèi)可以用于降維和矢量量化(vectorquantization),可以將高維特征壓縮到一列當(dāng)中,常常用于圖像,聲音,視頻等非結(jié)構(gòu)化數(shù)據(jù),可以大幅度壓縮數(shù)據(jù)量。

1 聚類(lèi)與分類(lèi)

?聚類(lèi)分類(lèi)
核心將數(shù)據(jù)分成多個(gè)組,探索每個(gè)組的數(shù)據(jù)是否有聯(lián)系從已經(jīng)分組的數(shù)據(jù)中去學(xué)習(xí),把新數(shù)據(jù)放到已經(jīng)分好的組中
學(xué)習(xí)類(lèi)型無(wú)監(jiān)督,無(wú)需標(biāo)簽進(jìn)行訓(xùn)練有監(jiān)督,需要標(biāo)簽進(jìn)行訓(xùn)練
典型算法K-Means, DBSCAN, 層次聚類(lèi),光譜聚類(lèi)決策樹(shù),貝葉斯,邏輯回歸
算法輸出聚類(lèi)結(jié)果是不確定的,不一定總是能夠反映數(shù)據(jù)的真實(shí)分類(lèi),同樣的分類(lèi)根據(jù)不同的業(yè)務(wù)需求可能是好結(jié)果也可能是壞結(jié)果分類(lèi)結(jié)果是確定的,分類(lèi)的優(yōu)劣是客觀的,不是根據(jù)業(yè)務(wù)或算法需求來(lái)決定的

聚類(lèi)算法是無(wú)監(jiān)督類(lèi)機(jī)器學(xué)習(xí)算法中最常用的?類(lèi),其目的是將數(shù)據(jù)劃分成有意義或有用的組(也被稱(chēng)為簇)。這種劃分可以基于我們的業(yè)務(wù)需求或建模需求來(lái)完成,也可以單純地幫助我們探索數(shù)據(jù)的自然結(jié)構(gòu)和分布。如果目標(biāo)是劃分成有意義的組,則簇應(yīng)當(dāng)捕獲數(shù)據(jù)的自然結(jié)構(gòu)。然而,在某種意義下,聚類(lèi)分析只是解決其他問(wèn)題(如數(shù)據(jù)匯總)的起點(diǎn)。無(wú)論是旨在理解還是應(yīng)用,聚類(lèi)分析都在廣泛的領(lǐng)域扮演著重要角色。這些領(lǐng)域包括:心理學(xué)和其他社會(huì)科學(xué)、生物學(xué)、統(tǒng)計(jì)學(xué)、模式識(shí)別、信息檢索、機(jī)器學(xué)習(xí)和數(shù)據(jù)挖掘。

那么接下來(lái),我會(huì)詳細(xì)講解無(wú)監(jiān)督學(xué)習(xí)算法中的K-Means算法,來(lái)借此幫助大家了解K-Means算法。

2 K-Means算法

2.1 K-Means的基本原理

2.1.1 K-Means 是如何工作的?

  • 關(guān)鍵概念:簇和質(zhì)心

KMeans 算法將一組 N 個(gè)樣本的特征矩陣 X 劃分為 K 個(gè)無(wú)交集的簇,直觀上來(lái)看是簇是一組一組聚集在一起的數(shù)據(jù),在一個(gè)簇中的數(shù)據(jù)就認(rèn)為是同一類(lèi)。簇就是聚類(lèi)的結(jié)果表現(xiàn)。

簇中所有數(shù)據(jù)的均值通常被稱(chēng)為這個(gè)簇的“質(zhì)心”(centroids)。在一個(gè)二維平面中,一簇?cái)?shù)據(jù)點(diǎn)的質(zhì)心的橫坐標(biāo)就是這一簇?cái)?shù)據(jù)點(diǎn)的橫坐標(biāo)的均值,質(zhì)心的縱坐標(biāo)就是這一簇?cái)?shù)據(jù)點(diǎn)的縱坐標(biāo)的均值。同理可推廣至高維空間。

在 KMeans 算法中,簇的個(gè)數(shù) K 是一個(gè)超參數(shù),需要我們?nèi)藶檩斎雭?lái)確定。KMeans 的核心任務(wù)就是根據(jù)我們?cè)O(shè)定好的 K,找出 K 個(gè)最優(yōu)的質(zhì)心,并將離這些質(zhì)心最近的數(shù)據(jù)分別分配到這些質(zhì)心代表的簇中去。

具體過(guò)程可以總結(jié)如下:

  • 創(chuàng)建 k 個(gè)點(diǎn)作為初始質(zhì)心(通常是隨機(jī)選擇)
  • 當(dāng)任意一個(gè)點(diǎn)的簇分配結(jié)果發(fā)生改變時(shí):
    ? 計(jì)算質(zhì)心與數(shù)據(jù)點(diǎn)之間的距離
    ? 將數(shù)據(jù)點(diǎn)分配到據(jù)其最近的簇
  • 對(duì)每個(gè)簇,計(jì)算簇中所有點(diǎn)的均值并將均值作為新的質(zhì)心
  • 直到簇不再發(fā)生變化或者達(dá)到最大迭代次數(shù)
  • 那什么情況下,質(zhì)心的位置會(huì)不再變化呢?

    當(dāng)我們找到一個(gè)質(zhì)心,在每次迭代中被分配到這個(gè)質(zhì)心上的樣本都是一致的,即每次新生成的簇都是一致的,所有的樣本點(diǎn)都不會(huì)再?gòu)囊粋€(gè)簇轉(zhuǎn)移到另一個(gè)簇,質(zhì)心就不會(huì)變化了。

    下面我們可以看到例題:

    我們先來(lái)看下思路(其實(shí)也就是上面提到的):

    然后看下解題過(guò)程:


    總之,我感覺(jué)K-Means這一整個(gè)流程還是非常容易理解和實(shí)現(xiàn)的。

    那接下來(lái),我們來(lái)講一下聚類(lèi)算法聚出的類(lèi)有什么含義。

    2.1.2 簇內(nèi)誤差平方和的定義

    聚類(lèi)算法聚出的類(lèi)有什么含義?這些類(lèi)有什么樣的性質(zhì)?我們認(rèn)為,被分在同一個(gè)簇中的數(shù)據(jù)是有相似性的,而不同簇中的數(shù)據(jù)是不同的,當(dāng)聚類(lèi)完畢之后,我們就要分別去研究每個(gè)簇中的樣本都有什么樣的性質(zhì),從而根據(jù)業(yè)務(wù)需求制定不同的商業(yè)或者科技策略。

    聚類(lèi)算法的目的就是追求“簇內(nèi)差異小,簇外差異大”(圈起來(lái),下次要考)。而這個(gè)“差異“,由樣本點(diǎn)到其所在簇的質(zhì)心的距離來(lái)衡量。

    對(duì)于一個(gè)簇來(lái)說(shuō),所有樣本點(diǎn)到質(zhì)心的距離之和越小,我們就認(rèn)為這個(gè)簇中的樣本越相似,簇內(nèi)差異就越小。而距離的衡量方法有多種,令:
    ? x 表示簇中的一個(gè)樣本點(diǎn);
    ? μ表示該簇中的質(zhì)心;
    ? n 表示每個(gè)樣本點(diǎn)中的特征數(shù)目;
    ? i 表示組成點(diǎn) x 的每個(gè)特征編號(hào);

    則該樣本點(diǎn)到質(zhì)心的距離可以由以下距離來(lái)度量:

    • 歐幾里得距離:d(x,u)=∑i=1n(xi?ui)2d(x,u)=\sqrt{}{\sum^{n}_{i=1}{(x_i-u_i)^2}}d(x,u)=?i=1n?(xi??ui?)2
    • 曼哈頓距離:d(x,u)=∑i=1n(∣xi?ui∣)d(x,u)=\sum^{n}_{i=1}{(|x_i- u_i|)}d(x,u)=i=1n?(xi??ui?)
    • 余弦距離:cosθ=∑1n(i?u)∑1n(xi)2?∑1n(ui)2cos\theta=\frac{\sum^n_1(_i*u)}{\sqrt{}{\sum^n_1(x_i)^2}*\sqrt{}{\sum^n_1(u_i)^2}}cosθ=?1n?(xi?)2??1n?(ui?)21n?(i??u)?

    如我們采用歐幾里得距離,則一個(gè)簇中所有樣本點(diǎn)到質(zhì)心的距離的平方和為:ClusterSumofSquare(CSS)=∑j=0m∑i=1n(xi?ui)2Cluster \, Sum \, of \, Square(CSS)=\sum^{m}_{j=0}\sum^{n}_{i=1}{(x_i-u_i)^2}ClusterSumofSquare(CSS)=j=0m?i=1n?(xi??ui?)2? 其中,m 為一個(gè)簇中樣本的個(gè)數(shù);
    ? j 是每個(gè)樣本的編號(hào);

    這個(gè)公式被稱(chēng)為簇內(nèi)平方和(cluster Sum of Square),又叫做 Inertia。

    而將一個(gè)數(shù)據(jù)集中的所有簇的簇內(nèi)平方和相加,就得到了整體平方和(Total Cluster Sum of
    Square),又叫做total inertia:TotalClusterSumofSquare=∑i=1kCSSlTotal \, Cluster \, Sum \, of \, Square=\sum^{k}_{i=1}{CSS_l}TotalClusterSumofSquare=i=1k?CSSl?Total Inertia 越小,代表著每個(gè)簇內(nèi)樣本越相似,聚類(lèi)的效果就越好。(記住,后期會(huì)考!)

    因此 KMeans 追求的是,求解能夠讓 Inertia 最小化的質(zhì)心。

    實(shí)際上,在質(zhì)心不斷變化不斷迭代的過(guò)程中,總體平方和是越來(lái)越小的。當(dāng)整體平方和最小的時(shí)候,質(zhì)心就不再發(fā)生變化了

    大家可以發(fā)現(xiàn),我們的 Inertia 是基于歐幾里得距離的計(jì)算公式得來(lái)的。實(shí)際上,我們也可以使用其他距離,每個(gè)距離都有自己對(duì)應(yīng)的 Inertia。在過(guò)去的經(jīng)驗(yàn)中,我們總結(jié)出不同距離所對(duì)應(yīng)的質(zhì)心選擇方法和 Inertia,在Kmeans 中,只要使用了正確的質(zhì)心和距離組合,無(wú)論使用什么樣的距離,都可以達(dá)到不錯(cuò)的聚類(lèi)效果:

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

    而這些組合,都可以由嚴(yán)格的數(shù)學(xué)證明來(lái)推導(dǎo)。在實(shí)際中我們往往都使用歐式距離,因此我們也無(wú)需去擔(dān)憂這些距離所搭配的質(zhì)心選擇是如何得來(lái)的了。

    2.2 K-Means算法的python實(shí)現(xiàn)

    那同樣的,老規(guī)矩,我們嘗試用Python來(lái)實(shí)現(xiàn)Kmeans算法。

    import numpy as np import pandas as pd import matplotlib.pyplot as plt from IPython.core.interactiveshell import InteractiveShell InteractiveShell.ast_node_interactivity = "all" # 解決坐標(biāo)軸刻度負(fù)號(hào)亂碼 plt.rcParams['axes.unicode_minus'] = False# 解決中文亂碼問(wèn)題 plt.rcParams['font.sans-serif'] = ['Simhei']

    2.2.1 導(dǎo)入數(shù)據(jù)集

    此處先以經(jīng)典的鳶尾花數(shù)據(jù)集為例,來(lái)幫助我們建模,數(shù)據(jù)存放在 iris.txt 中。

    import numpy as np import pandas as pd import matplotlib as mpl import matplotlib.pyplot as plt %matplotlib inline #導(dǎo)入數(shù)據(jù)集 iris = pd.read_csv("iris.txt",header = None) iris


    這里最后一類(lèi)呢是標(biāo)簽,不過(guò)我們不需要,后面訓(xùn)練時(shí)記得不要取到最后一列。

    2.2.2 編寫(xiě)距離計(jì)算函數(shù)

    我們需要定義一個(gè)兩個(gè)長(zhǎng)度相等的數(shù)組之間歐式距離計(jì)算函數(shù),在不直接應(yīng)用計(jì)算距離計(jì)算結(jié)果,只比較距離遠(yuǎn)近的情況下,我們可以用距離平方和代替距離進(jìn)行比較,化簡(jiǎn)開(kāi)平方運(yùn)算,從而減少函數(shù)計(jì)算量。此外需要說(shuō)明的是,涉及到距離計(jì)算的,一定要注意量綱的統(tǒng)一。如果量綱不統(tǒng)一的話,模型極易偏向量綱大的那一方。此處選用鳶尾花數(shù)據(jù)集,基本不需要考慮量綱問(wèn)題。

    • 函數(shù)功能:計(jì)算兩個(gè)數(shù)據(jù)集之間的歐式距離
    • 輸入:兩個(gè) array 數(shù)據(jù)集
    • 返回:兩個(gè)數(shù)據(jù)集之間的歐氏距離(此處用距離平方和代替距離)
    def distEclud(arrA, arrB):d = arrA - arrBdist = np.sum(np.power(d,2), axis=1)return dist

    2.2.3 編寫(xiě)隨機(jī)生成質(zhì)心函數(shù)

    在定義隨機(jī)質(zhì)心生成函數(shù)時(shí),首先需要計(jì)算每列數(shù)值的范圍,然后從該范圍中隨機(jī)生成指定個(gè)數(shù)的質(zhì)心。此處我們使用 numpy.random.uniform()函數(shù)生成隨機(jī)質(zhì)心。

    • 函數(shù)功能:隨機(jī)生成 k 個(gè)質(zhì)心
    • 參數(shù)說(shuō)明:
      dataSet:包含標(biāo)簽的數(shù)據(jù)集
      k:簇的個(gè)數(shù)
    • 返回:
      data_cent:K 個(gè)質(zhì)心
    def randCent(dataSet, k):n = dataSet.shape[1] # n為列數(shù),iris一共5列data_min = dataSet.iloc[:,:n-1].min() # 前4列,每一列最小值data_max = dataSet.iloc[:,:n-1].max() # 前4列,每一列最大值data_cent = np.random.uniform(data_min,data_max,(k, n-1)) # 均勻分布中抽樣,形狀為(k, n-1)return data_cent iris_cent = randCent(iris, 3) iris_cent

    2.2.4 編寫(xiě) K-Means 聚類(lèi)函數(shù)

    這一部分相對(duì)來(lái)說(shuō)比較麻煩一點(diǎn),python基礎(chǔ)不是很好的朋友也不用太過(guò)在意,了解為主,而且之后也會(huì)介紹如何利用sklearn實(shí)現(xiàn)K-Means算法。

    在執(zhí)行 K-Means 的時(shí)候,需要不斷的迭代質(zhì)心,因此我們需要兩個(gè)可迭代容器來(lái)完成該目標(biāo):

    第一個(gè)容器用于存放和更新質(zhì)心,該容器可考慮使用 list 來(lái)執(zhí)行,list 不僅是可迭代對(duì)象,同時(shí) list內(nèi)不同元素索引位置也可用于標(biāo)記和區(qū)分各質(zhì)心,即各簇的編號(hào);即代碼中的 centroids。

    第二個(gè)容器則需要記錄、保存和更新各點(diǎn)到質(zhì)心之間的距離,并能夠方便對(duì)其進(jìn)行比較,該容器考慮使用一個(gè)三列的數(shù)組來(lái)執(zhí)行,其中:

    • 第一列用于存放最近一次計(jì)算完成后某點(diǎn)到各質(zhì)心的最短距離。
    • 第二列用于記錄最近一次計(jì)算完成后根據(jù)最短距離得到的代表對(duì)應(yīng)質(zhì)心的數(shù)值索引,即所屬簇,即質(zhì)心的編號(hào)。
    • 第三列用于存放上一次某點(diǎn)所對(duì)應(yīng)質(zhì)心編號(hào)(某點(diǎn)所屬簇),后兩列用于比較質(zhì)心發(fā)生變化后某點(diǎn)所屬簇的情況是否發(fā)生變化。

    函數(shù)功能:k-均值聚類(lèi)算法

    參數(shù)說(shuō)明:

    • dataSet:帶標(biāo)簽數(shù)據(jù)集
    • k:簇的個(gè)數(shù)
    • distMeas:距離計(jì)算函數(shù)
    • createCent:隨機(jī)質(zhì)心生成函數(shù)

    返回:

    • centroids:質(zhì)心
    • result_set:所有數(shù)據(jù)劃分結(jié)果
    def kMeans(dataSet, k, distMeas=distEclud, createCent=randCent): # iris為150*5m,n = dataSet.shape # m是行數(shù)(數(shù)據(jù)量),n是列數(shù)iris為150*5# 下面生成的centroids,即第一個(gè)容器,后面用來(lái)存儲(chǔ)最新更新的質(zhì)心centroids = createCent(dataSet, k) # centroids為3*4,用三個(gè)長(zhǎng)度為4的一維數(shù)組記載3個(gè)質(zhì)心# 第一次centroids是隨機(jī)生成的# 這段生成的result_set,即第二個(gè)容器# result_set結(jié)構(gòu): [數(shù)據(jù)集, 該行到最近質(zhì)心的距離, 本次迭代中最近質(zhì)心編號(hào),上次迭代中最近質(zhì)心編號(hào)]clusterAssment = np.zeros((m,3)) # clusterAssment為150*3clusterAssment[:, 0] = np.inf # np.inf為無(wú)窮大clusterAssment[:, 1: 3] = -1 # 此時(shí)clusterAssment為150*3result_set = pd.concat([dataSet, pd.DataFrame(clusterAssment)], axis=1,ignore_index = True) # result_set為150*8clusterChanged = Truewhile clusterChanged:clusterChanged = Falsefor i in range(m): # 遍歷result_set中每一行,一共m行# 小心,下面的n為5,而resulit_set的列數(shù)已經(jīng)變成8dist = distMeas(dataSet.iloc[i, :n-1].values, centroids) # 第i行與三個(gè)質(zhì)心的距離,dist為3*1result_set.iloc[i, n] = dist.min() # result_set[i,n]記錄該行與3個(gè)質(zhì)心的最小距離result_set.iloc[i, n+1] = np.where(dist == dist.min())[0] # result_set[i,n]記錄最近質(zhì)心的索引clusterChanged = not (result_set.iloc[:, -1] == result_set.iloc[:,-2]).all() # 只要result_set最后兩列不完全相等,意味著本次for循環(huán)結(jié)束時(shí),m行所有的新質(zhì)心與上次while循環(huán)留下的不完全一樣# 后果:clusterChanged為T(mén)rue,while繼續(xù)循環(huán)# clusterChanged為T(mén)rue,則需要運(yùn)行下面的if語(yǔ)句代碼塊,重置第一個(gè)容器centroids和第二個(gè)容器result_setif clusterChanged:cent_df = result_set.groupby(n+1).mean() # 按照列索引為n+1(質(zhì)心索引)(第6列)進(jìn)行分組求均值# 即:按照最新的簇分類(lèi),計(jì)算最新3個(gè)質(zhì)心的位置centroids = cent_df.iloc[:,:n-1].values # 重置centroids,用最新質(zhì)心位置,替換上次的。3*4result_set.iloc[:, -1] = result_set.iloc[:, -2] # result_set最后一列,本次的簇分類(lèi)編碼,替換掉上次的return centroids, result_set

    鳶尾花數(shù)據(jù)集帶進(jìn)去,查看模型運(yùn)行效果:

    iris_cent,iris_result = kMeans(iris, 3) iris_cent

    iris_result.head()


    以上代碼編寫(xiě)時(shí),有以下幾點(diǎn)需要特別注意:

    • 設(shè)置統(tǒng)一的操作對(duì)象 result_set
      為了調(diào)用和使用的方便,此處將 clusterAssment 轉(zhuǎn)換為了 DataFrame 并與輸入 DataFrame 合并,組成的對(duì)象可作為后續(xù)調(diào)用的統(tǒng)一對(duì)象,該對(duì)象內(nèi)即保存了原始數(shù)據(jù),也保存了迭代運(yùn)算的中間結(jié)果,包括數(shù)據(jù)所屬簇標(biāo)記和數(shù)據(jù)質(zhì)心距離等,該對(duì)象同時(shí)也作為最終函數(shù)的返回結(jié)果;
    • 判斷質(zhì)心發(fā)生是否發(fā)生改變條件
      注意,在 K-Means 中判斷質(zhì)心是否發(fā)生改變,即判斷是否繼續(xù)進(jìn)行下一步迭代的依據(jù)并不是某點(diǎn)距離新的質(zhì)心距離變短,而是某點(diǎn)新的距離向量(到各質(zhì)心的距離)中最短的分量位置是否發(fā)生變化,即質(zhì)心變化后某點(diǎn)是否應(yīng)歸屬另外的簇。在質(zhì)心變化導(dǎo)致各點(diǎn)所屬簇發(fā)生變化的過(guò)程中,點(diǎn)到質(zhì)心的距離不一定會(huì)變短,即判斷條件不能用下述語(yǔ)句表示
    if not (result_set.iloc[:, -1] == result_set.iloc[:, -2]).all()
    • 質(zhì)心和類(lèi)別一一對(duì)應(yīng)
      即在最后生成的結(jié)果中,centroids 的行標(biāo)即為 result_set 中各點(diǎn)所屬類(lèi)別。

    2.2.5 算法驗(yàn)證

    函數(shù)編寫(xiě)完成后,先以 testSet 數(shù)據(jù)集測(cè)試模型運(yùn)行效果(為了可以直觀看出聚類(lèi)效果,此處采用一個(gè)二維數(shù)據(jù)集進(jìn)行驗(yàn)證)。testSet 數(shù)據(jù)集是一個(gè)二維數(shù)據(jù)集,每個(gè)觀測(cè)值都只有兩個(gè)特征,且數(shù)據(jù)之間采用空格進(jìn)行分隔,因此可采用 pd.read_table()函數(shù)進(jìn)行讀取。

    testSet = pd.read_csv(r"testSet.txt", sep='\t') testSet.head() testSet.shape


    然后利用二維平面圖形觀察其分布情況:

    plt.scatter(testSet.iloc[:,0], testSet.iloc[:,1]);


    可以大概看出數(shù)據(jù)大概分布在空間的四個(gè)角上,后續(xù)我們將對(duì)此進(jìn)行驗(yàn)證。然后利用我們剛才編寫(xiě)的 K-Means 算法對(duì)其進(jìn)行聚類(lèi),在執(zhí)行算法之前需要添加一列虛擬標(biāo)簽列(算法是從倒數(shù)第二列開(kāi)始計(jì)算特征值,因此這里需要人為增加多一列到最后)

    label = pd.DataFrame(np.zeros(testSet.shape[0]).reshape(-1, 1)) test_set = pd.concat([testSet, label], axis=1, ignore_index = True) test_set.head()


    然后帶入算法進(jìn)行計(jì)算,根據(jù)二維平面坐標(biāo)點(diǎn)的分布特征,我們可考慮設(shè)置四個(gè)質(zhì)心,即將其分為四個(gè)簇,并簡(jiǎn)單查看運(yùn)算結(jié)果:

    test_cent, test_cluster = kMeans(test_set, 4) test_cent test_cluster.head()


    將分類(lèi)結(jié)果進(jìn)行可視化展示,使用 scatter 函數(shù)繪制不同分類(lèi)點(diǎn)不同顏色的散點(diǎn)圖,同時(shí)將質(zhì)心也放入同一張圖中進(jìn)行觀察:

    plt.scatter(test_cluster.iloc[:,0], test_cluster.iloc[:, 1],c=test_cluster.iloc[:, -1]) plt.scatter(test_cent[:, 0], test_cent[:, 1], color='red',marker='x',s=100);


    從圖的結(jié)果來(lái)看,結(jié)果還是非常符合我們預(yù)期的。

    結(jié)束語(yǔ)

    那么到這里,關(guān)于我們無(wú)監(jiān)督學(xué)習(xí)及K-Means算法的介紹先告一段落啦。在下一篇文章中,我會(huì)介紹如何利用sklearn玩轉(zhuǎn)K-Means算法,以及無(wú)監(jiān)督算法模型如何評(píng)估,感興趣的朋友可以關(guān)注我下面的專(zhuān)欄啦。


    推薦關(guān)注的專(zhuān)欄

    👨?👩?👦?👦 機(jī)器學(xué)習(xí):分享機(jī)器學(xué)習(xí)實(shí)戰(zhàn)項(xiàng)目和常用模型講解
    👨?👩?👦?👦 數(shù)據(jù)分析:分享數(shù)據(jù)分析實(shí)戰(zhàn)項(xiàng)目和常用技能整理

    機(jī)器學(xué)習(xí)系列往期回顧

    💚 以??簡(jiǎn)單易懂??的語(yǔ)言帶你搞懂邏輯回歸算法【附Python代碼詳解】機(jī)器學(xué)習(xí)系列之邏輯回歸篇
    ?? 一文帶你用Python玩轉(zhuǎn)線性回歸模型 ??加利福尼亞房?jī)r(jià)預(yù)測(cè)??回歸模型評(píng)估指標(biāo)介紹
    💜 如何搞懂機(jī)器學(xué)習(xí)中的線性回歸模型?機(jī)器學(xué)習(xí)系列之線性回歸基礎(chǔ)篇
    🖤 你真的了解分類(lèi)模型評(píng)估指標(biāo)都有哪些嗎?【附Python代碼實(shí)現(xiàn)】
    💙 一文帶你用Python玩轉(zhuǎn)決策樹(shù) ??畫(huà)出決策樹(shù)&各種參數(shù)詳細(xì)說(shuō)明??決策樹(shù)的優(yōu)缺點(diǎn)又有哪些?
    🧡 開(kāi)始學(xué)習(xí)機(jī)器學(xué)習(xí)時(shí)你必須要了解的模型有哪些?機(jī)器學(xué)習(xí)系列之決策樹(shù)進(jìn)階篇
    💚 開(kāi)始學(xué)習(xí)機(jī)器學(xué)習(xí)時(shí)你必須要了解的模型有哪些?機(jī)器學(xué)習(xí)系列之決策樹(shù)基礎(chǔ)篇
    ?? 以??簡(jiǎn)單易懂??的語(yǔ)言帶你搞懂有監(jiān)督學(xué)習(xí)算法【附Python代碼詳解】機(jī)器學(xué)習(xí)系列之KNN篇
    💜 開(kāi)始學(xué)習(xí)機(jī)器學(xué)習(xí)之前你必須要了解的知識(shí)有哪些?機(jī)器學(xué)習(xí)系列入門(mén)篇


    往期內(nèi)容回顧

    🖤 我和關(guān)注我的前1000個(gè)粉絲“合影”啦!收集前1000個(gè)粉絲進(jìn)行了一系列數(shù)據(jù)分析,收獲滿滿
    💚 MySQL必須掌握的技能有哪些?超細(xì)長(zhǎng)文帶你掌握MySQL【建議收藏】
    💜 Hive必須了解的技能有哪些?萬(wàn)字博客帶你掌握Hive??【建議收藏】


    關(guān)注我,了解更多相關(guān)知識(shí)!


    CSDN@報(bào)告,今天也有好好學(xué)習(xí)

    總結(jié)

    以上是生活随笔為你收集整理的以《简单易懂》的语言带你搞懂无监督学习算法【附Python代码详解】机器学习系列之K-Means篇的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

    如果覺(jué)得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。