【scikit-learn基础】--『监督学习』之 均值聚类
聚類算法屬于無監(jiān)督學(xué)習(xí),其中最常見的是均值聚類,scikit-learn中,有兩種常用的均值聚類算法:
一種是有名的K-means(也就是K-均值)聚類算法,這個(gè)算法幾乎是學(xué)習(xí)聚類必會(huì)提到的算法;
另一個(gè)是均值偏移聚類,它與K-means各有千秋,只是針對(duì)的應(yīng)用場景不太一樣,但是知名度遠(yuǎn)不如K-Means。
本篇介紹如何在scikit-learn中使用這兩種算法。
1. 算法概述
1.1. K-Means
K-means算法起源于1967年,由James MacQueen和J. B. Hartigan提出。
它的基本原理是是將n個(gè)點(diǎn)劃分為K個(gè)集群,使得每個(gè)點(diǎn)都屬于離其最近的均值(中心點(diǎn))對(duì)應(yīng)的集群。
K-Means算法主要包含2個(gè)部分:
- 距離公式:通常采用歐幾里得距離來計(jì)算數(shù)據(jù)點(diǎn)與質(zhì)心之間的距離
\(d(X_i, C_j) = ||X_i - C_j||^2\) 其中,\(X_i\)是數(shù)據(jù)點(diǎn),\(C_j\)是質(zhì)心。
- 目標(biāo)函數(shù):目標(biāo)是最小化所有數(shù)據(jù)點(diǎn)與所屬簇的質(zhì)心之間的距離平方和
\(J = \sum_{j=1}^k \sum_{i=1}^{N_j} ||X_i - C_j||^2\) 其中,\(N_j\)表示第\(j\)個(gè)簇中的樣本數(shù)量。
1.2. 均值漂移
均值漂移算法最早是由Fukunaga等人在1975年提出的。
它的基本原理是對(duì)每一個(gè)數(shù)據(jù)點(diǎn),算法都會(huì)估算其周圍點(diǎn)的密度梯度,然后沿著密度上升的方向移動(dòng)該點(diǎn),直至達(dá)到密度峰值。
均值漂移算法主要有3個(gè)步驟:
- 用核函數(shù)估計(jì)數(shù)據(jù)點(diǎn)的密度:常用的核函數(shù)比如高斯核,
\(K(x) = \exp(-||x||^2 / (2h^2))\) 其中,\(h\)為帶寬參數(shù),控制核的寬度。
- 均值漂移向量:也就是對(duì)于每個(gè)數(shù)據(jù)點(diǎn),計(jì)算其周圍點(diǎn)的密度梯度
- 迭代更新:根據(jù)均值漂移向量,每個(gè)數(shù)據(jù)點(diǎn)會(huì)沿著密度上升的方向移動(dòng),更新自己的位置
2. 創(chuàng)建樣本數(shù)據(jù)
利用scikit-learn中的樣本生成器,創(chuàng)建一些用于聚類的數(shù)據(jù)。
import matplotlib.pyplot as plt
from sklearn.datasets import make_blobs
X, y = make_blobs(n_samples=1000, centers=5)
plt.scatter(X[:, 0], X[:, 1], marker="o", c=y, s=25)
plt.show()
生成了包含5個(gè)類別的1000條樣本數(shù)據(jù)。
3. 模型訓(xùn)練
首先,劃分訓(xùn)練集和測試集。
from sklearn.model_selection import train_test_split
# 分割訓(xùn)練集和測試集
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2)
按照8:2的比例劃分了訓(xùn)練集和測試集。
3.1. K-Means
對(duì)于K-Means算法來說,需要指定聚類的數(shù)目,通過觀察數(shù)據(jù),我們指定聚類的數(shù)目5。
這里的樣本數(shù)據(jù)比較簡單,能夠一下看出來,實(shí)際情況下并不會(huì)如此容易的知道道聚類的數(shù)目是多少,
常常需要多次的嘗試,才能得到一個(gè)比較好的聚類數(shù)目,也就是K的值。
基于上面的數(shù)據(jù),我們?cè)O(shè)置5個(gè)簇,看看聚類之后的質(zhì)心在訓(xùn)練集和測試集上的表現(xiàn)。
from sklearn.cluster import KMeans
# 定義
reg = KMeans(n_clusters=5, n_init="auto")
# 訓(xùn)練模型
reg.fit(X_train, y_train)
# 繪制質(zhì)心
_, axes = plt.subplots(nrows=1, ncols=2, figsize=(10, 4))
markers = ["x", "o", "^", "s", "*"]
centers = reg.cluster_centers_
axes[0].scatter(X_train[:, 0], X_train[:, 1], marker="o", c=y_train, s=25)
axes[0].set_title("【訓(xùn)練集】的質(zhì)心位置")
axes[1].scatter(X_test[:, 0], X_test[:, 1], marker="o", c=y_test, s=25)
axes[1].set_title("【測試集】的質(zhì)心位置")
for idx, c in enumerate(centers):
axes[0].plot(c[0], c[1], markers[idx], markersize=10)
axes[1].plot(c[0], c[1], markers[idx], markersize=10)
plt.show()
3.2. 均值漂移
均值漂移聚類,事先是不用指定聚類的數(shù)目的,通過調(diào)整它的bandwidth參數(shù),
可以訓(xùn)練出擁有不同數(shù)目質(zhì)心的模型。
下面,設(shè)置了bandwidth=5,訓(xùn)練之后得到了擁有3個(gè)質(zhì)心的模型。
from sklearn.cluster import MeanShift
# 定義
reg = MeanShift(cluster_all=False, bandwidth=5)
# 訓(xùn)練模型
reg.fit(X, y)
# 繪制質(zhì)心
_, axes = plt.subplots(nrows=1, ncols=2, figsize=(10, 4))
markers = ["x", "o", "^", "s", "*"]
centers = reg.cluster_centers_
print(len(centers))
axes[0].scatter(X_train[:, 0], X_train[:, 1], marker="o", c=y_train, s=25)
axes[0].set_title("【訓(xùn)練集】的質(zhì)心位置")
axes[1].scatter(X_test[:, 0], X_test[:, 1], marker="o", c=y_test, s=25)
axes[1].set_title("【測試集】的質(zhì)心位置")
for idx, c in enumerate(centers):
axes[0].plot(c[0], c[1], markers[idx], markersize=10)
axes[1].plot(c[0], c[1], markers[idx], markersize=10)
plt.show()
它把左下角的3類比較接近的樣本數(shù)據(jù)點(diǎn)算作一類。
通過調(diào)整 bandwidth參數(shù),也可以得到和 K-Means 一樣的結(jié)果,
有興趣的話可以試試,大概設(shè)置 bandwidth=2 左右的時(shí)候,可以得到5個(gè)質(zhì)心,與上面的K-Means算法的結(jié)果類似。
4. 總結(jié)
K-Means和均值漂移聚類都是強(qiáng)大的聚類工具,各有其優(yōu)缺點(diǎn)。
K-Means 的優(yōu)勢是簡單、快速且易于實(shí)現(xiàn),當(dāng)數(shù)據(jù)集是密集的,且類別之間有明顯的分離時(shí),效果非常好;
不過,它需要預(yù)先設(shè)定簇的數(shù)量k,且對(duì)初始質(zhì)心的選擇敏感,所以,對(duì)于不是凸形狀或者大小差別很大的簇,效果并不好。
而均值漂移聚類的優(yōu)勢在于不需要預(yù)先知道簇的數(shù)量,可以自適應(yīng)地找到數(shù)據(jù)的“模式”,對(duì)噪聲和異常值也有很好的魯棒性。
不過,與K-Means相比,它需要選擇合適的帶寬參數(shù),對(duì)高維數(shù)據(jù)可能不太有效,且計(jì)算復(fù)雜度較高。
最后,對(duì)于這兩種均值聚類算法來說,選擇哪種取決于數(shù)據(jù)的性質(zhì)和應(yīng)用的需求。
總結(jié)
以上是生活随笔為你收集整理的【scikit-learn基础】--『监督学习』之 均值聚类的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 不止八股:阿里内部语雀一些有趣的并发编程
- 下一篇: 聊聊Llama2-Chinese中文大模