From 877fee7a9ac49f6ed9d69cd6423962695c73136a Mon Sep 17 00:00:00 2001 From: jiangzhonglian Date: Wed, 23 Aug 2017 14:19:32 +0800 Subject: [PATCH] =?UTF-8?q?=E6=9B=B4=E6=96=B0=20PCA=20md=E6=96=87=E6=A1=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/13.利用PCA来简化数据.md | 62 +++++++++++++++++++++++------------- src/python/13.PCA/pca.py | 55 +++++++++++++++++--------------- 2 files changed, 69 insertions(+), 48 deletions(-) diff --git a/docs/13.利用PCA来简化数据.md b/docs/13.利用PCA来简化数据.md index 988809b8..c8266b85 100644 --- a/docs/13.利用PCA来简化数据.md +++ b/docs/13.利用PCA来简化数据.md @@ -2,14 +2,7 @@ ![利用PCA简化数据_首页](/images/13.PCA/利用PCA简化数据_首页.jpg) -> 场景描述: - -* 我们正通过电视而非现场观看体育比赛,在电视的纯平显示器上有一个球。 -* 显示器大概包含了100万像素,而球则可能是由较少的像素组成,例如说一千个像素。 -* 人们实时的将显示器上的百万像素转换成为一个三维图像,该图像就给出运动场上球的位置。 -* 在这个过程中,人们已经将数据从一百万维降至了三维。这就被称为`降维(dimensionality reduction)` - -## 降维技术 +## 降维技术 概述 > 数据显示并非大规模特征下的唯一难题,对数据进行简化还有如下一系列的原因: @@ -48,25 +41,49 @@ * 假设数据为多个数据源的混合观察结果,这些数据源之间在统计上是相互独立的,而在PCA中只假设数据是不相关的。 * 同因子分析一样,如果数据源的数目少于观察数据的数目,则可以实现降维过程。 -## 主成分分析(PCA) -> PCA的优缺点 +## 降维技术 场景 -* 优点:降低数据的复杂性,识别最重要的多个特征。 -* 缺点:不一定需要,且可能损失有用信息。 -* 适用数据类型:数值型数据。 +* 我们正通过电视而非现场观看体育比赛,在电视的纯平显示器上有一个球。 +* 显示器大概包含了100万像素,而球则可能是由较少的像素组成,例如说一千个像素。 +* 人们实时的将显示器上的百万像素转换成为一个三维图像,该图像就给出运动场上球的位置。 +* 在这个过程中,人们已经将数据从一百万维降至了三维。这就被称为`降维(dimensionality reduction)` -> 通过PCA进行降维处理,我们就可以同时获得SVM和决策树的优点: -* 一方面,得到了和决策树一样简单的分类器,同时分类间隔和SVM一样好。 - * 1.第一个主成分就是来自于数据差异性最大(即 方差最大)的方向提取出来 - * 2.第二个主成分就是来自于数据差异性次大的方向,并且该方向于第一个主成分方向正交。 - * 3.通过数据集的协方差矩阵及其特征值分析,我们就可以得到这些主成分的值。 - * 一旦得到了协方差矩阵的特征向量,我们就可以保留最大的N个值。这些特征向量也给出了N个最重要特征的真实结构。我们可以通过将数据乘上这N个特征向量而将它转换到新的空间。 -* 例如下图: -* ![应用PCA降维](/images/13.PCA/应用PCA降维.png) +## PCA -## 对半导体数据进行降维处理 +### PCA 概述 + +主成分分析(Principal Component Analysis, PCA):`通俗理解:就是找出一个最主要的特征,然后进行分析。` + +### PCA 场景 + +`例如: 考察一个人的智力情况,就直接看数学成绩就行(存在:数学、语文、英语成绩)` + +### PCA 原理 + +> PCA 工作原理 + +通过PCA进行降维处理,我们就可以同时获得SVM和决策树的优点:(得到了和决策树一样简单的分类器,同时分类间隔和SVM一样好) +1. 第一个主成分就是来自于数据差异性最大(即: `方差最大`)的方向提取出来 +2. 第二个主成分就是来自于数据差异性次大的方向,并且该方向于第一个主成分方向`正交(orthogonal 如果是二维空间就叫垂直)`。 +3. 通过数据集的协方差矩阵及其特征值分析,我们就可以得到这些主成分的值。 +4. 一旦得到了协方差矩阵的特征向量,我们就可以保留最大的N个值。这些特征向量也给出了N个最重要特征的真实结构。 + 我们可以通过将数据乘上这N个特征向量而将它转换到新的空间。 + +例如下图: + +![应用PCA降维](/images/13.PCA/应用PCA降维.png) + +> PCA 优缺点 + +``` +优点:降低数据的复杂性,识别最重要的多个特征。 +缺点:不一定需要,且可能损失有用信息。 +适用数据类型:数值型数据。 +``` + +### 项目案例: 对半导体数据进行降维处理 ``` 半导体是在一些极为先进的工厂中制造出来的。设备的生命早期有限,并且话费极其巨大。 @@ -79,6 +96,7 @@ 目前该章节处理的方案是:将缺失值NaN(Not a Number缩写),全部用平均值来替代(如果用0来处理的策略就太差劲了)。 ``` + ## 本章小节 ``` diff --git a/src/python/13.PCA/pca.py b/src/python/13.PCA/pca.py index 52c1197e..b61dc69a 100644 --- a/src/python/13.PCA/pca.py +++ b/src/python/13.PCA/pca.py @@ -7,10 +7,9 @@ Update on 2017-05-18 @author: Peter Harrington/片刻 《机器学习实战》更新地址:https://github.com/apachecn/MachineLearning ''' -print(__doc__) from numpy import * -import matplotlib import matplotlib.pyplot as plt +print(__doc__) def loadDataSet(fileName, delim='\t'): @@ -106,6 +105,32 @@ def show_picture(dataMat, reconMat): plt.show() +def analyse_data(dataMat): + meanVals = mean(dataMat, axis=0) + meanRemoved = dataMat-meanVals + covMat = cov(meanRemoved, rowvar=0) + eigvals, eigVects = linalg.eig(mat(covMat)) + eigValInd = argsort(eigvals) + + topNfeat = 20 + eigValInd = eigValInd[:-(topNfeat+1):-1] + cov_all_score = sum(eigvals) + sum_cov_score = 0 + for i in range(0, len(eigValInd)): + line_cov_score = eigvals[eigValInd[i]] + sum_cov_score += line_cov_score + ''' + 我们发现其中有超过20%的特征值都是0。 + 这就意味着这些特征都是其他特征的副本,也就是说,它们可以通过其他特征来表示,而本身并没有提供额外的信息。 + + 最前面15个值的数量级大于10^5,实际上那以后的值都变得非常小。 + 这就相当于告诉我们只有部分重要特征,重要特征的数目也很快就会下降。 + + 最后,我们可能会注意到有一些小的负值,他们主要源自数值误差应该四舍五入成0. + ''' + print '主成分:%s, 方差占比:%s%%, 累积方差占比:%s%%' % (format(i+1, '2.0f'), format(line_cov_score/cov_all_score*100, '4.1f'), format(sum_cov_score/cov_all_score*100, '4.1f')) + + if __name__ == "__main__": # # 加载数据,并转化数据类型为float # dataMat = loadDataSet('input/13.PCA/testSet.txt') @@ -119,30 +144,8 @@ if __name__ == "__main__": # 利用PCA对半导体制造数据降维 dataMat = replaceNanWithMean() print shape(dataMat) + # # 分析数据 + # analyse_data(dataMat) lowDmat, reconMat = pca(dataMat, 20) print shape(lowDmat) show_picture(dataMat, reconMat) - - # meanVals = mean(dataMat, axis=0) - # meanRemoved = dataMat-meanVals - # covMat = cov(meanRemoved, rowvar=0) - # eigvals, eigVects = linalg.eig(mat(covMat)) - # eigValInd = argsort(eigvals) - - # topNfeat = 20 - # eigValInd = eigValInd[:-(topNfeat+1):-1] - # cov_all_score = sum(eigvals) - # sum_cov_score = 0 - # for i in range(0, len(eigValInd)): - # line_cov_score = eigvals[eigValInd[i]] - # sum_cov_score += line_cov_score - # ''' - # 我们发现其中有超过20%的特征值都是0。 - # 这就意味着这些特征都是其他特征的副本,也就是说,它们可以通过其他特征来表示,而本身并没有提供额外的信息。 - - # 最前面15个值的数量级大于10^5,实际上那以后的值都变得非常小。 - # 这就相当于告诉我们只有部分重要特征,重要特征的数目也很快就会下降。 - - # 最后,我们可能会注意到有一些小的负值,他们主要源自数值误差应该四舍五入成0. - # ''' - # print '主成分:%s, 方差占比:%s%%, 累积方差占比:%s%%' % (format(i+1, '2.0f'), format(line_cov_score/cov_all_score*100, '4.1f'), format(sum_cov_score/cov_all_score*100, '4.1f'))