猿创征文|机器学习实战——降维(代码片段)

WHJ226 WHJ226     2022-12-01     305

关键词:

目录

1 主成分

2 低维度投影

3 方差解释率

4 选择正确数量的维度

5 PCA压缩

6 增量PCA

7 核主成分分析

8 选择核函数和调整超参数

9 局部线性嵌入

10 其他降维技巧


数据降维会丢失一些信息(好比压缩图像带来的效果一样),所以,它虽然能够加速训练,但是也会轻微降低系统性能。

我们简要说一下降维的两种主要方法:投影和流形学习。投影:高维空间的所有训练实例实际上受一个低得多的低维子空间所影响,将训练实例投影到该子空间就是投影。但许多情况下,子空间可能是弯曲的或转动的,就引入了流形学习。流形假设(流形假说)认为大多数现实世界的高维度数据集存在一个低维度的流形来重新表示。我们可以把瑞士卷看做一个二维流形的例子。更概括的说,d维流形就是n维空间的一部分(d<n),局部类似于一个d维超平面。

主成分分析(PCA)是迄今最流行的降维算法。它能识别出最接近数据的超平面,然后将数据投影该平面。同时该超平面也保留了数据最大差异性。

常规模块的导入以及图像可视化的设置:

# Common imports
import numpy as np
import os
 
# to make this notebook's output stable across runs
np.random.seed(42)
 
# To plot pretty figures
%matplotlib inline
import matplotlib as mpl
import matplotlib.pyplot as plt
mpl.rc('axes', labelsize=14)
mpl.rc('xtick', labelsize=12)
mpl.rc('ytick', labelsize=12)

1 主成分

主成分分析(PCA)可以在训练集中识别出哪条轴(一维超平面)对差异性的贡献度最高。即下图中由实线表示的轴。同时它也找出了第二条轴,它对剩余差异性的贡献度最高,与第一条轴垂直。

选择投影的子空间

定义第i条轴的单位向量就叫作第i个主成分。上图中,第一个主成分是c1,第二个主成分是c2。前两个主成分是平面里正交的箭头所示,第三个主成分则垂直于平面。

那么我们该怎么找到训练集的主成分呢?我们有一种标准矩阵分解技术,叫作奇异值分解(SVD)。它可以将训练集矩阵X分解成三个矩阵的点积   ,其中  正包含我们想要的所有主成分,公式如下:

主成分矩阵

下面的代码使用NumPy的svd()函数来获取训练集中所有主成分,并提取前两个:

#3D数据集
np.random.seed(4)
m = 60
w1, w2 = 0.1, 0.3
noise = 0.1

angles = np.random.rand(m) * 3 * np.pi / 2 - 0.5
X = np.empty((m, 3))
X[:, 0] = np.cos(angles) + np.sin(angles)/2 + noise * np.random.randn(m) / 2
X[:, 1] = np.sin(angles) * 0.7 + noise * np.random.randn(m) / 2
X[:, 2] = X[:, 0] * w1 + X[:, 1] * w2 + noise * np.random.randn(m)

#获取主成分
X_centered = X - X.mean(axis=0)
U, s, Vt = np.linalg.svd(X_centered)
c1 = Vt.T[:, 0]
c2 = Vt.T[:, 1]

2 低维度投影

一旦确定了所有主成分,就可以将数据集投影到由前d个主成分定义的超平面上,从而将数据集的维度降低到d维,这个超平面的选择,能确保投影保留尽可能多的差异性。

要将训练集投影到超平面上,简单地计算训练集矩阵X和矩阵  的点积即可, 是包含前d个主成分的矩阵(即由矩阵  的前d列组成的矩阵),如下式:

下面的代码将训练集投影到由前两个主成分定义的平面上:

W2 = Vt.T[:, :2]
X2D = X_centered.dot(W2)

Scikit-Learn的PCA类使用SVD分解来实现主成分,下面代码应用PCA将数据集的维度降到二维(它会自动处理数据集中) :

from sklearn.decomposition import PCA

pca = PCA(n_components = 2)
X2D = pca.fit_transform(X)

我们可以通过变量components_来访问主成分:

pca.components_

运行结果如下:

array([[-0.93636116, -0.29854881, -0.18465208],
       [ 0.34027485, -0.90119108, -0.2684542 ]])

