K-means演算法優化(二分K-means演算法)
from numpy import * import xlrd import matplotlib.pyplot as plt # 計算歐氏距離 def distEclud(vector1, vector2): ''' :param vector1: 第j個均值向量 :param vector2: 第i個樣本 :return: 距離值 ''' return sqrt(sum(power(vector2 - vector1, 2))) #構建聚簇中心 def randCent(dataSet, k): n = shape(dataSet)[1] centroids = mat(zeros((k,n))) for j in range(n): minJ = min(dataSet[:,j]) maxJ = max(dataSet[:,j]) rangeJ = float(maxJ - minJ) centroids[:,j] = minJ + rangeJ * random.rand(k, 1) return centroids def biKmeans(dataSet, k, distMeas=distEclud): m = shape(dataSet)[0] #首先建立一個矩陣來儲存資料集中每個點的簇分配結果及平方誤差 clusterAssment = mat(zeros((m,2))) #----建立一個初始簇---- #計算整個資料集的質心 centroid0 = mean(dataSet, axis=0).tolist()[0] #使用一個列表來保留所有的質心 centList = [centroid0] #遍歷資料集中所有點來計算每個點到質心的誤差值 for j in range(m): clusterAssment[j,1] = distMeas(mat(centroid0), dataSet[j,:])**2 #while迴圈會不停的對簇進行劃分,直到得到想要的簇數目為止 while(len(centList) < k): lowestSSE = inf #python中inf表示正無窮 #遍歷簇列表centList中的每一個簇 for i in range(len(centList)): #-----嘗試劃分每一簇---- #對每個簇,將該簇中的所有點看成一個小的資料集ptsInCurrCluster ptsInCurrCluster = dataSet[nonzero(clusterAssment[:,0].A==i)[0],:] #將ptsInCurrCluster輸入到函式KMeans()中進行處理(k=2)。K-均值演算法會生成兩個質心(簇),同時給出每個簇的誤差值 centroidMat, splitClustAss = kMeans(ptsInCurrCluster, 2, distMeas) #劃分後的樣本誤差之和 sseSplit = sum(splitClustAss[:, 1]) #剩餘資料集的誤差之和 sseNotSplit = sum(clusterAssment[nonzero(clusterAssment[:, 0].A != i)[0], 1]) print("sseSplit, and notSplit: ", sseSplit, sseNotSplit) #將劃分後的樣本誤差之和+剩餘資料集的誤差之和作為本次劃分的誤差 if(sseSplit + sseNotSplit) < lowestSSE: #決定要劃分某一個簇 bestCentToSplit = i #劃分後的質心 bestNewCents = centroidMat #劃分後的簇分配結果矩陣,包含兩列:第一列記錄簇索引,第二列儲存誤差 bestClustAss = splitClustAss.copy() # 本次劃分的誤差 lowestSSE = sseSplit + sseNotSplit #----更新簇的分配結果---- #將劃分簇中所有點的簇分配結果進行修改,當使用KMeans()函式並且指定簇數為2時,會得到兩個編號分別為0和1的結果簇 #需要將這些簇編號修改為劃分簇及新加簇的編號,該過程可以通過兩個陣列過濾器來完成。 bestClustAss[nonzero(bestClustAss[:, 0].A == 1)[0], 0] = len(centList) bestClustAss[nonzero(bestClustAss[:, 0].A == 0)[0], 0] = bestCentToSplit print('the bestCentToSplit is: ', bestCentToSplit) print('the len of bestClustAss is: ', len(bestClustAss)) #新的質心會被新增到centList中 centList[bestCentToSplit] = bestNewCents[0, :].tolist()[0] centList.append(bestNewCents[1, :].tolist()[0]) # 更新SSE的值(sum of squared errors) clusterAssment[nonzero(clusterAssment[:, 0].A == bestCentToSplit)[0],:] = bestClustAss return mat(centList),clusterAssment #k-means 聚類演算法 def kMeans(dataSet, k, distMeans =distEclud, createCent = randCent): m = shape(dataSet)[0] clusterAssment = mat(zeros((m,2))) #用於存放該樣本屬於哪類及質心距離 centroids = createCent(dataSet, k) clusterChanged = True while clusterChanged: clusterChanged = False; for i in range(m): minDist = inf; minIndex = -1; for j in range(k): distJI = distMeans(centroids[j,:], dataSet[i,:]) if distJI < minDist: minDist = distJI; minIndex = j if clusterAssment[i,0] != minIndex: clusterChanged = True; clusterAssment[i,:] = minIndex,minDist**2 print(centroids) for cent in range(k): ptsInClust = dataSet[nonzero(clusterAssment[:,0].A == cent)[0]] # 去第一列等於cent的所有列 centroids[cent,:] = mean(ptsInClust, axis = 0) return centroids, clusterAssment # show your cluster only available with 2-D data def showCluster(dataSet, k, centroids, clusterAssment): numSamples, dim = dataSet.shape if dim != 2: print ("Sorry! I can not draw because the dimension of your data is not 2!") return 1 mark = ['or', 'ob', 'og', 'ok', '^r', '+r', 'sr', 'dr', '<r', 'pr'] if k > len(mark): print ("Sorry! Your k is too large! please contact Zouxy") return 1 # draw all samples for i in range(numSamples): markIndex = int(clusterAssment[i, 0]) plt.plot(dataSet[i, 0], dataSet[i, 1], mark[markIndex]) mark = ['Dr', 'Db', 'Dg', 'Dk', '^b', '+b', 'sb', 'db', '<b', 'pb'] # draw the centroids for i in range(k): plt.plot(centroids[i, 0], centroids[i, 1], mark[i], markersize=12) plt.show() def main(): ## step 1: load data print ("step 1: load data...") dataSet = [] data = xlrd.open_workbook('C:/Users/Microstrong/Desktop/watermelon4.0.xlsx') table = data.sheets()[0] for line in range(0,table.nrows): lineArr = table.row_values(line) dataSet.append([float(lineArr[0]), float(lineArr[1])]) ## step 2: clustering... print ("step 2: clustering...") dataSet = mat(dataSet) k = 3 centroids, clusterAssment = biKmeans(dataSet, k) ## step 3: show the result print ("step 3: show the result...") showCluster(dataSet, k, centroids, clusterAssment) if __name__ == '__main__': main()
相關推薦
K-means演算法優化(二分K-means演算法)
from numpy import * import xlrd import matplotlib.pyplot as plt # 計算歐氏距離 def distEclud(vector1, vector2): ''' :param vector1: 第j個均值向量 :param v
插入排序演算法+優化 (二分查詢優化有序部分)C語言實現
直接插入排序 插入排序思想 直接插入排序思想是將待排序的陣列看作兩個部分:有序部分和無序部分,排序過程就是不斷將無序部分的元素插入到有序部分合適的位置上,使有序部分元素不斷增加而無序部分資料不斷減少,直到陣列全部有序為止。 假設陣列A[0...
二分K-means聚類(bisecting K-means)
1 def biKmeans(dataSet, k, distMeas=distEclud): 2 m = shape(dataSet)[0] 3 clusterAssment = mat(zeros((m,2)))#記錄簇分配的結果及誤差 4 centroid0 = me
《機器學習實戰》二分-kMeans演算法(二分K均值聚類)
首先二分-K均值是為了解決k-均值的使用者自定義輸入簇值k所延伸出來的自己判斷k數目,其基本思路是: 為了得到k個簇,將所有點的集合分裂成兩個簇,從這些簇中選取一個繼續分裂,如此下去,直到產生k個簇。 虛擬碼: 初始化簇表,使之包含由所有的點組成的簇。 repeat &n
k-means k均值聚類 及二分k均值聚類
from numpy import * def load_data(file_name): data=[] fr=open(file_name) for line in fr.readlines(): cur_line=line.st
【演算法】topK問題:得到序列中前k小的數(含複雜度分析)
思路一 利用排序方法(快排/堆排序)對序列從小到大進行排序 輸出序列前k個數 void TopK( int a[], int n, int k ) { if(k<0 || k>n) return; sort(a,n);
資料探勘領域十大經典演算法之—K-鄰近演算法/kNN(超詳細附程式碼)
簡介 又叫K-鄰近演算法,是監督學習中的一種分類演算法。目的是根據已知類別的樣本點集求出待分類的資料點類別。 基本思想 kNN的思想很簡單:在訓練集中選取離輸入的資料點最近的k個鄰居,根據這個k個鄰居中出現次數最多的類別(最大表決規則),作為該資料
nyoj 第k個互質數(二分+容斥原理)
第k個互質數 描述 兩個數的a,b的gcd為1,即a,b互質,現在給你一個數m,你知道與它互質的第k個數是多少嗎?與m互質的數按照升序排列。 輸入輸入m ,k (1<=m<=10000
熱身訓練-k皇後問題(主副對角線計算)
tro 變量 線下 with prev span med cell edi Gargari is jealous that his friend Caisa won the game from the previous problem. He wants to prove
FZU 1919 -- K-way Merging sort(記憶化搜索)
one initial map from max task sys fzu pointer 題目鏈接 Problem Description As we all known, merge sort is an O(nlogn) comparison-based s
hdu-1150(二分圖+匈牙利演算法)
題目連結:http://acm.hdu.edu.cn/showproblem.php?pid=1150 思路:題目中給出兩個機器A,B;給出k個任務,每個任務可以由A的x狀態或者B的y狀態來完成。 完成任務的順序可以任意改變,每次改變一次狀態需要重啟一次機器。 將每個狀態看做一個點,每個任務看做兩個狀態
【LeetCode題解】347_前K個高頻元素(Top-K-Frequent-Elements)
目錄 描述 解法一:排序演算法(不滿足時間複雜度要求) Java 實現 Python 實現 複雜度分析 解法二:最小堆 思路 Java 實現 Python 實現 複雜度分析 解法三:桶排序(bucket s
演算法優化(1):基礎知識-凸集,單峰函式,擬凸函式與凸函式,函式凹凸性定義
本文筆記介紹我最近學習的演算法優化的基礎知識,有: 最優化問題的一般形式 約束問題的分類及形式 優化問題的分類 單峰函式(Unimodal function)的定義 擬凸函式(Quasiconvex function)的定義
匈牙利演算法(二分圖匹配問題)
匈牙利演算法(二分圖匹配問題) 問題連結(杭電2063題):http://acm.hdu.edu.cn/showproblem.php?pid=2063 參考部落格:https://blog.csdn.net/cillyb/article/details/55511666 找伴侶是個遞迴
【NOIP2012提高】藍書(演算法競賽進階指南)刷題記錄——疫情控制(二分+樹上倍增+貪心)
題目:luogu1084. 題目大意:給定一棵樹,以及一些在樹上的軍隊.現在這些軍隊可以走動,並能在點上駐紮,從一條邊的一段走到另一端需要與這條的長度等價的時間.現在要求用最短的時間,使得所有葉子節點到根節點的路徑上有軍隊,且軍隊不能在根節點駐紮. 由於我們肯定更想讓一個點覆蓋的葉子節點
演算法模板:匈牙利演算法模板(二分圖匹配)
pascal匈牙利演算法模板 //匈牙利演算法模板 var i,j,n,m,so,x,y,ans,t:longint; h:array[1..200]of longint; p:array[1..400]of longint; bz,gcl:array[0..40
最短路演算法優化(dijkstra演算法+鄰接表+佇列優化,bellman演算法+鄰接表+佇列優化)
dijkstra演算法+鄰接表+佇列優化: #include<bits/stdc++.h> using namespace std; const int M=1000000000;
1281(二分圖--匈牙利演算法)
HDU - 1281(二分圖–匈牙利演算法) 小希和Gardon在玩一個遊戲:對一個N*M的棋盤,在格子裡放盡量多的一些國際象棋裡面的“車”,並且使得他們不能互相攻擊,這當然很簡單,但是Gardon限制了只有某些格子才可以放,小希還是很輕鬆的解決了這個問題(見下
K-inversions URAL - 1523 (DP+樹狀陣列)
連結 https://cn.vjudge.net/problem/URAL-1523 題意 給你一個1-n的序列 問長度為K的序列有多少種 思路 首先想到DP 遞推式 dp[i][j] = ∑dp[x][j-1] ( 1<x<i,a[x] > a[i
協同過濾推薦演算法的優化(稀疏矩陣的處理)
簡單的協同過濾演算法流程如下 (1)、計算其他使用者和你的相似度,可以使用反差表忽略一部分使用者 (2)、根據相似度的高低找出K個與你最相似的鄰居 (3)、在這些鄰居喜歡的物品中,根據鄰居與你的遠近程度算出每一件物品的推薦度 (4)、根據每一件物品的推薦度高低給你推薦物品。