【机器学习】sklearn降维算法PCA

news2025/1/20 5:55:13

文章目录

  • 降维
  • PCA
  • sklearn中的PCA
    • 代码实践
  • PCA对手写数字数据集的降维


降维

如何实现降维?【即减少特征的数量,又保留大部分有效信息】

将那些带有重复信息的特征合并,并删除那些带无效信息的特征等等,逐渐创造出能够代表原特征矩阵大部分信息的,特征更少的,新特征矩阵。
在降维中,PCA使用的信息量衡量指标,就是样本方差,又称可解释性方差,方差越大,特征所带的信息量越多
S 2 = 1 n − 1 ∑ i = 1 n ( x i − x ^ ) 2 S^2=\frac{1}{n-1}\sum_{i=1}^n(x_i-\hat{x})^2 S2=n11i=1n(xix^)2

简单看一个二维降到一维的例子:
在这里插入图片描述我们原本有两个特征x1x2,同过将坐标系旋转45度形成一个新平面,形成两个新的特征和特征值,注意这时候 x 2 ∗ x2^* x2的方差是0,所以可以将 x 2 ∗ x2^* x2删除,同时也删除图中的 x 2 ∗ x2^* x2特征向量,剩下的 x 1 ∗ x1^* x1就代表了曾经需要两个特征来代表的三个样本点。

通过旋转原有特征向量组成的坐标轴来找到新特征向量和新坐标平面,我们将三个样本点的信息压缩到了一条直线上,实现了二维变一维,并且尽量保留原始数据的信息。一个成功的降维,就实现了。

以上面二维特征的降维推导到n维数据的降维:

过程二维特征矩阵n维特征矩阵
1输入原数据,结构为 (3,2)
找出原本的2个特征对应的直角坐标系,本质是找出这2个特征构成的2维平面
输入原数据,结构为 (m,n)
找出原本的n个特征向量构成的n维空间V
2决定降维后的特征数量:1决定降维后的特征数量:k
3旋转,找出一个新坐标系
本质是找出2个新的特征向量,以及它们构成的新2维平面
新特征向量让数据能够被压缩到少数特征上,并且总信息量不损失太多
通过某种变化,找出n个新的特征向量,以及它们构成的新n维空间V
4找出数据点在新坐标系上,2个新坐标轴上的坐标找出原始数据在新特征空间V中的n个新特征向量上对应的值,即“将数据映射到新空间中”
5选取第1个方差最大的特征向量,删掉没有被选中的特征,成功将2维平面降为1维选取前k个信息量最大的特征,删掉没有被选中的特征,成功将n维空间V降为k维

在步骤3当中,我们用来找出n个新特征向量,让数据能够被压缩到少数特征上并且总信息量不损失太多的技术就是矩阵分解。

其中PCA和SVD都是采用矩阵分解的方式来对特征进行降维,两种算法中矩阵分解的方法不同,信息量的衡量指标不同。


PCA

PCA(Principal Component Analysis) 是一种常见的数据分析方式,常用于高维数据的降维,可用于提取数据的主要特征分量,所以常常也叫做主成分分析。
降维,降维的同时尽可能防止数据失真。

核心:构造新的坐标系,丢弃新的坐标系中的部分坐标,从而达到降维。

PCA过程:

  1. 数据中心化。

求各样本点到坐标轴的平均值,然后对于所有的样例,都减去对应的均值。其目的是让数据通过中心化处理,得到均值为0的数据。同时中心化后的数据对向量来说也容易描述,因为是以原点为基准的。
在这里插入图片描述在这里插入图片描述

  1. 拟合线。
    数据点到线的距离(越小越好)

在这里插入图片描述在这里插入图片描述数据点到线的距离越小,样本点到原点的距离不变【a的值是固定的】,要使b尽可能的小,根据勾股定理,就是使c尽可能的大,也就是各样本点投影到线上的投影点到原点的距离越大越好。
样本点到线的距离(越小越好)
各样本点投影到线上的投影点到原点的距离(越大越好)
在这里插入图片描述找到所有样本点投影到线上的投影点到原点的距离之和最大的线
在这里插入图片描述
这条线就是主成分1(PC1)
在这里插入图片描述通过PC1,可以得出Gene1这个特征要比Gene2要重要,因为PC1中Gene1占的比重要大。

新的特征向量(拟合线):最佳拟合线也就是主成分线上的单位向量。

在这里插入图片描述最佳拟合线的距离叫做PC1的特征值

根据其定义Ax=cx,其中A是矩阵,c是特征值,x是特征向量;

Ax矩阵相乘的含义就是,矩阵A对向量x进行一系列的变换(旋转或者拉伸),其效果等于一个常数c乘以向量x。

通常我们求特征值和特征向量是想知道,矩阵能使哪些向量(当然是特征向量)只发生拉伸,其拉伸程度如何(特征值的大小)。这个真正的意义在于,是为了让我们看清矩阵能在哪个方向(特征向量)产生最大的变化效果

奇异值:
在这里插入图片描述通过垂直PC1构造出PC2,分别计算各样本的到PC1和PC2的方差。然后各自方差除以方差之和得到差异率。


sklearn中的PCA

  1. 类:sklearn.decomposition.PCA
  2. 参数:
    在这里插入图片描述在这里插入图片描述在这里插入图片描述
  3. 属性
    在这里插入图片描述
  4. 接口
    在这里插入图片描述

代码实践

  1. 导入库
import matplotlib.pyplot as plt  # 画图工具
from sklearn.datasets import load_iris  # 鸢尾花数据集
from sklearn.decomposition import PCA # PCA主成分分析类
  1. 查看原本数据集
iris = load_iris()
y = iris.target
X = iris.data
X.shape

在这里插入图片描述
可以看到鸢尾花数据集的特征是4维的。

  1. PCA进行降维
#调用PCA
pca = PCA(n_components=2) # 降到2维
pca = pca.fit(X) #拟合模型
X_dr = pca.transform(X) #获取新矩阵 (降维后的)
X_dr
#也可以fit_transform一步到位
#X_dr = PCA(2).fit_transform(X)

在这里插入图片描述
由原来的4维降到了2维,将降维后的特征通过2维平面画出来:

plt.figure()
plt.scatter(X_dr[y==0, 0], X_dr[y==0, 1], c="red", label=iris.target_names[0]) 
plt.scatter(X_dr[y==1, 0], X_dr[y==1, 1], c="black", label=iris.target_names[1])
plt.scatter(X_dr[y==2, 0], X_dr[y==2, 1], c="orange", label=iris.target_names[2])
plt.legend()
plt.title('PCA of IRIS dataset')
plt.show()

在这里插入图片描述可以看到3种类型的数据是一簇一簇的,可以预料到KNN模型会有很好的表现。

  1. 降维后数据探索
  • explained_variance_降维后每个新特征向量上所带的信息量大小
  • explained_variance_ratio_ 上面那个的百分比
#属性explained_variance_,查看降维后每个新特征向量上所带的信息量大小(可解释性方差的大小)
pca.explained_variance_
#属性explained_variance_ratio,查看降维后每个新特征向量所占的信息量占原始数据总信息量的百分比
#又叫做可解释方差贡献率
pca.explained_variance_ratio_
#大部分信息都被有效地集中在了第一个特征上
pca.explained_variance_ratio_.sum()

在这里插入图片描述

  1. 选择最好的n_components:累积可解释方差贡献率曲线

当参数n_components中不填写任何值,则默认返回min(X.shape)个特征,一般来说,样本量都会大于特征数目,所以什么都不填就相当于转换了新特征空间,但没有减少特征的个数。
可以通过查看转换了新特征空间后各个特征的占比。

import numpy as np
pca_line = PCA().fit(X)
plt.plot([1,2,3,4],np.cumsum(pca_line.explained_variance_ratio_))
plt.xticks([1,2,3,4]) #这是为了限制坐标轴显示为整数
plt.xlabel("number of components after dimension reduction")
plt.ylabel("cumulative explained variance ratio")
plt.show()

在这里插入图片描述一般选转折点,当n_components=3时已经占比达到99%多了,基本可以选择这个。

  1. 最大似然估计自选超参数
    n_components除了输入整数,还可以输入“mle”作为n_components的参数输入,了让PCA用最大似然估计(maximum likelihoodestimation)自选超参数的方法:
pca_mle = PCA(n_components="mle")
pca_mle = pca_mle.fit(X)
X_mle = pca_mle.transform(X)

在这里插入图片描述可以看得自动帮我们选择了降维到3.

  1. 按信息量占比选超参数

n_components还可以输入[0,1]的浮点数,搭配svd_solver="full"一起使用,表示希望降维后的总解释性方差占比大于n_components指定的百分比,即是说,希望保留百分之多少的信息量。

pca_f = PCA(n_components=0.97,svd_solver="full") # 降维后的数据占比大于97%
pca_f = pca_f.fit(X)
X_f = pca_f.transform(X)

在这里插入图片描述

  1. 原理

SVD可以找出一个新特征向量组成的n维空间, 而这个n维空间就是奇异值分解后的右矩阵 V T ( n , n ) V^T(n,n) VT(n,n),原特征需要降到k维
降维后的特征矩阵 X d r ( m , k ) = 原特征矩阵 X ( m , n ) ∗ V T [ : , k ] 降维后的特征矩阵X_{dr}(m,k)=原特征矩阵X(m,n)*V^T[:,k] 降维后的特征矩阵Xdr(m,k)=原特征矩阵X(m,n)VT[:,k]
k就是n_components,是我们降维后希望得到的维度。若X为(m,n)的特征矩阵, 就是结构为(n,n)的矩阵,取这个矩阵的前k行(进行切片),即将V转换为结构为(k,n)的矩阵。而 V ( k , n ) T V_{(k,n)}^T V(k,n)T与原特征矩阵X相乘,即可得到降维后的特征矩阵X_dr。这是说,奇异值分解可以不计算协方差矩阵等等结构复杂计算冗长的矩阵,就直接求出新特征空间和降维后的特征矩阵。

sklearn将降维流程拆成了两部分:一部分是计算特征空间V,由奇异值分解完成,另一部分是映射数据和求解新特征矩阵,由主成分分析完成,实现了用SVD的性质减少计算量,却让信息量的评估指标是方差,具体流程如下图:
在这里插入图片描述
在sklearn中,矩阵U和Σ虽然会被计算出来(同样也是一种比起PCA来说简化非常多的数学过程,不产生协方差矩阵),但完全不会被用到,也无法调取查看或者使用,因此我们可以认为,U和Σ在fit过后就被遗弃了。奇异值分解追求的仅仅是V,只要有了V,就可以计算出降维后的特征矩阵。在transform过程之后,fit中奇异值分解的结果除了V(k,n)以外,就会被舍弃,而V(k,n)会被保存在属性components_ 当中,可以调用查看。

PCA(2).fit(X).components_ # (k,n) V矩阵
PCA(2).fit(X).components_.shape

在这里插入图片描述

  1. 理解V(k,n),是新特征空间,是我们要将原始数据进行映射的那些新特征向量组成的矩阵。用它来
    计算新的特征矩阵。

可以通过图像的降维来理解:
(1)导入库和数据集

from sklearn.datasets import fetch_lfw_people # 人脸数据
from sklearn.decomposition import PCA 
import matplotlib.pyplot as plt
import numpy as np
faces = fetch_lfw_people(data_home = "../pca/" ,download_if_missing=False, min_faces_per_person=60)  #60是每个人最少提取60张

直接下载会报错forbidden403,直接自己下载

报错403 Forbidden 自己下载 https://pan.baidu.com/s/1J9lUvosuGJp6bLADzPN6aQ 提取码jqxx 解压后放入

(2)查看一下数据
在这里插入图片描述随便查看一下是什么样的图片:

import matplotlib.pyplot as plt
fig, axes = plt.subplots(4,8
                         ,figsize=(8,4)
                         ,subplot_kw={"xticks":[],"yticks":[]}  # 不要显示坐标
                         )
#填充图像
for i, ax in enumerate(axes.flat):
    ax.imshow(faces.images[i,:,:]
              ,cmap="gray" #选择色彩的模式
              )

在这里插入图片描述
(3)降维(降到150维)

X = faces.data
pca = PCA(150).fit(X)
V = pca.components_

查看要映射的矩阵V的信息

fig, axes = plt.subplots(3,8,figsize=(8,4),subplot_kw = {"xticks":[],"yticks":[]})
for i, ax in enumerate(axes.flat):
    ax.imshow(V[i,:].reshape(62,47),cmap="gray")

在这里插入图片描述
比起降维前的数据,新特征空间可视化后的人脸非常模糊,这是因为原始数据还没有被映射到特征空间中。但是可以看出,整体比较亮的图片,获取的信息较多,整体比较暗的图片,却只能看见黑漆漆的一块。

  1. 将降维后矩阵用inverse_transform返回原空间
X_inverse = pca.inverse_transform(X_dr)
fig, ax = plt.subplots(2,10,figsize=(10,2.5)
                       ,subplot_kw={"xticks":[],"yticks":[]}
                       )
#现在我们的ax中是2行10列,第一行是原数据,第二行是inverse_transform后返回的数据
#所以我们需要同时循环两份数据,即一次循环画一列上的两张图,而不是把ax拉平
for i in range(10):
    ax[0,i].imshow(faces.images[i,:,:],cmap="binary_r")
    ax[1,i].imshow(X_inverse[i].reshape(62,47),cmap="binary_r")

在这里插入图片描述可以看得并不能完全复原,降维不是完全可逆的。

  1. 小结

在这里插入图片描述


PCA对手写数字数据集的降维

  1. 导入库
from sklearn.decomposition import PCA  # pca降维
from sklearn.ensemble import RandomForestClassifier as RFC  # 随机森林
from sklearn.model_selection import cross_val_score # 交叉验证
import matplotlib.pyplot as plt # 画图
import pandas as pd 
import numpy as np
  1. 数据处理
data = pd.read_csv("./digit recognizor.csv")
X = data.iloc[:,1:]
y = data.iloc[:,0]
X.shape

在这里插入图片描述784维数据

  1. 画累计方差贡献率曲线,找最佳降维后维度的范围
pca_line = PCA().fit(X) 
plt.figure(figsize=[20,5])
plt.plot(np.cumsum(pca_line.explained_variance_ratio_))
plt.xlabel("number of components after dimension reduction")
plt.ylabel("cumulative explained variance ratio")
plt.show()

在这里插入图片描述转折点在100前面,缩小范围,重新画学习曲线:

score = []
for i in range(1,101,10):
    X_dr = PCA(i).fit_transform(X)
    once = cross_val_score(RFC(n_estimators=10,random_state=0)
                           ,X_dr,y,cv=5).mean()
    score.append(once)
plt.figure(figsize=[20,5])
plt.plot(range(1,101,10),score)
plt.show()

在这里插入图片描述20很明显的一个转折点,再次缩小范围:

score = []
for i in range(10, 25):
    X_dr = PCA(i).fit_transform(X)
    once = cross_val_score(RFC(n_estimators=10,random_state=0)
                           ,X_dr,y,cv=5).mean()
    score.append(once)
plt.figure(figsize=[20,5])
plt.plot(range(10, 25),score)
plt.show()

在这里插入图片描述最佳点:21

验证:

X_dr = PCA(21).fit_transform(X)
cross_val_score(RFC(n_estimators=10,random_state=0),X_dr,y,cv=5).mean()

可以再调一调n_estimators

cross_val_score(RFC(n_estimators=100,random_state=0),X_dr,y,cv=5).mean()

也可以试试其他模型:KNN

from sklearn.neighbors import KNeighborsClassifier as KNN
cross_val_score(KNN(),X_dr,y,cv=5).mean()

在这里插入图片描述可以看到,由原来的七百多维降到21维后,准确率还能有90%多,效果非常不错,最高的达96%。


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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

