持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第22天,点击查看活动详情
不知道读者是否还记得之前SVM中提到的数学方法-内核方法。它能够很神奇的使用高维中的线性决策边界对应于低维中复杂的非线性决策边界。在PCA中也有类似的方法叫内核PCA。
内核PCA
内核PCA,他是用复杂的非线性投影来降低维度。尤其是处理在投影后保留实例的聚类,或者也可以用于展开位于扭曲流形附近的数据集。
比如我们可以使用不同的内核实现对之前的瑞士卷的降维:
图1 不同内核PCA
# 使用不同的内核实现的降维
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)
内核PCA是一种无监督学习算法,没啥明显的性能指标好选择。通常降维也是监督学习任务的准备步骤,因此我们也可以选择网格搜索来获得某个任务上能获得最佳性能的内核和超参数。
例如可以创建一个流水线,包含一个kPCA和一个预测器,然后使用GridSearch来找到最好的分类率:
clf = Pipeline([
("kpca", KernelPCA(n_components=2)),
("log_reg", LogisticRegression(solver="lbfgs"))
])
param_grid = [{
"kpca__gamma": np.linspace(0.03, 0.05, 10),
"kpca__kernel": ["rbf", "sigmoid"]
}]
grid_search = GridSearchCV(clf, param_grid, cv=3)
上面的流水线包含了一个需要降维到2维的KernelPCA(),一个逻辑回归,以及我们要找kpca的超参数:
gamma只有在内核为rbf, poly and sigmoid时才有的系数。默认为1/n_featureskernel选择内核类型
除了上面的方法,还有一个不错的方法就是选择产生最低重构误差。那么该怎么处理呢?
重构误差不知道读者是否还记得,这是由于原始数据被压缩后,重新解压的数据与原始数据之间产生的均方距离。
内核技术的变换类似于使用特征图将训练集映射到无限维空间后,在使用线性PCA将变换后的训练集投射到2D。而我们需要将投射后的数据重新在原始数据所在的空间中映射回去,这个映射回去的点叫重建原像。减少原像和原始数据之间的距离就是我们的目标。
# 注意要设置fit_inverse_transform=True,否则没有inverse_transform方法
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)
mean_squared_error(X, X_preimage)
我就是需要使用网格搜索找到能够使得mean_squared_error(X, X_preimage)最小的超参数和内核。
LLE
最后我们呢再来了解一种新的比较好用的非线性降维技术-局部线性嵌入(Locally Linear Embedding ,LLE)。
他的工作方式是:对于每个训练实例都会找出其附近的k个邻居,然后将冲构成这些邻居的线性函数。
- 找到权重,使得的平方距离最小,并假设如果不是的邻居之一,则=0
同时我们也需要保证实例映射到d维空间后,能够尽可能保留这些局部关系。
- 是d维空间中的图像,我们希望于的平方距离也尽可能小