本文來自同步博客。python
前面幾篇文章介紹了迴歸或分類的幾個算法,它們的共同點是訓練數據包含了輸出結果,要求算法可以經過訓練數據掌握規律,用於預測新輸入數據的輸出值。所以,迴歸算法或分類算法被稱之爲監督學習(Supervised Learning)。git
本篇文章將接觸有別於監督學習的另外一類機器學習算法——無監督學習(Unsupervised Learning)。無監督學習是尋找缺少標準答案的輸入數據的規律。其中聚類算法是無監督學習主要的分支。今天介紹的K-Means算法就是聚類算法的其中一種比較常見的算法。github
K-Means算法的K指的是輸出類別的數目。該算法是一個迭代過程,每一次迭代分爲兩個步驟,第一步爲分類成簇,第二步爲移動簇中心,直到簇中心不變。算法
分類成簇的斷定方法是將與簇中心的歐幾里得距離最小的數據點歸爲對應的一類。而簇中心的計算方式是該類全部數據點的平均值,這就是均值‘Mean
’一詞的由來。app
下圖演示了K-Means算法每一次迭代數據點的分類狀況:機器學習
能夠從上圖看到,K-Means通過4次迭代就完成了聚類過程。每次迭代,圓圈表示的數據點都被分類到離它最近的「x」表示的中心點,而後對中心點進行了更新。oop
下面的代碼展現了K-Means算法的原理,上面的圖片也是經過這塊代碼生成的。依舊經過註釋方式講代碼,請看:學習
import numpy as np import matplotlib.pyplot as plt # Input data set X = np.array([ [-4, -3.5], [-3.5, -5], [-2.7, -4.5], [-2, -4.5], [-2.9, -2.9], [-0.4, -4.5], [-1.4, -2.5], [-1.6, -2], [-1.5, -1.3], [-0.5, -2.1], [-0.6, -1], [0, -1.6], [-2.8, -1], [-2.4, -0.6], [-3.5, 0], [-0.2, 4], [0.9, 1.8], [1, 2.2], [1.1, 2.8], [1.1, 3.4], [1, 4.5], [1.8, 0.3], [2.2, 1.3], [2.9, 0], [2.7, 1.2], [3, 3], [3.4, 2.8], [3, 5], [5.4, 1.2], [6.3, 2] ]) # K-Means def k_means(data, k=2): if not isinstance(k, int) or k <= 0 or len(data) < k: return # Select first K points as centroids centroids = {0: data[0], 1: data[1]} # configurations limit = 0.0001 max_loop_count = 300 total_steps = [] # Loop for i in range(max_loop_count): # Classification data into K groups groups = {} for j in range(k): groups[j] = [] for item in data: dist = [np.linalg.norm(centroids[centroid] - item) for centroid in centroids] index = dist.index(min(dist)) groups[index].append(item) # Calculate new centroids new_centroids = [np.average(groups[i], axis=0) for i in groups] # Store data for matplotlib total_steps.append({ 'loop': i, 'groups': groups, 'centroids': centroids.copy() }) # Check whether they change or not stop_loop = True for c in centroids: if abs(np.sum((new_centroids[c] - centroids[c])/centroids[c]*100.0)) > limit: stop_loop = False break if stop_loop: break # Update centroids for c in centroids: centroids[c] = new_centroids[c] # Draw pictures colors = k*['g', 'r', 'b', 'c', 'm', 'y', 'k', 'w'] fig = plt.figure() for step in total_steps: # This may cause error if len(total_steps) > 9 ax = fig.add_subplot(1, len(total_steps), step['loop'] + 1) for g in step['groups']: for point in step['groups'][g]: ax.scatter(point[0], point[1], s=20, color=colors[g]) ax.scatter(step['centroids'][g][0], step['centroids'][g][1], marker='x', s=30, color=colors[g]) plt.show() k_means(X)
代碼連接spa
scikit-learn
中的KMeansscikit-learn
中的KMeans存在cluster模塊中,在官方有關KMeans的API文檔中能夠看到,數據處理結果存放在‘cluster_centers_’、‘labels_’和‘ inertia_’中。下面用到了前二者,分別是聚類中心點和標籤。code
import numpy as np import matplotlib.pyplot as plt from sklearn.cluster import KMeans # Input data set X = np.array([ [-4, -3.5], [-3.5, -5], [-2.7, -4.5], [-2, -4.5], [-2.9, -2.9], [-0.4, -4.5], [-1.4, -2.5], [-1.6, -2], [-1.5, -1.3], [-0.5, -2.1], [-0.6, -1], [0, -1.6], [-2.8, -1], [-2.4, -0.6], [-3.5, 0], [-0.2, 4], [0.9, 1.8], [1, 2.2], [1.1, 2.8], [1.1, 3.4], [1, 4.5], [1.8, 0.3], [2.2, 1.3], [2.9, 0], [2.7, 1.2], [3, 3], [3.4, 2.8], [3, 5], [5.4, 1.2], [6.3, 2] ]) clf = KMeans(n_clusters=2) clf.fit(X) centroids = clf.cluster_centers_ labels = clf.labels_ colors = ['r', 'g'] for i in range(len(X)): plt.scatter(X[i][0], X[i][1], color=colors[labels[i]], s=20) plt.scatter(centroids[:, 0], centroids[:, 1], marker='x', s=30) plt.show()
執行結果以下: