K均值 - 案例实现(python)
K均值
- K均值案例(python)
- 背景介紹
- 算法定義
- K值的選取
- 案例實現(python)
- 數據集
- 代碼實現
- 運行結果
- 總結
- 參考文獻
K均值案例(python)
k均值聚類算法(k-means clustering algorithm)是一種迭代求解的聚類分析算法,在這一章里,你將使用有效的數據集對k-means聚類算法進行分析,并了解到數據挖掘中的若干重要概念。
背景介紹
k均值算法群集中的每個點都應靠近該群集的中心。要想實現kmeans算法,
首先我們選擇k,即我們想要在數據中找到的簇數。然后,以某種方式初始化這k個簇的中心,稱為質心。
然后,我們將數據中的每個點分配給質心最接近的點,然后將每個質心的位置重新計算為分配給其質心的所有點的均值。
下面介紹一個網站
這個網站能把kmeans算法的聚類過程動態圖畫出來,如圖我們點擊Add Centroid,添加了四個中心點
然后點擊GO,就能看到kmeans算法聚類的動畫過程
算法步驟
首先輸入k的值,即我們希望將數據集經過聚類得到k個分組;
從數據集中隨機選擇k個數據點作為初始聚類中心,對任意一個樣本點,求其到K個聚類中心的距離,將樣本點歸類到距離最小的中心的聚類,如此迭代n次;
每次迭代過程中,利用均值等方法更新各個聚類的中心點;
對K個聚類中心,利用2,3步迭代更新后,如果位置點變化很小,則認為達到穩定狀態,對不同的聚類塊和聚類中心可選擇不同的顏色標注。
算法優缺點
優點
1.kmeans算法原理比較簡單,實現起來也很容易,收斂速度較快。
2.聚類效果相對于其他聚類算法來說較好,算法的可解釋度比較強。
3.參數較少,主要需要調參的參數僅僅是簇數k。
缺點
1.字符串等非數值型數據不適用,kmeans算法基于均值計算,首先要求簇的平均值可以被定義和使用。
2.K-Means的第一步是確定k(要生成的簇的數目),對于不同的初始值K,可能會導致不同結果。
3.應用數據集存在局限性,適用于球狀或集中分布數據,不適用于特殊情況數據。
算法定義
k均值聚類是最著名的劃分聚類算法,給定一個數據點集合和需要的聚類數目k,k由用戶指定,其主要目的是將n個樣本點劃分為k個簇,使得相似的樣本盡量被分到同一個聚簇。
K值的選取
在實際應用中,由于Kmeans一般作為數據預處理,或者用于輔助分類貼標簽。所以k一般不會設置很大。對于k值的選取,一般采用以下幾種方法。
手肘法
手肘法的核心指標是SSE(sum of the squared errors誤差平方和)
聚類數k增大,數據劃分就會更精細,每個簇的聚合程度也會提高,從而誤差平方和SSE會逐漸變小。當k小于真實聚類數時,k的增大會增加每個簇的聚合程度,
故SSE的下降幅度會很大。當k到達真實聚類數時,再增加k所得到的聚合程度會迅速變小,所以SSE的下降幅度會驟減,
然后隨著k值的繼續增大而趨于平緩,由此可見SSE和k的關系圖是
一個手肘的形狀,而這個肘部對應的k值就是數據的真實聚類數。
具體做法是讓k從1開始取值直到取到你認為合適的上限,對每一個k值進行聚類并且記下對于的SSE,然后畫出k和SSE的關系圖,
最后選取肘部對應的k作為我們的最佳聚類數。
下圖利用了UCI上葡萄酒的數據集wine.data,然后用sklearn庫中自帶的k-means算法對K值的選取進行了可視化操作。
輪廓系數法
輪廓系數(silhouette coefficient)是簇的密集與分散程度的評價指標
計算樣本i到同一類中其他樣本的平均距離ai。如果ai越小,說明樣本i與同類中其他樣本的距離越近,即越相似。我們將ai稱為樣本i的類別內不相似度。
計算樣本i到其他類別的所有樣本的平均距離bi,稱為樣本i與其他類之間的不相似度。如果bi越大,說明樣本i與其他類之間距離越遠,即越不相似。
輪廓系數的值在-1和1之間,該值越接近于1,簇越緊湊,聚類越好。當輪廓系數接近1時,簇內緊湊,并遠離其他簇。其中,輪廓系數的計算如下所示:
案例實現(python)
數據集
數據集介紹
本章的數據樣本來源于UCI上的小麥種子數據集。部分數據集如下圖所示:
其中,數據集包含210個樣本。每個樣品具有7個屬性:面積A,周長P,緊密度C = 4piA / P ^ 2,籽粒長度,籽粒寬度,不對稱系數和籽粒凹槽長度。
所有這些參數都是實值連續的。數據集包含屬于三種不同小麥品種的籽粒:卡瑪,羅莎和加拿大。
| 屬性特征: | 真實 | 屬性數量: | 7 | 上傳日期: | 2012.9.29 |
| 相關人物: | 分類/聚類 | 缺值: | N/A | 瀏覽次數: | 326689 |
代碼實現
1、導入我們需要的庫
import matplotlib.pyplot as plt from numpy import * import numpy as np2、計算歐氏距離
#利用公式計算兩個向量p1與p2之間的距離,返回diff def get_distance(p1, p2):diff = (sum(power(p1 - p2, 2)))return diff3、導入數據
#1、根據數據文件的路徑file_path打開樣本數據 #2、將存儲的文本信息轉換成向量并傳出 def load_data(file_path):f = open(file_path)data = []for line in f.readlines():row = []lines = line.strip().split()for x in lines:row.append(float(x))data.append(row)f.close()return np.mat(data)4、初始化聚類中心
#參數 data:樣本數據點集合 #參數 k:已確定的最終聚類的類別數 #return:聚類中心集合my_cluster_center def random_data(my_data, k):sum = np.shape(my_data)[1] # 特征個數print(sum)my_cluster_center = np.mat(np.zeros((k, sum))) # 初始化k個聚類中心for j in range(sum): # 最小值+0-1之間的隨機數*變化范圍,即得到在最大最小值之間的隨機數Xmin = np.min(my_data[:, j]) #得到最小值Xrange = np.max(my_data[:, j]) - Xmin #得到隨機數的變化范圍my_cluster_center[:, j] = Xmin * np.mat(np.ones((k, 1))) + np.random.rand(k, 1) * Xrangeprint('初始化的聚類中心如下:')print(my_cluster_center)return my_cluster_center5、k_means算法聚類分析
#參數ata:樣本數據點集合 #參數k:聚類中心的個數 #參數cluster_center:傳進來的為初始的聚類中心集合 #首先,在數據集中選擇K個點作為每個簇的初始中心,接著觀察其他的數據,然后將這些數據劃分到距離這K個點最近的簇中, 這個過程將數據劃分成K個簇,從而完成第一次劃分。但實際算法過程中,形成的新簇不一定就是最好的劃分,因此在生成的新簇中, 再一次計算每個簇的中心點,然后進行劃分,直到每次劃分的結果保持不變為止。 def k_means(data, k, cluster_center):m, n = np.shape(data) # m:樣本個數;n:特征的維度sub_center = np.mat(np.zeros((m, 2))) # 初始化:每個樣本所屬的類別(m行n列:共m個樣本,第一列為所屬類的標號,第二列為最小距離)change = 1 # 判斷是否重新計算聚類中心while change == 1:change = 0for i in range(m):min_distance = np.inf # 初始樣本與聚類中心的最小值為正無窮Index = 0 #所屬類別for j in range(k):# 分別計算i到這k個聚類中心的距離,找到距離最近的diff = get_distance(data[i,], cluster_center[j,])if diff < min_distance:min_distance = diffIndex = j# 判斷所屬聚類中心是否發生變化(可能原本就屬于這個聚類中心)if sub_center[i, 0] != Index:change = 1sub_center[i,] = np.mat([Index, min_distance])# 重新計算聚類中心for j in range(k):all = np.mat(np.zeros((1, n))) # all記錄所有屬于中心j的樣本,在n個維度的總和r = 0 # 每個類別中的樣本個數for i in range(m):if sub_center[i, 0] == j: # 屬于第j個類別,計算進去all = all + data[i,]r = r + 1for a in range(n):try: # sum_all除以本中心的樣本個數r,即得到中心cluster_center[j, a] = all[0, a] / rexcept:print("沒有樣本屬于這個聚類中心!")# 打印,顯示聚類中心的變化過程print("聚類中心發生變化如下:")print(cluster_center)return cluster_center, sub_center6、保存數據
#把數據data寫入Myfile_name文件中,并保存 def save_result(Myfile_name, data):m, n = np.shape(data)f = open(Myfile_name, "w")for i in range(m):X = []for j in range(n):X.append(str(data[i, j]))f.write("\t".join(X) + "\n")f.close()7、畫圖
#輸出數據樣本點的總個數,并根據數據進行聚類分析,對每一個屬性進行聚類,并繪圖顯示 def draw(point_data, center, sub_center):Myfig = plt.figure()axes = Myfig.add_subplot(111)length = len(point_data)print(length)for a in range(length):if sub_center[a, 0] == 0:axes.scatter(point_data[a, 2], point_data[a, 3], color='m', alpha=0.4)if sub_center[a, 0] == 1:axes.scatter(point_data[a, 2], point_data[a, 3], color='b', alpha=0.4)if sub_center[a, 0] == 2:axes.scatter(point_data[a, 2], point_data[a, 3], color='g', alpha=0.4)for i in range(len(center)):axes.scatter(center[i, 2], center[i, 3], color='red', marker='p')plt.xlabel('X')plt.ylabel('Y')plt.title('kmeans-JYZ')plt.show()8、主函數
if __name__ == "__main__":K = 3 # 預設好聚類中心數kprint("第一步:導入樣本數據")sample_data = load_data("seeds.data")print("第二步:初始化k個聚類中心")cluster_center = random_data(sample_data, K)print("第三步:K_Means算法")cluster_center, sub_center = k_means(sample_data, K, cluster_center)print("第四步:保存最終的聚類中心")save_result("cluster_center.txt", cluster_center)print("第五步:保存每個樣本所屬類別")save_result("sub_center.txt", sub_center)# 畫圖draw(sample_data, cluster_center, sub_center)運行結果
第一步:導入樣本數據 第二步:初始化k個聚類中心 8 初始化的聚類中心如下: [[17.51686311 16.40829437 0.91619839 6.60986498 3.15821884 5.490055134.80842984 1.67208591][19.37741169 16.76073519 0.91290766 6.40031021 3.85596015 2.233959095.15480027 2.34787189][14.9196659 13.09405509 0.82642333 5.51808314 3.06647918 3.53024894.7662341 2.10372636]] 第三步:K_Means算法 聚類中心發生變化如下: [[17.81384615 15.93923077 0.87981154 6.0735 3.61865385 4.723307695.90411538 1.92307692][19.0005 16.40125 0.8873 6.24715 3.7551 2.9353756.11635 1.975 ][13.15833333 13.79847222 0.86487917 5.37635417 3.05568056 3.7279255.12176389 2.02083333]] 聚類中心發生變化如下: [[17.23121212 15.66787879 0.88107879 5.97942424 3.56660606 4.401272735.81918182 1.84848485][18.9372093 16.36790698 0.88761628 6.23623256 3.74776744 2.919744196.07788372 1.90697674][12.94813433 13.70589552 0.86318358 5.34711194 3.02578358 3.777994035.09188806 2.06716418]] 聚類中心發生變化如下: [[16.62634146 15.39829268 0.88052439 5.89009756 3.49668293 3.755563415.67960976 1.65853659][19.19767442 16.48046512 0.8879907 6.26725581 3.77960465 3.211534886.12765116 2. ][12.78412698 13.63063492 0.8621 5.32544444 3.00333333 3.848953175.07414286 2.11111111]] 聚類中心發生變化如下: [[15.944 15.0836 0.880146 5.78036 3.42138 3.1334625.50546 1.44 ][19.15104167 16.46916667 0.88708958 6.26885417 3.7729375 3.460416676.12725 2. ][12.51366071 13.50669643 0.86001875 5.28633036 2.96550893 4.055974115.056375 2.25 ]] 聚類中心發生變化如下: [[15.38075758 14.81636364 0.8797803 5.68925758 3.35859091 2.944653035.36257576 1.28787879][19.06 16.43176471 0.88679804 6.25333333 3.76323529 3.515470596.11290196 2. ][12.15903226 13.35 0.85610215 5.24280645 2.91091398 4.33775.05383871 2.50537634]] 聚類中心發生變化如下: [[15.06763889 14.66194444 0.87993194 5.63831944 3.32394444 2.849572225.28854167 1.22222222][18.96296296 16.39666667 0.88595185 6.24272222 3.74992593 3.540333336.10077778 2. ][12.01321429 13.29011905 0.85372857 5.22530952 2.88675 4.532083335.06521429 2.66666667]] 聚類中心發生變化如下: [[14.84614286 14.54828571 0.88059429 5.59571429 3.30232857 2.747617145.22582857 1.15714286][18.78677966 16.32915254 0.88474746 6.22098305 3.72767797 3.581881366.07911864 2. ][11.97938272 13.27962963 0.85269136 5.22535802 2.87914815 4.609604945.07677778 2.72839506]] 聚類中心發生變化如下: [[14.67805556 14.47152778 0.87971389 5.56618056 3.28319444 2.713461115.18791667 1.13888889][18.72180328 16.29737705 0.88508689 6.20893443 3.72267213 3.603590166.06609836 1.98360656][11.93675325 13.26441558 0.85168831 5.22703896 2.86797403 4.69940265.09263636 2.81818182]] 聚類中心發生變化如下: [[14.63202703 14.45324324 0.8790973 5.56178378 3.27489189 2.744043245.18493243 1.13513514][18.72180328 16.29737705 0.88508689 6.20893443 3.72267213 3.603590166.06609836 1.98360656][11.90906667 13.25026667 0.85154933 5.22233333 2.86509333 4.722186675.09304 2.86666667]] 聚類中心發生變化如下: [[14.63202703 14.45324324 0.8790973 5.56178378 3.27489189 2.744043245.18493243 1.13513514][18.72180328 16.29737705 0.88508689 6.20893443 3.72267213 3.603590166.06609836 1.98360656][11.90906667 13.25026667 0.85154933 5.22233333 2.86509333 4.722186675.09304 2.86666667]] 第四步:保存最終的聚類中心 第五步:保存每個樣本所屬類別 210總結
在這里,我們借助小麥種子seeds.data的數據集,介紹了K均值聚類算法的概念,以及利用python實現算法聚類分析以及可視化的過程, 并分析了kmeans算法的優缺點。主要思想就是把相似對象歸為同一簇,把不相似對象歸到不同簇。簇內的對象越相似,聚類的效果越好。
參考文獻
1.https://blog.csdn.net/weixin_42029738/article/details/81978038
2.https://blog.csdn.net/sinat_36710456/article/details/88019323
3.Ahmad EL ALLAOUI. Clustering Kmeans with Evolutionary Strategies[J]. International Journal of Imaging and Robotics?,2017,17(3).
4.劉子熠,張喆,高天,武強. Analysis of Pump Data Based on Association and Kmeans Algorithm[J]. 數據挖掘,2020,10(02).
5.Yi Yi Aung,Myat Myat Min. An Analysis of Kmeans Algorithm Based Network Intrusion Detection System[J]. Advances in Science, Technology and Engineering Systems,2018,3(1).
總結
以上是生活随笔為你收集整理的K均值 - 案例实现(python)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Set_output_delay怎么使用
- 下一篇: Python3网络爬虫:今日头条新闻Ap