最近期末需要提交的paper比较多,所以更新进度有点慢。为了弥补空白期,以后会转载一些好的论文给大家。感谢兄弟姐妹们一直以来的支持。如果你只对降维的代码部分感兴趣,可以直接看文末,一直在研究机器学习相关算法的理论。最近打算参加一些Kaggle的比赛,但是对于给定的数据,仅有一些理论知识是不够的。建立一个比较好的模型,其中还包括很多必要的操作,比如缺失值处理,特征工程等等。今天,我们来谈谈特征降维。我们在实践中通常会使用sklearn自带的数据集,比如iris数据集。通常,此类数据集经过处理,具有规模小、完整性强的特点。但对于Kaggle而言,比赛或其他领域的Given数据集通常规模较大且缺失值较多。大规模可以分为两个方面,一个是数据多特征少,一个是数据少特征多。我们都知道,数据越多越好建模,因为数据越多,覆盖面越广,模型的准确性就会提高。当然,这可能会牺牲一些内存和计算时间。然而,许多功能并不一定是好事。如果将数据集映射到一个空间,则每个特征对应一个维度。随着维数的增加,学习器需要的样本数通常呈指数增长,但通常高维数据集的样本数达不到要求,数据稀疏度特别高,可能导致低维模型的准确性,并且对内存和计算时间不是很友好。特征降维对于多特征的数据集,我们可以想象会有一些特征是高度相关的?比如学习年限和学业成绩之间会存在正相关关系,那么删除其中一个可能对数据集的影响很小,其他的特征也会做类似的操作,剩下的特征之间就没有关系了他们俩。此操作称为丢弃。方面。降维是一种针对高维数据集的数据预处理方法。其基本思想是保留一些相对重要的特征,去除数据中剩余的特征和噪声。降维操作可以大大节省运行内存和计算量。时间,使数据处理更有效率。数据降维也有一系列的原因:为了让数据集更容易使用;减少许多算法的计算开销;去除数据中的噪声;使结果易于理解。常见的降维方法包括主成分分析(PCA)、因子分析(FA)、独立成分分析(ICA)和奇异值分解(SVD)。其中PCA和SVD是最常用的两种。本文介绍第一种PCA降维方法。主成分分析原理及相应操作主成分分析顾名思义就是对主成分进行分析,所以找出主成分应该是重点。PCA的基本思想是将初始数据集中的n维特征映射到k维,得到的k维特征可以称为主成分。重建基础。PCA将在已知数据的基础上重建坐标轴。其原理是最大化保留样本之间的方差。两个特征之间的方差越大,相关性越差。例如:第一个新的坐标轴是原始数据中方差最大的方向。第二个新坐标轴是与第一个新坐标轴正交的平面中方差最大的方向。第三个新坐标轴应该是与第一和第二个新坐标轴正交的平面中方差最大的方向。第四、第五……以此类推,直到第n个新的坐标轴(对应n维)。为了加深对这部分的理解,我们以二维平面为例。在二维平面上,根据原始数据新建一个坐标轴如下图:为了更直观的理解,如果将方差换成另一项,那么第一个新的坐标轴就是coverage的那个对于最多的样本(向右上方倾斜),第二个新坐标轴需要与第一个新坐标轴正交并覆盖最多样本(向左上方倾斜),依此类推。覆盖样本的数量不是通过坐标轴经过多少个样本点来判断的,而是垂直映射到轴上的样本点有多少,如下图所示:回到之前的n维重构坐标轴,由于toorder是按照方差的大小排序的,所以方差越小,方差越小,特征之间的相关性越强,那么这样的特征可以删掉,只保留前k个坐标轴(对应k维),相当于保留了包含数据集大部分方差的特征,而去掉了方差几乎为零的特征。那么问题来了,二维和三维可以根据样本点的分布绘制重建坐标轴,但是更高维的人脑不接受,我们要计算特征之间的方差,然后获取这些新轴的方向。具体方法是计算原始数据矩阵对应的协方差矩阵,然后得到协方差矩阵对应的特征值和特征向量,选择特征值最大的前k个特征向量组成的矩阵,利用特征矩阵对将原始数据矩阵从n维空间映射到k维空间,实现特征降维。方差、协方差和协方差矩阵如果你接触过线性代数,你可能对这三个概念很熟悉,可能区间太长了,下面给大家复习一下:方差(Variance)一般用来描述样本集中的数据。每个样本点与样本均值之差的平方和的均值:$$S^2=\frac{1}{n-1}\sum_{i=1}^n(x_i-\widehat{x})^2$$协方差(Covariance)的目的是衡量两个变量(只有两个)之间线性相关的程度:$$cov(x,y)=\frac{1}{n-1}\sum_{i=1}^n(x_i-\widehat{x})(y_i-\widehat{y})$$$cov=0$可以证明两个变量线性无关,但不能证明两个变量相互独立,当$cov>0$时,两者正相关,当$cov<0$时,两者负相关。协方差矩阵由两个变量之间的协方差组成,具有以下特点:协方差矩阵可以处理多维问题。协方差矩阵是一个对称矩阵,对角线是每个维度上的方差。协方差矩阵计算不同维度之间的协方差,而不是不同样本之间的协方差。如果样本矩阵中的每一行都是一个样本,那么每一列就是一个维度。假设数据是3维的,那么对应的协方差矩阵为:$$C=\begin{bmatrix}cov(x,x)&cov(x,y)&cov(x,z)\\cov(y,x)&cov(y,y)&cov(y,z)\\cov(z,x)&cov(z,y)&cov(z,z)\\\end{bmatrix}$$这是小结协方差矩阵是如何得到的?假设一个数据集有3维特征,每个特征有m个变量。该数据集对应的数据矩阵如下:$$X=\begin{bmatrix}x_1&x_2&..。&x_3\\y_1&y_2&...&y_3\\z_1&z_2&...&z_3\\\end{bmatrix}$$如果假设它们的均值都为0,则以下等式可以得到:$$\frac{1}{m}XX^T=\begin{bmatrix}\frac{1}{m}\sum_{i=1}^mx_i^2&\frac{1}{m}\sum_{i=1}^mx_iy_i&\frac{1}{m}\sum_{i=1}^mx_iz_i\\\frac{1}{m}\sum_{i=1}^my_ix_i&\frac{1}{m}\sum_{i=1}^my_i^2&\frac{1}{m}\sum_{i=1}^my_iz_i\\\frac{1}{m}\sum_{i=1}^mz_ix_i&\frac{1}{m}\sum_{i=1}^mz_iy_i&\frac{1}{m}\sum_{i=1}^mz_i^2\\\end{bmatrix}$$可以看到每个特征的方差在对角线上,剩下的位置就是两个特征之间的协方差。$\frac{1}{m}XX^T$是协方差矩阵。这里的描述有些简略,有兴趣的朋友可以自行查询相关知识。特征值和特征向量得到数据矩阵的协方差矩阵。接下来,我们应该找到协方差矩阵的特征值和特征向量。首先理解这两个概念。如果一个向量v是矩阵A的特征向量,那么必然有下面的等式:特征向量v的特征值。数据矩阵的主成分是协方差矩阵的相应特征向量根据相应的特征值从大到小排序得到的。最大特征值对应的特征向量为第一主成分,第二大特征值对应的特征向量为第二主成分,以此类推,如果从n维映射到k维,截取到第k-th主成分。实例操作通过以上部分总结PCA降维操作的步骤:去均值化根据数据矩阵计算协方差矩阵计算协方差矩阵的特征值和特征向量将特征值从大到小排序并保留前k个特征值对应的特征向量将原始数据的n维映射到k维公式手推降维原始数据集矩阵,每一行代表一个特征:$$X=\begin{bmatrix}1&1&2&4&2\\1&3&3&4&4\\\end{bmatrix}$$对每个特征去平均:$$\begin{bmatrix}-1&-1&0&2&0\\-2&0&0&1&1\\\end{bmatrix}$$计算对应的协方差矩阵:$$C=\frac{1}{5}\begin{bmatrix}-1&-1&0&2&0\\-2&0&0&1&1\\\end{bmatrix}\begin{bmatrix}-1&-2\\-1&0\\0&0\\2&1\\0&1\\\end{bmatrix}=\begin{bmatrix}\frac{6}{5}&\frac{4}{5}\\\frac{4}{5}&\frac{6}{5}\\\end{bmatrix}$$根据协方差矩阵Vector计算特征值和特征,嵌套在公式中:$$(C-\lambdaE)v=0$$拆解计算如下:$$|C-\lambdaE|=\begin{vmatrix}\frac{6}{5}-\lambda&\frac{4}{5}\\\frac{4}{5}&\frac{6}{5}-\lambda\\\end{vmatrix}=(\frac{6}{5}-\lambda)^2-\frac{16}{25}$$可以得到两个特征值:$$\lambda_1=2,\lambda_2=\frac{2}{5}$$当$\lambda_1=2$时,对应的向量应满足以下等式:$$\begin{bmatrix}\frac{6}{5}-2&\frac{4}{5}\\\frac{4}{5}&\frac{6}{5}-2\\\end{bmatrix}\begin{bmatrix}x_1\\x_2\\\end{bmatrix}=\begin{bmatrix}0\\0\\\end{bmatrix}$$对应的特征向量为可取的是:$$p_1=\begin{bmatrix}1\\1\\\end{bmatrix}$$同理$\lambda_1=\frac{2}{5}$时,对应的特征向量可以取为:$$p_2=\begin{bmatrix}-1\\1\\\end{bmatrix}$$这里我就不对两个特征向量进行标准化,直接合并两个特征向量得到矩阵P:$$P=\begin{bmatrix}1&1\\-1&1\\\end{bmatrix}$$选取大特征值对应的特征向量与原数据矩阵相乘,得到降维后的矩阵A:$$A=\begin{bmatrix}1&1\\\end{bmatrix}\begin{bmatrix}-1&-1&0&2&0\\-2&0&0&1&1\\\end{bmatrix}=\begin{bmatrix}-3&-1&0&3&1\\\end{bmatrix}$$综上所述,以上步骤是实现操作of通过PCA手推公式将二维降为一维numpy实现降维importnumpyasnpdefPCA(X,k):'''X:inputmatrixk:dimensiontobereducedto'''X=np.array(X)#converttomatrixsample_num,feature_num=X.shape#样本数和特征数meanVals=np.mean(X,axis=0)#求每个特征的均值X_mean=X-meanVals#去均值Cov=np.dot(X_mean.T,X_mean)/sample_num#求协方差矩阵feature_val,feature_vec=np.linalg.eig(Cov)#打包特征值和特征向量val_sort=[(np.abs(feature_val[i]),feature_vec[:,i])foriinrange(feature_num)]val_sort.sort(reverse=True)#按特征值从大到小排列#截取前k个特征向量组成特征矩阵feature_mat=[feature[1]forfeatureinval_sort[:k]]#dropn维映射到k维PCA_mat=np.dot(X_mean,np.array(feature_mat).T)returnPCA_matif__name__=="__main__":X=[[1,1],[1,3],[2,3],[4,4],[2,4]]print(PCA(X,1))截图如下:code部分是公式的应用,每一步后面都有注释,就不多解释了。可以看出,得到的结果与上述手推公式得到的结果有些不同。上面说到特征向量可以随意缩放,这也是造成两者结果不同的原因。您可以在运行代码时打印特征向量feature_vec。观察这个特征。sklearn库实现降维fromsklearn.decompositionimportPCAimportnumpyasnpX=[[1,1],[1,3],[2,3],[4,4],[2,4]]X=np.array(X)pca=PCA(n_components=1)PCA_mat=pca.fit_transform(X)print(PCA_mat)这里只讲参数n_components。如果输入是整数,则表示需要映射的数据集的维度。比如输入3表示,最后需要映射到3个维度;如果输入是小数,则表示映射后的维度是原始数据维度的比例。例如,输入0.3。如果原始数据有20个维度,它将被映射到6个维度。综上所述,上面使用的数据集非常简单。建议练习时使用一些特征比较多的数据集。您可以使用图像绘制每个主成分占总方差的比例。一个很直观的结果是,一些排序较早的主成分成分占比特别大,最后一个可能只占零点几。这也是我们上面描述的内容最基本的原理。关注公众号【奶糖猫】第一时间获取更多精彩好文
