You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

轮廓分数计算的高效并行化实现方案问询

问题分析与解决

错误原因

你的并行实现逻辑完全错误:Parallel(n_jobs=36)需要接收一个任务迭代器,但你只传入了单次调用silhouette_samples(data, labels)的任务;同时silhouette_samples返回的是一维数组,joblib内部处理时会错误尝试拆包返回值,最终导致"not enough values to unpack"报错。

另外,你完全没必要手动用joblib实现并行——scikit-learn的轮廓分数计算函数本身已经内置了多核并行支持,直接指定参数就能高效利用36核资源。

可行解决方案

方案1:使用sklearn内置并行(推荐)

silhouette_score和silhouette_samples都支持n_jobs参数,直接设置为核数即可,sklearn内部会自动完成并行优化,比手动实现更稳定高效:

from sklearn.metrics import silhouette_score
from sklearn.cluster import MiniBatchKMeans

# 拟合MiniBatchKMeans
kmeans = MiniBatchKMeans(n_clusters=50, batch_size=1000, random_state=42)
kmeans.fit(data)
labels = kmeans.labels_

# 直接用内置并行计算轮廓分数
score = silhouette_score(data, labels, n_jobs=36)

如果需要获取每个样本的轮廓值再求平均,同样可以用silhouette_samples的n_jobs参数:

from sklearn.metrics import silhouette_samples
import numpy as np

silhouette_values = silhouette_samples(data, labels, n_jobs=36)
average_score = np.mean(silhouette_values)

方案2:手动用joblib拆分数据并行(仅作参考,不推荐)

如果一定要手动实现并行,需要将数据集拆分为多个子集,分别计算每个子集的轮廓值后再合并结果:

from sklearn.metrics import silhouette_samples
from sklearn.cluster import MiniBatchKMeans
from joblib import Parallel, delayed
import numpy as np

# 拟合MiniBatchKMeans
kmeans = MiniBatchKMeans(n_clusters=50, batch_size=1000, random_state=42)
kmeans.fit(data)
labels = kmeans.labels_

# 将数据集拆分为36个批次
num_splits = 36
data_splits = np.array_split(data, num_splits)
label_splits = np.array_split(labels, num_splits)

# 并行计算每个批次的轮廓值
silhouette_parts = Parallel(n_jobs=36)(
    delayed(silhouette_samples)(data_split, label_split)
    for data_split, label_split in zip(data_splits, label_splits)
)

# 合并结果并计算平均分
silhouette_values = np.concatenate(silhouette_parts)
average_score = np.mean(silhouette_values)

额外优化建议

  • 针对200万行的数据集,可尝试调整MiniBatchKMeans的batch_size(比如设为2000或5000),平衡内存占用与拟合速度。
  • 如果需要测试多个n_clusters值,可将整个K-Means拟合+轮廓分数计算的过程并行化:
def compute_score(n_clusters):
    kmeans = MiniBatchKMeans(n_clusters=n_clusters, batch_size=1000, random_state=42)
    labels = kmeans.fit_predict(data)
    return silhouette_score(data, labels, n_jobs=1)  # 每个任务用1核,总核数由Parallel控制

# 并行测试多个簇数
cluster_range = [30, 40, 50, 60, 70]
scores = Parallel(n_jobs=6)(delayed(compute_score)(n) for n in cluster_range)

内容的提问来源于stack exchange,提问作者AbliusKarfax

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.16 10:07:46