sklearn機器學習:K-Means

K-Means類的格式

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=None, algorithm=’auto’)

重要參數:n_clusters

n_clusters是K-Means中的k,告訴模型要分幾類。是K-Means當中唯一必填的參數,默認爲8類,但通常聚類結果會是一個小於8的結果。通常,在開始聚類之前,並不知道n_clusters究竟是多少,因此要對它進行探索。
當拿到一個數據集,如果可能的話,希望能夠通過繪圖先觀察一下這個數據集的數據分佈,以此來爲聚類時輸入的n_clusters做一個參考。
首先,創建一個有標籤的數據集。

import matplotlib.pyplot as plt
from sklearn.datasets import make_blobs
#自己創建數據集
X, y = make_blobs(n_samples=500,n_features=2,centers=4,random_state=1)
#看一下點的分佈情況
color = ["red","pink","orange","gray"]
for i in range(4):
    plt.scatter(X[y==i, 0], X[y==i, 1]
                ,marker='o' #點的形狀
                ,s=8 #點的⼤大⼩小
                ,c=color[i]
                )
plt.show()

在這裏插入圖片描述
基於這個分佈,使用K-Means聚類。首先,猜測一下,這個數據中有幾簇?

from sklearn.cluster import KMeans
#先用k=3試試
n_clusters = 3
cluster = KMeans(n_clusters=n_clusters, random_state=0).fit(X)
#重要屬性labels_,查看聚好的類別,每個樣本所對應的類
y_pred = cluster.labels_
y_pred
array([0, 0, 2, 1, 2, 1, 2, 2, 2, 2, 0, 0, 2, 1, 2, 0, 2, 0, 1, 2, 2, 2,
       2, 1, 2, 2, 1, 1, 2, 2, 0, 1, 2, 0, 2, 0, 2, 2, 0, 2, 2, 2, 1, 2,
       2, 0, 2, 2, 1, 1, 1, 2, 2, 2, 0, 2, 2, 2, 2, 2, 1, 1, 2, 2, 1, 2,
       0, 2, 2, 2, 0, 2, 2, 0, 2, 2, 0, 2, 2, 2, 1, 1, 2, 1, 1, 2, 2, 1,
       ...
       0, 2, 2, 0, 2, 2, 2, 0, 2, 1, 2, 2, 0, 0, 0, 2])
#KMeans因爲並不需要建立模型或者預測結果,因此只需要fit就能夠得到聚類結果
#KMeans也有接口predict和fit_predict,表示學習數據X並對X的類進行預測
#但所得到的結果和我們不調用predict,直接fit之後調用屬性labels一模一樣
pre = cluster.fit_predict(X)
pre == y_pred
array([ True,  True,  True,  True,  True,  True,  True,  True,  True,
        True,  True,  True,  True,  True,  True,  True,  True,  True,
        True,  True,  True,  True,  True,  True,  True,  True,  True,
		...
        True,  True,  True,  True,  True])
#什麼時候需要predict呢?當數據量太大的時候
#其實不必使用所有的數據來尋找質⼼,少量的數據就可以幫助我們確定質⼼
#當數據量非常大的時候,可以使用部分數據來幫助我們確認質⼼
#剩下的數據的聚類結果,使用predict來調用
cluster_smallsub = KMeans(n_clusters=n_clusters, random_state=0).fit(X[:200])
y_pred_ = cluster_smallsub.predict(X)
y_pred == y_pred_
'''但這樣的結果,肯定與直接fit全部數據會不一致。有時候,當我們不要求那麼精確,或者我們的數據量
實在太大,可以使用這樣的方法。'''
array([False, False,  True, False,  True, False,  True,  True,  True,
        True, False, False,  True, False,  True, False,  True, False,
       False,  True,  True,  True,  True, False,  True,  True, False,
       ...
       True, False, False, False,  True])
#重要屬性cluster_centers_,查看質⼼
centroid = cluster.cluster_centers_
centroid
array([[-7.09306648, -8.10994454],
       [-1.54234022,  4.43517599],
       [-8.0862351 , -3.5179868 ]])
centroid.shape
(3, 2)
#重要屬性inertia_,查看總距離平方和
inertia = cluster.inertia_
inertia
1903.4503741659223
#查看聚類
color = ["red","pink","orange","gray"]
for i in range(n_clusters):
    plt.scatter(X[y_pred==i, 0], X[y_pred==i, 1]
                ,marker='o' #點的形狀
                ,s=8 #點的大小
                ,c=color[i]
                )

在這裏插入圖片描述

#查看質心
plt.scatter(centroid[:,0],centroid[:,1]
            ,marker="x"
            ,s=15
            ,c="black");

在這裏插入圖片描述

#如果我們把猜測的簇數換成4,Inertia會怎麼樣?
n_clusters = 4
cluster_ = KMeans(n_clusters=n_clusters, random_state=0).fit(X)
inertia_ = cluster_.inertia_
inertia_
908.3855684760613
n_clusters = 5
cluster_ = KMeans(n_clusters=n_clusters, random_state=0).fit(X)
inertia_ = cluster_.inertia_
inertia_
811.0841324482415
n_clusters = 6
cluster_ = KMeans(n_clusters=n_clusters, random_state=0).fit(X)
inertia_ = cluster_.inertia_
inertia_
733.153835008308

可見,隨着質心數量的增加,inertia_(總距離平方和)下降,SSE收斂率在k=4時最高,符合我們建立的數據集屬性。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章