機器學習 | KMeans聚類分析詳解
大家好,我是老表,今天給大家分享一篇機器學習KMaens聚類分析算法文章,在后面的實戰(zhàn)中我們將用到該算法,希望大家認真學習閱讀,覺得對自己學習有幫助的話,歡迎點贊、轉發(fā)、留言。
大量數(shù)據(jù)中具有"相似"特征的數(shù)據(jù)點或樣本劃分為一個類別。聚類分析提供了樣本集在非監(jiān)督模式下的類別劃分。聚類的基本思想是"物以類聚、人以群分",將大量數(shù)據(jù)集中相似的數(shù)據(jù)樣本區(qū)分出來,并發(fā)現(xiàn)不同類的特征。
聚類模型可以建立在無類標記的數(shù)據(jù)上,是一種非監(jiān)督的學習算法。盡管全球每日新增數(shù)據(jù)量以PB或EB級別增長,但是大部分數(shù)據(jù)屬于無標注甚至非結構化。所以相對于監(jiān)督學習,不需要標注的無監(jiān)督學習蘊含了巨大的潛力與價值。聚類根據(jù)數(shù)據(jù)自身的距離或相似度將他們劃分為若干組,劃分原則是組內樣本最小化而組間距離最大化。

聚類分析常用于數(shù)據(jù)探索或挖掘前期
沒有先驗經(jīng)驗做探索性分析 樣本量較大時做預處理 常用于解決
數(shù)據(jù)集可以分幾類;每個類別有多少樣本量 不同類別中各個變量的強弱關系如何 不同類型的典型特征是什么 一般應用場景
群類別間的差異性特征分析 群類別內的關鍵特征提取 圖像壓縮、分割、圖像理解 異常檢測 數(shù)據(jù)離散化 當然聚類分析也有其缺點
無法提供明確的行動指向 數(shù)據(jù)異常對結果有影響
本文將從算法原理、優(yōu)化目標、sklearn聚類算法、算法優(yōu)缺點、算法優(yōu)化、算法重要參數(shù)、衡量指標以及案例等方面詳細介紹KMeans算法。
KMeans
K均值(KMeans)是聚類中最常用的方法之一,基于點與點之間的距離的相似度來計算最佳類別歸屬。
KMeans算法通過試著將樣本分離到 個方差相等的組中來對數(shù)據(jù)進行聚類,從而最小化目標函數(shù) (見下文)。該算法要求指定集群的數(shù)量。它可以很好地擴展到大量的樣本,并且已經(jīng)在許多不同領域的廣泛應用領域中使用。
被分在同一個簇中的數(shù)據(jù)是有相似性的,而不同簇中的數(shù)據(jù)是不同的,當聚類完畢之后,我們就要分別去研究每個簇中的樣本都有什么樣的性質,從而根據(jù)業(yè)務需求制定不同的商業(yè)或者科技策略。常用于客戶分群、用戶畫像、精確營銷、基于聚類的推薦系統(tǒng)。
算法原理
從 個樣本數(shù)據(jù)中隨機選取 個質心作為初始的聚類中心。質心記為
定義優(yōu)化目標
開始循環(huán),計算每個樣本點到那個質心到距離,樣本離哪個近就將該樣本分配到哪個質心,得到K個簇
對于每個簇,計算所有被分到該簇的樣本點的平均距離作為新的質心
直到 收斂,即所有簇不再發(fā)生變化。