计算机毕业设计 基于协同过滤算法的白酒销售系统的设计与实现 Javaweb项目 Java实战项目 前后端分离 文档报告 代码讲解 安装调试

🍊作者:计算机编程-吉哥 🍊简介:专业从事JavaWeb程序开发,微信小程序开发,定制化项目、 源码、代码讲解、文档撰写、ppt制作。做自己喜欢的事,生活就是快乐的。 🍊心愿:点…

线性表的插入、删除和查询操作

线性表的插入、删除和查询操作 1、定义线性表 定义一个线性结构&#xff0c;有列表默认长度设置为50&#xff0c;列表数量 #include <stdio.h> #define MaxSize 50typedef int Element; typedef struct{Element data[MaxSize];int length; }SqList;2、顺序表插入 插入…

【算法训练-排序算法 一】【手撕排序】快速排序、堆排序、归并排序

废话不多说&#xff0c;喊一句号子鼓励自己&#xff1a;程序员永不失业&#xff0c;程序员走向架构&#xff01;本篇Blog的主题是【手撕排序系列】&#xff0c;使用【数组】这个基本的数据结构来实现&#xff0c;这个高频题的站点是&#xff1a;CodeTop&#xff0c;筛选条件为&…

PCL点云处理之配准中的匹配对连线可视化显示 Correspondences(二百一十九)

PCL点云处理之配准中的匹配对连线可视化显示 Correspondences(二百一十九) 一、算法介绍二、算法实现1.可视化代码2.完整代码(特征匹配+可视化)最终效果一、算法介绍 关于点云配准中的匹配对,如果能够可视化将极大提高实验的准确性,还好PCL提供了这样的可视化工具,做法…

【Java零基础入门到就业】第一天:java简介和cmd窗口的一些常见命令

1、java简介 Java是一种基于类的、面向对象的编程语言&#xff0c;它被设计成具有尽可能少的实现依赖。它旨在让应用程序开发人员编写一次&#xff0c;并在任何地方运行(WORA)&#xff0c;这意味着编译后的Java代码可以在所有支持Java的平台上运行&#xff0c;而无需重新编译。…

pikachu靶场搭建及通关

一、靶场搭建 下载工具&#xff1a;phpstudy Pikachu靶机下载地址&#xff1a; https://github.com/zhuifengshaonianhanlu/pikachu 下载后解压缩并放入如下文件夹&#xff08;网站根目录&#xff09; 建议修改文件名称为 pikachu 修改配置文件&#xff08;mysql 用户名&…

ORA-00600: internal error code, arguments

通过rman将11g异机升级到19c时&#xff0c;应用归档时报错&#xff0c;报错如下 RMAN> recover database ; Starting recover at 2023-10-15 21:10:02 allocated channel: ORA_DISK_1 channel ORA_DISK_1: SID5776 device typeDISK starting media recovery media recove…

在vs code中创建一个名为 “django_env“ 的虚拟环境报错?!以下方法可以解决

# vs code 终端窗口中运行&#xff1a; mkvirtualenv django_env # 拓展&#xff1a; mkvirtualenv django_env 是一个命令&#xff0c;用于创建一个名为 "django_env" 的虚拟环境。虚拟环境是一种用于隔离不同Python项目所需依赖的工具。通过创建虚拟环境&#x…

在pycharm中运行js文件,附加node.js下载步骤

文章目录 一、前言二、node.js安装和配置(如果之前就安装好了可以直接跳过)1、进入官网下载安装包2、在本地安装node.js3、环境配置4、验证是否安装成功5、修改下载位置(默认是在c盘&#xff0c;这个根据个人需求)6、设置默认模块包7、测试一下是否修改成功(要进入管理员模式的…

YOLOv5网络结构图

网络结构图&#xff08;简易版和详细版&#xff09; 网络框架介绍 前言&#xff1a; YOLOv5是一种基于轻量级卷积神经网络&#xff08;CNN&#xff09;的目标检测算法&#xff0c;整体可以分为三个部分&#xff0c; backbone&#xff0c;neck&#xff0c;head。 如上图所示…

测试左移右移-理论篇

目录 前言一、浅解左移1.什么是测试左移&#xff1f;1.1对产品1.2对开发1.3对测试1.4对运维 二、浅解右移1.1对产品1.2对开发1.3对测试1.4对运维 三、总结 前言 测试左移右移&#xff0c;很多人说能让测试更拥有主动权&#xff0c;展示出测试岗位也是有很大的价值&#xff0c;…

分享一个制作AI视频的好工具

点击上方“Python爬虫与数据挖掘”&#xff0c;进行关注 回复“书籍”即可获赠Python从入门到进阶共10本电子书 今 日 鸡 汤 同行十二年&#xff0c;不知木兰是女郎。 前几天在【AI破局俱乐部】看到了【元峰】老师的分享&#xff0c;干货满满&#xff0c;这个分享是关于数字人的…

动态规划算法(3)--0-1背包、石子合并、数字三角形

目录 一、0-1背包 1、概述 2、暴力枚举法 3、动态规划 二、石子合并问题 1、概述 2、动态规划 3、环形石子怎么办&#xff1f; 三、数字三角形问题 1、概述 2、递归 3、线性规划 四、租用游艇问题 一、0-1背包 1、概述 0-1背包&#xff1a;给定多种物品和一个固定…

OpenCV完美实现两张图片的全景拼接(详细教程)

目录 1&#xff0c;主要步骤 1.1 导入需要的包和模块&#xff0c;并读取两张待拼接的图片&#xff0c;这里我们假设它们为 left.jpg 和 right.jpg。 1.2 创建SIFT检测器 1.3 创建一个基于 FLANN 的匹配器 1.4 筛选过程删除掉一些不合适的匹配点&#xff0c;只保留最好的…

[Spring] SpringMVC 简介(三)

目录 九、SpringMVC 中的 AJAX 请求 1、简单示例 2、RequestBody&#xff08;重点关注“赋值形式”&#xff09; 3、ResponseBody&#xff08;经常用&#xff09; 4、为什么不用手动接收 JSON 字符串、转换 JSON 字符串 5、RestController 十、文件上传与下载 1、Respo…

03_51单片机点亮LED灯

51单片机是一种非常常见的单片机型号&#xff0c;广泛应用于各种嵌入式系统和电子设备中。LED灯是一种常见的输出设备&#xff0c;用于显示信息或指示状态。下面是关于51单片机控制LED灯的介绍&#xff1a; 1. 连接LED灯&#xff1a;将LED的正极连接到51单片机的一个I/O引脚&a…

英语——歌曲篇——All Out Of Love

All Out Of Love [Air Supply失落的爱] 歌词 I’m lying alone with my head on the phone Thinking of you till it hurts I know you hurt too but what else can we do Tormented and torn apart I wish I could carry your smile in my heart For times when my life se…

MacOS ventura跳过配置锁

Macbook pro 2021跳配置锁 1.什么是配置锁&#xff1f; 配置锁顾名思义就是美国一些企业和公司向苹果工公司定制采购的机器&#xff0c;这些机器一般供应内部员工使用&#xff0c;这种机器和正常机没有什么区别&#xff0c;也是无锁三网机器&#xff0c;功能和正常机器一摸一…

去雨去雪去雾算法本地实验速度对比

在进行去雨去雪去雾算法的实验过程中&#xff0c;博主使用自己的电脑进行实验&#xff0c;尽管能够成功运行&#xff0c;但速度却属实不尽人意&#xff0c;博主的笔记本显卡是GTX960&#xff0c;显存为4G&#xff0c;在进行实验的过程中&#xff0c;batch-size只能设置为3&…

找不到mfc140u.dll,无法继续执行代码 cdr

在计算机系统中&#xff0c;DLL文件&#xff08;动态链接库&#xff09;是一种非常重要的资源。它们包含了许多可以在程序运行时被调用的代码和数据。然而&#xff0c;当某个特定的DLL文件丢失或损坏时&#xff0c;可能会导致程序无法正常运行。本文将详细介绍五个解决mfc140u.…