在降维过程中,我们会减少特征的数量,这意味着删除数据,数据量变少则表示模型可以获取的信息会变少,模型的表现可能会因此受影响。同时,在高维数据中,必然有一些特征是不带有有效的信息的(比如噪音),或者有一些特征带有的信息和其他一些特征是重复的(比如一些特征可能会线性相关)。我们希望能够找出一种办法来帮助我们衡量特征上所带的信息量,让我们在降维的过程中,能够即减少特征的数量,又保留大部分有效信息——将那些带有重复信息的特征合并,并删除那些带无效信息的特征等等——逐渐创造出能够代表原特征矩阵大部分信息的,特征更少的新特征矩阵。
如果一个特征的方差很大,则说明这个特征上带有大量的信息。因此,在降维中,PCA使用的信息量衡量指标,就是样本方差,又称可解释性方差,方差越大,特征所带的信息量越多。
其中Var代表一个特征的方差,n代表样本量,xi代表一个特征中的每个样本取值,xhat代表这一列样本的均值。
这里以一组二维数据降维为例:现有一组二维数据,有特征x1和x2,三个样本数据的坐标点分别为(1,1),(2,2),(3,3)。我们可以让x1和x2分别作为两个特征向量,很轻松地用一个二维平面来描述这组数据。这组数据现在每个特征的均值都为2,方差x1_var=x2_var=1,每个特征的方差均为1,数据的方差总和是2。
现在我们的目标是:只用一个特征向量来描述这组数据,即将二维数据降为一维数据,并且尽可能地保留信息量,即让数据的总方差尽量靠近2。于是就有了x1*和x2*此时x1*_var=2,x2*_var=0,数据的方差总和是2。
思考:降维和特征选择都是特征工程技术,它们有什么不同?特征选择是从已存在的特征中选取携带信息最多的,选完之后的特征依然具有可解释性,我们依然知道这个特征在原数据的哪个位置,代表着原数据上的什么含义。而降维算法,是将已存在的特征进行压缩,降维完毕后的特征不是原本的特征矩阵中的任何一个特征,而是通过某些方式组合起来的新特征。通常来说, 在新的特征矩阵生成之前,我们无法知晓降维算法们都建立了怎样 的新特征向量,新特征矩阵生成之后也不具有可读性 ,我们无法判断新特征矩阵的特征是从原数据中的什么特征组合而来,新特征虽然带有原始数据的信息,却已经不是原数据上代表着的含义了。降维算法因此是特征创造(feature creation ,或 feature construction )的一种。PCA一般不适用于探索特征和标签之间的关系的模型(如线性回归),因为无法解释的新特征和标签之间的关系不具有意义。在线性回归模型中,我们使用特征选择。
n_components是我们降维后需要的维度,即降维后需要保留的特征数量,一般输入[0, min(X.shape)]范围中的整数。类似于KNN中的K和随机森林中的n_estimators,这是一个需要我们人为去确认的超参数,并且我们设定的数字会影响到模型的表现。如果留下的特征太多,就达不到降维的效果,如果留下的特征太少,那新特征向量可能无法容纳原始数据集中的大部分信息。
以鸢尾花数据集为例:对鸢尾花数据集从四维降至二维
import matplotlib.pyplot as plt
from sklearn.datasets import load_iris
from sklearn.decomposition import PCA
iris=load_iris() #实例化
y=iris.target
x=iris.data
#调用PCA
pca=PCA(n_components=2)#实例化
pca=pca.fit(x)#拟合模型
x_dr=pca.transform(x)#获取新矩阵
iris.target_names #array(['setosa', 'versicolor', 'virginica'], dtype='
属性explained_variance 查看降维后每个新特征向量上所带的信息量大小(可解释性方差大小)
属性explained_variance_ratio_,查看降维后每个新特征向量所占的信息量占原始数据总信息量的百分比,又叫可解释方差贡献率
探索降维后的数据:
pca.explained_variance_ #array([4.22824171, 0.24267075])
pca.explained_variance_ratio_ #array([0.92461872, 0.05306648])
pca.explained_variance_ratio_.sum() #0.9776852063187949
可以看出大部分有效信息集中在第一个特征上,且降维后的有效信息达到原数据集的97%以上。
当参数components中不填写任何值时,则默认返回min{样本量,特征数目}个特征,一般来说,样本量都会大于特征数目,所以什么都不填就相当于转换了新特征空间,但没有减少特征的个数。一般来说,不会使用这种输入方式。但我们却可以使用这种输入方式来画出累计可解释方差贡献率曲线,以此选择最好的n_components的整数取值。
import numpy as np
pca_line=PCA().fit(x)
plt.plot([1,2,3,4],np.cumsum(pca_line.explained_variance_ratio_))
plt.xticks([1,2,3,4])#限制坐标轴显示为整数
plt.xlabel("number of components after dimension reduction")
plt.ylabel("cumulative explained variance")
plt.show()
n_components="mle":让PCA用最大似然估计自选超参数
pca_mle=PCA(n_components="mle")
x_mle=pca_mle.fit_transform(x)
print(pca_mle.explained_variance_ratio_.sum())
-------------------------------------------------------------------
0.9947878161267246
mle自动为我们选了3个特征,且降维后的有效信息达到原数据集的99%以上。
pca_f=PCA(n_components=0.97,svd_solver='full')
x_f=pca_f.fit_transform(x)
print(pca_f.explained_variance_ratio_.sum())
------------------------------------------------------------
0.9776852063187949