机器学习实战-利用PCA来简化数据

在体育比赛中,人们面对的原本是百万像素的数据,但是只有球的三维位置才最重要,这就成为降维(dimensionlity reduction)。通常而言,我们在应用其他机器学习算法之前,必须先识别出其相关特征。
第一种降维称作主方法分析(Principal Component Analysis,PCA)。
第一个坐标值选择的是原始数据中方差最大的方向,第二个新坐标轴的选择和第一个坐标轴正交且具有最大方差的方向。
另一种降维技术是因子分析(Factor Analysis)。在因子分析中,我们假设在观察数据的生成一些观察不到的隐变量(latent variable)。假设观察数据是这些隐变量和某些噪声的线性组合。那么隐变量的数据可能比观察数据的数目少,也就是说通过隐变量可以实现数据的降维。
还有一种方法就是独立成分分析(Independent Component Analysis,ICA)。ICA假设数据是从N个数据源生成的,这一点和因子分析有些类似。假设数据为多个数据源的混合观察结果,这些数据源之间在统计上是互相独立的,而在PCA中之假设数据是不相关的。
在上述3种降维技术中,PCA的应用目前最为广泛,因此本章主要关注PCA。在下一节中,我们将会对PCA进行介绍,然后再通过一段Python代码来运行PCA。

主成分分析
优点:降低数据的复杂性,识别最重要的多个特征
缺点:不一定需要,且可能损失有用信息
适用数据类型:数据型数据

将数据转化成前N个主成分的伪代码大致如下:

去除平均值
计算协方差矩阵
计算协方差矩阵的特征值和特征向量
将特征值从打到小排序
保留最上面的N个特征向量
将数据转换到上述N个特征向量构建的新空间中

下面开始构建PCA算法

from numpy import *

def loadDataSet(fileName, delim='\t'):
    fr = open(fileName)
    stringArr = [line.strip().split(delim) for line in fr.readlines()]
    datArr = [map(float,line) for line in stringArr]
    return mat(datArr)

def pca(dataMat, topNfeat=9999999):#数据集,返回特征数
    meanVals = mean(dataMat, axis=0)
    meanRemoved = dataMat - meanVals #去平均值
    covMat = cov(meanRemoved, rowvar=0) #协方差
    eigVals,eigVects = linalg.eig(mat(covMat))#特征值,特征矩阵
    eigValInd = argsort(eigVals)            #从小到大排序
    eigValInd = eigValInd[:-(topNfeat+1):-1]  #逆序,从大到小
    redEigVects = eigVects[:,eigValInd]       
    lowDDataMat = meanRemoved * redEigVects#将数据转化到新的维度空间
    reconMat = (lowDDataMat * redEigVects.T) + meanVals
    return lowDDataMat, reconMat

我们在testSet.txt文件中加入一个由1000个数据点组成的数据集,开始进行PCA操作:

In [17]: import pca
    ...: dataMat = pca.loadDataSet('testSet.txt')
    ...: lowDMat, reconMat = pca.pca(dataMat, 1)
    ...: shape(lowDMat)
    ...: 
Out[17]: (1000L, 1L)

lowDMat,包含了降维之后的矩阵。我们可以通过如下命令将降维后的数据和原始数据一起绘制出来:

import matplotlib
import matplotlib.pyplot as plt
fig = plt.figure()
ax = fig.add_subplot(111)

ax.scatter(dataMat[:,0].flatten().A[0], dataMat[:,1].flatten().A[0], marker='^', s=90)

ax.scatter(reconMat[:,0].flatten().A[0], reconMat[:,1].flatten().A[0], marker = 'o', s = 50, c='red')
plt.show()
    ...:
原始数据集(三角形点)及第一主成分(圆形点)

使用如下命令代替PCA调用,也会看到类似结果:

lowDMat, reconMat = pca.pca(dataMat, 2)

下面我们先处理一些异常值,用平均值代替NaN:

def replaceNanWithMean(): 
    datMat = loadDataSet('secom.data', ' ')
    numFeat = shape(datMat)[1]
    for i in range(numFeat):
        meanVal = mean(datMat[nonzero(~isnan(datMat[:,i].A))[0],i]) 
        datMat[nonzero(isnan(datMat[:,i].A))[0],i] = meanVal  #将所有nan置为平均值
    return datMat

PCA会给出数据中所包含的信息量。数据(data)和信息(information)之间具有巨大的差别。数据指的是接受的原始材料,其中包含噪声和不相关的信息。信息指数据中的相关部分。下面开始操作,首先将所有的NaN值替换为平均值:

In [36]: import pca
    ...: dataMat = pca.replaceNanWithMean()
    ...: 

接下来从pca()函数中借用一些代码来达到我们的目的,之所以借用是因为我们想了解中间结果而非最后输出结果,调用如下语句去除均值:

In [37]: meanVals = mean(dataMat, axis = 0)
    ...: meanRemoved = dataMat - meanVals
    ...:

然后计算协方差矩阵:

In [38]: covMat = cov(meanRemoved, rowvar=0)

最后对该矩阵进行特征值分析:

In [39]: eigVals,eigVects = linalg.eig(mat(covMat))
    ...: 
    ...: eigVals
    ...: 
Out[39]: 
array([ 53415197.85687517+0.j,  21746671.90465918+0.j,
         8248376.61529074+0.j, ...,         0.00000000+0.j,
               0.00000000+0.j,         0.00000000+0.j])

我们会发现超过20%的特征值都是0。这意味着这些特征都是其他特征的副本,也就是说,他们可以通过其他特征来表示,而本身并没有提供额外的信息。
接下来,我们了解一下部分数值的数量级。最前面15个值的数量级大于10的五次方,实际上那以后的值都变得非常小。这相当于告诉我们部分重要特征,重要特征的数目也很快就会下降。
最后,我们注意到一些负值,他们主要源于数值误差,应该四舍五入为0。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,590评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 86,808评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,151评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,779评论 1 277
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,773评论 5 367
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,656评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,022评论 3 398
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,678评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 41,038评论 1 299
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,659评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,756评论 1 330
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,411评论 4 321
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,005评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,973评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,203评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,053评论 2 350
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,495评论 2 343

推荐阅读更多精彩内容