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時最高,符合我們建立的數據集屬性。