在數據科學和機器學習中,聚類算法是一種常用的非監督學習方法,旨在將數據分組,使同一組中的數據點之間的相似性最大化,而不同組之間的相似性最小化。根據不同的應用場景和數據特性,不同的聚類算法適合不同的數據集。
# 可使用目錄功能快速確認要閱覽的主題
K-means 是一種基於劃分的聚類算法,它的核心思想是將數據集分成 K 個群集,使得每個數據點與其最近的群集中心的距離最小。
from sklearn.cluster import KMeans
from sklearn.datasets import load_iris
import pandas as pd
# 加載數據集(以 iris 為例)
data = load_iris()
X = data.data
# K-means 聚類,設置 K=3
kmeans = KMeans(n_clusters=3, random_state=42)
kmeans_labels = kmeans.fit_predict(X)
# 將結果轉換為 DataFrame 便於查看
df = pd.DataFrame(X, columns=data.feature_names)
df['Cluster'] = kmeans_labels
print(df.head()) # 顯示前幾個樣本和它們的群集標籤
"""
sepal length (cm) sepal width (cm) petal length (cm) petal width (cm) \
0 5.1 3.5 1.4 0.2
1 4.9 3.0 1.4 0.2
2 4.7 3.2 1.3 0.2
3 4.6 3.1 1.5 0.2
4 5.0 3.6 1.4 0.2
Cluster
0 1
1 1
2 1
3 1
4 1
"""
優點:
缺點:
DBSCAN 是一種基於密度的聚類算法,它通過識別密度較高的區域來形成群集,同時能夠標識出噪音點。
eps
和最小點數 min_samples
,算法會檢查每個數據點周圍有多少個點在 eps
距離範圍內。min_samples
個點在 eps
範圍內,則該點是核心點。2-2 邊界點:不滿足核心點條件,但在其他核心點的 eps
鄰域內的點。2-3 噪音點:既不是核心點,也不在任何核心點的鄰域內的點,標記為噪音點(label = -1)。from sklearn.cluster import DBSCAN
from sklearn.datasets import load_iris
from sklearn.preprocessing import StandardScaler
import pandas as pd
# 加載數據集(以 iris 為例)
data = load_iris()
X = data.data
# 標準化數據
scaler = StandardScaler()
X_scaled = scaler.fit_transform(X)
# DBSCAN 聚類
dbscan = DBSCAN(eps=0.5, min_samples=5)
dbscan_labels = dbscan.fit_predict(X_scaled)
# 將結果轉換為 DataFrame 便於查看
df = pd.DataFrame(X, columns=data.feature_names)
df['Cluster'] = dbscan_labels
print(df.head()) # 顯示前幾個樣本和它們的群集標籤
"""
sepal length (cm) sepal width (cm) petal length (cm) petal width (cm) \
0 5.1 3.5 1.4 0.2
1 4.9 3.0 1.4 0.2
2 4.7 3.2 1.3 0.2
3 4.6 3.1 1.5 0.2
4 5.0 3.6 1.4 0.2
Cluster
0 0
1 0
2 0
3 0
4 0
"""
優點:
缺點:
eps
和 min_samples
參數的選擇,選擇不當可能導致糟糕的聚類結果。層次聚類 是一種基於層次結構的聚類算法,它可以將數據從小群集逐步合併為大群集,也可以從大群集逐步分裂為小群集。層次聚類可以分為兩種類型:
凝聚型聚類是從每個數據點開始,將最近的兩個群集合併,逐步形成較大的群集,最終所有數據點合併成一個群集。它是一種自底向上的方法。
from sklearn.cluster import AgglomerativeClustering
from sklearn.datasets import load_iris
import pandas as pd
# 加載數據集(以 iris 為例)
data = load_iris()
X = data.data
# 凝聚型聚類
agg_clustering = AgglomerativeClustering(n_clusters=3)
agg_labels = agg_clustering.fit_predict(X)
# 將結果轉換為 DataFrame 便於查看
df = pd.DataFrame(X, columns=data.feature_names)
df['Cluster'] = agg_labels
print(df.head()) # 顯示前幾個樣本和它們的群集標籤
"""
sepal length (cm) sepal width (cm) petal length (cm) petal width (cm) \
0 5.1 3.5 1.4 0.2
1 4.9 3.0 1.4 0.2
2 4.7 3.2 1.3 0.2
3 4.6 3.1 1.5 0.2
4 5.0 3.6 1.4 0.2
Cluster
0 1
1 1
2 1
3 1
4 1
"""
優點:
缺點:
分裂型聚類是從整個數據集作為一個群集開始,然後逐步將其分裂成更小的群集,直到每個數據點成為單獨的群集或達到預定的群集數量。它是一種自頂向下的方法。
scikit-learn
並不直接支持分裂型聚類。常見的分裂型聚類可以通過 自頂向下 的策略來模擬,比如使用 K-means
或 二分法
進行每步的分裂。
這裡我們用二分法(通過 K-means)來模擬分裂型聚類:
from sklearn.cluster import KMeans
from sklearn.datasets import load_iris
import pandas as pd
# 自定義一個分裂型聚類函數,遞歸進行 K-means 分裂
def divisive_clustering(X, max_clusters=3):
# 初始情況,將所有數據視為一個群集
df = pd.DataFrame(X)
df['Cluster'] = 0 # 所有數據點都標記為群集 0
current_cluster = 0
while current_cluster < max_clusters:
# 對當前群集進行 K-means 分裂成 2 個子群集
cluster_data = df[df['Cluster'] == current_cluster].drop(columns=['Cluster'])
if len(cluster_data) > 1: # 當群集內有多於1個點時才進行分裂
kmeans = KMeans(n_clusters=2, random_state=42)
sub_clusters = kmeans.fit_predict(cluster_data)
# 更新群集標籤
df.loc[df['Cluster'] == current_cluster, 'Cluster'] = sub_clusters + current_cluster + 1
current_cluster += 1
return df
# 加載數據集(以 iris 為例)
data = load_iris()
X = data.data
# 執行分裂型聚類
df = divisive_clustering(X, max_clusters=3)
print(df.head()) # 顯示前幾個樣本和它們的群集標籤
"""
0 1 2 3 Cluster
0 5.1 3.5 1.4 0.2 3
1 4.9 3.0 1.4 0.2 3
2 4.7 3.2 1.3 0.2 3
3 4.6 3.1 1.5 0.2 3
4 5.0 3.6 1.4 0.2 3
"""
優點:
缺點: