聚類分析是什么
相對于分類,聚類是一種不清楚類別的種類,或類別不清楚的情況下,通過計算數據之間的相似度(其中用得最多的是距離)來進行小組劃分的一種數據挖掘方法。其特點是組中數據的相似度很高,而不同組別之間的相似度卻很低。
聚類分析有哪些
根據不同的劃分方式,聚類可分為K-Means聚類、K-中心點聚類、系統聚類等。其中最常用以及應用范圍最廣的是K-Means聚類,下面著重介紹K-Means聚類。
K-Means聚類
K-Means聚類是很典型的基于距離的聚類算法,以組內元素的均值作為每個組的中心,采用距離作為相似性的指標,即認為兩個對象距離近,則相似,否則,不相似。該算法認為組內元素是由距離相近的元素組成的,因此,組間元素的距離相近,不同組的距離則較遠。
算法步驟:
- 隨機選取K個對象作為聚類中心
- while 聚類中心發生變化
- 計算數據集中各個對象到K個聚類中心的距離,并將距離相近的對象歸為同一個聚類
- 重新計算聚類中心(即重新計算組內均值)
算法實踐:
我們以常用的分類數據集Iris作為我們的原始數據
iris = datasets.load_iris()
x,y = iris.data,iris.target
data = x[:, [1, 3]] #只取兩個維度便于可視化
f = plt.scatter(data[:, 0], data[:, 1])
Iris
歐幾里得距離:
我們采用歐幾里得距離來計算點與點之間的距離
def distance(p1, p2):
"""
返回兩個點之間的歐幾里得距離
"""
tmp = np.sum((p1-p2)**2)
return np.sqrt(tmp)
聚類中心的初始化:
def _rand_center(data, k):
"""
隨機挑選K個初始點
"""
n = data.shape[1] #數據集包含的特征數
centroids = np.zeros((k, n)) #初始化一個K行n列的0矩陣
for i in range(n):
dmin, dmax = np.min(data[:, i]), np.max(data[:, i])
centroids[:, i] = dmin + (dmax - dmin) * np.random.rand(k)
# 這里產生的是介于極小值和極大值之間的數,產生的數有可能不是數據集的數據
return centroids
K均值聚類:
該算法中,當聚類中心不再改變的時候,迭代停止,返回聚類中心,各點歸屬于哪一聚類和他們之間距離的和。
注意到K-Means有可能陷于局部最小值,我們采用多次計算取最小值來解決此問題,當然也可以用二分K均值來解決此問題。
n = data.shape[0] #數據集的行數
centroids = _rand_center(data, k)
label = np.zeros(n, dtype=np.int) #用于標記最近的聚類中心
assessment = np.zeros(n) #用于對模型的評估
converged = False
while not converged:
old_centroids = np.copy(centroids)
for i in range(n): #決定最相近的聚類中心并記錄在label中
min_dist, min_index = np.inf, -1
for j in range(k):
dist = distance(data[i], centroids[j])
if dist < min_dist:
min_dist, min_index = dist, j
label[i] = j
assessment[i] = distance(data[i], centroids[j])
for m in range(k): #更新聚類中心
centroids[m] = np.mean(data[label == m], axis=0)
converged = _converged(old_centroids, centroids)
return centroids, label, np.sum(assessment)
最后經過多次計算之后顯示的結果如下圖:
K-Means
從圖可以看出,聚類的效果還不錯。