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

使用sklearn的PCA得到意外结果,附心脏病数据预处理代码

嘿,我来帮你排查下用sklearn做PCA时出现意外结果的常见问题——结合你用的克利夫兰心脏病数据集,大概率是这几个环节没处理好:

1. 先搞定数据里的缺失值

这个数据集的ca和thal列存在?作为缺失值标记,pd.read_csv默认会把这类值识别为字符串,导致整列变成object类型。PCA只能处理数值型数据,这种非数值特征会直接导致结果异常(甚至悄悄报错)。你需要在预处理里补全这步:

import pandas as pd
import numpy as np

def loadAndPreprocess(filename):
    print("Activity 1a: ")
    dataLabels = [ 
        'age', 'sex', 'cp', 'trestbps', 'chol', 'fbs', 
        'restecg', 'thalach', 'exang', 'oldpeak', 'slope', 
        'ca', 'thal', 'class' 
    ]
    # 读取时指定列名
    data = pd.read_csv(filename, names=dataLabels)
    # 把?替换为标准缺失值标记NaN
    data = data.replace('?', np.nan)
    # 可选:删除含缺失值的行,或者用均值/中位数填充
    data = data.dropna()  # 简单直接的方式,适合初步排查
    # 把原本是字符串的列转成数值型
    data['ca'] = data['ca'].astype(float)
    data['thal'] = data['thal'].astype(float)
    return data
2. PCA必须先做数据标准化

PCA对数据尺度极度敏感:比如age是几十的范围,chol是几百的范围,如果不做标准化,方差大的特征会完全主导主成分的方向,导致你得到的PCA结果完全偏离预期。一定要在PCA前用标准化工具处理:

from sklearn.preprocessing import StandardScaler
from sklearn.decomposition import PCA

# 用你的函数加载预处理后的数据
data = loadAndPreprocess("processed.cleveland.data")
# 分离特征和标签
X = data.drop('class', axis=1)
y = data['class']

# 标准化特征:让每个特征均值为0,方差为1
scaler = StandardScaler()
X_scaled = scaler.fit_transform(X)

# 再执行PCA
pca = PCA(n_components=2)
X_pca = pca.fit_transform(X_scaled)
3. 检查特征列的类型是否全为数值型

可以在预处理函数末尾加一行print(data.dtypes),确认所有特征列都是int64或float64类型。如果还有object类型的列,说明还有非数值数据没处理干净,这也是PCA出问题的常见原因。

4. 验证PCA结果的小技巧

可以打印主成分的解释方差比,判断结果是否合理:

print("主成分解释方差占比:", pca.explained_variance_ratio_)

如果前几个主成分的解释方差占比极低,要么是数据本身特征相关性弱,要么就是你没做标准化,导致方差被大尺度特征垄断了。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.25 03:44:41