一、聚類算法
1. K-Means 聚類
- 原理:K-Means 是一種基于劃分的聚類算法,目標是將 n n n 個樣本劃分到 k k k 個簇中,使得簇內樣本的相似度盡可能高,簇間樣本的相似度盡可能低。算法通過迭代的方式,不斷更新簇的質心(即簇內樣本的均值),直到質心不再變化或達到最大迭代次數。
- 步驟:
- 隨機初始化 k k k 個質心。
- 將每個樣本分配到距離最近的質心所在的簇。
- 重新計算每個簇的質心。
- 重復步驟 2 和 3,直到質心不再變化或達到最大迭代次數。
- 優點:實現簡單,計算效率高,對于大規模數據集有較好的性能。
- 缺點:需要預先指定簇的數量 k k k;對初始質心的選擇敏感,可能會陷入局部最優解;對噪聲和離群點敏感。
2. DBSCAN 聚類
- 原理:DBSCAN(Density-Based Spatial Clustering of Applications with Noise)是一種基于密度的聚類算法,它將具有足夠密度的區域劃分為簇,并在具有噪聲的數據中發現任意形狀的簇。核心概念包括核心點、邊界點和噪聲點。
- 步驟:
- 定義兩個參數:鄰域半徑 ? \epsilon ? 和最小樣本數 M i n P t s MinPts MinPts。
- 遍歷所有樣本,找出所有核心點(在其 ? \epsilon ? 鄰域內至少有 M i n P t s MinPts MinPts 個樣本)。
- 從一個核心點開始,通過密度可達關系(即從一個核心點出發,通過一系列核心點相連)擴展出一個簇。
- 重復步驟 3,直到所有核心點都被訪問過。未被訪問的樣本被標記為噪聲點。
- 優點:不需要預先指定簇的數量;可以發現任意形狀的簇;對噪聲和離群點具有較好的魯棒性。
- 缺點:對于密度變化較大的數據集,參數 ? \epsilon ? 和 M i n P t s MinPts MinPts 的選擇比較困難;在高維數據上的性能可能較差。
3. 層次聚類
- 原理:層次聚類是一種基于樣本間相似度的聚類算法,它通過構建一個層次化的聚類樹來表示樣本之間的聚類關系。層次聚類可以分為凝聚式(自底向上)和分裂式(自頂向下)兩種方式。
- 步驟(凝聚式):
- 將每個樣本看作一個單獨的簇。
- 計算所有簇之間的相似度,將相似度最高的兩個簇合并成一個新的簇。
- 重復步驟 2,直到所有樣本都合并到一個簇中或達到停止條件。
- 優點:不需要預先指定簇的數量;可以生成一個層次化的聚類結構,方便用戶根據需要選擇合適的聚類結果。
- 缺點:計算復雜度較高,對于大規模數據集的計算效率較低;一旦一個合并操作完成,就不能再撤銷,可能會導致聚類結果不理想。
在論文中聚類的策略不一定是針對所有特征,可以針對其中幾個可以解釋的特征進行聚類,得到聚類后的類別,這樣后續進行解釋也更加符合邏輯。
二、聚類的流程,實操
-
標準化數據
-
選擇合適的算法,根據評估指標調參( )
KMeans 和層次聚類的參數是K值,選完k指標就確定
DBSCAN 的參數是 eps 和min_samples,選完他們出現k和評估指標
以及層次聚類的 linkage準則等都需要仔細調優。
除了經典的評估指標,還需要關注聚類出來每個簇對應的樣本個數,避免太少沒有意義。 -
將聚類后的特征添加到原數據中
-
原則t-sne或者pca進行2D或3D可視化
作業: 對心臟病數據集進行聚類。
import pandas as pd
from sklearn.cluster import DBSCAN
from sklearn.preprocessing import StandardScaler
import matplotlib.pyplot as plt
import numpy as np# 讀取 heart.csv 文件
file_path = r'.\csv\heart.csv'
data = pd.read_csv(file_path)# 假設數據集中所有列都是數值型特征,若有非數值型需要先處理
# 提取特征
X = data.values# 數據標準化
scaler = StandardScaler()
X_scaled = scaler.fit_transform(X)
接下來以DBSCAN聚類算法為例
# 使用 DBSCAN 進行聚類
db = DBSCAN(eps=0.3, min_samples=10).fit(X_scaled)
core_samples_mask = np.zeros_like(db.labels_, dtype=bool)
core_samples_mask[db.core_sample_indices_] = True
labels = db.labels_# 聚類數量(排除噪聲點)
n_clusters_ = len(set(labels)) - (1 if -1 in labels else 0)
n_noise_ = list(labels).count(-1)print(f'估計的聚類數量: {n_clusters_}')
print(f'估計的噪聲點數量: {n_noise_}')
這個由于特征過多,所以不能做可視化展示,如果想做可視化展示,可以講一個特征和標簽對應,用這個特征來做聚類分析,最后可以做可視化分析。
三、總結
本文介紹了三種常見的聚類算法,對心臟病數據集做DBSCAN 聚類分析。先讀取數據并標準化,設參數完成聚類得簇數與噪聲點數。