第一个主成分等于 pca.components_.T[:,0] 。

pca.components_.T[:,0]

运行结果如下:

array([-0.93636116, -0.29854881, -0.18465208])

3 方差解释率

方差解释率可以通过变量 explained_variance_ratio_ 获得。它表示每个主成分轴对整个数据集的方差贡献度。我们看一下(3D数据集)前两个主成分的方差解释率:

pca.explained_variance_ratio_

运行结果如下:

array([0.84248607, 0.14631839])

结果表示,数据集方差的84%由第一条轴贡献,14%由第二条轴。

4 选择正确数量的维度

除了选择要降至的维度数量,通常更好的办法是将靠前的主成分方差解释率依次相加,直到得到足够大比例的方差,此时的维度数量就是很好的选择。

下面代码(基于MNIST数据集)计算了PCA但是没有降维,而是计算若要保留训练集方差的95%所需要的最低维度数量:

from sklearn.datasets import fetch_openml
from sklearn.model_selection import train_test_split

mnist = fetch_openml('mnist_784', version=1, cache=True, as_frame=False)

X = mnist["data"]
y = mnist["target"]

X_train, X_test, y_train, y_test = train_test_split(X, y)
pca = PCA()
pca.fit(X)
cumsum = np.cumsum(pca.explained_variance_ratio_)
d = np.argmax(cumsum >= 0.95) + 1

d

运行结果如下:

154

然后,我们可以设置 n_components = d ,再次运行PCA。不过还有一个更好的方法:不需要指定保留主成分的数量,我们可以直接将 n_compents 设置为 0.0 到 1.0 之间的浮点数,表示希望保留的方差比:

pca = PCA(n_components = 0.95)
X_reduced = pca.fit_transform(X)

pca.n_components_

运行结果如下:

154

我们再来看一下此时的方差解释率:

np.sum(pca.explained_variance_ratio_)

运行结果如下:

0.9503499702078603

5 PCA压缩

上述对MNIST数据集应用主成分分析后,保留的特征只有154个(原784个)。我们也可以将缩小的数据集解压缩会784维数据集,但是它只是非常接近原始数据,并不完全相同。原始数据和重建数据(压缩后再解压缩)之间的均方距离,被称为重建误差。我们可以使用 inverse_transform() 方法实现解压缩。

下面简单实现:

pca = PCA(n_components = 154)
X_reduced = pca.fit_transform(X_train)
X_recovered = pca.inverse_transform(X_reduced)

def plot_digits(instances, images_per_row=5, **options):
    size = 28
    images_per_row = min(len(instances), images_per_row)
    images = [instance.reshape(size,size) for instance in instances]
    n_rows = (len(instances) - 1) // images_per_row + 1
    row_images = []
    n_empty = n_rows * images_per_row - len(instances)
    images.append(np.zeros((size, size * n_empty)))
    for row in range(n_rows):
        rimages = images[row * images_per_row : (row + 1) * images_per_row]
        row_images.append(np.concatenate(rimages, axis=1))
    image = np.concatenate(row_images, axis=0)
    plt.imshow(image, cmap = mpl.cm.binary, **options)
    plt.axis("off")
    
    
plt.figure(figsize=(7, 4))
plt.subplot(121)
plot_digits(X_train[::2100])
plt.title("Original", fontsize=16)
plt.subplot(122)
plot_digits(X_recovered[::2100])
plt.title("Compressed", fontsize=16)

运行结果如下:

结果中,左图表示原始数据,右图表示重建数据。可以看出图像质量有轻微损伤外,数字基本完好无损。说明保留其方差的95%,保留了数据的绝大部分差异性。 

6 增量PCA

主成分分析的问题在于它需要整个训练集都进入内存,才能运行SVD算法。增量主成分分析:我们可以将训练集分成一个个小批量,一次给IPCA算法喂一个。

下面的代码将MNIST数据集分成100个小批量(使用NumPy的array_split()函数),将它们提供给Scikit-Learn的 IncrementalPCA ,将数据集降到154维。注意,我们还必须为每个小批量调用 partial_fit() 方法,而不是之前整个训练集的fit()方法:

from sklearn.decomposition import IncrementalPCA

n_batches = 100
inc_pca = IncrementalPCA(n_components=154)
for X_batch in np.array_split(X_train, n_batches):
    print(".", end="") # not shown in the book
    inc_pca.partial_fit(X_batch)

