本文是对PCA和SVD学习的整理笔记,为了避免很多重复内容的工作,我会在介绍概念的时候引用其他童鞋的工作和内容,具体来源我会标记在参考资料中。

一.PCA (Principle component analysis)

PCA(主成分分析)通过线性变换将原始数据变换为一组各维度线性无关的表示,可用于提取数据的主要特征分量,常用于高维数据的降维。

为什么需要降维?以下图为例,图c中的点x y 呈现明显线性相关,假如以数据其实以数据点分布的方向的直线上的投影(一维)已经能够很好的描述这组数据特点了 。明显的,将数据维度降低:1能够降低数据计算量  2压缩数据重构  3.部分情况下甚至能够改善数据特征。

  那么如何在降维时尽量保留源数据的特征,PCA就是一种。关于如何理解,PCA,通常可以用两种方式进行理解:一是让降维后的数据分布尽量分散能够保留信息(方差尽量大) 二是降维导致的信息损失尽量小。关于第一种理解方式,大家可以参考这里,细致而清晰。第二种方法通常需要简单的公式推导,利用拉格朗日乘子将带约束的优化转化为无约束优化后求导,有兴趣的童鞋可以参考这里.

上面两篇文章关于两个不同方向解释PCA,那么这里就直接写出PCA的降维方法,假设原数据为X:

    设有m条n个特征的数据。

    1)将原始数据按列组成n行m列矩阵X,即每一列代表一组数据

    2)将X的每一行(代表一个属性字段)进行零均值化,即减去这一行的均值

    3)求出协方差矩阵\[C=\frac{1}{m}XX^{T}\]

    4)求出协方差矩阵的特征值及对应的特征向量(对\[XX^{T}\]进行特征分解)

    5)将特征向量按对应特征值大小从上到下按行排列成矩阵,取前k行组成矩阵P

    6)Y=PX即为降维到k维后的数据

好了,PCA的流程中似乎和奇异值似乎没有什么关系。但是,首先\[XX^{T}\]计算过程中如果有较小的值很容易造成精度损失,其次特征分解只能处理方针,有没有更方便的方式获得降维矩阵P,这就要用到SVD了。

二 SVD(Singular value decomposition)

首先,关于特征分解和奇异值分解的物理意义理解,我推荐看这里

总结一下,特征值分解和奇异值分解都是给一个矩阵(线性变换)找一组特殊的基,特征值分解找到了特征向量这组基,在这组基下该线性变换只有缩放效果。而奇异值分解则是找到另一组基,这组基下线性变换的旋转、缩放、投影三种功能独立地展示出来了, 简而言之:

1.特征值分解其实是对旋转缩放两种效应的归并

2.奇异值分解其实是岁旋转缩放和投影效应的归并

 也就是说,奇异值分解可以说是包含了特征分解!来看Wikipedia的解释:

在矩阵M的奇异值分解中

  • V的列(columns)组成一套对正交"输入"或"分析"的基向量。这些向量是特征向量
  • U的列(columns)组成一套对正交"输出"的基向量。这些向量是特征向量
  • Σ对角线上的元素是奇异值,可视为是在输入与输出间进行的标量的"膨胀控制"。这些是特征值的非负平方根,并与UV的行向量相对应。

这里的*标识转置T。看到其中U就是MM*的特征向量了,那么也就是说利用奇异值分解也可以做PCA了,而且还不用求\[XX^{T}\]!

不仅如此,单独观看奇异值分解的式子,我们也可以利用主成分的思想,利用奇异值分解的公式对高维数据进行压缩,具体看下面的代码。

from PIL import Image
import numpy as np
import matplotlib.pyplot as plt def decide_k(s, ratio):
sum_tmp = 0
sum_s = np.sum(s)
k = 0
for i in s:
k += 1
sum_tmp += i
if (sum_tmp / sum_s) >= ratio:
print("reduce dims is:", k)
return k if k >= s.shape:
raise ValueError('input dim could not less than compress dims') def svd_refactor(x, ratio=0.90): # compress to a k dims data before = x.shape[0] * x.shape[1]
print("before compress:", before) # after svd, save cu cv and cs ,then we could use them to refactor picture
mean_ = np.mean(x, axis=1, keepdims=True)
x = x - mean_
u, s, v = np.linalg.svd(x)
k = decide_k(s, ratio)
c_u = u[:, :k]
c_v = v[:k, :]
c_s = s[0:k] after = c_u.shape[0] * c_u.shape[1] + c_v.shape[0] * c_v.shape[1] + c_s.shape[0]
print("after compress:", after)
print("ratio", after / before) # refactor
s_s = np.diag(c_s)
return np.dot(c_u, np.dot(s_s, c_v)) def pca_refactor(x, ratio=0.90): # compress to a k dims data before = x.shape[0] * x.shape[1]
print("before pca:", before) # after svd, save cu cv and cs ,then we could use them to refactor picture
mean_ = np.mean(x, axis=1, keepdims=True)
x = x - mean_
u, s, v = np.linalg.svd(x)
k = decide_k(s, ratio)
c_u = u[:, :k] eig_vec = c_u.transpose()
pca_result = np.dot(eig_vec, x) after = c_u.shape[0] * c_u.shape[1] + pca_result.shape[0] * pca_result.shape[1]
print("after pca:", after)
print("ratio", after / before) # since U*U=I
return np.dot(c_u, pca_result) if __name__ == '__main__':
img_file = Image.open('test.jpg').convert('L') # convert picture to gray
img_array = np.array(img_file)
print(img_array.shape) img_array = pca_refactor(img_array) plt.figure("beauty")
plt.imshow(img_array, cmap=plt.cm.gray)
plt.axis('off')
plt.show()

