首页 > 教程攻略 > ai资讯 >使用 PCA 可视化数据的分类能力

使用 PCA 可视化数据的分类能力

来源:互联网 时间:2026-05-30 19:08:53

主成分分析,简写为PCA,可以说是数据科学家手里一件趁手的兵器。它最拿手的本事,就是给特征空间“降维”,顺便还能帮我们摆脱特征之间的相关性。不过,很多人可能没意识到,PCA还有一个隐藏技能——帮你透视数据的分类能力。今天这篇文章,我们就来聊聊怎么用它干这件漂亮事。

我们会结合一个实际的例子来展开,文中也会附上对应的Python代码。完整的项目代码,可以在文末的参考中找到。

PCA到底是个什么算法?

先从理论简单过一遍。不用深究那些繁复的数学推导——如果你想彻底搞明白PCA的内核,网上已经有非常棒的资源可以查阅。这里只需要把握住一个要点:PCA是一种降维算法,它做的事情,就是从一大堆原始特征中提炼出所谓的“主成分”(Principal Components,简称PC)。

这些主成分的构造遵循一个原则:第一个主成分(PC1)会尽可能多地解释特征中的变异性;剩下没解释完的,再交给PC2去处理,以此类推。通常情况下,前两个主成分就能扛起解释绝大多数特征变异的大旗。这也意味着,我们可以用这两个“总代表”在二维平面上,直观地打量数据的分类能力。

用个数据集来试试手

说干就干。我们选用乳腺癌数据集来演示。代码很简单,一句话就能把数据加载进来。这个数据集的目标变量,是乳腺癌检测的结果——恶性还是良性。每次检测都会采集不少癌细胞,然后对每个细胞进行10种不同的测量,比如细胞半径、细胞对称性等等。为了凑出最终那30个特征,我们又把每一次测量的均值、标准误差和最大值(文中也称为“最差值”)都算了一遍。

来看看其中两个特征的分布情况——细胞平均对称性和最差平滑度。不难看出,这两个特征确实能在一定程度上帮我们区分两类样本:良性肿瘤的细胞,通常更对称、更光滑。但问题是,重叠的部分还是不少,单靠这两个特征就想做出精准判断,显然不太现实。如果我们一个一个地去画30个特征的可视化图,工作量可不小,而且它们也反映不出整个数据集的预测能力。这时候,就该PCA登场了。

import numpy as np
import pandas as pd
from sklearn.datasets import load_breast_cancer
cancer = load_breast_cancer()

data = pd.DataFrame(cancer['data'],columns=cancer['feature_names'])
data['y'] = cancer['target']

对整个数据集做PCA

先对整个数据集跑一遍PCA。我们先把所有特征做标准化处理,让它们都有均值为0、方差为1的平衡状态——这一步非常关键。因为PCA是靠最大化主成分解释的方差来工作的,如果某个特征因为量纲不同天然具有超高方差,它就会在分析中“一票独大”,带偏整个方向。做了标准化,大家才站在了同一起跑线上。

标准化之后,我们拟合PCA模型,然后把原始特征转换成主成分。因为原始有30个特征,理论上最多可以算出30个主成分。但对我们来说,只需要前两个就够了。看看二维散点图的结果:两个不同的类别已经清晰地分离成了两个不同的集群,比刚才只看两个原始特征时的效果强太多了。

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

scaler = StandardScaler()
scaler.fit(data)
scaled = scaler.transform(data)

pca = PCA().fit(scaled)
pc = pca.transform(scaled)
pc1 = pc[:,0]
pc2 = pc[:,1]

plt.figure(figsize=(10,10))
colour = ['#ff2121' if y == 1 else '#2176ff' for y in data['y']]
plt.scatter(pc1,pc2 ,c=colour,edgecolors='#000000')
plt.ylabel("Glucose",size=20)
plt.xlabel('Age',size=20)
plt.yticks(size=12)
plt.xticks(size=12)
plt.xlabel('PC1')
plt.ylabel('PC2')