X_reduced = inc_pca.transform(X_train)


X_recovered_inc_pca = inc_pca.inverse_transform(X_reduced)

plt.figure(figsize=(7, 4))
plt.subplot(121)
plot_digits(X_train[::2100])
plt.subplot(122)
plot_digits(X_recovered_inc_pca[::2100])
plt.tight_layout()

运行结果如下:

7 核主成分分析

核技巧是一种数学技巧,隐性地将实例映射到非常高维的空间(特征空间),从而使支持向量机能够进行非线性分类和回归。同时核技巧也可以应用PCA,使复杂的非线性投影降维成为可能。这就是所谓的核主成分分析。

下面的代码使用 Scikit-Learn 的 KernelPCA ,执行带有RBF核函数的kPCA:

from sklearn.datasets import make_swiss_roll
X, t = make_swiss_roll(n_samples=1000, noise=0.2, random_state=42)

from sklearn.decomposition import KernelPCA

rbf_pca = KernelPCA(n_components = 2, kernel="rbf", gamma=0.04)
X_reduced = rbf_pca.fit_transform(X)

from sklearn.decomposition import KernelPCA

lin_pca = KernelPCA(n_components = 2, kernel="linear", fit_inverse_transform=True)
rbf_pca = KernelPCA(n_components = 2, kernel="rbf", gamma=0.0433, fit_inverse_transform=True)
sig_pca = KernelPCA(n_components = 2, kernel="sigmoid", gamma=0.001, coef0=1, fit_inverse_transform=True)

y = t > 6.9

plt.figure(figsize=(11, 4))
for subplot, pca, title in ((131, lin_pca, "Linear kernel"), (132, rbf_pca, "RBF kernel, $\\gamma=0.04$"), (133, sig_pca, "Sigmoid kernel, $\\gamma=10^-3, r=1$")):
    X_reduced = pca.fit_transform(X)
    if subplot == 132:
        X_reduced_rbf = X_reduced
    
    plt.subplot(subplot)
    #plt.plot(X_reduced[y, 0], X_reduced[y, 1], "gs")
    #plt.plot(X_reduced[~y, 0], X_reduced[~y, 1], "y^")
    plt.title(title, fontsize=14)
    plt.scatter(X_reduced[:, 0], X_reduced[:, 1], c=t, cmap=plt.cm.hot)
    plt.xlabel("$z_1$", fontsize=18)
    if subplot == 131:
        plt.ylabel("$z_2$", fontsize=18, rotation=0)
    plt.grid(True)

plt.show()

运行结果如下:

使用不同核函数的kPCA将瑞士卷降到2D

上图显示了使用不同核函数降到二维的瑞士卷,包括线性函数(PCA类)、RBF核函数,以及sigmoid核函数(Logistic)。

8 选择核函数和调整超参数

由于kPCA是一种无监督的学习算法,因此没有明显的性能指标来帮你选择最佳的核函数和超参数值。而降维通常是监督式学习任务的准备步骤,所以可以使用网格搜索,来找到使任务性能最佳的核和超参数。

例如,下面的代码创建了一个两步流水线,首先使用kPCA将维度将至二维,然后应用逻辑回归进行分类。接下来使用 GridSearchCV 为 kPCA 找到最佳的核和gamma 值,从而在流水线最后获得最准确的分类:

from sklearn.model_selection import GridSearchCV
from sklearn.linear_model import LogisticRegression
from sklearn.pipeline import Pipeline

clf = Pipeline([
        ("kpca", KernelPCA(n_components=2)),
        ("log_reg", LogisticRegression(solver="liblinear"))
    ])

param_grid = [
        "kpca__gamma": np.linspace(0.03, 0.05, 10),
        "kpca__kernel": ["rbf", "sigmoid"]
    ]

grid_search = GridSearchCV(clf, param_grid, cv=3)
grid_search.fit(X, y)

#最佳的核和超参数
print(grid_search.best_params_)

运行结果如下:

'kpca__gamma': 0.043333333333333335, 'kpca__kernel': 'rbf'