優(yōu)化目標
KMeans 在進行類別劃分過程及最終結果,始終追求"簇內差異小,簇間差異大",其中差異由樣本點到其所在簇的質心的距離衡量。在KNN算法學習中,我們學習到多種常見的距離 ---- 歐幾里得距離、曼哈頓距離、余弦距離。
在sklearn中的KMeans使用歐幾里得距離:
(cluster Sum of Square), 又叫做Inertia。而將一個數(shù)據(jù)集中的所有簇的簇內平方和相加,就得到了整體平方和(Total Cluster Sum of Square),又叫做Total Inertia。Total Inertia越小,代表著每個簇內樣本越相似,聚類的效果就越好。因此 KMeans 追求的是,求解能夠讓Inertia最小化的質心。
KMeans有損失函數(shù)嗎?損失函數(shù)本質是用來衡量模型的擬合效果的,只有有著求解參數(shù)需求的算法,才會有損失函數(shù)。
KMeans不求解什么參數(shù),它的模型本質也沒有在擬合數(shù)據(jù),而是在對數(shù)據(jù)進行一 種探索。另外,在決策樹中有衡量分類效果的指標準確度
accuracy,準確度所對應的損失叫做泛化誤差,但不能通過最小化泛化誤差來求解某個模型中需要的信息,我們只是希望模型的效果上表現(xiàn)出來的泛化誤差很小。因此決策樹,KNN等算法,是絕對沒有損失函數(shù)的。
雖然在sklearn中只能被動選用歐式距離,但其他距離度量方式同樣可以用來衡量簇內外差異。不同距離所對應的質心選擇方法和Inertia如下表所示, 在KMeans中,只要使用了正確的質心和距離組合,無論使用什么樣的距離,都可以達到不錯的聚類效果。
| 距離度量 | 質心 | Inertia |
|---|---|---|
| 歐幾里得距離 | 均值 | 最小化每個樣本點到質心的歐式距離之和 |
| 曼哈頓距離 | 中位數(shù) | 最小化每個樣本點到質心的曼哈頓距離之和 |
| 余弦距離 | 均值 | 最小化每個樣本點到質心的余弦距離之和 |
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')
參數(shù)與接口詳解見文末附錄
例:
>>> 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算法優(yōu)缺點
優(yōu)點
KMeans算法是解決聚類問題的一種經(jīng)典算法, 算法簡單、快速 。 算法嘗試找出使平方誤差函數(shù)值最小的 個劃分。當簇是密集的、球狀或團狀的,且簇與簇之間區(qū)別明顯時,聚類效果較好 。
缺點
KMeans方法只有在簇的平均值被定義的情況下才能使用,且對有些分類屬性的數(shù)據(jù)不適合。 要求用戶必須事先給出要生成的簇的數(shù)目 。 對初值敏感,對于不同的初始值,可能會導致不同的聚類結果。 不適合于發(fā)現(xiàn)非凸面形狀的簇,或者大小差別很大的簇。 KMeans本質上是一種基于歐式距離度量的數(shù)據(jù)劃分方法,均值和方差大的維度將對數(shù)據(jù)的聚類結果產(chǎn)生決定性影響。所以在聚類前對數(shù)據(jù)(具體的說是每一個維度的特征)做歸一化(點擊查看歸一化詳解)和單位統(tǒng)一至關重要。此外,異常值會對均值計算產(chǎn)生較大影響,導致中心偏移,因此對于"噪聲"和孤立點數(shù)據(jù)最好能提前過濾 。
KMeans算法優(yōu)化
KMeans算法雖然效果不錯,但是每一次迭代都需要遍歷全量的數(shù)據(jù),一旦數(shù)據(jù)量過大,由于計算復雜度過大迭代的次數(shù)過多,會導致收斂速度非常慢。
由KMeans算法原來可知,KMeans在聚類之前首先需要初始化 個簇中心,因此 KMeans算法對初值敏感,對于不同的初始值,可能會導致不同的聚類結果。因初始化是個"隨機"過程,很有可能 個簇中心都在同一個簇中,這種情況 KMeans 聚類算法很大程度上都不會收斂到全局最小。
想要優(yōu)化KMeans算法的效率問題,可以從以下兩個思路優(yōu)化算法,一個是樣本數(shù)量太大,另一個是迭代次數(shù)過多。
MiniBatchKMeans 聚類算法
mini batch 優(yōu)化思想非常樸素,既然全體樣本當中數(shù)據(jù)量太大,會使得我們迭代的時間過長,那么隨機從整體當中做一個抽樣,選取出一小部分數(shù)據(jù)來代替整體以達到縮小數(shù)據(jù)規(guī)模的目的。
mini batch 優(yōu)化非常重要,不僅重要而且在機器學習領域廣為使用。在大數(shù)據(jù)的場景下,幾乎所有模型都需要做mini batch優(yōu)化,而MiniBatchKMeans就是mini batch 優(yōu)化的一個應用。直接上模型比較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優(yōu)化方法是通過減少計算樣本量來達到縮短迭代時長,另一種方法是降低收斂需要的迭代次數(shù),從而達到快速收斂的目的。收斂的速度除了取決于每次迭代的變化率之外,另一個重要指標就是迭代起始的位置。2007年Arthur, David, and Sergei Vassilvitskii三人發(fā)表了論文"k-means++: The advantages of careful seeding" http://ilpubs.stanford.edu:8090/778/1/2006-13.pdf,他們開發(fā)了'k-means++'初始化方案,使得初始質心(通常)彼此遠離,以此來引導出比隨機初始化更可靠的結果。
'k-means++' 聚類算法
'k-means++'聚類算法是在KMeans算法基礎上,針對迭代次數(shù),優(yōu)化選擇初始質心的方法。sklearn.cluster.KMeans 中默認參數(shù)為 init='k-means++',其算法原理為在初始化簇中心時,逐個選取 個簇中心,且離其他簇中心越遠的樣本越有可能被選為下個簇中心。
算法步驟:
從數(shù)據(jù)即 中隨機(均勻分布)選取一個樣本點作為第一個初始聚類中心
計算每個樣本與當前已有聚類中心之間的最短距離;再計算每個樣本點被選為下個聚類中心的概率,最后選擇最大概率值所對應的樣本點作為下一個簇中心
重復上步驟,直到選擇個聚類中心
'k-means++'算法初始化的簇中心彼此相距都十分的遠,從而不可能再發(fā)生初始簇中心在同一個簇中的情況。當然'k-means++'本身也具有隨機性,并不一定每一次隨機得到的起始點都能有這么好的效果,但是通過策略,我們可以保證即使出現(xiàn)最壞的情況也不會太壞。
'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 < 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
重要參數(shù)
初始質心
KMeans算法的第一步"隨機"在樣本中抽取 個樣本作為初始質心,因此并不符合"穩(wěn)定且更快"的需求。因此可通過random_state參數(shù)來指定隨機數(shù)種子,以控制每次生成的初始質心都在相同位置。
一個random_state對應一個質心隨機初始化的隨機數(shù)種子。如果不指定隨機數(shù)種子,則 sklearn中的KMeans并不會只選擇一個隨機模式扔出結果,而會在每個隨機數(shù)種子下運行多次,并使用結果最好的一個隨機數(shù)種子來作為初始質心。我們可以使用參數(shù)n_init來選擇,每個隨機數(shù)種子下運行的次數(shù)。
而以上兩種方法仍然避免不了基于隨機性選取 個質心的本質。在sklearn中,我們使用參數(shù)init ='k-means++'來選擇使用'k-means++'作為質心初始化的方案。
init : 可輸入
"k-means++","random"或者一個n維數(shù)組。這是初始化質心的方法,默認"k-means++"。輸入"k- means++":一種為K均值聚類選擇初始聚類中心的聰明的辦法,以加速收斂。如果輸入了n維數(shù)組,數(shù)組的形狀應該是(n_clusters,n_features)并給出初始質心。random_state : 控制每次質心隨機初始化的隨機數(shù)種子。
n_init : 整數(shù),默認10,使用不同的質心隨機初始化的種子來運行
KMeans算法的次數(shù)。最終結果會是基于Inertia來計算的n_init次連續(xù)運行后的最佳輸出。
迭代停止
max_iter : 整數(shù),默認300,單次運行的
KMeans算法的最大迭代次數(shù)。tol : 浮點數(shù),默認
1e-4,兩次迭代間Inertia下降的量,如果兩次迭代之間Inertia下降的值小于tol所設定的值,迭代就會停下。
衡量指標
聚類模型的結果不是某種標簽輸出,并且聚類的結果是不確定的,其優(yōu)劣由業(yè)務需求或者算法需求來決定,并且沒有永遠的正確答案。那么如何衡量聚類的效果呢?
衡量簇內差異來衡量聚類的效果
簇內平方和:
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();
輸出結果:

