栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Python

机器学习(四)—PCA(主成分分析)理论与代码详解

Python 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

机器学习(四)—PCA(主成分分析)理论与代码详解

文章目录
    • 1. 概要
    • 2. 规范化
    • 3. 协方差矩阵的特征分解方法
    • 5. 数据矩阵的奇异值分解方法
    • 6. Sklearn API
    • 7. 总结

1. 概要

主成分分析是一种无监督算法,主要思想是利用正交变换将线性相关变量表示的观测数据转换为少数几个由线性无关变量表示的数据,线性无关变量称为主成分。

主要方法有:协方差矩阵的特征值分解方法和数据矩阵的奇异值分解方法

PCA的本质:寻找方差最大的坐标轴作为主轴

用途:数据可视化、噪声过滤、特征抽取和特征工程等领域

说明:《统计学习方法》中行为特征维度m,列为样本维度n,这里使用了常规的理解方式(nxm),因此公式与书本不同

2. 规范化

输入:n x m 样本矩阵 X X X.

输出:n x m 样本矩阵 X X X(规范化结果)

  1. 计算m个均值以及方差
  2. 每个特征维度减去对应均值和方差得到结果
import numpy as np

X = np.arange(12).reshape(3, 4)          # 样本矩阵

x_mean = X.mean(axis=0)
# 一个随机变量一个方差
x_var = np.var(X, axis=0, ddof=1)
# 规范化
X = (X - x_mean) / (np.sqrt(x_var)+1e-19)

注意:计算方差ddof=1,指的是样本方差需要除以n-1,为什么呢?可以从自由度的角度进行考虑,因为这里计算样本方差时使用了样本均值,所以自由度降低了1,举例:1+2+3 = 6,在知道均值与其中两个样本后,其实已经确定了所有样本,所以自由度降低了1

3. 协方差矩阵的特征分解方法

算法流程:

输入:n x m 样本矩阵 X X X(默认已经规范化)

输出:样本主成分矩阵 Y Y Y(n x m).

  1. 计算协方差矩阵 S S S(m x m)或者计算样本相关矩阵 R = 1 n − 1 X T X R=frac{1}{n-1}X^{rm{T}}X R=n−11​XTX
  2. 计算协方差矩阵的特征值和单位特征向量eigen, eigen_vector
  3. 按特征值从大到小排序,选取前k个特征值对应的特征向量作为k个主成分V
  4. Y = X V Y=XV Y=XV,V(m x k),Y(n x k)
# 1. 计算协方差矩阵
S = np.cov(X, rowvar=False)   # 协方差是关于特征维度的,一个特征是一个随机变量

# 2. 计算特征值,单位特征向量
eigenvalue, featurevector = np.linalg.eig(S)     # 得到的就是单位特征向量
# a = np.linalg.norm(featurevector, axis=0)   
# single_featurevector = featurevector / np.linalg.norm(featurevector, axis=0)

# 3. 排序,取前k个主成分,也可以计算占比情况
sort_eigenvalue = sorted(eigenvalue, reverse=True)
precent = 0.7 * 100              # 70%信息
temp_value = np.percentile(sort_eigenvalue, precent)         # 返回的是70%分位的数
temp_index = np.where(eigenvalue >= temp_value)              # 选择大于等于70%元素的位置
V = featurevector[:, temp_index].squeeze()                   # 变换矩阵

# 4. 得到降维矩阵
Y = X.dot(V)
# 1. 计算相关矩阵
R = 1/(X.shape[0]-1) * X.T.dot(X)               # X:[n, m]->R:[m, m]

# 2. 计算特征值,单位特征向量
eigenvalue, eigenvector = np.linalg.eig(R)      # 特征值,单位特征向量

# 3. 排序,取前k个主成分
sort_eigenvalue = sorted(eigenvalue, reverse=True)
precent = 0.7 * 100              # 70%信息
temp_value = np.percentile(sort_eigenvalue, 70)
temp_index = np.where(eigenvalue >= temp_value)
V = featurevector[:, temp_index].squeeze()             # 变换矩阵

# 4. 得到降维矩阵
Y = X.dot(V)

协方差矩阵和样本相关矩阵,但是使用样本相关矩阵会更快些,都可以得到结果

5. 数据矩阵的奇异值分解方法

算法流程:

输入:n x m 样本矩阵 X X X(默认已经规范化)

输出:样本主成分矩阵 Y Y Y(n x k)

  1. X ′ = 1 n − 1 X X^prime=frac{1}{sqrt{n-1}}X X′=n−1 ​1​X, X ′ X^prime X′(n x m)
  2. X ′ = U S V T X^{prime}=USV^{rm{T}} X′=USVT,进行奇异值分解,保留k个奇异值和奇异向量,U(n x n),S(n x m),V(m x m),V的每一列队以一个主成分,选择对应(m x k)作为变换矩阵
  3. Y = X V Y=XV Y=XV,这里的V已经保留了k个主成分即(m x k),Y(n x k)
# 1. 样本矩阵进行修改
X_ = 1 / np.sqrt(X.shape[0]-1) * X

# 2. svd分解
U, S, V = np.linalg.svd(X_)

# 3. 排序找百分位置,其实svd分解中S已经排序了,从大到小
temp_value = np.percentile(S, 50)
temp_index = np.where(S >= temp_value)
V_k = V[:, temp_index].squeeze()            # 变换矩阵

# 4. 样本主成分矩阵
Y = X.dot(V_k)
6. Sklearn API
temp = PCA(n_components=1)
Y = temp.fit_transform(X)              # 样本主成分矩阵

注意使用sklearn api 默认是没有规范化操作

7. 总结

为什么要使用奇异值分解?
数据特别大,方便计算,进行分解保留重要信息,进行实验过程中发现,特征维度较小时使用特征值分解较好(相关矩阵比协方差矩阵快),当特征维度很大时,奇异值分解更快

参考链接:《统计学习方法》、《机器学习》

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/960397.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号