PCA(Principal Component Analysis)

PCA的本质就是找一些投影方向,使得数据在这些投影方向上的方差最大,而且这些投影方向是相互正交的。

这其实就是找新的正交基的过程,计算原始数据在这些正交基上投影的方差,方差越大,就说明在对应正交基上包含了更多的信息量。

而原始数据协方差矩阵的特征值越大,对应的方差越大,在对应的特征向量上投影的信息量就越大。反之,如果特征值较小,

则说明数据在这些特征向量上投影的信息量很小,可以将小特征值对应方向的数据删除,从而达到了降维的目的。

算法思想

将一组P维向量降为K维(K

各字段两两间协方差为0,而字段的方差则尽可能大——这不就是对角矩阵吗?

Y = XP,其中X为原始数据(每个维度按列组成),Y为X对P做基变换后的数据,P的基行列组成。

设X、Y的协方差矩阵(对称矩阵)分别为C、D,则:D=PCP’。

我们希望D为对角矩阵,则D为C对P做相似对角化所得。

由于协方差矩阵为对称矩阵,则构成相似变换矩阵P的特征向量是正交的,实现逆变换。

实验步骤

(1)分别求每个维度的平均值,然后对于所有的样例,都减去对应维度的均值,得到去中心化的数据;

(2)求协方差矩阵C:用去中心化的数据矩阵乘上它的转置,然后除以(N-1)即可,N为样本数量;

(3)求协方差的特征值和特征向量;

(4)将特征值按照从大到小排序,选择前k个,然后将其对应的k个特征向量分别作为列向量组成特征向量矩阵;

(5)将样本点从原来维度投影到选取的k个特征向量,得到低维数据;

(6)通过逆变换,重构低维数据,进行复原。

import numpy as np

创建 eigValPct(eigVals, percentage)

通过方差的百分比来计算将数据降到多少维。

函数传入的参数是特征值eigVals和百分比percentage,返回需要降到的维度数num

def eigValPct(eigVals, percentage):

sortArray=np.sort(eigVals)[::-1] # 特征值从大到小排序

pct = np.sum(sortArray)*percentage

tmp = 0

num = 0

for eigVal in sortArray:

tmp += eigVal

num += 1

if tmp>=pct:

return num

创建 im_PCA(dataMat, percentage=0.9)

函数有两个参数,其中dataMat是已经转换成矩阵matrix形式的数据集,每列表示一个维度;

其中的percentage表示取前多少个特征需要达到的方差占比,默认为0.9。

注意:

np.cov(dataMat, rowvar=False),按照rowvar的默认值,会把一行当成一个特征,一列当成一个样本。

def im_PCA(dataMat, percentage=0.9):

meanVals = np.mean(dataMat, axis=0)

meanRemoved = dataMat - meanVals

# 这里不管是对去中心化数据 or 原始数据计算协方差矩阵,结果都一样,特征值大小会变,但相对大小不会改变

# covMat = np.cov(dataMat, rowvar=False)

# 标准的计算需要除以(dataMat.shape[0]-1),不算也不会影响结果,理由同上

covMat = np.dot(np.transpose(meanRemoved), meanRemoved)

eigVals, eigVects = np.linalg.eig(np.mat(covMat))

k = eigValPct(eigVals,percentage) #要达到方差的百分比percentage,需要前k个向量

print('K =', k)

eigValInd = np.argsort(eigVals)[::-1] #对特征值eigVals从大到小排序

eigValInd = eigValInd[:k]

redEigVects = eigVects[:,eigValInd] #主成分

lowDDataMat = meanRemoved*redEigVects #将原始数据投影到主成分上得到新的低维数据lowDDataMat

reconMat = (lowDDataMat*redEigVects.T)+meanVals #得到重构数据reconMat

return lowDDataMat, reconMat

注意:

图像Matrix格式必须转换为uint8格式,否则cv2.imshow时图像不能正常显示!np.array(reconMat, dtype=‘uint8’)。

但是,强制类型转化后会丢失信息,比如将 6. 变成 5 ,因为强制类型转化是直接采用截断二进制位的方式。。。

import cv2

img = cv2.imread('ava.jpg')

blue = img[:,:,0]

dataMat = np.mat(blue)

lowDDataMat, reconMat = im_PCA(dataMat, 1)

print('原始数据', blue.shape, '降维数据', lowDDataMat.shape)

# print(dataMat)

# print(reconMat)

# 格式必须转换为uint8格式,这里丢失了很多信息!!!

# reconMat = np.array(reconMat, dtype='uint8')

cv2.imshow('blue', blue)

cv2.imshow('reconMat', np.array(reconMat, dtype='uint8'))

cv2.waitKey(0)

K = 426

原始数据 (640, 426) 降维数据 (640, 426)

计算降维误差率

根据PCA的误差计算方式:信息丢失率 =

注意:np.dot(A, B)

(1)如果处理的是一维数组,则得到的是两数组的内积;

(2)如果是二维数组/矩阵之间的运算,得到的是矩阵积;

def PrintError(data, recdata):

sum1 = 0

sum2 = 0

D_value = data - recdata # 计算两幅图像之间的差值矩阵

# 计算两幅图像之间的误差率,即信息丢失率

for i in range(data.shape[0]):

sum1 += np.dot(data[i],data[i])

sum2 += np.dot(D_value[i], D_value[i])

print('丢失信息量:', sum2)

print('原始信息量:', sum1)

print('信息丢失率:', sum2/sum1)

print(dataMat)

print(reconMat)

PrintError(np.array(blue, dtype='double'), np.array(reconMat, dtype='double'))

[[ 6 6 6 ... 11 13 13]

[ 6 6 6 ... 12 15 15]

[ 7 7 7 ... 13 17 17]

...

[16 16 16 ... 29 29 29]

[16 16 16 ... 29 29 29]

[16 16 16 ... 29 29 29]]

[[ 6. 6. 6. ... 11. 13. 13.]

[ 6. 6. 6. ... 12. 15. 15.]

[ 7. 7. 7. ... 13. 17. 17.]

...

[16. 16. 16. ... 29. 29. 29.]

[16. 16. 16. ... 29. 29. 29.]

[16. 16. 16. ... 29. 29. 29.]]

丢失信息量: 7.140138346734739e-16

原始信息量: 784219850.0

信息丢失率: 9.104766152928595e-25

使用sklearn的PCA方法

参数说明:

sklearn.decomposition.PCA(n_components=None, copy=True, whiten=False);

n_components: PCA算法中所要保留的主成分个数n,也即保留下来的特征个数n。赋值为int,比如n_components=1,将把原始数据降到一个维度。赋值为string,比如n_components=‘mle’,将自动选取特征个数n,使得满足所要求的方差百分比。

copy: 是否在原始数据的副本上进行运算。

whiten: 白化,使得每个特征具有相同的方差。

from sklearn.decomposition import PCA

pca = PCA(n_components=426).fit(blue)

# 降维

x_new = pca.transform(blue)

# 还原降维后的数据到原空间

recdata = pca.inverse_transform(x_new)

print(recdata)

# 计算误差

PrintError(np.array(blue, dtype='double'), np.array(reconMat, dtype='double'))

cv2.imshow('sklearn-recdata', np.array(recdata, dtype='uint8'))

cv2.waitKey(0)

[[ 6. 6. 6. ... 11. 13. 13.]

[ 6. 6. 6. ... 12. 15. 15.]

[ 7. 7. 7. ... 13. 17. 17.]

...

[16. 16. 16. ... 29. 29. 29.]

[16. 16. 16. ... 29. 29. 29.]

[16. 16. 16. ... 29. 29. 29.]]

丢失信息量: 7.140138346734739e-16

原始信息量: 784219850.0

信息丢失率: 9.104766152928595e-25

Reference

计算过程

https://www.cnblogs.com/lzllovesyl/p/5235137.html

PCA详解,原理及步骤,包括数学基础

https://my.oschina.net/gujianhan/blog/225241#OSC_h2_1

PCA,图像压缩还原

https://blog.csdn.net/Vincent_zbt/article/details/88648739

scikit-learn中PCA的使用方法

https://blog.csdn.net/u012162613/article/details/42192293/

python图像压缩主成分分析实例_PCA - 主成分分析(Python实现图像压缩)相关推荐

  1. python爬虫程序实例-10个python爬虫入门实例

    作者:h3zh1 来源:cnblogs.com/h3zh1/p/12548946.html 今天为大家准备了几个简单的python爬虫入门实例,分享给大家. 涉及主要知识点:web是如何交互的 req ...

  2. python主成分分析代码_PCA主成分分析 原理讲解 python代码实现

    1. 用途: 通俗来说: 考察一个人的智力情况,就直接看数学成绩就行(存在:数学.语文.英语成绩) .就是找出一个最主要的特征,然后进行分析. 数据压缩 (Data Compression) ,将高维 ...

  3. python教程实例-python 类和实例 - 刘江的python教程

    类和实例 阅读: 19079 评论:6 类,英文名字Class,有"类别","分类","聚类"的意思.必须牢记类是抽象的模板,用来描述具有相 ...

  4. python面向对象编程实例爬虫_​Python面向对象编程⑭

    14)函数参数注解 你写好了一个函数,然后想为这个函数的参数增加一些额外的信息(每个参数的类型),这样的话其他调用者就能清楚的知道这个函数应该怎么使用. 解决方案:使用函数参数注解是一个很好的办法,它 ...

  5. python网络自动化实例_【python自动化第八篇:网络编程】

    一.拾遗 动态导入模块 目的是为了在导入模块的过程中将模块以字符的格式导入. #!/usr/bin/env python # -*- coding:utf-8 -*- #Author:wanghui ...

  6. python tkinter计算器实例_使用Python自带GUI tkinter编写一个期权价格计算器

    0 准备工作 首先,确认环境中有numpy.scipy.stats和tkinter三个功能包.前两个功能包可用于Python的数学计算,比如使用numpy来生成随机数用于Monte Carlo模拟,以 ...

  7. python大数据分析实例-如何用Python分析大数据(以Twitter数据挖掘为例)

    原标题:如何用Python分析大数据(以Twitter数据挖掘为例) 来源:艾翻译(http://www.itran.cc/) 原文标题:Twitter Data Mining: A Guide to ...

  8. python爬虫入门实例-终于领会python爬虫入门示例

    随着人工智能 大数据的火热 Python成为了广大科学家和普通大众的学习语言.在学习Python的过程中 有很多人感到迷茫 不知道自己该从什么地方入手,今天我们就来说一些新手该如何学习Python编程 ...

  9. python多元线性回归实例_利用Python进行数据分析之多元线性回归案例

    线性回归模型属于经典的统计学模型,该模型的应用场景是根据已知的变量(自变量)来预测某个连续的数值变量(因变量).例如,餐厅根据每天的营业数据(包括菜谱价格.就餐人数.预定人数.特价菜折扣等)预测就餐规 ...

最新文章

  1. ModuleNotFoundError: No module named 'tools.nnwrap' pytorch 安装
  2. PIC单片机入门_输入输出端口详解
  3. jcg q8 固件_JCG学院开设了Java设计模式课程!
  4. ztree java 增删改_Ztree实现增删改查
  5. java并发 cpu高_java高并发核心要点|系列5|CPU内存伪共享
  6. 人工智能的主要研究领域
  7. 民生银行用户画像搭建与应用 / 民生银行客户画像搭建与应用
  8. js 日语索引 日文排序
  9. Linux下cuda卸载
  10. 如何进行邮件营销,邮件营销群发是否有效?
  11. 以游戏玩家的视角开启设计模式
  12. 超全!全国近90所大学考研报录比汇总!
  13. 感冒初期试试食疗方 盲目用药伤脾胃
  14. oracle12c口令文件,学习笔记:Oracle 12C ASM 新特性 共享密码文件
  15. mysql数据库存储经度纬度
  16. 5年多工作经验,工资给15k,要是你,你会接受吗?
  17. laravel集成Telegram Bot 机器人
  18. OpenGL之基本图元连接方式
  19. #金数据#微信小程序#微信小程序跳转金数据小程序并获取问卷信息
  20. 10个最好的获取免费书籍的网站

热门文章

  1. UI Automation编程辅助工具Inspect的下载和使用
  2. 微信群运营方案及技巧策略(精华版)
  3. 100php多少人民币,【100泰币等于多少人民币】
  4. 项目管理学习---四约束
  5. 太阳电池仿真模块 matlab 程序,基于MATLAB的月球车锂离子电池充放电过程仿真
  6. 《Go语言圣经》第一章 - 读书笔记
  7. Ip102: a large-scale bench-mark dataset for insect pest recognition.
  8. 物联网安全专题 | 浅谈物联网设备安全分析方法 — 软件篇
  9. Oracle 在存储过程或函数中执行字符串sql
  10. 预备1-window常用快捷键