【数学】主成分分析(PCA)的应用案例解析(Python)

接着上文PCA的数学详细推导过程,本文介绍使用Python结合图像压缩案例解释PCA的具体实现流程,以了解数据处理的一些方法
Jupyter Notebook file

文章目录

  • 借助 scikit-learn 实现 PCA
    • 输入数据
    • PCA降维并重建
  • 手动实现 PCA 过程
    • 输入数据
    • 数据居中处理
    • 协方差矩阵计算
    • 矩阵的特征分解
    • 重构数据

借助 scikit-learn 实现 PCA

使用scikit-learn库执行PCA过程,以对输入的数字图像数据进行降维。然后比较原始数据和重构数据之间的差异以熟悉过程。

输入数据

导入库,并可视化源输入数据。

# 导入所需的库
import numpy as np
import matplotlib.pyplot as plt
from sklearn.datasets import load_digits
from sklearn.decomposition import PCA
from sklearn.metrics import mean_squared_error
# 加载数字数据集
digits = load_digits()
X = digits.data
y = digits.target

# 计算原始数据大小
original_size = X.nbytes / (1024 * 1024)  # in megabytes
print("original data size is: %.2f MB" % original_size)
original data size is: 0.88 MB
# 将前10个样本作为图像显示
fig, axes = plt.subplots(1, 10, figsize=(12, 4))
for i in range(10):
    axes[i].imshow(X[i].reshape(8, 8), cmap='gray')
    axes[i].set_title(f"Label: {y[i]}")
    axes[i].axis('off')
plt.tight_layout()
plt.show()

在这里插入图片描述

PCA降维并重建

定义函数以计算重构误差和执行PCA

# Function to calculate reconstruction error
def reconstruction_error(original, reconstructed):
    return mean_squared_error(original, reconstructed)

# 函数用于执行PCA并使用n_components重构数据。
def perform_pca(n_components):
    pca = PCA(n_components=n_components)
    X_pca = pca.fit_transform(X)
    X_reconstructed = pca.inverse_transform(X_pca)
    return X_reconstructed, pca
# 执行PCA,并可视化结果
def analyze_pca(n_components):
    X_reconstructed, pca = perform_pca(n_components)
    reconstruction_error_val = reconstruction_error(X, X_reconstructed)
    print(f"Number of Components: {n_components}, Reconstruction Error: {reconstruction_error_val}")

    # 压缩文件的大小
    compressed_size = (pca.components_.nbytes + pca.mean_.nbytes + X_reconstructed.nbytes) / (1024 * 1024)  # in megabytes
    print(f"Size of Compressed File: {compressed_size} MB")

    # 大小差异
    size_difference = original_size - compressed_size
    print(f"Difference in Size: {size_difference} MB")

    # 绘制每个数字的原始和重构图像
    fig, axes = plt.subplots(2, 10, figsize=(10, 2))
    for digit in range(10):
        digit_indices = np.where(y == digit)[0]  # Indices of samples with the current digit
        original_matrix = X[digit_indices[0]].reshape(8, 8)  # Take the first sample for each digit
        reconstructed_matrix = np.round(X_reconstructed[digit_indices[0]].reshape(8, 8), 1)  # Round to one decimal place
        axes[0, digit].imshow(original_matrix, cmap='gray')
        axes[0, digit].axis('off')
        axes[1, digit].imshow(reconstructed_matrix, cmap='gray')
        axes[1, digit].axis('off')

    plt.suptitle(f'Reconstruction with {n_components} Components')
    plt.show()

    # 打印第一个数据的原始矩阵
    print("Original Matrix of the First Data:")
    print(original_matrix)

    # 打印重构矩阵
    print("\nReconstruction Matrix of the First Data:")
    print(reconstructed_matrix)

分析当使用一个主成分PCA时的重建结果

analyze_pca(1)
Number of Components: 1, Reconstruction Error: 15.977678462238496
Size of Compressed File: 0.87841796875 MB
Difference in Size: -0.0009765625 MB

在这里插入图片描述

Original Matrix of the First Data:
[[ 0.  0. 11. 12.  0.  0.  0.  0.]
 [ 0.  2. 16. 16. 16. 13.  0.  0.]
 [ 0.  3. 16. 12. 10. 14.  0.  0.]
 [ 0.  1. 16.  1. 12. 15.  0.  0.]
 [ 0.  0. 13. 16.  9. 15.  2.  0.]
 [ 0.  0.  0.  3.  0.  9. 11.  0.]
 [ 0.  0.  0.  0.  9. 15.  4.  0.]
 [ 0.  0.  9. 12. 13.  3.  0.  0.]]

