6.8 程序示例--二分 K-Means-机器学习笔记-斯坦福吴恩达教授
生活随笔
收集整理的這篇文章主要介紹了
6.8 程序示例--二分 K-Means-机器学习笔记-斯坦福吴恩达教授
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
程序示例–二分 K-Means
仍然是在 kmeans.py 中,我們又添加了二分 K-Means 算法:
# coding: utf-8 # kmeans/kmeans.py# ... def biKmeans(dataSet, k):"""Args:def biKmeans(dataSet, k):"""二分kmeans算法Args:dataSet: 數據集k: 聚類數Returns:centroids: 聚類中心clusterAssment: 點分配結果"""m, n = np.shape(dataSet)# 起始時,只有一個簇,該簇的聚類中心為所有樣本的平均位置centroid0 = np.mean(dataSet, axis=0).tolist()[0]# 設置一個列表保存當前的聚類中心currentCentroids = [centroid0]# 點分配結果: 第一列指明樣本所在的簇,第二列指明該樣本到聚類中心的距離clusterAssment = np.mat(np.zeros((m, 2)))# 初始化點分配結果,默認將所有樣本先分配到初始簇for j in range(m):clusterAssment[j, 1] = distEclud(dataSet[j, :], np.mat(centroid0))**2# 直到簇的數目達標while len(currentCentroids) < k:# 當前最小的代價lowestError = np.inf# 對于每一個簇for j in range(len(currentCentroids)):# 獲得該簇的樣本ptsInCluster = dataSet[np.nonzero(clusterAssment[:, 0].A == j)[0], :]# 在該簇上進行2-means聚類# 注意,得到的centroids,其聚類編號含0,1centroids, clusterAss = kMeans(ptsInCluster, 2)# 獲得劃分后的誤差之和splitedError = np.sum(clusterAss[:, 1])# 獲得其他簇的樣本ptsNoInCluster = dataSet[np.nonzero(clusterAssment[:, 0].A != j)[0]]# 獲得剩余數據集的誤差nonSplitedError = np.sum(ptsNoInCluster[:, 1])# 比較,判斷此次劃分是否劃算if (splitedError + nonSplitedError) < lowestError:# 如果劃算,刷新總誤差lowestError = splitedError + nonSplitedError# 記錄當前的應當劃分的簇needToSplit = j# 新獲得的簇以及點分配結果newCentroids = centroids.AnewClusterAss = clusterAss.copy()# 更新簇的分配結果# 第0簇應當修正為被劃分的簇newClusterAss[np.nonzero(newClusterAss[:, 0].A == 0)[0], 0] = needToSplit# 第1簇應當修正為最新一簇newClusterAss[np.nonzero(newClusterAss[:, 0].A == 1)[0], 0] = len(currentCentroids)# 被劃分的簇需要更新currentCentroids[needToSplit] = newCentroids[0, :]# 加入新的劃分后的簇currentCentroids.append(newCentroids[1, :])# 刷新點分配結果clusterAssment[np.nonzero(clusterAssment[:, 0].A == needToSplit)[0], :] = newClusterAssreturn np.mat(currentCentroids), clusterAssmentdataSet: 數據集k: 聚類數Returns:centroids: 聚類中心clusterAssment: 點分配結果"""# 隨機初始化聚類中心centroids = randCent(dataSet, k)m, n = np.shape(dataSet)# 點分配結果: 第一列指明樣本所在的簇,第二列指明該樣本到聚類中心的距離clusterAssment = np.mat(np.zeros((m, 2)))# 標識聚類中心是否仍在改變clusterChanged = True# 直至聚類中心不再變化while clusterChanged:clusterChanged = False# 分配樣本到簇for i in range(m):# 計算第i個樣本到各個聚類中心的距離minIndex = 0minDist = np.inffor j in range(k):dist = distEclud(dataSet[i, :], centroids[j, :])if(dist < minDist):minIndex = jminDist = dist# 判斷cluster是否改變if(clusterAssment[i, 0] != minIndex):clusterChanged = TrueclusterAssment[i, :] = minIndex, minDist**2# 刷新聚類中心: 移動聚類中心到所在簇的均值位置for cent in range(k):# 通過數組過濾獲得簇中的點ptsInCluster = dataSet[np.nonzero(clusterAssment[:, 0].A == cent)[0]]# 計算均值并移動centroids[cent, :] = np.mean(ptsInCluster, axis=0)return centroids, clusterAssment # ...測試
# coding: utf-8 # kmeans/test_bi_kmeans.pyimport kmeans import numpy as np import matplotlib.pyplot as pltif __name__ == "__main__":dataMat = np.mat(kmeans.loadDataSet('data/testSet2.txt'))centroids, clusterAssment = kmeans.biKmeans(dataMat, 3)clusterCount = centroids.shape[0]m = dataMat.shape[0]# 繪制散點圖patterns = ['o', 'D', '^']colors = ['b', 'g', 'y']fig = plt.figure()title = 'bi-kmeans with k=3'ax = fig.add_subplot(111, title=title)for k in range(clusterCount):# 繪制聚類中心ax.scatter(centroids[k,0], centroids[k,1], color='r', marker='+', linewidth=20)for i in range(m):# 繪制屬于該聚類中心的樣本ptsInCluster = dataMat[np.nonzero(clusterAssment[:, 0].A==k)[0]]ax.scatter(ptsInCluster[:, 0].flatten().A[0], ptsInCluster[:, 1].flatten().A[0], marker=patterns[k], color=colors[k])plt.show()運行結果如下:
總結
以上是生活随笔為你收集整理的6.8 程序示例--二分 K-Means-机器学习笔记-斯坦福吴恩达教授的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 6.7 程序示例--K-Means-机器
- 下一篇: 7.1 概述-机器学习笔记-斯坦福吴恩达