机器学习算法总结--K均值算法
參考自:
- 《機器學習》
- 機器學習&數據挖掘筆記_16(常見面試之機器學習算法思想簡單梳理)
- K-Means Clustering
- 斯坦福大學公開課 :機器學習課程
簡介
K-均值是最普及的聚類算法,算法接受一個未標記的數據集,然后將數據集聚類成不同的組。
K-均值是一個迭代算法,假設我們想要將數據聚類成n個組,其方法為:
這個過程中分兩個主要步驟,第一個就是第二步,將訓練集中的樣本點根據其與聚類中心的距離,分配到距離最近的聚類中心處,接著第二個就是第三步,更新類中心,做法是計算每個類的所有樣本的平均值,然后將這個平均值作為新的類中心值,接著繼續這兩個步驟,直到達到終止條件,一般是指達到設定好的迭代次數。
當然在這個過程中可能遇到有聚類中心是沒有分配數據點給它的,通常的一個做法是刪除這種聚類中心,或者是重新選擇聚類中心,保證聚類中心數還是初始設定的K個。
優化目標
K-均值最小化問題,就是最小化所有的數據點與其所關聯的聚類中心之間的距離之和,因此K-均值的代價函數(又稱為畸變函數)為:?
其中 μc(i)代表與 x(i)最近的聚類中心點。
所以我們的優化目標是找出是的代價函數最小的和c(1),c(2),…,c(m)和μ1,μ2,…,μm:?
回顧K-均值迭代算法的過程可知,第一個循環就是用于減小 c(i)引起的代價,而第二個循環則是用于減小 μi引起的代價,因此, 迭代的過程一定會是每一次迭代都在減小代價函數,不然便是出現了錯誤。
隨機初始化
在運行K-均值算法之前,首先需要隨機初始化所有的聚類中心點,做法如下:
K-均值的一個問題在于,它有可能會停留在一個局部最小值處,而這取決于初始化的情況。
為了解決這個問題,通常需要多次運行K-均值算法,每一次都重新進行隨機初始化,最后再比較多次運行K-均值的結果,選擇代價函數最小的結果。這種方法在K較小(2-10)的時候還是可行的,但是如果K較大,這種做法可能不會有明顯地改善。
優缺點
優點
缺點
代碼實現
代碼參考自K-Means Clustering。
#!/usr/bin/env python # -*- coding: utf-8 -*- """ @Time : 2016/10/21 16:35 @Author : cai實現 K-Means 聚類算法 """import numpy as np import matplotlib.pyplot as plt from scipy.io import loadmat import os# 尋址最近的中心點 def find_closest_centroids(X, centroids):m = X.shape[0]k = centroids.shape[0]idx = np.zeros(m)for i in range(m):min_dist = 1000000for j in range(k):# 計算每個訓練樣本和中心點的距離dist = np.sum((X[i, :] - centroids[j, :]) ** 2)if dist < min_dist:# 記錄當前最短距離和其中心的索引值min_dist = distidx[i] = jreturn idx# 計算聚類中心 def compute_centroids(X, idx, k):m, n = X.shapecentroids = 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()return centroids# 初始化聚類中心 def init_centroids(X, k):m, n = X.shapecentroids = np.zeros((k, n))# 隨機初始化 k 個 [0,m]的整數idx = np.random.randint(0, m, k)for i in range(k):centroids[i, :] = X[idx[i], :]return centroids# 實現 kmeans 算法 def run_k_means(X, initial_centroids, max_iters):m, n = X.shape# 聚類中心的數目k = initial_centroids.shape[0]idx = np.zeros(m)centroids = initial_centroidsfor i in range(max_iters):idx = find_closest_centroids(X, centroids)centroids = compute_centroids(X, idx, k)return idx, centroidsdataPath = os.path.join('data', 'ex7data2.mat') data = loadmat(dataPath) X = data['X']initial_centroids = init_centroids(X, 3) # print(initial_centroids) # idx = find_closest_centroids(X, initial_centroids) # print(idx)# print(compute_centroids(X, idx, 3))idx, centroids = run_k_means(X, initial_centroids, 10) # 可視化聚類結果 cluster1 = X[np.where(idx == 0)[0], :] 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()# 載入一張測試圖片,進行測試 imageDataPath = os.path.join('data', 'bird_small.mat') image = loadmat(imageDataPath) # print(image)A = image['A'] print(A.shape)# 對圖片進行歸一化 A = A / 255.# 重新調整數組的尺寸 X = np.reshape(A, (A.shape[0] * A.shape[1], A.shape[2])) # 隨機初始化聚類中心 initial_centroids = init_centroids(X, 16) # 運行聚類算法 idx, centroids = run_k_means(X, initial_centroids, 10)# 得到最后一次的最近中心點 idx = find_closest_centroids(X, centroids) # map each pixel to the centroid value X_recovered = centroids[idx.astype(int), :] # reshape to the original dimensions X_recovered = np.reshape(X_recovered, (A.shape[0], A.shape[1], A.shape[2]))# plt.imshow(X_recovered) # plt.show()完整代碼例子和數據可以查看Kmeans練習代碼。
總結
以上是生活随笔為你收集整理的机器学习算法总结--K均值算法的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: SQL语言:嵌入式SQL知识笔记
- 下一篇: 电脑小常识:电脑键盘失灵怎么办?