这两天学习了吴恩达老师机器学习中的[主成分分析法](https://study.163.com/course/courseMain.htm?courseId=1004570029)(Principal Component Analysis, PCA),PCA是一种常用的降维方法。这里对PCA算法做一个小笔记,并利用python完成对应的练习(ps:最近公式有点多,开始没找到怎么敲公式,前面几篇都是截的图^_^,后面问了度娘,原来是支持latex的)。代码和数据见[github](https://github.com/zhoujinhai/pca)

一、PCA基本思路

  将数据从原来的坐标系转换到新的坐标系,新坐标系的选择由数据本身决定。第一个新坐标轴选择的是原始数据中方差最大的方向,第二个新坐标轴选择的是和第一个坐标轴正交且具有最大方差的方向,依次类推,直到找出\(k\)个新坐标轴。也就是将原始数据投影到一个低维的坐标系中。

二、PCA目标函数

  以最小化投影误差为目标函数,这里注意与线性回归的区别,线性回归是最小化垂直距离。下图左边图中蓝线是线性回归的目标,右图中蓝线是PCA的目标。

![](https://img2018.cnblogs.com/blog/1188959/201901/1188959-20190115154356900-850382945.png '线性回归与PCA区别')

三、PCA算法步骤

1、数据预处理,数据维度为 $ m*n $ 。

  对 $ X= x^{(1)}, x^{(2)}, ... , x^{(m)} $ 计算平均值和方差,$$ u_j = \frac{1}{m}\sum_{i=1}{m}x_j{(i)} $$ $$ s_j = \frac{1}{m}\sum_{i=1}{m}(x_j{(i)}-u_j)^2 $$

对原始数据进行归一化处理得到 $$ x_j = \frac{x_j-u_j}{s_j} $$

其中 $ u_j $ 表示均值, $ s_j $ 表示方差。

2、计算协方差矩阵 $ \Sigma $ 。

\[\Sigma = \frac{1}{m} \sum_{i=1}^{m}(x^{(i)}.(x^{(i)})^T)
\]

  其中 $ x^{(i)} $ 是 $ n \times 1 $ 维的,则其转秩是$ 1 \times n $ 维的,所以 $ \Sigma $ 是 $ n \times n $ 维的。

3、对 $ \Sigma $ 进行奇异值分解。

\[U,S,V = svd(\Sigma)
\]

奇异值分解可以参考博客,博主讲的比较清楚。上式中

\[U = [u^{(1)}, u^{(2)},...,u^{(n)}]\in R^{n*n}
\]

从中选取 $ k $ 个主要成分

\[U_k = [u^{(1)}, u^{(2)},...,u^{(k)}]
\]

则 $ x^{(i)} $ 在新坐标上的投影可以表示为

\[ z^{(i)} = [u^{(1)}, u^{(2)},...,u^{(k)}]^T\cdot x^{(i)}= \begin{bmatrix}
u^{(1)}\\
u^{(2)}\\
\vdots \\
u^{(k)}\\
\end{bmatrix}\cdot x^{(i)} \]

其中 $ U_k $ 是 $ k \times n $ 维的,其转秩为 $ n \times k $ 维的,$ x^{(i)} $ 是 $ n \times 1 $ 维,所以 $ z^{(i)} $ 是 $ k \times 1 $ 维的。投影 $ Z $ 可以表示为

\[Z = U_k^T \cdot X
\]

4、计算重构后特征 $ x_{approx}^{(i)} $ 。

\[x^{(i)}_{approx} = U_k \cdot z^{(i)}
\]

其中 $ U_k $ 是 $ n \times k $ 维,$ z^{(i)} $ 是 $ k \times 1 $ 维,则 $ x_{approx}^{(i)} $ 是 $ n \times 1 $ 维。

5、根据投影误差检验选择的 $ k $ 个主要成分是否满足要求。

\[\frac{\frac{1}{m}\sum_{i=1}^{m}||x^{(i)}-x^{(i)}_{approx}||^2}{\frac{1}{m}\sum_{i=1}^{m}||x^{(i)}||^2} \leq 0.01
\]

如果不满足上式,则从步骤3中重新选择 $ k $ 个主成分,继续第4和第5步,直到满足要求为止。小于等于0.01表明保留了原始数据99%信息,这里可以根据需求进行更改。

这里如果不用奇异值分解后的 $ U $ 矩阵,也可以根据奇异值矩阵 $ S $ 计算 ,$ S $ 是主对角线上为从大到小排列的奇异值,其他元素全为0的对角矩阵。

\[1-\frac{\sum_{i=1}^{k}S_{ii}}{\sum_{i=1}^{n}S_{ii}}\leq 0.01
\]

PCA应用实例

1、二维数据投影到一维,熟悉PCA流程

第一步 引入相关库并导入数据

from scipy.io import loadmat
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
data1 = loadmat('./ex7/ex7data1.mat')
data1



X = data1['X']
X.shape

原始数据展示

plt.scatter(X[:,0], X[:,1])
plt.show()

第二步 数据预处理

# 定义归一化函数featureNormalize
def featureNormalizse(x):
mean = x.mean(axis=0)
std = x.std(axis=0)
return (x-mean)/std, mean, std
# test
x_norm, means, stds = featureNormalizse(X)
x_norm[:5]

第三步 计算协方差矩阵

print(x_norm.shape)
sigma = (x_norm.T.dot(x_norm))/x_norm.shape[0]
sigma

第四步 奇异值分解

U,S,V = np.linalg.svd(sigma)
U,S,V

# 整合sigma和svd
def pca(x):
sigma = (x.T.dot(x))/x.shape[0]
U,S,V = np.linalg.svd(sigma)
return U,S,V

可视化主成分

x_norm, means, stds = featureNormalizse(X)
U, S, V = pca(x_norm) plt.figure(figsize=(8, 6))
plt.scatter(X[:,0], X[:,1], label='sample data') # 样本数据点 plt.plot([means[0], means[0] + 1.5*S[0]*U[0,0]],
[means[1], means[1] + 1.5*S[0]*U[0,1]],
c='r', linewidth=3, label='First Principal Component') # 第一个成分
plt.plot([means[0], means[0] + 1.5*S[1]*U[1,0]],
[means[1], means[1] + 1.5*S[1]*U[1,1]],
c='g', linewidth=3, label='Second Principal Component') # 第二个成分 plt.grid()
plt.axis("equal")
plt.legend()
plt.show()

第五步 计算 $ x_{approx} $

# 根据U_reduce计算x_norm的投影Z
def compute_z(X, U, k):
Z = X.dot(U[:,:k])
return Z # test
Z = compute_z(x_norm, U, 1)
Z[:5]

# 计算x_approx
def compute_x_approx(U, k, Z):
x_approx = Z.dot(U[:,:k].T) # 50*1 * 1*2
return x_approx # test
x_approx = compute_x_approx(U, 1, Z)
x_approx[:5]

第六步 可视化投影效果

plt.figure(figsize=(8,6))
plt.axis("equal")
plot = plt.scatter(x_norm[:,0], x_norm[:,1], s=30, facecolors='none',
edgecolors='b',label='Original Data Points') # 画出归一化后原始样本点
plot = plt.scatter(x_approx[:,0], x_approx[:,1], s=30, facecolors='none',
edgecolors='r',label='PCA Reduced Data Points') # 画出经过PCA后构造的估计值 plt.title("Example Dataset: Reduced Dimension Points Shown",fontsize=14)
plt.xlabel('x1 [Feature Normalized]',fontsize=14)
plt.ylabel('x2 [Feature Normalized]',fontsize=14)
plt.grid(True) for x in range(x_norm.shape[0]): # 画出变换前后的连线
plt.plot([x_norm[x,0],x_approx[x,0]],[x_norm[x,1],x_approx[x,1]],'k--')
# 输入第一项全是X坐标,第二项都是Y坐标
plt.legend()
plt.show()

2、利用PCA减少图片维度

第一步 导入数据

# 导入数据
face_data = loadmat('./ex7/ex7faces.mat')
face = face_data['X']
face.shape

第二步 展示数据

def showFace(X, row, col):
fig, axs = plt.subplots(row, col, figsize=(8,8))
for r in range(row):
for c in range(col):
axs[r][c].imshow(X[r*col + c].reshape(32,32).T, cmap = 'Greys_r')
axs[r][c].set_xticks([])
axs[r][c].set_yticks([]) showFace(face, 10, 10)
plt.show()

第三步 降维并重构

face_norm, means, stds = featureNormalizse(face) # 归一化
U, S, V = pca(face_norm) # 奇异值分解
Z = compute_z(face_norm, U, 16) # 计算Z
face_approx = compute_x_approx(U, 16, Z) # 计算降维重构后的数据
face_approx.shape

第四步 前后对比图

showFace(face, 10, 10)
showFace(face_approx, 10, 10)
plt.show()



主成分分析(PCA)学习笔记的更多相关文章

  1. PCA学习笔记

    主成分分析(Principal Component Analysis,简称PCA)是最常用过的一种降维方法 在引入PCA之前先提到了如何使用一个超平面对所有的样本进行恰当的表达? 即若存在这样的超平面 ...

  2. 机器学习之主成分分析PCA原理笔记

    1.    相关背景 在许多领域的研究与应用中,通常需要对含有多个变量的数据进行观测,收集大量数据后进行分析寻找规律.多变量大数据集无疑会为研究和应用提供丰富的信息,但是也在一定程度上增加了数据采集的 ...

  3. 机器学习13—PCA学习笔记

     主成分分析PCA 机器学习实战之PCA test13.py #-*- coding:utf-8 import sys sys.path.append("pca.py") impo ...

  4. 数据降维PCA——学习笔记

    PCA主成分分析 无监督学习 使方差(数据离散量)最大,更易于分类. 可以对隐私数据PCA,数据加密. 基变换 投影->内积 基变换 正交的基,两个向量垂直(内积为0,线性无关) 先将基化成各维 ...

  5. 主成分分析PCA学习一条龙

    转自:https://yoyoyohamapi.gitbooks.io/mit-ml/content/%E7%89%B9%E5%BE%81%E9%99%8D%E7%BB%B4/articles/PCA ...

  6. LDA PCA 学习笔记

    提要: 本文主要介绍了和推导了LDA和PCA,参考了这篇博客 LDA LDA的原理是,将带上标签的数据(点),通过投影的方法,投影到维度更低的空间中,使得投影后的点,会形成按类别区分,一簇一簇的情况, ...

  7. PCA 学习笔记

    先简单记下,等有时间再整理 PCA 主要思想,把 协方差矩阵 对角化,协方差矩阵是实对称的.里面涉及到矩阵论的一点基础知识: 基变换: Base2 = P · Base1 相应的 坐标变换 P · c ...

  8. 深度学习入门教程UFLDL学习实验笔记三:主成分分析PCA与白化whitening

    主成分分析与白化是在做深度学习训练时最常见的两种预处理的方法,主成分分析是一种我们用的很多的降维的一种手段,通过PCA降维,我们能够有效的降低数据的维度,加快运算速度.而白化就是为了使得每个特征能有同 ...

  9. 机器学习实战(Machine Learning in Action)学习笔记————09.利用PCA简化数据

    机器学习实战(Machine Learning in Action)学习笔记————09.利用PCA简化数据 关键字:PCA.主成分分析.降维作者:米仓山下时间:2018-11-15机器学习实战(Ma ...

  10. 机器学习降维方法概括, LASSO参数缩减、主成分分析PCA、小波分析、线性判别LDA、拉普拉斯映射、深度学习SparseAutoEncoder、矩阵奇异值分解SVD、LLE局部线性嵌入、Isomap等距映射

    机器学习降维方法概括   版权声明:本文为博主原创文章,未经博主允许不得转载. https://blog.csdn.net/u014772862/article/details/52335970 最近 ...

随机推荐

  1. 【CF845F】Guards In The Storehouse 插头DP

    [CF845F]Guards In The Storehouse 题意:一个n*m的房间,每个格子要么是障碍要么是空地.对于每个空地你可以选择放或者不放守卫.一个守卫能保护到的位置是:他右面的一行空地 ...

  2. node.js发送邮件email

    通常我们做node项目时,可能我们会碰到做一个简单的邮件反馈,那么我们今天就来讨论一下,其中遇到的各种坑. 总的来说做这个东西,我们可能需要node第三方依赖模块,来实现我们要达到的效果. 这里我推荐 ...

  3. lombok 一个不错的小工具

    (1)官方文档  Lombok features (2)Lombok Reduces Your Boilerplate Code (3)Lombok-Java代码自动生成 开发利器

  4. ztree学习---将默认勾选的展开

    这里只给出前台页面上的代码,数据可以从后台获取,注意,在封装数据的时候,注意:Id(节点的id,可以是数字也可以是字符串) , pid(父亲节点的id) , name(节点名称)不能少 . html页 ...

  5. Ubuntu 下 kdevelop下 怎么向主函数传递参数

    1.打开工程 2.点击窗口上的运行”--“配置启动器” 3.左栏选择要传递参数的工程名,在参数一栏中,输入参数“ubuntu.png”,再输入“工作目录”.点击OK,运行就可以了.

  6. ZOJ 2760 - How Many Shortest Path - [spfa最短路][最大流建图]

    人老了就比较懒,故意挑了到看起来很和蔼的题目做,然后套个spfa和dinic的模板WA了5发,人老了,可能不适合这种刺激的竞技运动了…… 题目链接:http://acm.zju.edu.cn/onli ...

  7. HDU-2680 Choose the best route 单向边+反向dijkstra

    https://vjudge.net/problem/HDU-2680 题意:以起始点 终点 长度 给出一个图,已知可以从w个起点出发,求从任一起点到同一个终点s的最短路径.注意是单向边.m<1 ...

  8. TCP 123=网络时间协议(NTP),Net Controller

    TCP 123=网络时间协议(NTP),Net Controller

  9. 通过qemu复现路由器漏洞

    目录 简介 环境搭建 固件解包 复现漏洞,IDA调试 参考资料 简介 qemu和vmware一样,一种虚拟机软件,只不过qemu能够虚拟的平台更加丰富一些.能够虚拟很多嵌入式平台的设备. 工作上需要向 ...

  10. mybatis联接查询例子

    where判断如果放在最外层就是对连接查询后的结果经行筛选. SELECT * from ( and lw_area.area_id like '35%' ) la LEFT JOIN ( selec ...