Sklearn 聚类算法
sklearn.cluster 提供 K-Means、层次聚类、DBSCAN、GMM 等经典聚类算法。
🎯 基于划分的聚类
1. KMeans — K 均值聚类 ⭐
from sklearn.cluster import KMeans
model = KMeans(
n_clusters=8, # 簇的数量
init='k-means++', # 'k-means++' 或 'random' 或 ndarray
n_init='auto', # 初始化运行次数('auto'=1 次,int=多次取最优)
max_iter=300, # 单次运行的最大迭代次数
tol=1e-4, # 收敛容忍度
verbose=0,
random_state=42,
copy_x=True,
algorithm='lloyd' # 'lloyd','elkan'(密集数据快),'full','auto'
)
model.fit(X)
# 核心属性
print(model.cluster_centers_) # 簇中心 (n_clusters, n_features)
print(model.labels_) # 每个样本的簇标签
print(model.inertia_) # 样本到最近簇中心的平方距离之和 ⭐
print(model.n_iter_) # 迭代次数
print(model.n_features_in_) # 特征数
# 预测新样本
labels = model.predict(X_new)
# 将新样本分配到最近簇
# 变换(到各簇中心的距离)
distances = model.transform(X)
# (n_samples, n_clusters) → 可以用作降维特征
# 一步到位
labels = model.fit_predict(X)
2. MiniBatchKMeans — 小批量 K 均值
from sklearn.cluster import MiniBatchKMeans
model = MiniBatchKMeans(
n_clusters=8,
init='k-means++',
max_iter=100,
batch_size=1024, # 每批样本数
verbose=0,
random_state=42,
tol=0.0,
max_no_improvement=10, # 连续无改善轮数
init_size=None, # 初始化的样本数
n_init=3,
reassignment_ratio=0.01 # 重新分配中心的比例
)
model.fit(X)
# 支持 partial_fit(在线学习)
model.partial_fit(X_batch)
📊 基于密度的聚类
1. DBSCAN — 密度聚类 ⭐
from sklearn.cluster import DBSCAN
model = DBSCAN(
eps=0.5, # 邻域半径
min_samples=5, # 核心点所需的最小邻域点数
metric='euclidean', # 距离度量
metric_params=None,
algorithm='auto', # 'auto','ball_tree','kd_tree','brute'
leaf_size=30, # BallTree/KDTree 的叶大小
p=None, # Minkowski 度量的幂参数
n_jobs=None
)
model.fit(X)
# 核心属性
print(model.labels_) # -1=噪音, >=0=簇标签
print(model.core_sample_indices_) # 核心样本的索引
print(model.components_) # 每个核心样本的副本
# 注意: DBSCAN 没有 predict 方法!
# 对新数据需使用训练后的 dbscan 作为 nearest neighbors 查询
调参指南:
from sklearn.neighbors import NearestNeighbors
import numpy as np
import matplotlib.pyplot as plt
# K-距离图选择合适的 eps
k = 5 # 一般取 min_samples 值
nbrs = NearestNeighbors(n_neighbors=k).fit(X)
distances, indices = nbrs.kneighbors(X)
k_dist = np.sort(distances[:, -1])
plt.plot(k_dist)
plt.xlabel('Points sorted by distance')
plt.ylabel(f'{k}-NN distance')
plt.title('K-distance Graph (elbow method)')
plt.show()
# 曲线的"肘部"即为合适的 eps
2. OPTICS — 排序点识别聚类结构
from sklearn.cluster import OPTICS
model = OPTICS(
min_samples=5,
max_eps=np.inf, # 最大邻域半径
metric='minkowski',
p=2,
cluster_method='xi', # 'xi' 或 'dbscan'
eps=None, # 提取簇的阈值(cluster_method='dbscan' 时需要)
xi=0.05, # 最小陡度(cluster_method='xi' 时)
predecessor_correction=True,
min_cluster_size=None, # 最小簇大小
algorithm='auto',
leaf_size=30,
n_jobs=None
)
model.fit(X)
print(model.labels_) # 簇标签(-1=噪音)
print(model.reachability_) # 可达距离
print(model.ordering_) # 簇排序
print(model.core_distances_) # 核心距离
print(model.predecessor_) # 前驱索引
3. HDBSCAN — 层次 DBSCAN
from sklearn.cluster import HDBSCAN
model = HDBSCAN(
min_cluster_size=5, # 最小簇大小
min_samples=None, # 保守性(越大越保守)
cluster_selection_epsilon=0.0,
max_cluster_size=None, # 最大簇大小
metric='euclidean',
alpha=1.0, # 距离持久性
algorithm='auto',
leaf_size=40,
n_jobs=None,
cluster_selection_method='eom', # 'eom'(Excess of Mass) 或 'leaf'
allow_single_cluster=False,
store_centers=None
)
model.fit(X)
print(model.labels_)
print(model.probabilities_) # 每个样本的簇成员强度 (0~1)
print(model.cluster_persistence_) # 每个簇的持久性分数
# HDBSCAN 特有的方法
soft_clusters = model.membership_vector() # 软聚类向量
🏗️ 基于层次的聚类
1. AgglomerativeClustering — 凝聚层次聚类 ⭐
from sklearn.cluster import AgglomerativeClustering
model = AgglomerativeClustering(
n_clusters=2, # 目标簇数
metric='euclidean', # 距离度量
linkage='ward', # 链接准则
# 'ward' — 最小方差(仅 euclidean)
# 'complete' — 最大距离(最远邻)
# 'average' — 平均距离
# 'single' — 最小距离(最近邻)
connectivity=None, # 连接性约束矩阵
compute_distances=False, # 存储距离矩阵
distance_threshold=None, # 距离阈值(代替 n_clusters)
)
model.fit(X)
print(model.labels_)
print(model.n_clusters_) # 估计的簇数
print(model.n_leaves_) # 树的叶节点数
print(model.children_) # 每个合并步骤的子节点 (2, n_samples-1)
print(model.distances_) # 每个合并步骤的距离(compute_distances=True)
使用距离阈值而非指定 K:
model = AgglomerativeClustering(
n_clusters=None,
distance_threshold=0, # 设置为 0 会计算全树
linkage='ward'
)
model.fit(X)
2. FeatureAgglomeration — 特征凝聚
from sklearn.cluster import FeatureAgglomeration
model = FeatureAgglomeration(
n_clusters=2,
metric='euclidean',
linkage='ward',
pooling_func=np.mean # 合并后特征的聚合函数
)
X_reduced = model.fit_transform(X)
print(model.labels_) # 每个原始特征的簇标签
3. Birch — 层次聚类(大数据友好)
from sklearn.cluster import Birch
model = Birch(
threshold=0.5, # 子簇合并阈值
branching_factor=50, # 每个节点的最大 CF 子簇数
n_clusters=3, # 最终簇数
compute_labels=True,
copy=True
)
model.fit(X)
print(model.labels_)
print(model.root_) # 内部树的根节点
print(model.subcluster_centers_) # 子簇中心
# 支持 partial_fit
model.partial_fit(X_batch)
🎲 基于模型的聚类
GaussianMixture — 高斯混合模型(GMM)
from sklearn.mixture import GaussianMixture
model = GaussianMixture(
n_components=1, # 混合成分数
covariance_type='full', # 'full','tied','diag','spherical'
tol=1e-3,
reg_covar=1e-6, # 协方差对角线上加的正则化
max_iter=100,
n_init=1, # 初始化次数
init_params='kmeans', # 'kmeans','k-means++','random','random_from_data'
weights_init=None,
means_init=None,
precisions_init=None,
random_state=None,
warm_start=False,
verbose=0,
verbose_interval=10
)
model.fit(X)
# 关键属性
print(model.weights_) # 各成分的混合权重
print(model.means_) # 各成分的均值
print(model.covariances_) # 各成分的协方差
print(model.precisions_) # 各成分的精度矩阵(协方差逆)
print(model.precisions_cholesky_) # 精度矩阵的 Cholesky 分解
print(model.converged_) # 是否收敛
print(model.n_iter_) # 实际迭代数
print(model.lower_bound_) # 对数似然的下界
# 预测方法
labels = model.predict(X) # 硬分配
probs = model.predict_proba(X) # 软分配(后验概率)
log_likelihood = model.score(X) # 每个样本的对数似然
total_ll = model.score_samples(X) # 加权对数似然
# 采样
X_sampled, y_sampled = model.sample(n_samples=100)
# AIC / BIC(模型选择)
print(model.aic(X))
print(model.bic(X))
GMM 模型选择:
import numpy as np
n_components = range(1, 11)
models = [GaussianMixture(n, random_state=42).fit(X) for n in n_components]
bics = [m.bic(X) for m in models]
aics = [m.aic(X) for m in models]
best_n = n_components[np.argmin(bics)]
print(f"Best n_components (BIC): {best_n}")
BayesianGaussianMixture — 贝叶斯 GMM
from sklearn.mixture import BayesianGaussianMixture
model = BayesianGaussianMixture(
n_components=10, # 设置足够大的初始值
covariance_type='full',
tol=1e-3,
reg_covar=1e-6,
max_iter=1000,
n_init=1,
init_params='kmeans',
weight_concentration_prior_type='dirichlet_process',
# 'dirichlet_process' — 自动推断成分数
# 'dirichlet_distribution' — 固定成分数
weight_concentration_prior=None, # Dirichlet 先验浓度
mean_precision_prior=None,
mean_prior=None,
degrees_of_freedom_prior=None,
covariance_prior=None,
random_state=None,
warm_start=False,
verbose=0
)
model.fit(X)
print(model.weights_) # 部分权重接近 0(自动选择成分数)
print(model.n_components) # 原始设定的成分数
# 实际有效的成分数
effective_n = np.sum(model.weights_ > 0.01)
print(f"Effective components: {effective_n}")
📈 其他聚类算法
1. MeanShift — 均值漂移
from sklearn.cluster import MeanShift
model = MeanShift(
bandwidth=None, # 带宽(None 用 estimate_bandwidth 估计)
seeds=None, # 初始核位置
bin_seeding=False, # 使用离散化加速
min_bin_freq=1,
cluster_all=True, # 是否将所有点分配给簇(False 时孤立点为 -1)
n_jobs=None,
max_iter=300
)
model.fit(X)
print(model.cluster_centers_)
print(model.labels_)
print(model.n_iter_)
# 带宽估计
from sklearn.cluster import estimate_bandwidth
bandwidth = estimate_bandwidth(X, quantile=0.3, n_samples=500, random_state=42)
2. AffinityPropagation — 近邻传播
from sklearn.cluster import AffinityPropagation
model = AffinityPropagation(
damping=0.5, # 阻尼因子 (0.5~1)
max_iter=200,
convergence_iter=15, # 连续迭代无变化判定收敛
copy=True,
preference=None, # 优先度(None=相似度中值)
affinity='euclidean', # 或 'precomputed'
verbose=False,
random_state=None
)
model.fit(X)
print(model.cluster_centers_indices_) # 簇中心在原数据中的索引
print(model.labels_)
print(model.affinity_matrix_) # 相似度矩阵
print(model.n_iter_)
3. SpectralClustering — 谱聚类
from sklearn.cluster import SpectralClustering
model = SpectralClustering(
n_clusters=8,
eigen_solver=None, # None,'arpack','lobpcg','amg'
n_components=None, # 谱嵌入维度
random_state=42,
n_init=10, # k-means 运行次数
gamma=1.0, # RBF 核参数
affinity='rbf', # 'rbf','nearest_neighbors','precomputed',callable
n_neighbors=10, # nearest_neighbors affinity 的邻居数
eigen_tol='auto',
assign_labels='kmeans', # 'kmeans','discretize','cluster_qr'
degree=3, # 多项式核的次数
coef0=1 # 多项式核/ sigmoid 核的独立项
)
model.fit(X)
print(model.labels_)
print(model.affinity_matrix_) # 亲和矩阵
4. SpectralBiclustering / SpectralCoclustering — 谱双聚类
from sklearn.cluster import SpectralBiclustering, SpectralCoclustering
# 双聚类(同时对行和列聚类)
model = SpectralBiclustering(
n_clusters=3,
method='bistochastic', # 'bistochastic','scale','log'
n_components=6,
n_best=3,
svd_method='randomized',
n_svd_vecs=None,
mini_batch=False,
init='k-means++',
n_init=10,
random_state=42
)
model.fit(X)
print(model.row_labels_) # 行标签
print(model.column_labels_) # 列标签
# 共聚类(仅用于文档-词矩阵)
model = SpectralCoclustering(n_clusters=3, random_state=42)
model.fit(X)
print(model.row_labels_)
print(model.column_labels_)
🎯 选择簇数 K
肘部法则(Elbow Method)
from sklearn.cluster import KMeans
import matplotlib.pyplot as plt
inertias = []
K_range = range(1, 11)
for k in K_range:
km = KMeans(n_clusters=k, random_state=42, n_init=10)
km.fit(X)
inertias.append(km.inertia_)
plt.plot(K_range, inertias, 'bo-')
plt.xlabel('k')
plt.ylabel('Inertia')
plt.title('Elbow Method')
plt.show()
轮廓系数
from sklearn.metrics import silhouette_score
silhouettes = []
for k in range(2, 11):
km = KMeans(n_clusters=k, random_state=42, n_init=10)
labels = km.fit_predict(X)
sil = silhouette_score(X, labels)
silhouettes.append(sil)
best_k = K_range[np.argmax(silhouettes)]
📝 算法选择指南
| 场景 | 推荐 |
|---|---|
| 一般用途、快速 | KMeans |
| 大数据集在线学习 | MiniBatchKMeans |
| 任意形状簇、含噪音 | DBSCAN |
| 变密度簇 | HDBSCAN / OPTICS |
| 层次结构 | AgglomerativeClustering |
| 软聚类、概率 | GaussianMixture |
| 自动推断簇数 | BayesianGaussianMixture |
| 非凸簇 | SpectralClustering |
| K 已知、球形簇 | KMeans |
[[sklearn-总览|← 返回总览]]

1704

被折叠的 条评论
为什么被折叠?



