PCA降维简化数据

一.介绍
 主成分分析技术,又称主分量分析技术,旨在利用降维的思想,把多指标转化为少数几个综合指标.
  在统计学中,主成分分析PCA是一种简化数据集的技术。它是一个线性变换。这个变换把数据变换到一个新的坐标系统中,使得任何数据投影的第一大方差在第一个坐标(称为第一主成分)上,第二大方差在第二个坐标(第二主成分)上,依次类推。主成分分析经常用于减少数据集的维数,同时保持数据集的对方差贡献最大的特征。这是通过保留低阶主成分,忽略高阶主成分做到的。这样低阶成分往往能够保留住数据的最重要方面。但是,这也不是一定的,要视具体应用而定。本文旨在本人学习代码的笔记,原理部分就有些略过了


二.伪代码

  • 去除平均值

  • 计算协方差矩阵

  • 计算协方差矩阵的特征向量

  • 将特征值从大到小排序

  • 保留最上面的N个特征向量

  • 将数据转换到上述N个特征向量构建的新空间中



代码如下

import matplotlib
import numpy as np
from numpy import *
import matplotlib.pyplot as plt


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

def PCA(dataMat, topNfeat=9999999):
    #去平均值
    #axis = 0,那么输出矩阵是1行,[x,x,x.....x,x]   x是每一列的平均
    meanVals = mean(dataMat, axis=0)
    meanRemoved = dataMat - meanVals
    #计算协方差矩阵
    covMat = cov(meanRemoved, rowvar=0)
    #计算协方差矩阵的特征值和特征向量
    eigVals,eigVects = linalg.eig(np.mat(covMat))
    #从低到高排序
    eigValind = np.argsort(eigVals)
    #切断多余的尺寸,因为我们取的是前k个
    eigValind = eigValind[:-(topNfeat+1):-1]
    #重新组织eigVects最大到最小,这样我们可以更好的明显感受到方差百分比
    redEigVects = eigVects[:,eigValind]
    #将数据转换为新的维度
    lowDDataMat = meanRemoved * redEigVects
    #重构原始数据
    reconMat = (lowDDataMat * redEigVects.T) + meanVals
    return lowDDataMat, reconMat




if __name__ == '__main__':
    dataMat = loadDataSet('testSet.txt')
    lowDDataMat, reconMat = PCA(dataMat, 1)
    print('lowDDataMat包含了降维之后的矩阵,这是一个一维矩阵')
    print(np.shape(lowDDataMat))
    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], dataMat[:, 1].flatten().A[0], marker='o', s=50, c='red')
    plt.show()

在这里插入图片描述
在这里插入图片描述

- 小总结
  PCA降维之前有必要对数据标准化吗?

在PCA降维前对数据作标准化操作是重要且必要的,如果数据其中某一特征(矩阵的某一列)的数值特别大,那么它在整个误差计算的比重上就很大,那么可以想象在投影到低维空间之后,为了使低秩分解逼近原数据,整个投影会去努力逼近最大的那一个特征,而忽略数值比较小的特征。因为在建模前我们并不知道每个特征的重要性,这很可能导致了大量的信息缺失。


四.实战项目
        利用PCA对半导体制造数据降维

1. 引言
  半导体工厂制造设备仅能在几年内保持其先进性,设备生命期有限,t在花费又及其宝贵的情况下,如果制造过程中存在瑕疵,我们就必须要尽早发现,以确保宝贵的时间不会花费在缺陷产品的生产上。
  因此我们会考察厂家所提供的数据集,运用机器学习知识进一步减少生产中的错误,为厂家节省大量资金。但是它也比前面使用的数据集更大。准确的来说,包含了590个特征,因此我们需要对这些特征进行降维处理
  我们也从数据集中发现此数据集包含了很多的缺失值,NaN标识。几乎每个特征下都有NaN,去除不完整的样本不现实了。因此我们需使用平均值来代替缺失值。
2.代码

  • 将NaN代替成平均值的函数
def loadDataSet(filename,delim='\t'):
    fr = open(filename)
    stringArr = [line.strip().split(delim) for line in fr.readlines()]
    dataArr = [list(map(float, line)) for line in stringArr]
    return np.mat(dataArr)

  • 整体
import matplotlib
import numpy as np
from numpy import *
import matplotlib.pyplot as plt


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


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]) # 利用该维度所有非NaN特征求取均值
        datMat[nonzero(isnan(datMat[:,i].A))[0],i] = meanVal # 将该维度中所有NaN特征全部用均值替换
    return datMat

if __name__ == '__main__':
    dataMat = replaceNanWithMean()
    meanVals = mean(dataMat, axis=0)
    meanRemoved = dataMat - meanVals
    covMat = cov(meanRemoved, rowvar=0)
    eigVals, eigVects = linalg.eig(mat(covMat))
    print(eigVals)
    print('计算90%的主成分方差总和')
    print(sum(eigVals)*0.9)
    print('计算前6个主成分所占的方差')
    print(sum(eigVals[:6]))
    print('对前20个画图观察')
    plt.plot(eigVals[:20])
    plt.show()

在这里插入图片描述
在这里插入图片描述
 由上图,我们也就可以很明显的看到。前六个主成分覆盖率数据96.8%的方差,前二十个主成分覆盖率数据99.3%的方差.因此保留前六个去除后584个主成分,我们就大概可以实现100:1的压缩比。

  • 2
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值