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

K-means聚类分组统计结果与Statistica不符,代码正确性咨询

代码正确性分析与结果差异排查

首先,你的代码逻辑框架是正确的,但存在几个明显的问题和可能导致与Statistica结果不一致的原因,下面逐一拆解:

1. 代码中的直接错误

你在打印cardio == 0 count()时,实际计算的是cardio ==1的数量,这是明显的逻辑错误:

print('cardio == 0 count() for each cluster')
for x in X:
    check = clusterDB_1[kmeans.labels_ == x]
    print(len(check[check['cardio'] == 1]))  # 这里应该是 ==0

这个错误会直接导致你得到的cardio计数结果和预期不符。

2. 导致与Statistica结果不一致的核心原因

(1)KMeans的随机性差异

scikit-learn的KMeans默认使用随机初始化质心(init='k-means++'但仍有随机性),且默认n_init=10(运行10次取最优结果),而Statistica可能使用了不同的初始化策略、固定了随机种子,或者运行次数不同。这会导致聚类分组完全不同,最终统计量自然不一致。

解决方法:固定随机种子,确保聚类结果可复现:

kmeans = KMeans(n_clusters=8, random_state=42, n_init='auto').fit(clusterDB_1)

random_state=42固定随机种子,n_init='auto'让sklearn自动选择合适的运行次数(避免旧版本默认值差异)。

(2)数据预处理差异

检查Statistica是否对数据做了预处理:

  • Age字段单位:你的数据集里Age可能是以天为单位(比如值在10000以上),Statistica可能将其转换为了年(除以365),而你在Python中直接使用原始值计算均值,这会导致Age的均值差异极大。
  • 数据标准化/归一化:Statistica可能对Age、BMI做了标准化(比如Z-score)后再聚类,而你直接使用原始数据聚类,这会因为特征尺度差异(Age数值远大于BMI)导致聚类偏向Age维度,结果自然不同。

(3)聚类数量与参数匹配

确认Statistica中设置的聚类数是否也是8,以及是否有其他参数差异(比如距离度量,sklearn默认是欧氏距离,Statistica是否用了相同的距离)。

3. 优化后的代码(更高效且正确)

你可以不用多次循环,直接将聚类标签合并到数据框中,然后用groupby一次性计算所有需要的统计量,更简洁且不易出错:

import pandas as pd
from sklearn.cluster import KMeans

# 读取数据
dataset = pd.read_csv("C:/Users/../cardio_train_py.csv", sep=';')
clusterDB_1 = dataset[['Age','BMI','cardio']].copy()

# 固定随机种子,确保聚类结果可复现
kmeans = KMeans(n_clusters=8, random_state=42, n_init='auto').fit(clusterDB_1)

# 将聚类标签加入数据框
clusterDB_1['cluster_label'] = kmeans.labels_

# 一次性计算所有统计量
cluster_stats = clusterDB_1.groupby('cluster_label').agg(
    Age_mean=('Age', 'mean'),
    Age_min=('Age', 'min'),
    Age_max=('Age', 'max'),
    Age_std=('Age', 'std'),
    BMI_mean=('BMI', 'mean'),
    BMI_min=('BMI', 'min'),
    BMI_max=('BMI', 'max'),
    BMI_std=('BMI', 'std'),
    cardio_0_count=('cardio', lambda x: (x == 0).sum()),
    cardio_1_count=('cardio', lambda x: (x == 1).sum())
)

print(cluster_stats)

4. 验证你的BMI结果异常

你给出的Python计算BMI结果中有一个值是166.57,这明显异常,说明你的数据集中可能存在BMI的异常值(比如输入错误),建议先检查数据:

print(clusterDB_1['BMI'].describe())
print(clusterDB_1[clusterDB_1['BMI'] > 100])  # 找出异常大的BMI值

这个异常值会严重影响聚类结果和统计量,Statistica可能自动过滤了异常值,而你的Python代码没有处理,这也是结果不一致的可能原因之一。


内容的提问来源于stack exchange,提问作者Marcin Miśkowiec

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.09 00:28:13