其中 关于如何选择降低维度到多少维的decide_k函数,采用了贡献率。就是指当剩余特征值和的比例小于一定百分比(0.05)的时候舍弃他们。

Reference:

李航《统计学习方法》

Relationship between SVD and PCA. How to use SVD to perform PCA?

PCA的数学原理

机器学习中的数学(5)-强大的矩阵奇异值分解(SVD)及其应用

机器学习中的SVD和PCA.知乎

奇异值的物理意义是什么?

矩阵的奇异值与特征值有什么相似之处与区别之处

从PCA和SVD的关系拾遗

PCA, SVD以及代码示例的更多相关文章

  1. 高级渲染技巧和代码示例 GPU Pro 7

    下载代码示例 移动设备正呈现着像素越来越高,屏幕尺寸越来越小的发展趋势. 由于像素着色的能耗非常大,因此 DPI 的增加以及移动设备固有的功耗受限环境为降低像素着色成本带来了巨大的压力. MSAA 有 ...

  2. Java8-Function使用及Groovy闭包的代码示例

    导航 定位 概述 代码示例 Java-Function Groovy闭包 定位 本文适用于想要了解Java8 Function接口编程及闭包表达式的筒鞋. 概述 在实际开发中,常常遇到使用模板模式的场 ...

  3. [IOS 开发] 懒加载 (延迟加载) 的基本方式,好处,代码示例

    懒加载的好处: 1> 不必将创建对象的代码全部写在viewDidLoad方法中,代码的可读性更强 2> 每个属性的getter方法中分别负责各自的实例化处理,代码彼此之间的独立性强,松耦合 ...

  4. SELECT控件操作的JS代码示例

    SELECT控件操作的JS代码示例 1 检测是否有选中 if(objSelect.selectedIndex > -1) { //说明选中 } else { //说明没有选中 } 2.动态创建s ...

  5. 转:HIBERNATE一些_方法_@注解_代码示例---写的非常好

    HIBERNATE一些_方法_@注解_代码示例操作数据库7步骤 : 1 创建一个SessionFactory对象 2 创建Session对象 3 开启事务Transaction : hibernate ...

  6. Python实现各种排序算法的代码示例总结

    Python实现各种排序算法的代码示例总结 作者:Donald Knuth 字体:[增加 减小] 类型:转载 时间:2015-12-11我要评论 这篇文章主要介绍了Python实现各种排序算法的代码示 ...

  7. C#与数据库访问技术总结(十五)之 DataAdapter对象代码示例

    DataAdapter对象代码示例 下面的代码将说明如何利用DataAdapter对象填充DataSet对象. private static string strConnect=" data ...

  8. C#与数据库访问技术总结(六)之Command对象创建SQl语句代码示例

    Command对象创建SQl语句代码示例 说明:前面介绍了 Command 对象的方法和一些属性,回顾一下 Command对象主要用来执行SQL语句.利用Command对象,可以查询数据和修改数据. ...

  9. 领域驱动开发推荐代码示例 — Microsoft NLayerApp

    简介: Microsoft NLayerApp是由微软西班牙团队出品的基于.NET 4.0的“面向领域N层分布式架构”代码示例,在codeplex上的地址是:http://microsoftnlaye ...

随机推荐

  1. 笔记-测试崩溃之memcpy_s

    昨天晚上提测,今天早上测试发来贺电,程序崩溃!!!!!! 而问题出在memcpy_s errno_t memcpy_s( void *dest, size_t numberOfElements, co ...

  2. Lua如何管理”package”

    Lua如何管理"package" 方式一: 私有方法和变量都需要显式定义为local类型的,这很容易造成错误.一旦不小心漏写,就又将方法定义为全局的了. "package ...

  3. Host文件简介

    摘抄自:http://www.cnblogs.com/zgx/archive/2009/03/10/1408017.html.百度百科:hosts文件 很奇怪有很多人不知道Hosts是什么东西.在网络 ...

  4. Can you solve this equation?

    Problem Description Now,given the equation 8*x^4 + 7*x^3 + 2*x^2 + 3*x + 6 == Y,can you find its sol ...

  5. 交换知识 VLAN VTP STP 单臂路由

    第1章 交换基础 1.1 园区网分层结构 层次 作用 出口层 广域网接入 出口策略 带宽控制 核心层 高速转发 服务器接入 路由选择 汇聚层 流量汇聚 链路冗余 设备冗余 路由选择 接入层 用户接入 ...

  6. ASP.NET Core的身份认证框架IdentityServer4(6)- 开始

    安装和概述 启动一个新的IdentityServer项目有两种基本方法: 从头开始 从Visual Studio中的ASP.NET身份模板开始 如果从头开始,我们提供了一些文档.项目帮助和内存存储支持 ...

  7. 解决打开MATLAB时出现“Waring:could not read file classpath.txt”,等问题

    估计刚安装好的matlab是不会出现这个问题的,出现问题肯定是在某一次用360或者电脑管家清理垃圾之后才会出现这个问题. 首先声明我的matlab版本是matlab R2014a,下载链接:(额,网盘 ...

  8. Nginx HTTP 核心模块

    原文链接:http://blog.chinaunix.net/xmlrpc.php?r=blog/article&uid=17238776&id=2982697aio 语法:aio [ ...

  9. AngularJS学习篇(五)

    AngularJS Scope(作用域) Scope(作用域) 是应用在 HTML (视图) 和 JavaScript (控制器)之间的纽带. Scope 是一个对象,有可用的方法和属性. Scope ...

  10. 网站出现service unavailable的解决方法

    特别提示:本文的教程仅适合采用windows服务器的IIS组件上操作,service unavailable是许多网站会经常遇到的问题,希望对大家有用. 昨天一小段时间网站出现了service una ...