还有一种完全不受监督方法,就是选择重建误差最低的核和超参数。但是这个重建不像线性PCA重建那样容易。原因如下,如下图,左上是瑞士卷的原始3D数据集,和应用RBF核的kPCA得到的二维数据集(右上)。因为核技巧,所以这在数学上等同于:通过特征映射函数  ,将训练集映射到无限维度的特征空间(右下),然后用线性PCA将转换后的训练集投影到2D平面。注意,如果我们对一个已经降维的实例进行PCA逆转换,重建的点将存在于特征空间,而不是原始空间中(例如,图中x表示的那个点)。而这里特征空间是无限维度的,所以我们无法计算出重建点,因此也无法计算出真实的重建误差。不过,我们可以在原始空间中找到一个点,使其映射接近于重建点,这被称为重建原像。一旦有了这个原像,我们就可以测量它到原始实例的平方距离。最后,选择使这个重建原像误差最小化的核和超参数。

如何重建?方法之一是训练一个监督式回归模型,以投影后的实例作为训练集,并以原始实例作为目标。如果我们设置 fit_inverse_transform=True ,Scikit-Learn会自动执行该操作,如下:

rbf_pca = KernelPCA(n_components = 2, kernel="rbf", gamma=0.0433,
                    fit_inverse_transform=True)
X_reduced = rbf_pca.fit_transform(X)
X_preimage = rbf_pca.inverse_transform(X_reduced)

然后我们就可以计算重建原像误差:

from sklearn.metrics import mean_squared_error

mean_squared_error(X, X_preimage)

运行结果如下:

4.236482168742404e-27

 然后,我们可以使用交叉验证的网格搜索寻找使这个原像重建误差最小的核和超参数。

9 局部线性嵌入

局部线性嵌入(LLE)是另一种非常强大的非线性降维技术。不像之前的算法依赖于投影,它是一种流形学习技术。简单来说,LLE首先测量每个算法如何与其最近的邻居线性相关,然后为训练集寻找一个能最大程度保留这些局部关系的低维表示。这也使得它特别擅长展开弯曲的流形,特别是没有太多噪声时。

下面的代码使用 Scikit-Learn 的 LocallyLinearEmbedding 类来展开瑞士卷。得到的二维数据集如下图所示。瑞士卷展开后,实例之间的距离局部保存得很好,不过从整体来看,距离保存得不太理想:展开的瑞士卷左侧被挤压,右侧被拉长。但是,对于流形建模来说,LLE还是做得相当不错。

X, t = make_swiss_roll(n_samples=1000, noise=0.2, random_state=41)

from sklearn.manifold import LocallyLinearEmbedding

lle = LocallyLinearEmbedding(n_components=2, n_neighbors=10, random_state=42)
X_reduced = lle.fit_transform(X)

plt.title("Unrolled swiss roll using LLE", fontsize=14)
plt.scatter(X_reduced[:, 0], X_reduced[:, 1], c=t, cmap=plt.cm.hot)
plt.xlabel("$z_1$", fontsize=18)
plt.ylabel("$z_2$", fontsize=18)
plt.axis([-0.065, 0.055, -0.1, 0.12])
plt.grid(True)

plt.show()

运行结果如下:

 LLE工作原理:

首先,对于每个训练实例  ,算法会识别出离它最近的 k个邻居(上面的代码中k=10),然后尝试将 重建为这些邻居的线性函数。具体来说,就是要找到权重  使实例和  之间的距离平方最小,如果实例 不是实例 的k个最近的邻居之一, 。因此,LLE的第一步就是如下公式所示的约束优化问题,其中W是包含所有权重  的权重矩阵,第二个约束则是简单地对每个训练实例  的权重进行归一。

LLE第一步:对局部关系线性建模

这一步完成后,权重矩阵  (包含权重  )对训练实例之间的局部线性关系进行编码。现在,第二步就是要将训练实例映射到一个d维空间(d<n),同时尽可能保留这些局部关系。如果 是实例  在这个d维空间的映像,那么我们希望从 到  之间的平方距离尽可能小。如下无约束优化问题。它看起来与第一步雷士,但不是保持固定距离寻找最佳权重,而是保持固定权重,并在低维空间中找到每个实例映像的最佳位置。注意,Z是包含所有的矩阵 。

LLE第二步:保留关系并降维

10 其他降维技巧

  1. 多维缩放算法(MDS),保持实例之间的距离,降低维度。
  2. 等度量映射算法(Isomap),将每个实例与其最近的邻居连接起来,创建连接图形,然后保留实例之间的这个测地距离,降低维度。
  3. t-分布随机近邻嵌入(t-SNE)算法在降低维度时,试图让其相似的实例彼此靠近,不相似的实例彼此远离。它主要用于可视化,尤其是将高维空间中的实例集群可视化。

下面代码是上述算法的简单实现:

from sklearn.manifold import MDS

mds = MDS(n_components=2, random_state=42)
X_reduced_mds = mds.fit_transform(X)

from sklearn.manifold import Isomap

isomap = Isomap(n_components=2)
X_reduced_isomap = isomap.fit_transform(X)

from sklearn.manifold import TSNE

tsne = TSNE(n_components=2, random_state=42)
X_reduced_tsne = tsne.fit_transform(X)

from sklearn.discriminant_analysis import LinearDiscriminantAnalysis

lda = LinearDiscriminantAnalysis(n_components=2)
X_mnist = mnist["data"]
y_mnist = mnist["target"]
lda.fit(X_mnist, y_mnist)
X_reduced_lda = lda.transform(X_mnist)

titles = ["MDS", "Isomap", "t-SNE"]

plt.figure(figsize=(11,4))

for subplot, title, X_reduced in zip((131, 132, 133), titles,
                                     (X_reduced_mds, X_reduced_isomap, X_reduced_tsne)):
    plt.subplot(subplot)
    plt.title(title, fontsize=14)
    plt.scatter(X_reduced[:, 0], X_reduced[:, 1], c=t, cmap=plt.cm.hot)
    plt.xlabel("$z_1$", fontsize=18)
    if subplot == 131:
        plt.ylabel("$z_2$", fontsize=18, rotation=0)
    plt.grid(True)

plt.show()

运行结果如下:

学习笔记——《机器学习实战:基于Scikit-Learn和TensorFlow》

猿创征文|python-sklearn机器学习快速入门:你的第一个机器学习实战项目(代码片段)

目录前言一、从目的出发1.导入数据二、项目开启1.导入数据2.预览数据3.数据预处理1.过采样 2.欠采样4.数据可视化 单变量图表多变量图表5.训练模型5.1划分数据集 5.2评估算法5.3模型建立 5.4模型预测点关注,防走丢,... 查看详情

猿创征文|国产数据库实战之使用docker部署oceanbase数据库(代码片段)

猿创征文|国产数据库实战之使用Docker部署OceanBase数据库一、OceanBase介绍1.OceanBase介绍2.OceanBase特点3.OceanBase数据库基础概念4.OceanBase相关概念①OBServer②区域(zone)③资源池④租户⑤数据分区⑥副本5.本次实践介绍二、检查... 查看详情

猿创征文|国产数据库实战之tidb数据库快速入门(代码片段)

猿创征文|国产数据库实战之TiDB数据库快速入门一、系统检查1.检查系统版本2.查看本地IP地址3.TiDB集群介绍二、快速部署本地测试集群1.安装TiUP工具2.声明全局环境变量3.快速部署TiDB集群三、连接TiDB数据库1.新开一个session以访问T... 查看详情

猿创征文|基于java+springboot+vue学生学习平台详细设计实现(代码片段)

博主介绍:✌全网粉丝20W+,csdn特邀作者、博客专家、CSDN新星计划导师、java领域优质创作者,博客之星、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java技术领域和毕业设计项目实战✌🍅文末获取联系🍅精彩专... 查看详情

猿创征文|基于java+springboot+vue学生学习平台详细设计实现(代码片段)

博主介绍:✌全网粉丝20W+,csdn特邀作者、博客专家、CSDN新星计划导师、java领域优质创作者,博客之星、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java技术领域和毕业设计项目实战✌🍅文末获取联系🍅精彩专... 查看详情

猿创征文|深度学习前沿应用文本审核(代码片段)

猿创征文|【深度学习前沿应用】文本审核作者简介:在校大学生一枚,C/C++领域新星创作者,华为云享专家,阿里云专家博主,腾云先锋(TDP)成员,云曦智划项目总负责人,全国高... 查看详情

猿创征文|前端到全栈,一名it初学者的学习与成长之路(代码片段)

目录导读写在前面创作之路❤前端开发工程师知识体系❤Vue&React开发框架❤前端开发实战❤Linux&云原生小马技术栈❤主打技术专栏❤其他专栏(实用干货)❤技术栈词云学习与成长总结写在前面2021年7月18日我在CSDN发布了第一... 查看详情

猿创征文|深度学习前沿应用文本生成(代码片段)

猿创征文|【深度学习前沿应用】文本生成作者简介:在校大学生一枚,C/C++领域新星创作者,华为云享专家,阿里云专家博主,腾云先锋(TDP)成员,云曦智划项目总负责人,全国高... 查看详情

猿创征文|国产数据库实战使用docker部署polardb-x云原生分布式开源数据库(代码片段)

猿创征文|【国产数据库实战】使用docker部署PolarDB-X云原生分布式开源数据库一、PolarDB-X介绍1.PolarDB-X简介2.PolarDB-X特点二、检查docker版本三、检查docker配置信息四、下载PolarDB-X镜像五、部署PolarDB-X1.创建PolarDB-X容器2.检查PolarDB-X容... 查看详情

猿创征文|云原生|24docker运行数据库实战之mongodb(代码片段)

作者简介:🏅云计算领域优质创作者🏅新星计划第三季python赛道第一名🏅 阿里云ACE认证高级工程师🏅✒️个人主页:小鹏linux💊个人社区:小鹏linux(个人社区)欢迎您的加入!目录... 查看详情

猿创征文|云原生|25docker运行数据库实战之redis(代码片段)

作者简介:🏅云计算领域优质创作者🏅新星计划第三季python赛道第一名🏅 阿里云ACE认证高级工程师🏅✒️个人主页:小鹏linux💊个人社区:小鹏linux(个人社区)欢迎您的加入!为大... 查看详情

猿创征文|游戏开发实战——2d项目1-ruby‘sadventure控制游戏角色移动(1-2)(代码片段)

文章目录1)使用指南2)具体步骤详细剖析2.1)《1.创建新场景》再补充2.2)《9.声明变量》再补充2.3)《4.审查你的脚本更改》再补充2.4)《11.以单位/秒表示Ruby的移动速度》再补充3)总结1)使用... 查看详情

猿创征文|unity开发实战——2d项目1-ruby‘sadventure游戏地图绘制(2-1)(代码片段)

文章目录1)使用指南2)具体步骤详细剖析2.1)《4-2.创建瓦片地图》操作更新2.2)《4-3.创建新瓦片》操作更新2.3)《5-2.如何才能解决排序问题?》操作注意2.3)《5-7.什么是预制件?》操作积累3... 查看详情

机器学习实战基础(二十七):sklearn中的降维算法pca和svdpca对手写数字数据集的降维(代码片段)

PCA对手写数字数据集的降维1.导入需要的模块和库fromsklearn.decompositionimportPCAfromsklearn.ensembleimportRandomForestClassifierasRFCfromsklearn.model_selectionimportcross_val_scoreimportmatplotlib.pyplotaspltimportpandas 查看详情

猿创征文丨深度学习基于双向lstm模型完成文本分类任务(代码片段)

大家好,我是猿童学,本期猿创征文的第三期,也是最后一期,给大家带来神经网络中的循环神经网络案例,基于双向LSTM模型完成文本分类任务,数据集来自kaggle,对电影评论进行文本分类。电影评论... 查看详情

猿创征文|一名大三学生的前端学习之路(真情流露)(代码片段)

✅作者简介:一名大三的大学生,致力于提高前端开发能力✨个人主页:前端小白在前进的主页🔥系列专栏:node.js学习专栏⭐️个人社区:个人交流社区🍀学习格言:☀️打不倒你的会使你更强!☀️&#... 查看详情

猿创征文|一名大三学生的前端学习之路(真情流露)(代码片段)

✅作者简介:一名大三的大学生,致力于提高前端开发能力✨个人主页:前端小白在前进的主页🔥系列专栏:node.js学习专栏⭐️个人社区:个人交流社区🍀学习格言:☀️打不倒你的会使你更强!☀️&#... 查看详情

13机器学习实战之pca(代码片段)

降维技术对数据进行降维有如下一系列的原因:使得数据集更容易使用降低很多算法的计算开销去除噪音使得结果易懂 在以下3种降维技术中,PCA的应用目前最为广泛,因此本章主要关注PCA。 主成分分析(PrincipalComponentAnal... 查看详情