这个图能告诉你什么呢?很直观:整个数据集的预测能力相当不错。当然,图中依然存在一些“游离”在集群之外的异常点,但这不代表我们一定会判错。得记住,前两个主成分并没有包含100%的特征信息,用全部30个特征训练的模型,理论上还能做得更好。

这里也有一个需要留意的点:PC1和PC2通常能解释很大比例的特征方差,但也不是绝对的。如果前两个主成分对特征的“总结”能力很差,即便你的数据本来可以完美分类,在图上你也看不到清晰的集群。这时候就要用上PCA的碎石图了。我们来画一张看一看:每个柱子的高度,代表了对应主成分解释的方差比例。可以看到,在这个例子里,PC1和PC2加起来才解释了大约20%的特征方差。你品,你细品——在这么低的解释率下,两个集群依然能清晰分离,这恰恰说明了数据本身的预测能力有多“硬核”。

var = pca.explained_variance_[0:10]
labels = ['PC1','PC2','PC3','PC4','PC5','PC6','PC7','PC8','PC9','PC10']

plt.figure(figsize=(15,7))
plt.bar(labels,var,)
plt.xlabel('Pricipal Component')
plt.ylabel('Proportion of Variance Explained')

按特征组对比来做PCA

这一招还能用来比较不同特征组的预测能力。比如,我们把特征分成两组:第一组包含所有与细胞“对称性”和“平滑度”相关的特征;第二组,是与“周长”和“凹度”相关的特征。然后,分别对这两组跑PCA,各自取前两个主成分,画出散点图。

结果非常有趣。第一组特征形成的散点图,虽然能看到一点分离的趋势,但重叠区域还是很大;再看第二组的图,两个集群就清晰多了。所以,合理的推断是:用第二组特征训练的模型,会比用第一组的效果好得多。

是不是这样呢?不妨做个简单的实验。我们用逻辑回归分别在两组特征上建模,用70%的数据训练,剩下30%测试。结果完全符合预期:第一组的测试集准确率只有约74%,而第二组直接飙到了97%。这正好印证了PCA图的判断。

group_1 = ['mean symmetry', 'symmetry error','worst symmetry',
'mean smoothness','smoothness error','worst smoothness']

group_2 = ['mean perimeter','perimeter error','worst perimeter',
'mean conca vity','conca vity error','worst conca vity']

from sklearn.model_selection import train_test_split
import sklearn.metrics as metric
import statsmodels.api as sm

for i,g in enumerate(group):
x = data[g]
x = sm.add_constant(x)
y = data['y']
x_train, x_test, y_train, y_test = train_test_split(x,y,test_size=0.3,
random_state = 101)
model = sm.Logit(y_train,x_train).fit()
predictions = np.around(model.predict(x_test))
accuracy = metric.accuracy_score(y_test,predictions)
print("Accuracy of Group {}: {}".format(i+1,accuracy))

---
Optimization terminated successfully.
Current function value: 0.458884
Iterations 7
Accuracy of Group 1: 0.7368421052631579
Optimization terminated successfully.
Current function value: 0.103458
Iterations 10
Accuracy of Group 2: 0.9707602339181286

所以,你看,在正式开始建模之前,用PCA提前“瞄”一眼数据,是能帮你建立对分类准确率的大致预期的。你还能从中摸索出哪些特征更有预测力,这对后续的特征选择可是大有裨益的。

当然,这个方法并非万能。它最好和其他探索性图表(比如箱线图、信息值分析)配合使用。建模之前,从不同的角度反复打量你的数据,总归是个好习惯。

参考

[^2]: Matt Brems, A One-Stop Shop for Principal Component Analysis (2017), https://towardsdatascience.com/a-one-stop-shop-for-principal-component-analysis-5582fb7e0a9c

[^3]: L. Pachter, What is principal component analysis? (2014), https://liorpachter.wordpress.com/2014/05/26/what-is-principal-component-analysis/

[^4]: UCI, Breast Cancer Wisconsin (Diagnostic) Dataset (2020), http://archive.ics.uci.edu/ml/datasets/breast+cancer+wisconsin+(diagnostic)

相关下载