什么是降维

降维是高维数据可视分析的一种重要的数据抽象技术, 它将高维数据降解到低维空间, 同时尽可能保留诸如异常点, 聚类等特征. 降维的方法林林总总, 在可视分析中很难一步到位使用不需要任何适配的降维方法. 常见的做法是通过交互的方式, 将标准的降维方法适配到具体的应用场景中.

主成分分析(PCA)

简述

主成分分析(Principal Component Analysis, PCA); 通俗理解: 就是找出几个最主要的特征, 然后进行分析.

原理

PCA 工作原理简述(这里不讨论详细算法):

  1. 找出第一个主成分的方向, 也就是数据 方差最大 的方向.
  2. 找出第二个主成分的方向, 也就是数据 方差次大 的方向, 并且该方向与第一个主成分方向 正交(orthogonal 如果是二维空间就叫垂直).
  3. 通过这种方式计算出所有的主成分方向.
  4. 通过数据集的协方差矩阵及其特征值分析, 我们就可以得到这些主成分的值.
  5. 一旦得到了协方差矩阵的特征值和特征向量, 我们就可以保留最大的 N 个特征. 这些特征向量也给出了 N 个最重要特征的真实结构, 我们就可以通过将数据乘上这 N 个特征向量 从而将它转换到新的空间上.

优缺点

优点:

  1. 它是无监督学习, 完全无参数限制的. 在PCA的计算过程中完全不需要人为的设定参数或是根据任何经验模型对计算进行干预, 最后的结果只与数据相关, 与用户是独立的.
  2. 用PCA技术可以对数据进行降维, 同时对新求出的”主元”向量的重要性进行排序, 根据需要取前面最重要的部分, 将后面的维数省去, 可以达到降维从而简化模型或是对数据进行压缩的效果, 同时最大程度的保持了原有数据的信息.
  3. 各主成分之间正交, 可消除原始数据成分间的相互影响.
  4. 计算方法简单, 易于在计算机上实现.

缺点:

  1. 如果用户对观测对象有一定的先验知识, 掌握了数据的一些特征, 却无法通过参数化等方法对处理过程进行干预, 可能会得不到预期的效果, 效率也不高.
  2. 贡献率小的主成分往往可能含有对样本差异的重要信息.
  3. 特征值矩阵的正交向量空间是否唯一有待讨论.
  4. 在非高斯分布的情况下, PCA方法得出的主元可能并不是最优的, 此时在寻找主元时不能将方差作为衡量重要性的标准.

scikit-learn库实现PCA

使用的是sklearn.decomposition 模块中的 PCA方法.

sklearn.decomposition.PCA(n_components=None, copy=True, whiten=False, svd_solver=’auto’)

各参数:

  • n_components(int, float, None or str):
    • 要保留的特征数, 如果不设置或为’None’的话, n_components == min(n_samples, n_features);
    • 如果设置的为float类型的值, 则会保留全部特征数的百分比的特征数数量;
    • 如果n_components='mle'svd_solver='full' 则会使用最大似然估计法(MLE)来估计特征数, 使用n_Components='mle'会将svd_solver='auto'解释为svd_solver='full';
    • 如果svd_solver='arpack', 则组件数量必须严格小于n_Feature和n_Samples的最小值. 因此, ‘None’会导致: n_Components == min(n_Samples, n_Feature)-1
  • copy(bool, default True): 如果为False, 则传递给fit的数据将被覆盖, 并且运行fit(X).transform(X)将不会产生预期的结果, 请改用fit_transform(X).
  • whiten(bool, optional, default False): 是否白化, 默认为否.
  • svd_solver (str, default ‘auto’):
    • ‘auto’: 解算器由基于X.shapen_components的默认策略选择: 如果输入数据大于500x500, 并且要提取的特征数量低于数据最小维度的80%, 则启用更高效的”randomized”方法; 否则, 使用”full”方案.
    • ‘full’: 通过scipy.linalg.svd调用标准LAPACK解算器运行精确完整的SVD, 并通过后处理选择特征.
    • ‘arpack’: 通过scipy.parse.linalg.svds调用ARPACK解算器. 它严格要求0 < n_components < min(X.shape)
    • ‘randomized’: 用Halko等人的方法进行随机化奇异值(SVD)分解.

实际使用时需要先调用 fit(X) 使用X拟合模型, 再调用transform(X)对X进行PCA降维.

下面是用PCA将鸢尾花数据降为二维的例子:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
import matplotlib.pyplot as plt

from sklearn import datasets
from sklearn.decomposition import PCA

# 导入鸢尾花数据集
iris = datasets.load_iris()
X = iris.data
y = iris.target
target_names = iris.target_names

# 进行PCA降维
pca = PCA(n_components=2)
X_r = pca.fit(X).transform(X)

