大量數據中具有"相似"特征的數據點或樣本划分為一個類別。聚類分析提供了樣本集在非監督模式下的類別划分。聚類的基本思想是"物以類聚、人以群分",將大量數據集中相似的數據樣本區分出來,並發現不同類的特征。
聚類模型可以建立在無類標記的數據上,是一種非監督的學習算法。盡管全球每日新增數據量以PB或EB級別增長,但是大部分數據屬於無標注甚至非結構化。所以相對於監督學習,不需要標注的無監督學習蘊含了巨大的潛力與價值。聚類根據數據自身的距離或相似度將他們划分為若干組,划分原則是組內樣本最小化而組間距離最大化。
常見聚類算法聚類效果對比圖
聚類分析常用於數據探索或挖掘前期
沒有先驗經驗做探索性分析
樣本量較大時做預處理
常用於解決
數據集可以分幾類;每個類別有多少樣本量
不同類別中各個變量的強弱關系如何
不同類型的典型特征是什么
一般應用場景
群類別間的差異性特征分析
群類別內的關鍵特征提取
圖像壓縮、分割、圖像理解
異常檢測
數據離散化
當然聚類分析也有其缺點
無法提供明確的行動指向
數據異常對結果有影響
本文將從算法原理、優化目標、sklearn聚類算法、算法優缺點、算法優化、算法重要參數、衡量指標以及案例等方面詳細介紹KMeans算法。
KMeans
K均值(KMeans)是聚類中最常用的方法之一,基於點與點之間的距離的相似度來計算最佳類別歸屬。
KMeans算法通過試着將樣本分離到 個方差相等的組中來對數據進行聚類,從而最小化目標函數 (見下文)。該算法要求指定集群的數量。它可以很好地擴展到大量的樣本,並且已經在許多不同領域的廣泛應用領域中使用。
被分在同一個簇中的數據是有相似性的,而不同簇中的數據是不同的,當聚類完畢之后,我們就要分別去研究每個簇中的樣本都有什么樣的性質,從而根據業務需求制定不同的商業或者科技策略。常用於客戶分群、用戶畫像、精確營銷、基於聚類的推薦系統。
算法原理
從 個樣本數據中隨機選取 個質心作為初始的聚類中心。質心記為
定義優化目標
開始循環,計算每個樣本點到那個質心到距離,樣本離哪個近就將該樣本分配到哪個質心,得到K個簇
對於每個簇,計算所有被分到該簇的樣本點的平均距離作為新的質心
直到 收斂,即所有簇不再發生變化。
KMeans迭代示意圖
優化目標
KMeans 在進行類別划分過程及最終結果,始終追求"簇內差異小,簇間差異大",其中差異由樣本點到其所在簇的質心的距離衡量。在KNN算法學習中,我們學習到多種常見的距離 ---- 歐幾里得距離、曼哈頓距離、余弦距離。
在sklearn中的KMeans使用歐幾里得距離:
則一個簇中所有樣本點到質心的距離的平方和為: 其中, 為一個簇中樣本的個數, 是每個樣本的編號。這個公式被稱為簇內平方和 (cluster Sum of Square) , 又叫做 Inertia 。
而將一個數據集中的所有簇的簇內平方和相加,就得到了整體平方和(Total Cluster Sum of Square),又叫做Total Inertia。Total Inertia越小,代表着每個簇內樣本越相似,聚類的效果就越好。因此 KMeans 追求的是,求解能夠讓Inertia最小化的質心。
KMeans有損失函數嗎?
損失函數本質是用來衡量模型的擬合效果的,只有有着求解參數需求的算法,才會有損失函數。KMeans不求解什么參數,它的模型本質也沒有在擬合數據,而是在對數據進行一 種探索。
另外,在決策樹中有衡量分類效果的指標准確度accuracy,准確度所對應的損失叫做泛化誤差,但不能通過最小化泛化誤差來求解某個模型中需要的信息,我們只是希望模型的效果上表現出來的泛化誤差很小。因此決策樹,KNN等算法,是絕對沒有損失函數的。
雖然在sklearn中只能被動選用歐式距離,但其他距離度量方式同樣可以用來衡量簇內外差異。不同距離所對應的質心選擇方法和Inertia如下表所示, 在KMeans中,只要使用了正確的質心和距離組合,無論使用什么樣的距離,都可以達到不錯的聚類效果。
距離度量 質心 Inertia
歐幾里得距離 均值 最小化每個樣本點到質心的歐式距離之和
曼哈頓距離 中位數 最小化每個樣本點到質心的曼哈頓距離之和
余弦距離 均值 最小化每個樣本點到質心的余弦距離之和
sklearn.cluster.KMeans
語法:
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')
參數與接口詳解見文末附錄
例:
>>> from sklearn.cluster import KMeans
>>> import numpy as np
>>> X = np.array([[1, 2], [1, 4], [1, 0],
... [10, 2], [10, 4], [10, 0]])
>>> kmeans = KMeans(n_clusters=2, random_state=0).fit(X)
>>> kmeans.labels_
array([1, 1, 1, 0, 0, 0], dtype=int32)
>>> kmeans.predict([[0, 0], [12, 3]])
array([1, 0], dtype=int32)
>>> kmeans.cluster_centers_
array([[10., 2.],
[ 1., 2.]])
KMeans算法優缺點
優點
KMeans算法是解決聚類問題的一種經典算法, 算法簡單、快速 。
算法嘗試找出使平方誤差函數值最小的 個划分。當簇是密集的、球狀或團狀的,且簇與簇之間區別明顯時,聚類效果較好 。
缺點
KMeans方法只有在簇的平均值被定義的情況下才能使用,且對有些分類屬性的數據不適合。
要求用戶必須事先給出要生成的簇的數目 。
對初值敏感,對於不同的初始值,可能會導致不同的聚類結果。
不適合於發現非凸面形狀的簇,或者大小差別很大的簇。
KMeans本質上是一種基於歐式距離度量的數據划分方法,均值和方差大的維度將對數據的聚類結果產生決定性影響。所以在聚類前對數據(具體的說是每一個維度的特征)做歸一化(點擊查看歸一化詳解)和單位統一至關重要。此外,異常值會對均值計算產生較大影響,導致中心偏移,因此對於"噪聲"和孤立點數據最好能提前過濾 。
KMeans算法優化
KMeans算法雖然效果不錯,但是每一次迭代都需要遍歷全量的數據,一旦數據量過大,由於計算復雜度過大迭代的次數過多,會導致收斂速度非常慢。
由KMeans算法原來可知,KMeans在聚類之前首先需要初始化 個簇中心,因此 KMeans算法對初值敏感,對於不同的初始值,可能會導致不同的聚類結果。因初始化是個"隨機"過程,很有可能 個簇中心都在同一個簇中,這種情況 KMeans 聚類算法很大程度上都不會收斂到全局最小。
想要優化KMeans算法的效率問題,可以從以下兩個思路優化算法,一個是樣本數量太大,另一個是迭代次數過多。
MiniBatchKMeans 聚類算法
mini batch 優化思想非常朴素,既然全體樣本當中數據量太大,會使得我們迭代的時間過長,那么隨機從整體當中做一個抽樣,選取出一小部分數據來代替整體以達到縮小數據規模的目的。
mini batch 優化非常重要,不僅重要而且在機器學習領域廣為使用。在大數據的場景下,幾乎所有模型都需要做mini batch優化,而MiniBatchKMeans就是mini batch 優化的一個應用。直接上模型比較MiniBatchKMeans和KMeans兩種算法計算速度(樣本量1,000,000)
KMeans用時接近 6 秒鍾,而MiniBatchKMeans 僅用時不到 1 秒鍾
且聚類中心基本一致
>>> KMeans.cluster_centers_
array([[-2.50889102, 9.01143598],
[-6.88150415, -6.88090477],
[ 4.63628843, 1.97271152],
[-8.83895916, 7.32493568]])
>>> MiniBatchKMeans.cluster_centers_
array([[-2.50141353, 8.97807161],
[-6.88418974, -6.87048909],
[ 4.65410395, 1.99254911],
[-8.84903186, 7.33075289]])
mini batch 優化方法是通過減少計算樣本量來達到縮短迭代時長,另一種方法是降低收斂需要的迭代次數,從而達到快速收斂的目的。收斂的速度除了取決於每次迭代的變化率之外,另一個重要指標就是迭代起始的位置。
2007年Arthur, David, and Sergei Vassilvitskii三人發表了論文"k-means++: The advantages of careful seeding" http://ilpubs.stanford.edu:8090/778/1/2006-13.pdf,他們開發了'k-means++'初始化方案,使得初始質心(通常)彼此遠離,以此來引導出比隨機初始化更可靠的結果。
'k-means++' 聚類算法
'k-means++'聚類算法是在KMeans算法基礎上,針對迭代次數,優化選擇初始質心的方法。sklearn.cluster.KMeans 中默認參數為 init='k-means++',其算法原理為在初始化簇中心時,逐個選取 個簇中心,且離其他簇中心越遠的樣本越有可能被選為下個簇中心。
算法步驟:
從數據即 中隨機(均勻分布)選取一個樣本點作為第一個初始聚類中心
計算每個樣本與當前已有聚類中心之間的最短距離;再計算每個樣本點被選為下個聚類中心的概率,最后選擇最大概率值所對應的樣本點作為下一個簇中心
重復上步驟,直到選擇個聚類中心
'k-means++'算法初始化的簇中心彼此相距都十分的遠,從而不可能再發生初始簇中心在同一個簇中的情況。當然'k-means++'本身也具有隨機性,並不一定每一次隨機得到的起始點都能有這么好的效果,但是通過策略,我們可以保證即使出現最壞的情況也不會太壞。
'k-means++' code:
def InitialCentroid(x, K):
c1_idx = int(np.random.uniform(0, len(x))) # Draw samples from a uniform distribution.
centroid = x[c1_idx].reshape(1, -1) # choice the first center for cluster.
k = 1
n = x.shape[0] # number of samples
while k d2 = []
for i in range(n):
subs = centroid - x[i, :] # D(x) = (x_1, y_1) - (x, y)
dimension2 = np.power(subs, 2) # D(x)^2
dimension_s = np.sum(dimension2, axis=1) # sum of each row
d2.append(np.min(dimension_s))
new_c_idx = np.argmax(d2)
centroid = np.vstack([centroid, x[new_c_idx]])
k += 1
return centroid
重要參數
初始質心
KMeans算法的第一步"隨機"在樣本中抽取 個樣本作為初始質心,因此並不符合"穩定且更快"的需求。因此可通過random_state參數來指定隨機數種子,以控制每次生成的初始質心都在相同位置。
一個random_state對應一個質心隨機初始化的隨機數種子。如果不指定隨機數種子,則 sklearn中的KMeans並不會只選擇一個隨機模式扔出結果,而會在每個隨機數種子下運行多次,並使用結果最好的一個隨機數種子來作為初始質心。我們可以使用參數n_init來選擇,每個隨機數種子下運行的次數。
而以上兩種方法仍然避免不了基於隨機性選取 個質心的本質。在sklearn中,我們使用參數init ='k-means++'來選擇使用'k-means++'作為質心初始化的方案。
init : 可輸入"k-means++","random"或者一個n維數組。這是初始化質心的方法,默認"k-means++"。輸入"k- means++":一種為K均值聚類選擇初始聚類中心的聰明的辦法,以加速收斂。如果輸入了n維數組,數組的形狀應該是(n_clusters,n_features)並給出初始質心。
random_state : 控制每次質心隨機初始化的隨機數種子。
n_init : 整數,默認10,使用不同的質心隨機初始化的種子來運行KMeans算法的次數。最終結果會是基於Inertia來計算的n_init次連續運行后的最佳輸出。
迭代停止
max_iter : 整數,默認300,單次運行的KMeans算法的最大迭代次數。
tol : 浮點數,默認1e-4,兩次迭代間Inertia下降的量,如果兩次迭代之間Inertia下降的值小於tol所設定的值,迭代就會停下。
衡量指標
聚類模型的結果不是某種標簽輸出,並且聚類的結果是不確定的,其優劣由業務需求或者算法需求來決定,並且沒有永遠的正確答案。那么如何衡量聚類的效果呢?
衡量簇內差異來衡量聚類的效果
簇內平方和:Total_Inertia
肘部法(手肘法)認為圖上的拐點就是 的最佳值。
# 應用肘部法則確定 kmeans方法中的k
from scipy.spatial.distance import cdist # 計算兩個輸入集合的每對之間的距離。
from sklearn.cluster import KMeans
import matplotlib.pyplot as plt
import numpy as np
import pandas as pd
from sklearn.datasets import make_blobs
plt.style.use('seaborn')
plt.rcParams['font.sans-serif']=['Simhei'] #顯示中文
plt.rcParams['axes.unicode_minus']=False #顯示負號
X, y = make_blobs(n_samples=5000, centers=4, cluster_std = 2.5, n_features=2,random_state=42)
K=range(1,10)
# 直接計算sse
sse_result=[]
for k in K:
kmeans=KMeans(n_clusters=k, random_state=666)
kmeans.fit(X)
sse_result.append(sum(np.min(cdist(X,kmeans.cluster_centers_,'euclidean'),axis=1))/X.shape[0])
plt.figure(figsize=(16,5))
plt.subplot(1,2,1)
plt.plot(K,sse_result,'gp-')
plt.xlabel('k',fontsize=20)
plt.ylabel(u'平均畸變程度')
plt.title(u'肘部法則確定最佳的K值(1)',fontdict={'fontsize':15})
# 第二種,使用inertia_
L = []
for k in K:
kmeans = KMeans(n_clusters=k, random_state=666)
kmeans.fit(X)
L.append((k, kmeans.inertia_))
a = pd.DataFrame(L)
a.columns = ['k', 'inertia']
plt.subplot(1,2,2)
plt.plot(a.k, a.inertia,'gp-')
plt.xlabel('k',fontsize=20)
plt.ylabel('inertia')
plt.title(u'肘部法則確定最佳的K值(2)',fontdict={'fontsize':15})
plt.xticks(a.k)
plt.show();
輸出結果:
但其有很大的局限:
它的計算太容易受到特征數目的影響。
它不是有界的,Inertia是越小越好,但並不知道合適達到模型的極限,能否繼續提高。
它會受到超參數 的影響,隨着 越大,Inertia注定會越來越小,但並不代表模型效果越來越好。
Inertia對數據的分布有假設,它假設數據滿足凸分布,並且它假設數據是各向同性的( isotropic),所以使用Inertia作為評估指標,會讓聚類算法在一些細長簇,環形簇,或者不規則形狀的流形時表現不佳。
其他衡量指標
1、真實標簽已知時
可以用聚類算法的結果和真實結果來衡量聚類的效果。但需要用到聚類分析的場景,大部分均屬於無真實標簽的情況,因此以下模型評估指標了解即可。
模型評估指標 說明
互信息分
普通互信息分metrics.adjusted_mutual_info_score (y_pred, y_true)調整的互信息分metrics.mutual_info_score (y_pred, y_true)標准化互信息分metrics.normalized_mutual_info_score (y_pred, y_true) 取值范圍在(0,1)之中越接近1,
聚類效果越好在隨機均勻聚類下產生0分。
V-measure:基於條件上分析的一系列直觀度量
同質性:是否每個簇僅包含單個類的樣本metrics.homogeneity_score(y_true, y_pred)完整性:是否給定類的所有樣本都被分配給同一個簇中metrics.completeness_score(y_true, y_pred) 同質性和完整性的調和平均,叫做V-measuremetrics.v_measure_score(labels_true, labels_pred)三者可以被一次性計算出來: metrics.homogeneity_completeness_v_measure(labels_true, labels_pred) 取值范圍在(0,1)之中越接近1,
聚類效果越好由於分為同質性和完整性兩種度量,可以更仔細地研究,模型到底哪個任務做得不夠好。對樣本分布沒有假設,在任何分布上都可以有不錯的表現在隨機均勻聚類下不會產生0分。
調整蘭德系數metrics.adjusted_rand_score(y_true, y_pred) 取值在(-1,1)之間,負值象征着簇內的點差異巨大,甚至相互獨立,正類的 蘭德系數比較優秀,
越接近1越好對樣本分布沒有假設,在任何分布上都可以有不錯的表現,尤其是在具有"折疊"形狀的數據上表現優秀,在隨機均勻聚類下產生0分。
2、真實標簽未知時
輪廓系數
對沒有真實標簽的數據進行探索,常用輪廓系數評價聚類算法模型效果。
樣本與其自身所在的簇中的其他樣本的相似度a,等於樣本與同一簇中所有其他點之間的平均距離 。
樣本與其他簇中的樣本的相似度b,等於樣本與下一個最近的簇中的所有點之間的平均距離。
根據聚類的要求"簇內差異小,簇外差異大",我們希望 b 永遠大於 a ,並且大得越多越好。 單個樣本的輪廓系數計算為: 組內差異,組間差異 取值范圍越大越好。
越接近 1 表示樣本與自己所在的簇中的樣本很相似,並且與其他簇中的樣本不相似,當樣本點與簇外的樣本更相似的時候,輪廓系數就為負。
當輪廓系數為 0 時,則代表兩個簇中的樣本相似度一致,兩個簇本應該是一個簇。
語法:
from sklearn.metrics import silhouette_score
# 返回所有樣本的輪廓系數的均值
from sklearn.metrics import silhouette_samples
# 返回的是數據集中每個樣本自己的輪廓系數
silhouette_score(X,y_pred)
silhouette_score(X,cluster_.labels_)
silhouette_samples(X,y_pred)
例:
L = []
for i in range(2, 20):
k = i
kmeans = KMeans(n_clusters=i)
kmeans.fit(X)
L.append([i, silhouette_score(X, kmeans.labels_)])
a = pd.DataFrame(L)
a.columns = ['k', '輪廓系數']
plt.figure(figsize=(8, 5), dpi=70)
plt.plot(a.k, a.輪廓系數,'gp-')
plt.xticks(a.k)
plt.xlabel('k')
plt.ylabel('輪廓系數')
plt.title('輪廓系數確定最佳的K值',fontdict={'fontsize':15})
輸出結果:
輪廓系數看出,k=3時輪廓系數最大,肘部法的拐點亦是k=3,從數據集可視化圖(文末案例)中也能看出數據集可以清洗分割3個簇(雖然初始創建了四個簇,但上面兩個簇邊界並不清晰,幾乎連到一起)。
輪廓系數有很多優點,它在有限空間中取值,使得我們對模型的聚類效果有一個"參考"。並且輪廓系數對數據的分布沒有假設,因此在很多數據集上都表現良好。但它在每個簇的分割比較清洗時表現最好。
其它評估指標
評估指標 sklearn.metrics
卡林斯基-哈拉巴斯指數
Calinski-Harabaz Index calinski_harabaz_score (X, y_pred)
戴維斯-布爾丁指數
Davies-Bouldin davies_bouldin_score (X, y_pred)
權變矩陣
Contingency cluster.contingency_matrix (X, y_pred)
這里簡單介紹卡林斯基-哈拉巴斯指數,有 個簇的聚類而言, Calinski-Harabaz指數寫作如下公式:
其中為數據集中的樣本量,為簇的個數(即類別的個數), 是組間離散矩陣,即不同簇之間的協方差矩陣, 是簇內離散矩陣,即一個簇內數據的協方差矩陣,而表示矩陣的跡。在線性代數中,一個矩陣的主對角線(從左上方至右下方的對角線)上各個元素的總和被稱為矩陣A的跡(或跡數),一般記作。
數據之間的離散程度越高,協方差矩陣的跡就會越大。組內離散程度低,協方差的跡就會越小,也就越小,同時,組間離散程度大,協方差的的跡也會越大,就越大,因此Calinski-harabaz指數越高越好。
雖然calinski-Harabaz指數沒有界,在凸型的數據上的聚類也會表現虛高。但是比起輪廓系數,其計算非常快速。
案例
from sklearn.cluster import KMeans
from sklearn.metrics import silhouette_samples, silhouette_score
import matplotlib.pyplot as plt
import matplotlib.cm as cm
import numpy as np
import pandas as pd
from sklearn.datasets import make_blobs
X, y = make_blobs(n_samples=6000, centers=4, cluster_std = 2.5, n_features=2,center_box=(-12.0, 12.0),
random_state=42)
data = pd.DataFrame(X)
fig, axes = plt.subplots(3, 2)
fig.set_size_inches(18, 27)
n_clusters = 2
for i in range(3):
for j in range(2):
n_clusters = n_clusters
clusterer = KMeans(n_clusters=n_clusters, random_state=10).fit(X)
cluster_labels = clusterer.labels_
silhouette_avg = silhouette_score(X, cluster_labels)
print("For n_clusters =", n_clusters,
"The average silhouette_score is :", silhouette_avg)
sample_silhouette_values = silhouette_samples(X, cluster_labels)
colors = cm.nipy_spectral(cluster_labels.astype(float) / n_clusters)
axes[i,j].scatter(X[:, 0], X[:, 1]
,marker='o'
,s=8
,c=colors
)
centers = clusterer.cluster_centers_
axes[i,j].scatter(centers[:, 0], centers[:, 1], marker='x',
c="red", alpha=1, s=200)
axes[i,j].set_title(f"The visualization of the clustered data when n_Clusters = {n_clusters}.")
axes[i,j].set_xlabel("Feature space for the 1st feature")
axes[i,j].set_ylabel("Feature space for the 2nd feature")
axes[i,j].text(0,-17,f"The average silhouette_score is :\n\n{silhouette_avg}",fontsize=10)
n_clusters += 1
plt.show()
輸出結果:
擴展--其他聚類算法
DBSCAN
從向量數組或距離矩陣執行DBSCAN聚類。
一種基於密度的帶有噪聲的空間聚類 。它將簇定義為密度相連的點的最大集合,能夠把具有足夠高密度的區域划分為簇,並可在噪聲的空間數據集中發現任意形狀的聚類。
基於密度的空間聚類與噪聲應用。尋找高密度的核心樣本,並從中擴展星團。適用於包含相似密度的簇的數據。
DBSCAN算法將聚類視為由低密度區域分隔的高密度區域。由於這種相當通用的觀點,DBSCAN發現的集群可以是任何形狀,而k-means假設集群是凸形的。DBSCAN的核心組件是核心樣本的概念,即位於高密度區域的樣本。因此,一個集群是一組彼此接近的核心樣本(通過一定的距離度量)和一組與核心樣本相近的非核心樣本(但它們本身不是核心樣本)。算法有兩個參數,min_samples和eps,它們正式定義了我們所說的密集。較高的min_samples或較低的eps表示較高的密度需要形成一個集群。
根據定義,任何核心樣本都是集群的一部分。任何非核心樣本,且與核心樣本的距離至少為eps的樣本,都被算法認為是離群值。
而主要控制參數min_samples寬容的算法對噪聲(在嘈雜和大型數據集可能需要增加此參數),選擇適當的參數eps至關重要的數據集和距離函數,通常不能在默認值。它控制着點的局部鄰域。如果選擇的數據太小,大多數數據根本不會聚集在一起(並且標記為-1表示"噪音")。如果選擇太大,則會導致關閉的集群合並為一個集群,並最終將整個數據集作為單個集群返回。
例:
>>> from sklearn.cluster import DBSCAN
>>> import numpy as np
>>> X = np.array([[1, 2], [2, 2], [2, 3],
... [8, 7], [8, 8], [25, 80]])
>>> clustering = DBSCAN(eps=3, min_samples=2).fit(X)
>>> clustering.labels_
array([ 0, 0, 0, 1, 1, -1])
>>> clustering
DBSCAN(eps=3, min_samples=2)
eps float, default=0.5
兩個樣本之間的最大距離,其中一個樣本被認為是相鄰的。這不是集群內點的距離的最大值,這是為您的數據集和距離函數選擇的最重要的DBSCAN參數。
min_samples int, default=5
被視為核心點的某一鄰域內的樣本數(或總權重)。這包括點本身。
更多DBSCAN聚類請參見
https://scikit-learn.org/stable/modules/generated/sklearn.cluster.DBSCAN.html#sklearn.cluster.DBSCAN
層次聚類
層次聚類Hierarchical Clustering 通過計算不同類別數據點間的相似度來創建一棵有層次的嵌套聚類樹。在聚類樹中,不同類別的原始數據點是樹的最低層,樹的頂層是一個聚類的根節點。創建聚類樹有自下而上合並和自上而下分裂兩種方法。
層次聚類的合並算法通過計算兩類數據點間的相似性,對所有數據點中最為相似的兩個數據點進行組合,並反復迭代這一過程。
簡單來說 通過計算每一個類別的數據點與所有數據點之間的歐式距離來確定它們之間的相似性,距離越小,相似度越高 。並將距離最近的兩個數據點或類別進行組合,生成聚類樹。
例:
>>> from sklearn.cluster import AgglomerativeClustering
>>> import numpy as np
>>> X = np.array([[1, 2], [1, 4], [1, 0],
... [4, 2], [4, 4], [4, 0]])
>>> clustering = AgglomerativeClustering().fit(X)
>>> clustering
AgglomerativeClustering()
>>> clustering.labels_
array([1, 1, 1, 0, 0, 0])
層次化聚類是一種通用的聚類算法,它通過合並或分割來構建嵌套的聚類。集群的層次結構表示為樹(或樹狀圖)。樹的根是收集所有樣本的唯一集群,葉子是只有一個樣本的集群。
聚類對象使用自底向上的方法執行分層聚類: 每個觀察從它自己的聚類開始,然后聚類依次合並在一起。連接標准決定了用於合並策略的度量。
最大或完全連接使簇對觀測之間的最大距離最小。
平均連接使簇對的所有觀測值之間的平均距離最小化。
單連接使簇對的最近觀測值之間的距離最小。
當與連通性矩陣聯合使用時,團聚向量聚合也可以擴展到大量的樣本,但是當樣本之間不加連通性約束時,計算開銷就大了:它在每一步都考慮所有可能的合並。
更多層次聚類請參見
https://scikit-learn.org/stable/modules/generated/sklearn.cluster.AgglomerativeClustering.html#sklearn.cluster.AgglomerativeClustering
附錄
KMeans參數
n_clusters int, default=8
要聚成的簇數,以及要生成的質心數。
init {‘k-means++’, ‘random’, ndarray, callable}, default=’k-means++’
這是初始化質心的方法,輸入"k- means++": 一種為K均值聚類選擇初始聚類中心的聰明的辦法,以加速收斂。如果輸入了n維數組,數組的形狀應該是(n_clusters,n_features)並給出初始質心。
n_init int, default=10
使用不同的質心隨機初始化的種子來運行KMeans算法的次數。最終結果會是基於Inertia來計算的n_init次連續運行后的最佳輸出。
max_iter int, default=300
單次運行的KMeans算法的最大迭代次數。
tol float, default=1e-4
兩次迭代間Inertia下降的量,如果兩次迭代之間Inertia下降的值小於tol所設定的值,迭代就會停下。
precompute_distances {‘auto’, True, False}, default=’auto’
預計算距離(更快,但需要更多內存)。
'auto': 如果 n_samples * n_clusters > 1200萬,不要預先計算距離。這對應於使用雙精度來學習,每個作業大約100MB的內存開銷。
True: 始終預先計算距離。False:從不預先計算距離。
verbose int, default=0
計算中的詳細模式。
random_state int, RandomState instance, default=None
確定質心初始化的隨機數生成。使用int可以是隨機性更具有確定性。
copy_x bool, default=True
在預計算距離時,若先中心化數據,距離的預計算會更加准確。如果copy_x為True(默認值),則不會修改原始數據,確保特征矩陣X是c-contiguous。如果為False,則對原始數據進行修改,在函數返回之前放回原始數據,但可以通過減去數據平均值,再加上數據平均值,引入較小的數值差異。注意,如果原始數據不是c -連續的,即使copy_x為False,也會復制,這可能導致KMeans 計算量顯著變慢。如果原始數據是稀疏的,但不是CSR格式的,即使copy_x是False的,也會復制一份。
n_jobs int, default=None
用於計算的作業數。計算每個n_init時並行作業數。
這個參數允許KMeans在多個作業線上並行運行。給這個參數正值n_jobs,表示使用 n_jobs 條處理器中的線程。值-1表示使用所用可用的處理器。值-2表示使用所有可能的處理器-1個處理器,以此類推。並行化通常以內存為代價增加計算(這種情況下,需要存儲多個質心副本,每個作業一個)
algorithm {“auto”, “full”, “elkan”}, default=”auto”
使用KMeans算法。經典的EM風格的算法是"full"的。通過使用三角不等式,"elkan"變異在具有定義明確的集群的數據上更有效。然而,由於分配了額外的形狀數組(n_samples、n_clusters),它會占用更多的內存。目前,"auto" 為密集數據選擇 "elkan" 為稀疏數據選擇"full"。
KMeans屬性
cluster_centers_ ndarray of shape (n_clusters, n_features)
收斂到的質心坐標。如果算法在完全收斂之前已停止(受到'tol'和'max_iter'參數的控制),這些返回的內容將與'labels_'中反應出的聚類結果不一致。
labels_ ndarray of shape (n_samples,)
每個樣本對應的標簽。
inertia_ float
每個樣本點到它們最近的簇中心的距離的平方的和,又叫做"簇內平方和"。
n_iter_ int
實際迭代的次數。
————————————————
版權聲明:本文為CSDN博主「晴天學姐」的原創文章,遵循CC 4.0 BY-SA版權協議,轉載請附上原文出處鏈接及本聲明。
原文鏈接:https://blog.csdn.net/weixin_34976470/article/details/112453968