但其有很大的局限:
它的計算太容易受到特征數(shù)目的影響。 它不是有界的, Inertia是越小越好,但并不知道合適達到模型的極限,能否繼續(xù)提高。它會受到超參數(shù) 的影響,隨著 越大, Inertia注定會越來越小,但并不代表模型效果越來越好。Inertia對數(shù)據(jù)的分布有假設,它假設數(shù)據(jù)滿足凸分布,并且它假設數(shù)據(jù)是各向同性的(isotropic),所以使用Inertia作為評估指標,會讓聚類算法在一些細長簇,環(huán)形簇,或者不規(guī)則形狀的流形時表現(xiàn)不佳。
其他衡量指標
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, 聚類效果越好在隨機均勻聚類下產(chǎn)生0分。 |
| V-measure:基于條件上分析的一系列直觀度量 同質性:是否每個簇僅包含單個類的樣本 metrics.homogeneity_score(y_true, y_pred)完整性:是否給定類的所有樣本都被分配給同一個簇中 同質性和完整性的調和平均,叫做V-measure metrics.v_measure_score(labels_true, labels_pred)三者可以被一次性計算出來: metrics.homogeneity_completeness_v_measure(labels_true, labels_pred) | 取值范圍在(0,1)之中越接近1, 聚類效果越好由于分為同質性和完整性兩種度量,可以更仔細地研究,模型到底哪個任務做得不夠好。對樣本分布沒有假設,在任何分布上都可以有不錯的表現(xiàn)在隨機均勻聚類下不會產(chǎn)生0分。 |
調整蘭德系數(shù)metrics.adjusted_rand_score(y_true, y_pred) | 取值在(-1,1)之間,負值象征著簇內的點差異巨大,甚至相互獨立,正類的 蘭德系數(shù)比較優(yōu)秀, 越接近1越好對樣本分布沒有假設,在任何分布上都可以有不錯的表現(xiàn),尤其是在具有"折疊"形狀的數(shù)據(jù)上表現(xiàn)優(yōu)秀,在隨機均勻聚類下產(chǎn)生0分。 |
輪廓系數(shù)
對沒有真實標簽的數(shù)據(jù)進行探索,常用輪廓系數(shù)評價聚類算法模型效果。
樣本與其自身所在的簇中的其他樣本的相似度
a,等于樣本與同一簇中所有其他點之間的平均距離 。樣本與其他簇中的樣本的相似度
b,等于樣本與下一個最近的簇中的所有點之間的平均距離。
b永遠大于a,并且大得越多越好。單個樣本的輪廓系數(shù)計算為:越接近 1 表示樣本與自己所在的簇中的樣本很相似,并且與其他簇中的樣本不相似,當樣本點與簇外的樣本更相似的時候,輪廓系數(shù)就為負。
當輪廓系數(shù)為 0 時,則代表兩個簇中的樣本相似度一致,兩個簇本應該是一個簇。
語法:
from sklearn.metrics import silhouette_score
# 返回所有樣本的輪廓系數(shù)的均值
from sklearn.metrics import silhouette_samples
# 返回的是數(shù)據(jù)集中每個樣本自己的輪廓系數(shù)
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', '輪廓系數(shù)']
plt.figure(figsize=(8, 5), dpi=70)
plt.plot(a.k, a.輪廓系數(shù),'gp-')
plt.xticks(a.k)
plt.xlabel('k')
plt.ylabel('輪廓系數(shù)')
plt.title('輪廓系數(shù)確定最佳的K值',fontdict={'fontsize':15})
輸出結果:

