1、K-Means聚類算法
K表示超參數個數,如分成幾個類別,K值就取多少。若無需求,可使用網格搜索找到最佳的K。
步驟:
1、隨機設置K個特征空間內的點作為初始聚類中心;
2、對于其他每個點計算到K個中心的距離,未知的點選擇最近的一個聚類中心點作為標記種類;
3、接著對標記的聚類中心之后,重新計算出每個聚類的中心點(平均值);
4、如果計算得出的新中心點與原中心點一樣,那么結束,否則執行第二步。
means表示尋找新的聚類中心點是采用特征平均值確定。
2、K-means圖解
具體演示視頻可查看(B站UP主:KnowingAI知智)
若我們手上有一些水果,我們希望對它們進行分類,假設分為兩類,則此時K=2。
step1:隨機選取兩個樣本點作為聚類中心點centrol
step2:計算其他每個樣本與聚類中心centrol的距離,距離誰近就歸為哪類,一般采用歐氏距離。
step3:根據已分類的結果,重新計算聚類中心,聚類中心是已分類的所有樣本的平均值(means)
然后重復之前的步驟,重新計算距離進行劃分,直到某一次計算聚類中心點和上次相同,則聚類結束。
3、聚類算法優缺點分析
聚類算法不需要手動設置標簽,故屬于無監督學習,相比于監督學習,它更加簡單、易于理解,但是準確率方面不如監督學習。
4、K-Means()算法實現案例
API調用:
API:sklearn.cluster.KMeans(n_clusters=8, init='k=means++')
n_cluster:初始聚類中心數量,即K值
from sklearn.cluster import KMeans
import numpy as np
import matplotlib.pyplot as plt
# 生成示例數據,100個二維數據,橫坐標縱坐標都在0-1范圍內
X = np.random.rand(100, 2)
# 創建K-means模型
kmeans = KMeans(n_clusters=3)
# 訓練模型
kmeans.fit(X)
# 獲取聚類結果
labels = kmeans.labels_
# 獲取每個數據點的簇標簽。labels_是一個數組,表示每個數據點所屬的簇的索引。
centroids = kmeans.cluster_centers_
# 獲取每個簇的質心坐標。cluster_centers_是一個形狀為(n_clusters, n_features)的數組,表示每個簇的質心位置。
# 可視化結果
plt.scatter(X[:, 0], X[:, 1], c=labels, cmap='viridis')
plt.scatter(centroids[:, 0], centroids[:, 1], s=300, c='red', marker='x')
plt.show()
5、聚類效果的評估(輪廓系數評估法)
內部距離最小化,外部距離最大化
輪廓系數: S C i = b i ? a i m a x ( b i , a i ) SCi=\frac{b_i-a_i}{max(b_i,a_i)} SCi=max(bi?,ai?)bi??ai??
b i b_i bi?:一個簇內某個樣本到其他簇的所有樣本距離的最小值
a i a_i ai?:一個簇內某個樣本到本身簇內所有樣本距離的平均值
b i > > a i b_i>>a_i bi?>>ai? 此時 S C i ≈ 1 SCi≈1 SCi≈1 效果好
b i < < a i b_i<<a_i bi?<<ai? 此時 S C i ≈ ? 1 SCi≈-1 SCi≈?1 效果差
輪廓系數取值范圍在 ( ? 1 , 1 ) (-1,1) (?1,1),越接近 1 1 1,聚類效果越好,越接近 ? 1 -1 ?1,聚類效果越差
from sklearn.metrics import silhouette_score #計算輪廓系數,傳入樣本點和分類標簽
如上例中,加上如下代碼
from sklearn.metrics import silhouette_score
score = silhouette_score(X,labels)
print(f"輪廓系數為{score}")
輪廓系數為0.3873688462341751,分類效果一般。可以加一個循環找到一定范圍內最優的K值,此處用輪廓系數衡量
from sklearn.cluster import KMeans
from sklearn.metrics import silhouette_score
import numpy as np
import matplotlib.pyplot as plt
# 生成示例數據,100個二維數據,橫坐標縱坐標都在0-1范圍內
X = np.random.rand(100, 2)
# 創建K-means模型
best_score=0
for k in range(2,11):kmeans = KMeans(n_clusters=k)# 訓練模型kmeans.fit(X)# 獲取聚類結果labels = kmeans.labels_# 獲取每個數據點的簇標簽。labels_是一個數組,表示每個數據點所屬的簇的索引。centroids = kmeans.cluster_centers_score = silhouette_score(X,labels)if score > best_score:best_score = scorebest_k = k
print(f'最佳簇數: {best_k}, 輪廓系數: {best_score}')
# 最佳簇數: 4, 輪廓系數: 0.42684837185343705