主成分分析
From Ufldl
(→Introduction 引言) |
|||
Line 67: | Line 67: | ||
【初译】:数据已经进行了预处理,所以特征值<math>\textstyle x_1</math>和<math>\textstyle x_2</math>有相近的平均值(零)和方差。 | 【初译】:数据已经进行了预处理,所以特征值<math>\textstyle x_1</math>和<math>\textstyle x_2</math>有相近的平均值(零)和方差。 | ||
+ | |||
为了更直观的区分,根据<math>\textstyle x_1</math>值的大小我们把它们分成了三种颜色。颜色的区分对于算法没有任何影响,仅仅是为了直观表示。 | 为了更直观的区分,根据<math>\textstyle x_1</math>值的大小我们把它们分成了三种颜色。颜色的区分对于算法没有任何影响,仅仅是为了直观表示。 | ||
【一审】:数据已经进行了预处理,所以特征值<math>\textstyle x_1</math>和<math>\textstyle x_2</math>有相近的平均值(零)和方差。 | 【一审】:数据已经进行了预处理,所以特征值<math>\textstyle x_1</math>和<math>\textstyle x_2</math>有相近的平均值(零)和方差。 | ||
+ | |||
为了更直观的区分,根据<math>\textstyle x_1</math>值的大小我们把它们分成了三种颜色。颜色的区分对于算法没有任何影响,仅仅是为了直观表示。 | 为了更直观的区分,根据<math>\textstyle x_1</math>值的大小我们把它们分成了三种颜色。颜色的区分对于算法没有任何影响,仅仅是为了直观表示。 | ||
【二审】:这些数据已经进行了预处理,所以每个特征值<math>\textstyle x_1</math>和<math>\textstyle x_2</math>有相同的平均值(零)和方差。 | 【二审】:这些数据已经进行了预处理,所以每个特征值<math>\textstyle x_1</math>和<math>\textstyle x_2</math>有相同的平均值(零)和方差。 | ||
+ | |||
为方便展示,根据<math>\textstyle x_1</math>值的大小,我们将每个点分别涂上了三种颜色的一种。该颜色并不用于算法而仅用于图解。 | 为方便展示,根据<math>\textstyle x_1</math>值的大小,我们将每个点分别涂上了三种颜色的一种。该颜色并不用于算法而仅用于图解。 | ||
Line 84: | Line 87: | ||
【一审】:PCA算法将选取一个低维空间来投影数据投影。从下图中可以看出,<math>\textstyle u_1</math>是数据变化的主方向,而<math>\textstyle u_2</math>是次方向。 | 【一审】:PCA算法将选取一个低维空间来投影数据投影。从下图中可以看出,<math>\textstyle u_1</math>是数据变化的主方向,而<math>\textstyle u_2</math>是次方向。 | ||
- | + | 【二审】:PCA算法将选取一个低维空间来投影我们的数据。从下图中可以看出,<math>\textstyle u_1</math>是数据变化的主方向,而<math>\textstyle u_2</math>是次方向。 | |
Line 98: | Line 101: | ||
【一审】:举例说,<math>\textstyle u_1</math>方向上的数据要比<math>\textstyle u_2</math>方向的变化大。为了计算出方向<math>\textstyle u_1</math>和<math>\textstyle u_2</math>,我们首先计算出矩阵<math>\textstyle \Sigma</math>,如下: | 【一审】:举例说,<math>\textstyle u_1</math>方向上的数据要比<math>\textstyle u_2</math>方向的变化大。为了计算出方向<math>\textstyle u_1</math>和<math>\textstyle u_2</math>,我们首先计算出矩阵<math>\textstyle \Sigma</math>,如下: | ||
- | + | 【二审】:也就是说,<math>\textstyle u_1</math>方向上的数据要比<math>\textstyle u_2</math>方向的变化大。为更正式地计算出方向<math>\textstyle u_1</math>和<math>\textstyle u_2</math>,我们首先计算出矩阵<math>\textstyle \Sigma</math>,如下所示: | |
Line 112: | Line 115: | ||
the second eigenvector. | the second eigenvector. | ||
- | 【初译】:假设<math>\textstyle x</math>的均值为零,那么<math>\textstyle \Sigma</math>就是<math>\textstyle x</math>的协方差矩阵。(符号<math>\textstyle \Sigma</math>,读"Sigma",是协方差矩阵的表示符。虽然看起来与求和符号<math>\sum_{i=1}^n i</math> | + | 【初译】:假设<math>\textstyle x</math>的均值为零,那么<math>\textstyle \Sigma</math>就是<math>\textstyle x</math>的协方差矩阵。(符号<math>\textstyle \Sigma</math>,读"Sigma",是协方差矩阵的表示符。虽然看起来与求和符号<math>\sum_{i=1}^n i</math>比较像,但他们是两个不同的概念。) |
- | 【一审】:假设<math>\textstyle x</math>的均值为零,那么<math>\textstyle \Sigma</math>就是<math>\textstyle x</math>的协方差矩阵。(符号<math>\textstyle \Sigma</math>,读"Sigma",是协方差矩阵的表示符。虽然看起来与求和符号<math>\sum_{i=1}^n i</math> | + | 由此可以得出,数据变化的主方向<math>\textstyle u_1</math>是协方差矩阵<math>\textstyle \Sigma</math>的主特征向量,而<math>\textstyle u_2</math>是次特征向量。 |
+ | |||
+ | 【一审】:假设<math>\textstyle x</math>的均值为零,那么<math>\textstyle \Sigma</math>就是<math>\textstyle x</math>的协方差矩阵。(符号<math>\textstyle \Sigma</math>,读"Sigma",是协方差矩阵的表示符。虽然看起来与求和符号<math>\sum_{i=1}^n i</math>比较像,但他们是两个不同的概念。) | ||
+ | |||
+ | 可以看出,数据变化的主方向<math>\textstyle u_1</math>是协方差矩阵<math>\textstyle \Sigma</math>的主特征向量,而<math>\textstyle u_2</math>是次特征向量。 | ||
+ | |||
+ | 【二审】:假设<math>\textstyle x</math>的均值为零,那么<math>\textstyle \Sigma</math>就是<math>\textstyle x</math>的协方差矩阵。(符号<math>\textstyle \Sigma</math>,读"Sigma",是协方差矩阵的标准符号。虽然看起来与求和符号,如<math>\sum_{i=1}^n i</math>,比较像,但它们是两个不同的概念。) | ||
+ | |||
+ | 可以看出,数据变化的主方向<math>\textstyle u_1</math>,是协方差矩阵<math>\textstyle \Sigma</math>的主特征向量,而<math>\textstyle u_2</math>是次特征向量。 | ||
- | |||
Line 125: | Line 135: | ||
【一审】:注意:如果你对这个结果更具体的数学推导过程感兴趣,可以参看CS229(机器学习)PCA部分的课件。如果仅仅是想跟上这门课程,可以不必如此。 | 【一审】:注意:如果你对这个结果更具体的数学推导过程感兴趣,可以参看CS229(机器学习)PCA部分的课件。如果仅仅是想跟上这门课程,可以不必如此。 | ||
- | + | 【二审】:注意:如果你对这个结果更具体的数学推导过程感兴趣,可以参看CS229(机器学习)PCA部分的课件(链接在本页底部)。如果仅仅是想跟上这门课程,可以不必如此。 | |
Line 136: | Line 146: | ||
【一审】:你可以通过标准的线性代数运算软件求得特征向量,在此,就是计算出协方差矩阵<math>\textstyle \Sigma</math>的特征向量值,并将其排成列组成矩阵<math>\textstyle U</math>: | 【一审】:你可以通过标准的线性代数运算软件求得特征向量,在此,就是计算出协方差矩阵<math>\textstyle \Sigma</math>的特征向量值,并将其排成列组成矩阵<math>\textstyle U</math>: | ||
- | + | 【二审】:你可以通过标准的线性代数运算软件求得特征向量(见实现说明),在此,让我们计算出协方差矩阵<math>\textstyle \Sigma</math>的特征向量值,并按列排放,组成矩阵<math>\textstyle U</math>: | |
Line 157: | Line 167: | ||
【一审】:此处,<math>\textstyle u_1</math>是主特征向量(相应于最大的特征值),<math>\textstyle u_2</math>是次特征向量。以此类推,<math>\textstyle \lambda_1, \lambda_2, \ldots, \lambda_n</math>是相应的特征值。 | 【一审】:此处,<math>\textstyle u_1</math>是主特征向量(相应于最大的特征值),<math>\textstyle u_2</math>是次特征向量。以此类推,<math>\textstyle \lambda_1, \lambda_2, \ldots, \lambda_n</math>是相应的特征值。 | ||
- | + | 【二审】:此处,<math>\textstyle u_1</math>是主特征向量(对应最大的特征值),<math>\textstyle u_2</math>是次特征向量。以此类推,<math>\textstyle \lambda_1, \lambda_2, \ldots, \lambda_n</math>是相应的特征值。 | |
Line 170: | Line 180: | ||
【一审】:实例中,向量<math>\textstyle u_1</math>和<math>\textstyle u_2</math>形成了一个我们可以表示数据的新数据基。令<math>\textstyle x \in \Re^2</math>是训练样本,那么<math>\textstyle u_1^Tx</math>就是样本点<math>\textstyle x</math>到维度<math>\textstyle u_1</math>上的投影长度(幅值)。同样的,<math>\textstyle u_2^Tx</math>是<math>\textstyle x</math>到维度<math>\textstyle u_2</math>上的幅值。 | 【一审】:实例中,向量<math>\textstyle u_1</math>和<math>\textstyle u_2</math>形成了一个我们可以表示数据的新数据基。令<math>\textstyle x \in \Re^2</math>是训练样本,那么<math>\textstyle u_1^Tx</math>就是样本点<math>\textstyle x</math>到维度<math>\textstyle u_1</math>上的投影长度(幅值)。同样的,<math>\textstyle u_2^Tx</math>是<math>\textstyle x</math>到维度<math>\textstyle u_2</math>上的幅值。 | ||
- | + | 【二审】:在我们的示例中,向量<math>\textstyle u_1</math>和<math>\textstyle u_2</math>构成了一个表示数据的新的基。令<math>\textstyle x \in \Re^2</math>为训练样本,那么<math>\textstyle u_1^Tx</math>就是样本点<math>\textstyle x</math>在维度<math>\textstyle u_1</math>上的投影长度(幅值)。同样的,<math>\textstyle u_2^Tx</math>是<math>\textstyle x</math>投影到<math>\textstyle u_2</math>维度上的幅值。 | |
+ | |||
== Rotating the Data 旋转数据 == | == Rotating the Data 旋转数据 == | ||
Line 197: | Line 208: | ||
(下标“rot”来源于单词“rotation”,意指这是原数据经过旋转(也可以说成映射)得到后得到的结果)数据集中的每个数据<math>\textstyle i</math>经过<math>\textstyle x_{\rm rot}^{(i)} = U^Tx^{(i)}</math>计算后,可以画出如下变换映射数据<math>\textstyle x_{\rm rot}</math>图: | (下标“rot”来源于单词“rotation”,意指这是原数据经过旋转(也可以说成映射)得到后得到的结果)数据集中的每个数据<math>\textstyle i</math>经过<math>\textstyle x_{\rm rot}^{(i)} = U^Tx^{(i)}</math>计算后,可以画出如下变换映射数据<math>\textstyle x_{\rm rot}</math>图: | ||
- | + | 【二审】:因此,我们可以计算出<math>\textstyle x</math>在<math>\textstyle (u_1, u_2)</math>基上的映射表示。 | |
+ | :<math>\begin{align} | ||
+ | x_{\rm rot} = U^Tx = \begin{bmatrix} u_1^Tx \\ u_2^Tx \end{bmatrix} | ||
+ | \end{align}</math> | ||
+ | (下标“rot”来源于单词“rotation”,意指这是原数据经过旋转(也可以说成映射)后得到的结果) | ||
+ | 对数据集<math>\textstyle x_{\rm rot}^{(i)} = U^Tx^{(i)}</math>中的每个<math>\textstyle i</math>取值经过计算后,根据变换后的数据<math>\textstyle x_{\rm rot}</math>作图,可得: | ||
Line 234: | Line 250: | ||
- | + | 【二审】:这就是训练数据集旋转到<math>\textstyle u_1</math>,<math>\textstyle u_2</math>基上所得数据。在更一般的情况下,训练数据集<math>\textstyle U^Tx</math>旋转到基<math>\textstyle u_1</math>,<math>\textstyle u_2</math>, ...,<math>\textstyle u_n</math>之上。矩阵<math>\textstyle U</math>具备正交性,也就是说它满足<math>\textstyle U^TU = UU^T = I</math>,所以假若想将旋转矩阵<math>\textstyle x_{\rm rot}</math>还原为原始数据<math>\textstyle x</math>,可以通过如下计算: | |
+ | |||
+ | :<math>\begin{align} | ||
+ | x = U x_{\rm rot} , | ||
+ | \end{align}</math> | ||
+ | |||
+ | 因为<math>\textstyle U x_{\rm rot} = UU^T x = x</math> | ||
+ | |||
== Reducing the Data Dimension 数据降维 == | == Reducing the Data Dimension 数据降维 == | ||
Line 247: | Line 270: | ||
【一审】:数据变化的主方向相应于旋转数据的第一维<math>\textstyle x_{{\rm rot},1}</math>。因此,如若想把数据降到一维,我们仅需令: | 【一审】:数据变化的主方向相应于旋转数据的第一维<math>\textstyle x_{{\rm rot},1}</math>。因此,如若想把数据降到一维,我们仅需令: | ||
- | + | 【二审】:数据变化的主方向是旋转数据的第一维<math>\textstyle x_{{\rm rot},1}</math>。因此,若想把这数据降到一维,需令: | |
:<math>\begin{align} | :<math>\begin{align} | ||
Line 263: | Line 286: | ||
【一审】:一般情况下,假如想把<math>\textstyle x \in \Re^n</math>的数据降到<math>\textstyle k</math>维,即<math>\textstyle \tilde{x} \in \Re^k</math>(<math>\textstyle k < n</math>),需要选取<math>\textstyle x_{\rm rot}</math>的前<math>\textstyle k</math>个成分,其相应于变量的前<math>\textstyle k</math>个方向。 | 【一审】:一般情况下,假如想把<math>\textstyle x \in \Re^n</math>的数据降到<math>\textstyle k</math>维,即<math>\textstyle \tilde{x} \in \Re^k</math>(<math>\textstyle k < n</math>),需要选取<math>\textstyle x_{\rm rot}</math>的前<math>\textstyle k</math>个成分,其相应于变量的前<math>\textstyle k</math>个方向。 | ||
- | + | 【二审】:更一般的情况下,假如想把数据<math>\textstyle x \in \Re^n</math>降到<math>\textstyle k</math>维表示<math>\textstyle \tilde{x} \in \Re^k</math>(令<math>\textstyle k < n</math>),需要选取<math>\textstyle x_{\rm rot}</math>的前<math>\textstyle k</math>个成分,对应方差的前<math>\textstyle k</math>个方向。 | |
Line 277: | Line 300: | ||
【一审】:PCA的另外一种解释是:<math>\textstyle x_{\rm rot}</math>是一个<math>\textstyle n</math>维的向量,其中前面几维比较大(例如,上例中对于大部分的样本<math>\textstyle i</math>通过<math>\textstyle x_{{\rm rot},1}^{(i)} = u_1^Tx^{(i)}</math>计算出了比较大的值),后面几维可能会比较小(例如,上例中<math>\textstyle x_{{\rm rot},2}^{(i)} = u_2^Tx^{(i)}</math>计算出了值较小)。 | 【一审】:PCA的另外一种解释是:<math>\textstyle x_{\rm rot}</math>是一个<math>\textstyle n</math>维的向量,其中前面几维比较大(例如,上例中对于大部分的样本<math>\textstyle i</math>通过<math>\textstyle x_{{\rm rot},1}^{(i)} = u_1^Tx^{(i)}</math>计算出了比较大的值),后面几维可能会比较小(例如,上例中<math>\textstyle x_{{\rm rot},2}^{(i)} = u_2^Tx^{(i)}</math>计算出了值较小)。 | ||
- | + | 【二审】:PCA的另外一种解释是:<math>\textstyle x_{\rm rot}</math>是一个<math>\textstyle n</math>维向量,其中前几维比较大(例如,上例中对于大部分样本<math>\textstyle i</math>,通过<math>\textstyle x_{{\rm rot},1}^{(i)} = u_1^Tx^{(i)}</math>计算出了比较大的值),后面的成分可能会比较小(例如,上例中<math>\textstyle x_{{\rm rot},2}^{(i)} = u_2^Tx^{(i)}</math>计算出的值较小)。 | |
Line 338: | Line 361: | ||
在我们的实验中,得到了如下的<math>\textstyle \tilde{x}</math>的图形(取<math>\textstyle n=2, k=1</math>): | 在我们的实验中,得到了如下的<math>\textstyle \tilde{x}</math>的图形(取<math>\textstyle n=2, k=1</math>): | ||
- | 【一审】:而PCA算法就是丢弃<math>\textstyle x_{\rm rot}</math>中后面的(较小的)成分,把他们赋值为零。更直观地说就是,<math>\textstyle \tilde{x}</math>也可以用 <math>\textstyle x_{{\rm rot}}</math>的除了前<math>\textstyle k</math>个成分,其余全赋值为零来表示。换句话说就是,我们可以运用如下算式: | + | 【一审】:而PCA算法就是丢弃<math>\textstyle x_{\rm rot}</math>中后面的(较小的)成分,把他们赋值为零。更直观地说就是,<math>\textstyle \tilde{x}</math>也可以用<math>\textstyle x_{{\rm rot}}</math>的除了前<math>\textstyle k</math>个成分,其余全赋值为零来表示。换句话说就是,我们可以运用如下算式: |
:<math>\begin{align} | :<math>\begin{align} | ||
\tilde{x} = | \tilde{x} = | ||
Line 363: | Line 386: | ||
在我们的实验中,得到了如下的<math>\textstyle \tilde{x}</math>的图形(取<math>\textstyle n=2, k=1</math>): | 在我们的实验中,得到了如下的<math>\textstyle \tilde{x}</math>的图形(取<math>\textstyle n=2, k=1</math>): | ||
- | + | 【二审】:PCA算法做的就是丢弃<math>\textstyle x_{\rm rot}</math>后面的(较小的)成分,将其取近似为零。具体的说,<math>\textstyle \tilde{x}</math>可以定义为,<math>\textstyle x_{{\rm rot}}</math>除了前<math>\textstyle k</math>个成分,其余全赋值为零的近似表示。换句话说: | |
+ | :<math>\begin{align} | ||
+ | \tilde{x} = | ||
+ | \begin{bmatrix} | ||
+ | x_{{\rm rot},1} \\ | ||
+ | \vdots \\ | ||
+ | x_{{\rm rot},k} \\ | ||
+ | 0 \\ | ||
+ | \vdots \\ | ||
+ | 0 \\ | ||
+ | \end{bmatrix} | ||
+ | \approx | ||
+ | \begin{bmatrix} | ||
+ | x_{{\rm rot},1} \\ | ||
+ | \vdots \\ | ||
+ | x_{{\rm rot},k} \\ | ||
+ | x_{{\rm rot},k+1} \\ | ||
+ | \vdots \\ | ||
+ | x_{{\rm rot},n} | ||
+ | \end{bmatrix} | ||
+ | = x_{\rm rot} | ||
+ | \end{align}</math> | ||
+ | 在我们的示例中,可得<math>\textstyle \tilde{x}</math>的图形如下(取<math>\textstyle n=2, k=1</math>): | ||
[[File:PCA-xtilde.png | 600px]] | [[File:PCA-xtilde.png | 600px]] | ||
Line 376: | Line 421: | ||
【一审】:然而,由于上面<math>\textstyle \tilde{x}</math>的后<math>\textstyle n-k</math>项都归为了零,所以也就没必要把这些零项保留下来。因此,我们仅用前<math>\textstyle k</math>个成分来定义<math>\textstyle k</math>维向量的<math>\textstyle \tilde{x}</math>。 | 【一审】:然而,由于上面<math>\textstyle \tilde{x}</math>的后<math>\textstyle n-k</math>项都归为了零,所以也就没必要把这些零项保留下来。因此,我们仅用前<math>\textstyle k</math>个成分来定义<math>\textstyle k</math>维向量的<math>\textstyle \tilde{x}</math>。 | ||
- | + | 【二审】:然而,由于上面<math>\textstyle \tilde{x}</math>的后<math>\textstyle n-k</math>项均为零,所以没必要把这些零项保留下来。因此,我们仅用前<math>\textstyle k</math>个(非零)成分来定义<math>\textstyle k</math>维向量<math>\textstyle \tilde{x}</math>。 | |
Line 387: | Line 432: | ||
【一审】:这也解释了为什么会以<math>\textstyle u_1, u_2, \ldots, u_n</math>为基来表示我们的数据:从决定哪些成分需要保留演变成了只需简单选取<math>\textstyle k</math>个关键成分。这种运算我们也可以描述为“我们保留了<math>\textstyle k</math>个PCA(主)成分”。 | 【一审】:这也解释了为什么会以<math>\textstyle u_1, u_2, \ldots, u_n</math>为基来表示我们的数据:从决定哪些成分需要保留演变成了只需简单选取<math>\textstyle k</math>个关键成分。这种运算我们也可以描述为“我们保留了<math>\textstyle k</math>个PCA(主)成分”。 | ||
- | + | 【二审】:这也解释了我们为什么会以<math>\textstyle u_1, u_2, \ldots, u_n</math>为基来表示数据:从决定哪些成分需要保留,变成只需简单选取前<math>\textstyle k</math>个成分。当我们这么做的时候,可以描述为我们“保留了前<math>\textstyle k</math>个PCA(主)成分”。 | |
== Recovering an Approximation of the Data 数据还原 == | == Recovering an Approximation of the Data 数据还原 == |