Python機器學(xué)習(xí)之K-Means聚類實現(xiàn)詳解
本文為大家分享了Python機器學(xué)習(xí)之K-Means聚類的實現(xiàn)代碼,供大家參考,具體內(nèi)容如下
1.K-Means聚類原理
K-means算法是很典型的基于距離的聚類算法,采用距離作為相似性的評價指標,即認為兩個對象的距離越近,其相似度就越大。其基本思想是:以空間中k個點為中心進行聚類,對最靠近他們的對象歸類。通過迭代的方法,逐次更新各聚類中心的值,直至得到最好的聚類結(jié)果。各聚類本身盡可能的緊湊,而各聚類之間盡可能的分開。
算法大致流程為:(1)隨機選取k個點作為種子點(這k個點不一定屬于數(shù)據(jù)集);(2)分別計算每個數(shù)據(jù)點到k個種子點的距離,離哪個種子點最近,就屬于哪類;(3)重新計算k個種子點的坐標(簡單常用的方法是求坐標值的平均值作為新的坐標值;(4)重復(fù)2、3步,直到種子點坐標不變或者循環(huán)次數(shù)完成。
2.數(shù)據(jù)及其尋找初步的聚類中心
數(shù)據(jù)為Matlab加載格式(mat),包含X變量,數(shù)據(jù)來源為(大家可以去這下載),X為300*2維變量,由于是2維,所以基本上就是在平面坐標軸上的一些點中進行聚類。
我們首先構(gòu)建初步尋找聚類中心(centroids,質(zhì)心)函數(shù),再隨機設(shè)置初始質(zhì)心,通過歐氏距離初步判斷X的每一個變量屬于哪個質(zhì)心。代碼為:
import numpy as np import pandas as pd import matplotlib.pyplot as plt import seaborn as sb from scipy.io import loadmat def find_closest_centroids(X, centroids): m = X.shape[0] k = centroids.shape[0] #要聚類的類別個數(shù) idx = np.zeros(m) for i in range(m): min_dist = 1000000 #迭代終止條件 for j in range(k): dist = np.sum((X[i,:] - centroids[j,:]) ** 2) if dist < min_dist: # 記錄當前最短距離和其中心的索引值 min_dist = dist idx[i] = j return idx data = loadmat('D:\python\Python ml\ex7data2.mat') X = data['X'] initial_centroids = np.array([[3, 3], [6, 2], [8, 5]]) idx = find_closest_centroids(X, initial_centroids) idx[0:3]
在這里先生成m(這里為300)個0向量,即idx,也就是假設(shè)X的每個變量均屬于0類,然后再根據(jù)與初始質(zhì)心的距離計算dist = np.sum((X[i,:] - centroids[j,:]) ** 2),初步判斷每個變量歸屬哪個類,最終替代idx中的0.
3.不斷迭代尋找質(zhì)心的位置并實現(xiàn)kmeans算法
上述idx得到的300維向量是判斷X中每個變量的歸屬類別,在此基礎(chǔ)上,再對初始質(zhì)心集群位置不斷調(diào)整,尋找最優(yōu)質(zhì)心。
def compute_centroids(X, idx, k): m, n = X.shape centroids = np.zeros((k, n)) for i in range(k): indices = np.where(idx == i) centroids[i,:] = (np.sum(X[indices,:], axis=1) / len(indices[0])).ravel() #這里簡單的將該類中心的所有數(shù)值求平均值作為新的類中心 return centroids compute_centroids(X, idx, 3)
根據(jù)上述函數(shù),來構(gòu)建kmeans函數(shù)實現(xiàn)K-means聚類算法。然后根據(jù)得到的每個變量歸屬類別與質(zhì)心坐標,進行可視化。
def run_k_means(X, initial_centroids, max_iters): m, n = X.shape k = initial_centroids.shape[0] idx = np.zeros(m) centroids = initial_centroids for i in range(max_iters): idx = find_closest_centroids(X, centroids) centroids = compute_centroids(X, idx, k) return idx, centroids idx, centroids = run_k_means(X, initial_centroids, 10) cluster1 = X[np.where(idx == 0)[0],:] #獲取X中屬于第一個類別的數(shù)據(jù)集合,即類別1的點 cluster2 = X[np.where(idx == 1)[0],:] cluster3 = X[np.where(idx == 2)[0],:] fig, ax = plt.subplots(figsize=(12,8)) ax.scatter(cluster1[:,0], cluster1[:,1], s=30, color='r', label='Cluster 1') ax.scatter(cluster2[:,0], cluster2[:,1], s=30, color='g', label='Cluster 2') ax.scatter(cluster3[:,0], cluster3[:,1], s=30, color='b', label='Cluster 3') ax.legend() plt.show()
得到圖形如下:
image.png
4.關(guān)于初始化質(zhì)心的設(shè)置
我們前邊設(shè)置的初始質(zhì)心:[3, 3], [6, 2], [8, 5],是事先設(shè)定的,并由此生成idx(每一變量歸屬類別的向量),這是后邊進行kmeans聚類的基礎(chǔ),實際上對于二維以上數(shù)據(jù),由于無法在平面坐標軸展示,很難一開始就設(shè)定較好的初始質(zhì)心,另外,初始質(zhì)心的設(shè)定也可能會影響算法的收斂性。所以需要我們再構(gòu)造個初始化質(zhì)心設(shè)定函數(shù),來更好地設(shè)置初始質(zhì)心。
def init_centroids(X, k): m, n = X.shape centroids = np.zeros((k, n)) #初始化零矩陣 idx = np.random.randint(0, m, k) #返回0-m之間的整數(shù)值 for i in range(k): centroids[i,:] = X[idx[i],:] return centroids init_centroids(X, 3)
這里所生成的初始質(zhì)心位置,其實就是從X的數(shù)據(jù)中隨機找3個變量作為初始值。在此基礎(chǔ)上,令initial_centroids = init_centroids(X, 3),然后代入前邊的code中,重新運行一遍即可。
以上就是本文的全部內(nèi)容,希望對大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
Python OpenCV 使用滑動條來調(diào)整函數(shù)參數(shù)的方法
這篇文章主要介紹了Python OpenCV 使用滑動條來調(diào)整函數(shù)參數(shù)的方法,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2019-07-07Python機器學(xué)習(xí)NLP自然語言處理基本操作關(guān)鍵詞
本文是Python機器學(xué)習(xí)NLP自然語言處理系列文章,帶大家開啟一段學(xué)習(xí)自然語言處理 (NLP) 的旅程. 本文主要學(xué)習(xí)NLP自然語言處理關(guān)鍵詞的操作2021-09-09解決Pytorch自定義層出現(xiàn)多Variable共享內(nèi)存錯誤問題
這篇文章主要介紹了解決Pytorch自定義層出現(xiàn)多Variable共享內(nèi)存錯誤問題,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2020-06-06python中dict字典的查詢鍵值對 遍歷 排序 創(chuàng)建 訪問 更新 刪除基礎(chǔ)操作方法
字典的每個鍵值(key=>value)對用冒號(:)分割,每個對之間用逗號(,)分割,整個字典包括在花括號({})中,本文講述了python中dict字典的查詢鍵值對 遍歷 排序 創(chuàng)建 訪問 更新 刪除基礎(chǔ)操作方法2018-09-09Numpy中的shape、reshape函數(shù)的區(qū)別
本文主要介紹了Numpy中的shape、reshape函數(shù)的區(qū)別,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2022-07-07