# 绘制降维后的数据图
fig, ax = plt.subplots()
for i, target_name in zip(range(3), target_names):
ax.scatter(X_r[y==i, 0], X_r[y==i, 1], label=target_name, alpha=0.8)
plt.legend()
plt.title('PCA of IRIS dataset')

输出结果如图:

sklearn07

线性判别分析(LDA)

简述

线性判别分析(Linear Discriminant Analysis,LDA)是一种可作为特征抽取的技术.
LDA可以提高数据分析过程中的计算效率, 对于未能正则化的模型, 可以降低维度灾难带来的过拟合.

和PCA的异同

相同点:

  1. 两者均可以对数据进行降维.
  2. 两者在降维时均使用了矩阵特征分解的思想.
  3. 两者都假设数据符合高斯分布.

不同点:

  1. LDA是有监督的降维方法, 而PCA是无监督的降维方法.
  2. LDA除了可以用于降维, 还可以用于分类.
  3. LDA选择分类性能最好的投影方向, 而PCA选择样本点投影具有最大方差的方向.

原理

  1. 对D维数据集进行标准化处理(D为特征数量, 即维度)
  2. 对每一类别, 计算D维的均值向量
  3. 构造类间的散布矩阵以及类内的散布矩阵
  4. 计算矩阵的特征值所对应的特征向量,
  5. 选取前k个特征值对应的特征向量, 构造一个D x K维的转换矩阵W, 特征向量以列的形式排列
  6. 使用转换矩阵W将样本映射到新的特征子空间上

优缺点

优点:

  1. 在降维过程中可以使用类别的先验知识经验, 而像PCA这样的无监督学习则无法使用类别先验知识.
  2. LDA在样本分类信息依赖均值而不是方差的时候, 比PCA之类的算法较优.

缺点有:

  1. LDA不适合对非高斯分布样本进行降维, PCA也有这个问题.
  2. LDA在样本分类信息依赖方差而不是均值的时候, 降维效果不好.
  3. LDA可能过度拟合数据.

scikit-learn库实现LDA

使用的是sklearn.discriminant_analysis 模块中的LinearDiscriminantAnalysis方法.

sklearn.discriminant_analysis.LinearDiscriminantAnalysis(solver=’svd’, shrinkage=None, n_components=None, store_covariance=False)
各参数:

  • solver({‘svd’, ‘lsqr’, ‘eigen’}, default=’svd’):

    • ‘svd’: 奇异值分解. 不计算协方差, 因此建议对具有大量特征的数据使用此求解器.
    • ‘lsqr’: 最小二乘解, 特征值分解, 可以与收缩相结合.
    • ‘eigen’: 特征值分解, 可以与收缩相结合.
  • shrinkage(‘auto’ or float, default=None): 收缩率参数

    • ‘auto’: 使用 Ledoit-Wolf lemma 自动收缩.
    • float(between 0 and 1): 在0和1之间浮动, 固定收缩参数.
    • 注意: shrinkage只适用’lsqr’和’eigen’求解器.
  • n_components(int, default=None): 降维时要保留的特征数(<= min(n_classes - 1, n_features)).如果是 None, 则会设置为min(n_classes - 1, n_features).

实际使用时需要先调用 fit(X, y) 使用X, y拟合模型, 再调用transform(X)对X进行LDA降维.

下面是用LDA将鸢尾花数据降为二维的例子:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
import matplotlib.pyplot as plt
from sklearn import datasets
from sklearn.discriminant_analysis import LinearDiscriminantAnalysis

# 导入鸢尾花数据
iris = datasets.load_iris()
X = iris.data
y = iris.target
target_names = iris.target_names

# 进行LDA降维
lda = LinearDiscriminantAnalysis(n_components=2)
X_r = lda.fit(X, y).transform(X)

# 绘制降维后的数据图
fig, ax = plt.subplots()
for i, target_name in zip(range(3), target_names):
ax.scatter(X_r[y==i, 0], X_r[y==i, 1], label=target_name, alpha=0.8)
plt.legend()
plt.title('LDA of IRIS dataset')

输出结果如图:

sklearn08

未完待续

后续其他降维方法日后补充.

参考文献

[1] 降维中的可视交互:一个结构化的文献分析 (Visual Interaction with Dimensionality Reduction: A Structured Literature Analysis) | PKU Visualization Blog
[2] AiLearning/13.利用PCA来简化数据.md at master · apachecn/AiLearning
[3] 从零开始实现主成分分析(PCA)算法_风雪夜归子-CSDN博客_pca算法
[4] 线性判别分析LDA原理总结 - 刘建平Pinard - 博客园
[5] 2.5. Decomposing signals in components (matrix factorization problems) — scikit-learn 0.23.1 documentation