輪廓系數(shù)看出,k=3時輪廓系數(shù)最大,肘部法的拐點亦是k=3,從數(shù)據(jù)集可視化圖(文末案例)中也能看出數(shù)據(jù)集可以清洗分割3個簇(雖然初始創(chuàng)建了四個簇,但上面兩個簇邊界并不清晰,幾乎連到一起)。
輪廓系數(shù)有很多優(yōu)點,它在有限空間中取值,使得我們對模型的聚類效果有一個"參考"。并且輪廓系數(shù)對數(shù)據(jù)的分布沒有假設,因此在很多數(shù)據(jù)集上都表現(xiàn)良好。但它在每個簇的分割比較清洗時表現(xiàn)最好。
其它評估指標
| 評估指標 | sklearn.metrics |
|---|---|
| 卡林斯基-哈拉巴斯指數(shù) Calinski-Harabaz Index | calinski_harabaz_score (X, y_pred) |
| 戴維斯-布爾丁指數(shù) Davies-Bouldin | davies_bouldin_score (X, y_pred) |
| 權變矩陣 Contingency | cluster.contingency_matrix (X, y_pred) |
這里簡單介紹卡林斯基-哈拉巴斯指數(shù),有 個簇的聚類而言, Calinski-Harabaz指數(shù)寫作如下公式:
其中為數(shù)據(jù)集中的樣本量,為簇的個數(shù)(即類別的個數(shù)), 是組間離散矩陣,即不同簇之間的協(xié)方差矩陣, 是簇內離散矩陣,即一個簇內數(shù)據(jù)的協(xié)方差矩陣,而表示矩陣的跡。在線性代數(shù)中,一個矩陣的主對角線(從左上方至右下方的對角線)上各個元素的總和被稱為矩陣A的跡(或跡數(shù)),一般記作。
數(shù)據(jù)之間的離散程度越高,協(xié)方差矩陣的跡就會越大。組內離散程度低,協(xié)方差的跡就會越小,也就越小,同時,組間離散程度大,協(xié)方差的的跡也會越大,就越大,因此Calinski-harabaz指數(shù)越高越好。
雖然calinski-Harabaz指數(shù)沒有界,在凸型的數(shù)據(jù)上的聚類也會表現(xiàn)虛高。但是比起輪廓系數(shù),其計算非??焖?。
案例
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
從向量數(shù)組或距離矩陣執(zhí)行DBSCAN聚類。
一種基于密度的帶有噪聲的空間聚類 。它將簇定義為密度相連的點的最大集合,能夠把具有足夠高密度的區(qū)域劃分為簇,并可在噪聲的空間數(shù)據(jù)集中發(fā)現(xiàn)任意形狀的聚類。
基于密度的空間聚類與噪聲應用。尋找高密度的核心樣本,并從中擴展星團。適用于包含相似密度的簇的數(shù)據(jù)。
DBSCAN算法將聚類視為由低密度區(qū)域分隔的高密度區(qū)域。由于這種相當通用的觀點,DBSCAN發(fā)現(xiàn)的集群可以是任何形狀,而k-means假設集群是凸形的。DBSCAN的核心組件是核心樣本的概念,即位于高密度區(qū)域的樣本。因此,一個集群是一組彼此接近的核心樣本(通過一定的距離度量)和一組與核心樣本相近的非核心樣本(但它們本身不是核心樣本)。算法有兩個參數(shù),min_samples和eps,它們正式定義了我們所說的密集。較高的min_samples或較低的eps表示較高的密度需要形成一個集群。
根據(jù)定義,任何核心樣本都是集群的一部分。任何非核心樣本,且與核心樣本的距離至少為eps的樣本,都被算法認為是離群值。
而主要控制參數(shù)min_samples寬容的算法對噪聲(在嘈雜和大型數(shù)據(jù)集可能需要增加此參數(shù)),選擇適當?shù)膮?shù)eps至關重要的數(shù)據(jù)集和距離函數(shù),通常不能在默認值。它控制著點的局部鄰域。如果選擇的數(shù)據(jù)太小,大多數(shù)數(shù)據(jù)根本不會聚集在一起(并且標記為-1表示"噪音")。如果選擇太大,則會導致關閉的集群合并為一個集群,并最終將整個數(shù)據(jù)集作為單個集群返回。
例:
>>> 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
兩個樣本之間的最大距離,其中一個樣本被認為是相鄰的。這不是集群內點的距離的最大值,這是為您的數(shù)據(jù)集和距離函數(shù)選擇的最重要的DBSCAN參數(shù)。
min_samples int, default=5
被視為核心點的某一鄰域內的樣本數(shù)(或總權重)。這包括點本身。
更多DBSCAN聚類請參見
https://scikit-learn.org/stable/modules/generated/sklearn.cluster.DBSCAN.html#sklearn.cluster.DBSCAN
層次聚類
層次聚類Hierarchical Clustering 通過計算不同類別數(shù)據(jù)點間的相似度來創(chuàng)建一棵有層次的嵌套聚類樹。在聚類樹中,不同類別的原始數(shù)據(jù)點是樹的最低層,樹的頂層是一個聚類的根節(jié)點。創(chuàng)建聚類樹有自下而上合并和自上而下分裂兩種方法。
層次聚類的合并算法通過計算兩類數(shù)據(jù)點間的相似性,對所有數(shù)據(jù)點中最為相似的兩個數(shù)據(jù)點進行組合,并反復迭代這一過程。
簡單來說 通過計算每一個類別的數(shù)據(jù)點與所有數(shù)據(jù)點之間的歐式距離來確定它們之間的相似性,距離越小,相似度越高 。并將距離最近的兩個數(shù)據(jù)點或類別進行組合,生成聚類樹。
例:
>>> 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])
層次化聚類是一種通用的聚類算法,它通過合并或分割來構建嵌套的聚類。集群的層次結構表示為樹(或樹狀圖)。樹的根是收集所有樣本的唯一集群,葉子是只有一個樣本的集群。
聚類對象使用自底向上的方法執(zhí)行分層聚類: 每個觀察從它自己的聚類開始,然后聚類依次合并在一起。連接標準決定了用于合并策略的度量。
最大或完全連接使簇對觀測之間的最大距離最小。 平均連接使簇對的所有觀測值之間的平均距離最小化。 單連接使簇對的最近觀測值之間的距離最小。 當與連通性矩陣聯(lián)合使用時,團聚向量聚合也可以擴展到大量的樣本,但是當樣本之間不加連通性約束時,計算開銷就大了:它在每一步都考慮所有可能的合并。
更多層次聚類請參見
https://scikit-learn.org/stable/modules/generated/sklearn.cluster.AgglomerativeClustering.html#sklearn.cluster.AgglomerativeClustering
附錄
KMeans參數(shù)
n_clusters int, default=8
要聚成的簇數(shù),以及要生成的質心數(shù)。
init {‘k-means++’, ‘random’, ndarray, callable}, default=’k-means++’
這是初始化質心的方法,輸入
"k- means++": 一種為K均值聚類選擇初始聚類中心的聰明的辦法,以加速收斂。如果輸入了n維數(shù)組,數(shù)組的形狀應該是(n_clusters,n_features)并給出初始質心。n_init int, default=10
使用不同的質心隨機初始化的種子來運行
KMeans算法的次數(shù)。最終結果會是基于Inertia來計算的n_init次連續(xù)運行后的最佳輸出。max_iter int, default=300
單次運行的
KMeans算法的最大迭代次數(shù)。tol float, default=1e-4
兩次迭代間
Inertia下降的量,如果兩次迭代之間Inertia下降的值小于tol所設定的值,迭代就會停下。precompute_distances {‘a(chǎn)uto’, True, False}, default=’auto’
預計算距離(更快,但需要更多內存)。
'auto': 如果n_samples * n_clusters > 1200萬,不要預先計算距離。這對應于使用雙精度來學習,每個作業(yè)大約100MB的內存開銷。
True: 始終預先計算距離。False:從不預先計算距離。verbose int, default=0
計算中的詳細模式。
random_state int, RandomState instance, default=None
確定質心初始化的隨機數(shù)生成。使用
int可以是隨機性更具有確定性。copy_x bool, default=True
在預計算距離時,若先中心化數(shù)據(jù),距離的預計算會更加準確。如果
copy_x為True(默認值),則不會修改原始數(shù)據(jù),確保特征矩陣X是c-contiguous。如果為False,則對原始數(shù)據(jù)進行修改,在函數(shù)返回之前放回原始數(shù)據(jù),但可以通過減去數(shù)據(jù)平均值,再加上數(shù)據(jù)平均值,引入較小的數(shù)值差異。注意,如果原始數(shù)據(jù)不是c -連續(xù)的,即使copy_x為False,也會復制,這可能導致KMeans計算量顯著變慢。如果原始數(shù)據(jù)是稀疏的,但不是CSR格式的,即使copy_x是False的,也會復制一份。n_jobs int, default=None
用于計算的作業(yè)數(shù)。計算每個
n_init時并行作業(yè)數(shù)。這個參數(shù)允許
KMeans在多個作業(yè)線上并行運行。給這個參數(shù)正值n_jobs,表示使用n_jobs條處理器中的線程。值-1表示使用所用可用的處理器。值-2表示使用所有可能的處理器-1個處理器,以此類推。并行化通常以內存為代價增加計算(這種情況下,需要存儲多個質心副本,每個作業(yè)一個)algorithm {“auto”, “full”, “elkan”}, default=”auto”
使用
KMeans算法。經(jīng)典的EM風格的算法是"full"的。通過使用三角不等式,"elkan"變異在具有定義明確的集群的數(shù)據(jù)上更有效。然而,由于分配了額外的形狀數(shù)組(n_samples、n_clusters),它會占用更多的內存。目前,"auto"為密集數(shù)據(jù)選擇"elkan"為稀疏數(shù)據(jù)選擇"full"。
KMeans屬性
cluster_centers_ ndarray of shape (n_clusters, n_features)
收斂到的質心坐標。如果算法在完全收斂之前已停止(受到'
tol'和'max_iter'參數(shù)的控制),這些返回的內容將與'labels_'中反應出的聚類結果不一致。labels_ ndarray of shape (n_samples,)
每個樣本對應的標簽。
inertia_ float
每個樣本點到它們最近的簇中心的距離的平方的和,又叫做"簇內平方和"。
n_iter_ int
實際迭代的次數(shù)。
點贊+留言+轉發(fā),就是對我最大的支持啦~
--End--
文章點贊超過100+
我將在個人視頻號直播(老表Max)
帶大家一起進行項目實戰(zhàn)復現(xiàn)
掃碼即可加我微信
老表朋友圈經(jīng)常有贈書/紅包福利活動
點擊上方卡片關注公眾號,回復:1024 領取最新Python學習資源 學習更多: 整理了我開始分享學習筆記到現(xiàn)在超過250篇優(yōu)質文章,涵蓋數(shù)據(jù)分析、爬蟲、機器學習等方面,別再說不知道該從哪開始,實戰(zhàn)哪里找了 “點贊”就是對博主最大的支持