Reconstruction Matrix of the First Data:
[[-0.   0.4  6.4 12.6 12.   6.3  1.4  0.1]
 [ 0.   2.6 11.7 11.2 10.5  9.4  1.9  0.1]
 [ 0.   3.   9.4  5.8  8.   8.7  1.6  0. ]
 [ 0.   2.1  7.7  9.  11.1  7.8  2.   0. ]
 [ 0.   1.5  5.6  8.2  9.8  8.5  2.8  0. ]
 [ 0.   1.   5.2  5.9  6.5  8.2  3.7  0. ]
 [ 0.   0.8  7.8  9.   8.8  9.5  4.1  0.2]
 [ 0.   0.4  6.8 12.9 11.9  7.3  2.3  0.4]]

分析当使用5个主成分PCA时的结果

analyze_pca(5)
Number of Components: 5, Reconstruction Error: 8.542447616249266
Size of Compressed File: 0.88037109375 MB
Difference in Size: -0.0029296875 MB

在这里插入图片描述

Original Matrix of the First Data:
[[ 0.  0. 11. 12.  0.  0.  0.  0.]
 [ 0.  2. 16. 16. 16. 13.  0.  0.]
 [ 0.  3. 16. 12. 10. 14.  0.  0.]
 [ 0.  1. 16.  1. 12. 15.  0.  0.]
 [ 0.  0. 13. 16.  9. 15.  2.  0.]
 [ 0.  0.  0.  3.  0.  9. 11.  0.]
 [ 0.  0.  0.  0.  9. 15.  4.  0.]
 [ 0.  0.  9. 12. 13.  3.  0.  0.]]

Reconstruction Matrix of the First Data:
[[ 0.   0.2  5.2 11.1 12.1  7.   1.6  0.1]
 [ 0.   2.1 11.2 10.7  9.7  9.6  2.3  0.2]
 [ 0.   3.1 11.2  6.2  6.   9.2  2.5  0.1]
 [ 0.   3.1 10.3  9.   9.6  9.6  2.9  0. ]
 [ 0.   2.2  6.   5.3  8.  11.6  3.9  0. ]
 [ 0.   1.2  4.2  1.9  4.9 11.7  5.1  0. ]
 [ 0.   0.6  6.7  6.2  8.8 12.1  4.4  0.2]
 [ 0.   0.2  5.4 12.1 13.4  8.2  1.8  0.3]]

一个明显的效果是使用更多的主成分,重构结果会更好。接下来手动计算PCA矩阵,了解其详细工作原理。

手动实现 PCA 过程

手动逐步执行PCA分析。

输入数据

导入数据并打印数据矩阵与图像

# 然后使用逐步的方法计算PCA步骤;
# 取第一个数据点进行分析
first_data = X[0]
print("Raw input data: \n", X[0])
# 将数据点重新整形为二维数组(图像)
input_matrix = first_data.reshape(8, 8)

print("Input matrix: ")
for row in input_matrix:
    print(" ".join(f"{val:4.0f}" for val in row))

# 打印原始矩阵(图像)
plt.imshow(input_matrix, cmap='gray')
plt.title("Input matrix (Image)")
plt.axis('off')
plt.show()
Raw input data: 
 [ 0.  0.  5. 13.  9.  1.  0.  0.  0.  0. 13. 15. 10. 15.  5.  0.  0.  3.
 15.  2.  0. 11.  8.  0.  0.  4. 12.  0.  0.  8.  8.  0.  0.  5.  8.  0.
  0.  9.  8.  0.  0.  4. 11.  0.  1. 12.  7.  0.  0.  2. 14.  5. 10. 12.
  0.  0.  0.  0.  6. 13. 10.  0.  0.  0.]
Raw data shape:  (64,)
Input matrix: 
   0    0    5   13    9    1    0    0
   0    0   13   15   10   15    5    0
   0    3   15    2    0   11    8    0
   0    4   12    0    0    8    8    0
   0    5    8    0    0    9    8    0
   0    4   11    0    1   12    7    0
   0    2   14    5   10   12    0    0
   0    0    6   13   10    0    0    0

在这里插入图片描述

数据居中处理

居中数据是PCA中的关键预处理步骤,它增强了结果的解释性,消除了偏差,并确保了计算中的数值稳定性。
均值计算有助于我们理解每个特征的平均值,这对于居中数据和在随后的步骤中计算协方差矩阵至关重要。

