首頁 > 軟體

如何利用python實現kmeans聚類

2022-05-17 16:00:24

一、先上手擼程式碼!

1、首先是匯入所需要的庫和資料

import pandas as pd
import numpy as np
import random
import math
import matplotlib.pyplot as plt
 
# 這兩行程式碼解決 plt 中文顯示的問題
plt.rcParams['font.sans-serif'] = ['SimHei']
plt.rcParams['axes.unicode_minus'] = False
 
df = pd.read_excel('13信科學生成績.xlsx')
data = np.array(df)
 
df.head(10)

先給大夥們看看資料集長啥樣:

用matplotlib簡單的視覺化一下初始資料:

# 輸入資料
x = data.T[0]
y = data.T[1]
 
plt.scatter(x, y, s=50, c='r')  # 畫散點圖
plt.xlabel('平時')  # 橫座標軸標題
plt.ylabel('期末')  # 縱座標軸標題
plt.show()

 2、接下來就是kmeans的核心演演算法了

k=3
i = 1
 
min1 = data.min(axis = 0)
max1 = data.max(axis = 0)
 
#在資料最大最小值中隨機生成k個初始聚類中心,儲存為t
centre = np.empty((k,2))
for i in range(k):
    centre[i][0] = random.randint(min1[0],max1[0])#平時成績
    centre[i][1] = random.randint(min1[1],max1[1])#期末成績
 
while i<500:
    
    #計算歐氏距離
    def euclidean_distance(List,t):
        return math.sqrt(((List[0] - t[0])**2 + (List[1] - t[1])**2))
 
    #每個點到每個中心點的距離矩陣
    dis = np.empty((len(data),k))
    for i in range(len(data)):
        for j in range(k):
            dis[i][j] = euclidean_distance(data[i],centre[j])
    
    #初始化分類矩陣
    classify = []
    for i in range(k):
        classify.append([])
    
    #比較距離並分類
    for i in range(len(data)):
        List = dis[i].tolist()
        index = List.index(dis[i].min())
        classify[index].append(i)
    
    #構造新的中心點
    new_centre = np.empty((k,2))
    for i in range(len(classify)):
 
        new_centre[i][0] = np.sum(data[classify[i]][0])/len(classify[i])
        new_centre[i][1] = np.sum(data[classify[i]][1])/len(classify[i])
     
    #比較新的中心點和舊的中心點是否一樣
    if (new_centre == centre).all():
        break
    else:
        centre = new_centre
        i = i + 1
 
# print('迭代次數為:',i)
print('聚類中心為:',new_centre)
print('分類情況為:',classify)

注意!!!這裡的k是指分成k類,讀者可以自行選取不同的k值做實驗

3、視覺化部分(將不用類用不同顏色區分開來~~)

mark = ['or', 'ob', 'og', 'ok','sb', 'db', '<b', 'pb'] #紅、藍、綠、黑四種顏色的圓點
#mark=['sb', 'db', '<b', 'pb']
plt.figure(3)#建立圖表1  
for i in range(0,k):
 
    x=[]
    y=[]
    for j in range(len(classify[i])):
        x.append(data[classify[i][j]][0])
        y.append(data[classify[i][j]][1])
 
    plt.xlim(xmax=105,xmin=45)
    plt.ylim(ymax=85,ymin=-5)
    plt.plot(x,y,mark[i])
    #plt.show()

 一起來康康視覺化結果8!!

二、接下來是調庫程式碼!(sklearn)

import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
from sklearn.cluster import KMeans  
from sklearn import metrics
 
df = pd.read_excel('13信科學生成績.xlsx')
data = np.array(df)
y_pred=KMeans(n_clusters=3,random_state=9).fit_predict(data)
plt.scatter(data[:,0],data[:,1],c=y_pred)
plt.show()
print(metrics.calinski_harabasz_score(data,y_pred))

 視覺化結果和手擼的結果略有差別,有可能是資料集的問題,也有可能是k值選取的問題,各位親們不需要擔心!!!

附:對k-means演演算法的認識

1.優點

(1)演演算法快速、簡單。

(2)對巨量資料集有較高的效率並且是可伸縮性的。

(3)時間複雜度近於線性,而且適合挖掘大規模資料集。K-Means聚類演演算法的時間複雜度是O(nkt) ,其中n代表資料集中物件的數量,t代表著演演算法迭代的次數,k代表著簇的數目。

2.缺點

(1)聚類是一種無監督的學習方法,在 K-means 演演算法中 K 是事先給定的,K均值演演算法需要使用者指定建立的簇數k,但這個 K 值的選定是非常難以估計的。

(2)在 K-means 演演算法中,首先需要根據初始聚類中心來確定一個初始劃分,然後對初始劃分進行優化。這個初始聚類中心的選擇對聚類結果有較大的影響,一旦初始值選擇的不好,可能無法得到有效的聚類結果,這也成為 K-means演演算法的一個主要問題。

(3)從 K-means 演演算法框架可以看出,該演演算法需要不斷地進行樣本分類調整,不斷地計算調整後的新的聚類中心,因此當資料量非常大時,演演算法的時間開銷是非常大的。所以需要對演演算法的時間複雜度進行分析、改進,提高演演算法應用範圍,而這導致K均值演演算法在巨量資料集上收斂較慢。

總結

到此這篇關於如何利用python實現kmeans聚類的文章就介紹到這了,更多相關python實現kmeans聚類內容請搜尋it145.com以前的文章或繼續瀏覽下面的相關文章希望大家以後多多支援it145.com!


IT145.com E-mail:sddin#qq.com