数据降维:投影及流形学习降维方法
【机器学习】使用scikitLearn对数据进行降维处理:KPCA法及参数选择
【机器学习】使用scikitLearn对数据进行降维处理:流形学习及局部线性嵌入LLE及其它降维技术
降维的意义:对于机器学习而言,降维意味着丢失原始数据的部分不重要的特征,从这个角度而言,降维使数据的信息丢失,会限制算法潜在的最高准确度,但对于某一种固定的算法,它有望在数据量恒定下,通过降维预处理提升算法的准确性,算法准确率是否获得提升,与数据集自己的特性高度相关。
降维的积极影响主要在于:通过减少特征的数目,从而减少训练的时间以及单位时间的计算内存占用。并且,当把原始数据的维度降至3维以下时,可以对数据点进行可视化处理,有积极意义。
高维数据不同于低维数据,其主要特点是:
稀疏性:原始数据在不同维度的分布并不总是均衡的,对于高维空间而言,数据分布常常很稀疏。可以理解为,数据分布在高维空间的低维子空间内:训练实例间通常有较远的间隔,很容易造成过拟合;如果通过增大数据量的方法解决这种过拟合,维度越高,数据所需越多,越困难。
目前降维的方法主要有两类:投影及流形学习:
投影法是指,高维数据沿某个轴进行垂直投影,投影后,原数据对应的该轴维度消失,达到对数据进行降维的效果。
目前,最流行的投影方法是PCA和KPCA,也就是主成分分析,及核主成分分析。
PCA首先找出n维数据集的n个正交轴,每个轴为一个原始数据的主成分,
将原始数据对每一个轴分别进行投影。
投影优劣的评判方法为:原始数据在经轴投影后,原始数据与投影数据求均方距离,该距离越小,投影效果越好,原始数据经投影后,丢失的信息越少。
在求这n个正交轴时,常用的方法是奇异值分解,将原始数据集分解为UΣV的矩阵乘法,其中V包含定义所有主要成分的单位向量的矩阵乘法。
下面是scikitLearn中的示例:
from sklearn.decomposition import PCA
pca = PCA(n_components=2)
X2D = pca.fit_transform(X)
并可使用反投影进行还原:
X3D_inv = pca.inverse_transform(X2D)
查看原始的每维主成分的单位向量:
pca.components_
继续查看每维可解释的方差比:
pca.explained_variance_ratio_
下面得到经过pca后损失的方差数量:
1 - pca.explained_variance_ratio_.sum()
如果想在降维后,仍然保留指定比率的方差,使用下面的代码:
from sklearn.decomposition import PCA
#要求降低的维度可以保留90%的方差
pca = PCA(n_components=0.9)
X2D = pca.fit_transform(X)
也可使用ratios=np.cumsum(pca.explained_variance_ratio_)给出方差的逐列累加和,则所需保留的维度为:np.argmax(ratios>0.9)+1,意为选取出现的第一个true值。
下面的代码可绘制累加图曲线,并寻找相应的拐点:
plt.figure(figsize=(6,4))
plt.plot(cumsum, linewidth=3)
olt.show()
对于大型的训练集及需要增量训练时,使用IPCA算法:
代码如下:
from sklearn.decomposition import IncrementalPCA
#下面代码将数据保存至内存文件
filename = "my_mnist.data"
m, n = X_train.shape
#模式为写模式
X_mm = np.memmap(filename, dtype='float32', mode='write', shape=(m, n))
X_mm[:] = X_train
#触发文件的持久化:
del X_mm
#使用时切换为读模式
X_mm = np.memmap(filename, dtype="float32", mode="readonly", shape=(m, n))
#调用增量式pca
batch_size = m
inc_pca = IncrementalPCA(n_components=154, batch_size=batch_size)
#数据只有在使用时,才被加载进内存
inc_pca.fit(X_mm)
如果不使用上述内存映射技术,即认为内存够用,只是需要PCA的数据分批次到达,直接使用partial_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):
inc_pca.partial_fit(X_batch)
X_reduced = inc_pca.transform(X_train)