# 步骤1:计算每个特征(列)的均值
mean_vec = np.mean(input_matrix, axis=0)
print(mean_vec)
[ 0.    2.25 10.5   6.    5.    8.5   4.5   0.  ]
# 步骤2:从每个特征中减去均值
centered_matrix = input_matrix - mean_vec
print(centered_matrix)
[[ 0.   -2.25 -5.5   7.    4.   -7.5  -4.5   0.  ]
 [ 0.   -2.25  2.5   9.    5.    6.5   0.5   0.  ]
 [ 0.    0.75  4.5  -4.   -5.    2.5   3.5   0.  ]
 [ 0.    1.75  1.5  -6.   -5.   -0.5   3.5   0.  ]
 [ 0.    2.75 -2.5  -6.   -5.    0.5   3.5   0.  ]
 [ 0.    1.75  0.5  -6.   -4.    3.5   2.5   0.  ]
 [ 0.   -0.25  3.5  -1.    5.    3.5  -4.5   0.  ]
 [ 0.   -2.25 -4.5   7.    5.   -8.5  -4.5   0.  ]]

协方差矩阵计算

计算居中处理后数据的协方差矩阵。

# 使用np.dot计算协方差。Bessel修正在末尾减1。 https://www.uio.no/studier/emner/matnat/math/MAT4010/data/forelesningsnotater/bessel-s-correction---wikipedia.pdf
cov_matrix = np.dot(centered_matrix.T, centered_matrix) / (centered_matrix.shape[0] - 1) 

# 或者使用np.cov计算协方差
# cov_matrix = np.cov(centered_matrix, rowvar=False)

print(cov_matrix)
[[  0.           0.           0.           0.           0.
    0.           0.           0.        ]
 [  0.           4.21428571   2.28571429 -13.14285714  -9.42857143
    4.14285714   6.14285714   0.        ]
 [  0.           2.28571429  14.          -9.42857143  -4.85714286
   17.           6.28571429   0.        ]
 [  0.         -13.14285714  -9.42857143  43.42857143  29.57142857
  -12.57142857 -17.85714286   0.        ]
 [  0.          -9.42857143  -4.85714286  29.57142857  26.
   -7.         -17.57142857   0.        ]
 [  0.           4.14285714  17.         -12.57142857  -7.
   28.85714286  11.           0.        ]
 [  0.           6.14285714   6.28571429 -17.85714286 -17.57142857
   11.          14.85714286   0.        ]
 [  0.           0.           0.           0.           0.
    0.           0.           0.        ]]

矩阵的特征分解

# 计算协方差矩阵的特征值和特征向量
eigenvalues, eigenvectors = np.linalg.eig(cov_matrix)

print(eigenvalues)
print(eigenvectors)
[8.92158455e+01 3.14545089e+01 7.61850164e+00 2.85144338e+00
 2.01453633e-01 1.53898738e-02 0.00000000e+00 0.00000000e+00]
[[ 0.          0.          0.          0.          0.          0.
   1.          0.        ]
 [-0.20365153  0.09344175  0.07506402 -0.23052329 -0.41043409 -0.85003703
   0.          0.        ]
 [-0.22550077 -0.48188982  0.20855091  0.79993174 -0.1168451  -0.14104805
   0.          0.        ]
 [ 0.65318552 -0.28875672 -0.59464342  0.12374602  0.11324705 -0.32898247
   0.          0.        ]
 [ 0.48997693 -0.31860576  0.39448425 -0.20610464 -0.63307453  0.24399318
   0.          0.        ]
 [-0.33563583 -0.75773097 -0.0607778  -0.49775699  0.24837474  0.00681139
   0.          0.        ]
 [-0.35818338 -0.00212894 -0.66178497  0.03760326 -0.58531429  0.29955628
   0.          0.        ]
 [ 0.          0.          0.          0.          0.          0.
   0.          1.        ]]

选择与最大特征值对应的特征向量作为主成分。

# 选择与最大特征值对应的主成分
max_eigenvalue_index = np.argmax(eigenvalues)
principal_component = eigenvectors[:, max_eigenvalue_index]
print(principal_component)
[ 0.         -0.20365153 -0.22550077  0.65318552  0.48997693 -0.33563583
 -0.35818338  0.        ]
# 将数据投影到主成分上
reduced_data = np.dot(centered_matrix, principal_component)

# 打印降维后的数据
print("Reduced data (1 principal component):\n", reduced_data)
Reduced data (1 principal component):
 [12.35977044  5.86229378 -8.32285024 -8.14946302 -7.7867473  -8.41834525
  1.49545914 12.95988243]

到目前为止,数据已从原来的 8x8 矩阵压缩为 8x1 的向量,接下来看一下使用降维后数据重建的效果。

重构数据

现在基于降维后的结果来重新组建原数据,并展示效果。

# 步骤7:重构数据
reconstructed_data = np.dot(reduced_data.reshape(-1, 1), principal_component.reshape(1, -1))

# 步骤8:将均值添加回重构的数据
reconstructed_data += mean_vec

# 步骤9:可视化原始数据和重构数据
fig, axes = plt.subplots(1, 2, figsize=(12, 6))

# 原始数据
axes[0].imshow(input_matrix, cmap='gray')
axes[0].set_title('Original Data')
axes[0].axis('off')

# Reconstructed data
axes[1].imshow(reconstructed_data.real, cmap='gray')
axes[1].set_title('Reconstructed Data')
axes[1].axis('off')

plt.show()

在这里插入图片描述
对比上图,发现重建数据清晰程度仍然不错,与输入图像有些许差别但是主要的特征都可以清晰分辨。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mfbz.cn/a/553088.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

自动驾驶(八十四)---------中间件对比分析

很久没有写博客了,CSDN无故非法删了我第82篇,让我很恼火,一直提不起兴趣重新写一遍第82篇。但回初心,知识需要用自己的语言输出,所以今天对比分析自动驾驶中间件: 1. 中间件介绍 在自动驾驶架构中&#xf…

【Git】git命令大全(持续更新)

本文架构 0.描述git简介术语 1.常用命令2. 信息管理新建git库命令更改存在库设置获取当前库信息 3.工作空间相关将工作空间文件添加到缓存区(增)从工作空间中移除文件(删)撤销提交 4.远程仓库相关同步远程仓库分支 (持…

【学习笔记】Python大数据处理与分析——数据预处理

一、数据清洗 1、唯一值与重复值 获取唯一值的方法是采用unique()函数,用于Series对象: s1 pd.Series([2, 3, 4, 1, 2, 5, 3, 6, 4, 9, 5, 3, 4, 2, 1, 2])print(s1.unique()) →[2 3 4 1 5 6 9] 但unique()函数不能用于DataFrame对象,而d…

html接入百度地图

1.申请key key申请地址&#xff1a;https://lbsyun.baidu.com/apiconsole/key#/home 注意&#xff1a;白名单设置*则所有可访问&#xff0c;正式发布保证安全需修改为域名 官方文档 https://lbsyun.baidu.com/index.php?titlejspopularGL 2.html接入示例 <!DOCTYPE …

基于51单片机智能鱼缸仿真LCD1602显示( proteus仿真+程序+设计报告+讲解视频)

基于51单片机智能鱼缸仿真LCD显示 1. 主要功能&#xff1a;2. 讲解视频&#xff1a;3. 仿真4. 程序代码5. 设计报告6. 设计资料内容清单&&下载链接资料下载链接&#xff1a; 基于51单片机智能鱼缸仿真LCD显示( proteus仿真程序设计报告讲解视频&#xff09; 仿真图prot…

基于springboot+vue+Mysql的汽车租赁系统

开发语言&#xff1a;Java框架&#xff1a;springbootJDK版本&#xff1a;JDK1.8服务器&#xff1a;tomcat7数据库&#xff1a;mysql 5.7&#xff08;一定要5.7版本&#xff09;数据库工具&#xff1a;Navicat11开发软件&#xff1a;eclipse/myeclipse/ideaMaven包&#xff1a;…

04-15 周一 GitHub仓库CI服务器actions-runner和workflow yaml配置文档解析

04-15 周一 GitHub仓库CI服务器配置过程文档 时间版本修改人描述2024年4月15日10:35:52V0.1宋全恒新建文档2024年4月17日10:33:20v1.0宋全恒完成github actions CI的配置和工作流配置文件解读文档的撰写 简介 一些基础概念 前提知识 仓库介绍 地址镜像介绍https://github.…

选择生产制造项目管理系统?全面解析功能与实际应用!

生产效率和项目规划是制造企业亟需解决的难题&#xff0c;想要从容的应对这些挑战&#xff0c;离不开好用的生产制造项目管理系统。下面我们全面解析什么才能称得上是好用的生产制造项目管理系统。 一、好用的生产制造项目管理系统 什么样的项目管理系统才能算是好用呢&#x…

【QT进阶】Qt Web混合编程之VS2019 CEF的编译与使用(图文并茂超详细介绍)

往期回顾 【QT入门】Qt自定义控件与样式设计之自定义QLineEdit实现搜索编辑框-CSDN博客 【QT入门】Qt自定义控件与样式设计之自定义QTabWidget实现tab在左&#xff0c;文本水平的效果-CSDN博客【QT进阶】Qt Web混合编程之CEF、QCefView简单介绍-CSDN博客 【QT进阶】Qt Web混合编…

微服务相关

1. 微服务主要七个模块 中央管理平台&#xff1a;生产者、消费者注册&#xff0c;服务发现&#xff0c;服务治理&#xff0c;调用关系生产者消费者权限管理流量管理自定义传输协议序列化反序列化 2. 中央管理平台 生产者A在中央管理平台注册后&#xff0c;中央管理平台会给他…

2024运营级租房源码管理PHP后台+uniapp前端(app+小程序+H5)

内容目录 一、详细介绍二、效果展示1.部分代码2.效果图展示 一、详细介绍 房产系统 一款基于ThinkPHPUniapp开发的房产管理系统&#xff0c;支持小程序、H5、APP&#xff1b;包含房客、房东、经纪人三种身份。核心功能有&#xff1a;新盘销售、房屋租赁、地图找房、房源代理、…

基于SSM+Jsp+Mysql的准速达物流管理系统

开发语言&#xff1a;Java框架&#xff1a;ssm技术&#xff1a;JSPJDK版本&#xff1a;JDK1.8服务器&#xff1a;tomcat7数据库&#xff1a;mysql 5.7&#xff08;一定要5.7版本&#xff09;数据库工具&#xff1a;Navicat11开发软件&#xff1a;eclipse/myeclipse/ideaMaven包…

保护视力,从 CareUEyes 开始 —— 你的电脑护眼小助手

在数字化时代&#xff0c;我们的眼睛比以往任何时候都更频繁地面对屏幕。长时间盯着电脑工作&#xff0c;不仅影响视力&#xff0c;还可能导致眼疲劳和不适。今天&#xff0c;我要向大家推荐一款专为电脑用户设计的护眼软件——CareUEyes。 CareUEyes&#xff1a;你的视力守护者…

数据大爆炸:WordCount程序的多元化执行方式

文章目录 主要内容1.左方工作区右键New,选择Map文件2.再创建mymap,myreducer,mywordcount类&#xff1a;3.打包在linux中运行&#xff0c;注意处理的文件式完全分布式文件3.1打jar包步骤&#xff1a; 4.完成内容 主要内容 尝试使用不同的方式运行wordcount程序。 1&#xff09…

【洛谷 P3366】【模板】最小生成树 题解(无向图+边集数组+Kruskal算法+最小生成树+并查集+路径压缩)

【模板】最小生成树 题目描述 如题&#xff0c;给出一个无向图&#xff0c;求出最小生成树&#xff0c;如果该图不连通&#xff0c;则输出 orz。 输入格式 第一行包含两个整数 N , M N,M N,M&#xff0c;表示该图共有 N N N 个结点和 M M M 条无向边。 接下来 M M M 行…

「Qt Widget中文示例指南」如何实现行编辑功能

Qt 是目前最先进、最完整的跨平台C开发工具。它不仅完全实现了一次编写&#xff0c;所有平台无差别运行&#xff0c;更提供了几乎所有开发过程中需要用到的工具。如今&#xff0c;Qt已被运用于超过70个行业、数千家企业&#xff0c;支持数百万设备及应用。 Line Edits&#xf…

PHP 使用 PHPMailer 发送电子邮件

1. PHPMailer 介绍 phpMailer 是一个非常强大的 php 发送邮件扩展包&#xff0c;可以设定发送邮件地址、回复地址、邮件主题、html邮件内容和上传附件等&#xff0c;使用起来非常方便。它目前有着有近 4 千万的下载量&#xff0c;是 PHP 开发者实现邮件发送功能的首选扩展包 它…

Oracle11.2.0.1,(CVE-2012-1675)漏洞解决方案

1.进入容器停止监听 docker exec -it -u 0 oracle11g bash su - oracle lsnrctl stop listener2.找到监听配置文件位置&#xff0c;修改监听文件 echo $ORACLE_HOMEvi network/admin/listener.ora #在文件底部添加 SECURE_REGISTER_LISTENER (IPC) #启动监听 lsnrctl start …

vue3:tree结构的全选和取消

实现的功能&#xff0c;上面有个选择框&#xff0c;当选中全部时&#xff0c;下方树被全选 代码&#xff1a; <template><div><el-select v-model"selectAll" style"margin-bottom: 10px;" change"handleSelectAllChange">&…

HarmonyOS开发实例:【分布式数据服务】

介绍 分布式数据服务(Distributed Data Service&#xff0c;DDS)为应用程序提供不同设备间数据分布式的能力。通过调用分布式数据接口&#xff0c;应用程序将数据保存到分布式数据库中。通过结合帐号、应用和分布式数据服务对属于不同的应用的数据进行隔离&#xff0c;保证不同…
最新文章