小白从零开始勇闯人工智能:机器学习初级篇(PCA数据降维)

小白从零开始勇闯人工智能系列
机器学习初级篇:PCA 数据降维

大家好!我们继续小白视角,一步一步把机器学习最常用的“降维神器”——PCA(Principal Component Analysis,主成分分析) 讲明白。

目标读者:完全零基础或刚入门,只会基本的 Python + numpy/pandas/matplotlib 的小伙伴。

先来一个最直观的比喻(别急着看公式)

想象你手里有一堆高中生的考试成绩表:语文、数学、英语、物理、化学、生物……一共 10 科。

  • 有些同学语文数学都高 → 明显文理兼备
  • 有些物理化学生物都高 → 理科强
  • 但其实很多科目之间高度相关(学好数学通常物理也更好)

如果你要用最少的“指标”来概括一个学生的整体水平,你会怎么做?

  • 最笨的方法:保留全部 10 科 → 高维、难可视化、计算慢、容易过拟合
  • 聪明的方法:找到 2~3 个“综合分数”,让它们尽量保留原始信息

PCA 就是自动帮你找到这几个“最能代表整体的综合分数”的算法,而且这些新分数之间互相不相关(正交)。

一句话总结 PCA 干的事:

在不丢失太多信息的前提下,把高维数据“挤”到低维(通常 2D/3D),方便可视化、加速训练、去噪、去冗余。

PCA 到底在解决什么痛点?(真实场景)

  1. 维度灾难:特征太多(几百上千维),模型训练极慢,容易过拟合
  2. 可视化需求:人眼只能很好看 2D/3D 散点图
  3. 多重共线性:特征之间高度相关,模型不稳定
  4. 去噪:很多特征其实是噪声,PCA 可以把主要信号留下
  5. 特征提取:人脸识别、图像压缩、基因表达数据……

手把手核心步骤(小白版,非数学恐怖版)

  1. 把数据标准化(最重要一步!)
    不同特征量纲不同(身高 cm、工资 万、年龄 岁),不能直接算
    → 每列都变成均值≈0,标准差≈1(StandardScaler)
  2. 计算协方差矩阵
    看哪些特征“一起变大/一起变小”(相关性强)
  3. 对协方差矩阵做特征值分解
    得到:特征值(大小 = 这个方向的信息量) + 特征向量(新坐标轴方向)
  4. 按特征值从大到小排序
    前几个最大的特征值对应的特征向量 = 主成分(PC1, PC2, …)
  5. 选前 k 个主成分
    把原始数据投影到这 k 个新轴上 → 得到降维后的数据

Python 实战:用 sklearn 一行代码搞定(推荐小白先这么用)

我们用经典的 鸢尾花数据集(150 条,4 个特征)来演示。

import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
from sklearn.datasets import load_iris
from sklearn.preprocessing import StandardScaler
from sklearn.decomposition import PCA

# 1. 加载数据
iris = load_iris()
X = iris.data          # 4 个特征:萼片长/宽、花瓣长/宽
y = iris.target        # 0,1,2 三种鸢尾花

feature_names = iris.feature_names

# 2. 标准化(必须做!)
scaler = StandardScaler()
X_scaled = scaler.fit_transform(X)

# 3. PCA 降到 2 维(最常见)
pca = PCA(n_components=2)          # 也可以写 0.95 保留 95% 方差
X_pca = pca.fit_transform(X_scaled)

# 4. 看看保留了多少信息
print("每个主成分解释的方差比例:", pca.explained_variance_ratio_)
print("总共保留的信息比例:", sum(pca.explained_variance_ratio_))

# 输出示例(大概这样):
# 每个主成分解释的方差比例: [0.729  0.229]
# 总共保留的信息比例: 0.958 (保留约 96% 的信息,只用 2 维!)

# 5. 可视化(超级直观!)
plt.figure(figsize=(8, 6))
scatter = plt.scatter(X_pca[:, 0], X_pca[:, 1], c=y, cmap='viridis', edgecolor='k', s=60)
plt.xlabel(f'PC1 ({pca.explained_variance_ratio_[0]:.1%} variance)')
plt.ylabel(f'PC2 ({pca.explained_variance_ratio_[1]:.1%} variance)')
plt.title('Iris 数据集 PCA 降维到 2D')
plt.colorbar(scatter, ticks=range(3), label='鸢尾种类 (0=setosa, 1=versicolor, 2=virginica)')
plt.grid(True, linestyle='--', alpha=0.7)
plt.show()

你会看到什么?
三种鸢尾花在 2D 平面上几乎完美分开!说明 PCA 非常成功地把 4 维信息压缩到了 2 维,还保留了绝大部分区分能力。

进阶一点:如何决定降到几维?(累计方差贡献率)

# 画累计解释方差曲线(肘部法)
pca_full = PCA()
pca_full.fit(X_scaled)
cum_ratio = np.cumsum(pca_full.explained_variance_ratio_)

plt.plot(range(1, len(cum_ratio)+1), cum_ratio, marker='o')
plt.xlabel('主成分个数')
plt.ylabel('累计解释方差比例')
plt.title('PCA 累计方差解释率')
plt.grid(True)
plt.axhline(0.95, color='r', linestyle='--')  # 常用 95% 阈值
plt.show()
  • 看到曲线在第几个主成分超过 0.9 或 0.95 时,就选那个 k

快速对比表(小白速记)

问题原始数据 (4维)PCA 后 (2维)
维度
特征相关性可能强相关主成分之间正交(不相关)
可视化难(要画多维图)容易(散点图)
训练速度快很多
信息损失少(看你选几维)
sklearn 一行代码PCA(n_components=2)

小练习 & 下一步建议

  1. 自己跑上面代码,看看 setosa(0)是不是被分得特别开?为什么?
  2. 换成 n_components=3,看看 explained_variance_ratio_ 增加了多少
  3. 试试把 n_components 设成 0.90,看自动保留几维
  4. 下节可以玩:用 PCA 降维后,再跑 KNN / 逻辑回归,对比准确率和训练时间

PCA 是机器学习里“用最少维度,抓住最多信息”的哲学起点。掌握它后,你看高维数据就不会怕了!

有问题直接问:想看手写 PCA(不用 sklearn)?想看人脸数据集的 PCA 效果图?还是想知道 PCA 和 t-SNE/UMAP 的区别?随时说~

继续勇闯 AI,下期见!🚀

文章已创建 3958

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

相关文章

开始在上面输入您的搜索词,然后按回车进行搜索。按ESC取消。

返回顶部