數據挖掘-聚類分析(Python實現K-Means算法)


概念:

聚類分析(cluster analysis ):是一組將研究對象分為相對同質的群組(clusters)的統計分析技術。聚類分析也叫分類分析,或者數值分類。聚類的輸入是一組未被標記的樣本,聚類根據數據自身的距離或者相似度將其划分成若干個組,划分的原則是組內距離最小化而組間(外部)距離最大化。聚類和分類的不同在於:聚類所要求划分的類是未知的。

 

聚類度量的方法:分距離和相似度來度量。

聚類研究分析的方法:

1.層次的方法(hierarchical  method)

2.划分方法(partitioning method)

3.基於密度的方法(density-based method)DBSCAN

4.基於網格的方法(grid-based method)

5.基於模型的方法(model-based method)

 

•K-Means 算法:

•受離群點的影響較大,由於其迭代每次的中心點到全部樣本點的距離和的平均值。

優點:

  • 原理簡單
  • 速度快
  • 對大數據集有比較好的伸縮性

缺點:

  • 需要指定聚類 數量K
  • 對異常值敏感
  • 對初始值敏感

•以歐式距離來衡量距離大小,使用誤差平方和(Sum of the Squared Error,SSE作為聚類的目標函數:

k表示k個聚類中心,ci表示第幾個中心,dist表示的是歐幾里得距離

•算法步驟;

•創建k個點作為初始的質心點(隨機選擇)

•當任意一個點的簇分配結果發生改變時

•       對數據集中的每一個數據點

•              對每一個質心

•                     計算質心與數據點的距離

•              將數據點分配到距離最近的簇

•       對每一個簇,計算簇中所有點的均值,並將均值作為質心

•算法圖示:

Python代碼實現K-Means算法:

有關於 .A 的用法:(flatten()函數可以是多維數組變換成一維數組, .A 則使得matrix 形式轉化成 array 形式)

>>> import numpy as np >>> demo_a2 = np.mat([[1,3],[2,4],[3,5]]) >>> demo_a2 matrix([[1, 3], [2, 4], [3, 5]]) >>> demo_a2.flatten() matrix([[1, 3, 2, 4, 3, 5]]) >>> demo_a2.flatten().A array([[1, 3, 2, 4, 3, 5]]) >>> demo_a2.flatten().A[0] array([1, 3, 2, 4, 3, 5])

#定義一個歐式距離的函數 :

#coding=gbk ''' Created on 2018年7月17日 @author: Administrator ''' # k-means 算法python實現 import numpy as np def distEclud(vecA, vecB): #定義一個歐式距離的函數 return np.sqrt(np.sum(np.power(vecA - vecB, 2))) print('----test_distEclud-----') vecA, vecB = np.array([1,1]), np.array([2,1]) distance = distEclud(vecA, vecB) print(distance) # 1.0 計算兩點之間的距離

隨機設置k個中心點:

def randCent(dataSet, k): #第一個中心點初始化 n = np.shape(dataSet)[1] centroids = np.mat(np.zeros([k, n])) #創建 k 行 n列的全為0 的矩陣 for j in range(n): minj = np.min(dataSet[:,j]) #獲得第j 列的最小值 rangej = float(np.max(dataSet[:,j]) - minj) #得到最大值與最小值之間的范圍 #獲得輸出為 K 行 1 列的數據,並且使其在數據集范圍內 centroids[:,j] = np.mat(minj + rangej * np.random.rand(k, 1)) return centroids print('----test_randCent-----') dataSet1 = np.array([[1,2],[3,6],[8,10],[12,23],[10,11],[13,18]]) print(dataSet1[1,:]) r = randCent(dataSet1, 2) print(r) # [[ 8.83544015 16.75467081] # [ 2.85688493 4.4799291 ]] np.random.seed(666) #定義一個隨機種子 rand_num = np.random.rand(3,1) #輸出為3行1 列,隨機數在 0 到 1 之間 print(rand_num) # [[0.70043712] # [0.84418664] # [0.67651434]] test = np.mat(np.zeros([3,2])) #此處的 zeros 函數內的矩陣形式需要加中括號 [] print(test) # [[0. 0.] #打印出 3行 2列的矩陣 # [0. 0.] # [0. 0.]] 

定義KMeans函數:

#參數: dataSet 樣本點, K 簇的個數 #disMeans 距離, 默認使用歐式距離, createCent 初始中心點的選取 def KMeans(dataSet, k, distMeans= distEclud, createCent= randCent): m = np.shape(dataSet)[0] #得到行數,即為樣本數 clusterAssement = np.mat(np.zeros([m,2])) #創建 m 行 2 列的矩陣 centroids = createCent(dataSet, k) #初始化 k 個中心點 clusterChanged = True while clusterChanged: clusterChanged = False for i in range(m): minDist = np.inf #初始設置值為無窮大 minIndex = -1 for j in range(k): # j循環,先計算 k個中心點到1 個樣本的距離,在進行i循環,計算得到k個中心點到全部樣本點的距離 distJ = distMeans(centroids[j,:], dataSet[i,:]) if distJ < minDist: minDist = distJ #更新 最小的距離 minIndex = j if clusterAssement[i,0] != minIndex: #如果中心點不變化的時候, 則終止循環 clusterChanged = True clusterAssement[i,:] = minIndex, minDist**2 #將 index,k值中心點 和 最小距離存入到數組中 print(centroids) #更換中心點的位置 for cent in range(k): ptsInClust = dataSet[np.nonzero(clusterAssement[:,0].A == cent)[0]] #分別找到屬於k類的數據 centroids[cent,:] = np.mean(ptsInClust, axis = 0) #得到更新后的中心點 return centroids, clusterAssement print('------test-----') demo_a = np.array([[1,0],[0,2],[0,0]]) non_a = np.nonzero(demo_a) print(demo_a) # [[1 0] # [0 2] # [0 0]] print(non_a) # 輸出的第一行為 行數, 第二行為列數,意思為 1行1列的數 和2行2列的數 是非0數 # (array([0, 1], dtype=int64), array([0, 1], dtype=int64)) demo_a1 = np.array([1,2,0,0,1]) #當只有一行時 non_a1 = np.nonzero(demo_a1) print(non_a1) # (array([0, 1, 4], dtype=int64),) a1 = np.inf > 100000 print(a1) # True inf 是無窮大 print('---------- test KMeans ---------') dataSet = np.mat([[ 0.90796996 ,5.05836784],[-2.88425582 , 0.01687006], [-3.3447423 , -1.01730512],[-0.32810867 , 0.48063528] ,[ 1.90508653 , 3.530091 ] ,[-3.00984169 , 2.66771831] ,[-3.38237045 ,-2.9473363 ] ,[ 2.22463036 ,-1.37361589] ,[ 2.54391447 , 3.21299611] ,[-2.46154315 , 2.78737555] ,[-3.38237045 ,-2.9473363 ] ,[ 2.8692781 ,-2.54779119] ,[ 2.6265299 , 3.10868015] ,[-2.46154315 , 2.78737555] ,[-3.38237045 ,-2.9473363 ] ,[ 2.80293085 ,-2.7315146 ]]) print(dataSet) center, cluster = KMeans(dataSet, 2) print('----') print(center) # [[-1.05990877 -2.0619207 ] # [-0.03469197 2.95415497]] print('----') print(cluster) # [[ 1. 5.31632331] # [ 0. 7.6496132 ] # [ 0. 6.31168598] # [ 1. 6.20439303] # [ 1. 4.09444295] # [ 1. 8.93356179] # [ 0. 6.17778903] # [ 0. 11.26196081] # [ 1. 6.71620993] # [ 1. 5.917422 ] # [ 0. 6.17778903] # [ 0. 15.67457959] # [ 1. 7.1059799 ] # [ 1. 5.917422 ] # [ 0. 6.17778903] # [ 0. 15.36988591]]

 

python中kmeans的參數:

sklearn.cluster.KMeans(
    n_clusters=8, init='k-means++', n_init=10, max_iter=300, tol=0.0001, precompute_distances='auto', verbose=0, random_state=None, copy_x=True, n_jobs=1, algorithm='auto' ) n_clusters: 簇的個數,即你想聚成幾類 init: 初始簇中心的獲取方法 n_init: 獲取初始簇中心的更迭次數,為了彌補初始質心的影響,算法默認會初始10個質心,實現算法,然后返回最好的結果。 max_iter: 最大迭代次數(因為kmeans算法的實現需要迭代) tol: 容忍度,即kmeans運行准則收斂的條件 precompute_distances:是否需要提前計算距離,這個參數會在空間和時間之間做權衡,如果是True 會把整個距離矩陣都放到內存中,auto 會默認在數據樣本大於featurs*samples 的數量大於12e6 的時候False,False 時核心實現的方法是利用Cpython 來實現的 verbose: 冗長模式(不太懂是啥意思,反正一般不去改默認值) random_state: 隨機生成簇中心的狀態條件。 copy_x: 對是否修改數據的一個標記,如果True,即復制了就不會修改數據。bool 在scikit-learn 很多接口中都會有這個參數的,就是是否對輸入數據繼續copy 操作,以便不修改用戶的輸入數據。這個要理解Python 的內存機制才會比較清楚。 n_jobs: 並行設置 algorithm: kmeans的實現算法,有:’auto’, ‘full’, ‘elkan’, 其中 ‘full’表示用EM方式實現 雖然有很多參數,但是都已經給出了默認值。所以我們一般不需要去傳入這些參數,參數的。可以根據實際需要來調用。

•基於密度的方法;

•DBSCAN (需要指定半徑,對離群點的尋找作用很大):

•大圓:核心對象,周圍半徑內有多於min_samples 個點

•小圓:非核心對象,周圍少於 min_samples 個點

•黑色點:離群點和任何核心對象之間的距離大於閾值

 

參考:https://blog.csdn.net/taoyanqi8932/article/details/53727841


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM