【机器学习实战】 降维

降维的主要方法

投影
将高维空间的点投影到低维子空间上

流形学习
d维流形是n维空间(且d<n)的一部分, 局部类似于d维超平面。
许多降维算法通过训练实例所在的流形进行建模工作, 称为流行学习。
它依赖于流形假说:大多数现实世界的高维数据集都接近于低维流形。
隐式假设:如果用流形的低维空间表示,任务(例如分类或回归)将更加简单。

PCA

主成分分析(PCA):识别最靠近数据的超平面, 然后将数据投影到其上

保留差异性
保留差异性大的轴更为合理, 相对其他的情况丢失的信息更少。
方法:比较原始数据集与其轴上的投影间的均方距离, 选取其最小的轴

主要成分
主成分分析可以在训练数据集中识别哪条轴对差异性的贡献度最高。
第i个轴称为数据的第i个主要成分(PC),PC两两正交

奇异值分解(SVD)找到训练集的主成分:

# 利用NumPy的svd()获取所有主要成分, 然后提取定义前两个PC的单位向量
import numpy as np
X_centered = X - X.mean(axis=0)
U, s, Vt = np.linalg.svd(X_centered)
c1 = Vt.T[:, 0]
c2 = Vt.T[:, 1]

PCA假定数据集以原点为中心。 Scikit-Learn负责居中数据,但如果自己实现PCA(如上例)或使用其他库, 首先需要将数据居中。

 

向下投影到d维度

Xd-proj = X Wd Wd定义为包含V的前d列矩阵

# 投影到前两个主要成分定义的平面上
W2 = Vt.T[:, :2]
X2D = X_centered.dot(W2)

使用Scikit-Learn

from sklearn.decomposition import PCA

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

其components_的属性是Wd的转置

 

可解释方差比
explained_variance_ratio_可解释方差比:沿每个成分数据集方差的比率

选择正确的维度
选择相加足够大的方差部分(如95%)的维度
如果是为了数据可视化, 需要将维度降低到2或3

# 不降维的情况下执行PCA, 计算保留95%训练集方差所需的最小维度
pca = PCA()
pca.fit(X_train)
cumsum = np.cumsum(pca.explained_variance_ratio_)
d = np.argmax(cumsum >= 0.95) + 1

# 或者:
pca = PCA(n_components=0.95)
X_reduced = pca.fit_transform(X_train)

 

PCA压缩
通过应用PCA投影的逆变换, 可以解压。 投影会丢失一部分数据, 解压不会给原始数据, 但可能会接近原始数据。原始数据和重构数据(压缩后再解压缩)之间的均方距离称为重构误差。

# 将MNIST数据集压缩为154个维度, 再用inverse_transform()方法解压缩回784个维度
pca = PCA(n_components=154)
X_reduced = pca.fit_transform(X_train)
X_recovered = pca.inverse_transform(X_reduced)

默认solver=“atuo”,当m或n > 500 && d < 80%(m or n)时, Scikit-Learn自动使用随机PCA, 如果强制使用完全PCA, 可以 svd_solver=“full”。

 

增量PCA

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):
    inc_pca.partial_fit(X_batch)
X_reduced = inc_pca.transform(X_train)

 

内核PCA

核技巧应用于PCA, 从而可以执行复杂的非线性投影来降低维度, 这叫做内核PCA(kPCA)

from sklearn.decomposition import KernelPCA

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

 

选择内核并调整超参数

网格搜索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())
])

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

grid_search = GridSearch(clf, para_grid, cv=3)
grid_search.fit(X, y)

>>> print(grid_search.best_params_)

另一种完全无监督方法是选择产生最低重构误差的内核和超参数

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)

利用网格搜索和交叉验证找到最大限度减少此错误的内核和超参数

 

LLE

局部线性嵌入(LLE), 非线性降维(NLDR), 流形学习技术
工作原理:首先测量每个训练实例如何与最近的邻居(c.n.)线性相关,然后寻找可以最好保留这些局部关系的低维表示形式。

from sklearn.manifold import LocallyLinearEmbedding

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

 

posted @ 2021-09-29 23:31  鱼儿冒个泡  阅读(277)  评论(0编辑  收藏  举报