文章目录

  • 1、sklearn中的降维算法
    • (1)PCA
    • (2)SVD
    • (3)思考
  • 2、重要参数n_components
  • 3、PCA中的SVD
  • 4、重要接口inverse_transform
  • 5、重要接口,参数和属性总结
  • 6、案例:PCA对手写数字数据集的降维

1、sklearn中的降维算法

PCA使用的信息量衡量指标,就是样本方差,又称可解释性方 差,方差越大,特征所带的信息量越多。

(1)PCA

我们希望能够找出一种办法来帮助我们衡量特征上所带的信息量,让我们在降维的过程中,能够即减少特征的数量,又保留大部分有效信息——将那些带有重复信息的特征合并,并删除那些带无效信息的特征等等——逐渐创造出能够代表原特征矩阵大部分信息的,特征更少的,新特征矩阵。因此,在降维中,PCA使用的信息量衡量指标,就是样本方差,又称可解释性方差,方差越大,特征所带的信息量越多。


有空可以补充一下这个知识点



将为过程的主要步骤如下:

(2)SVD

(3)思考

PCA和特征选择技术都是特征工程的一部分,它们有什么不同?

特征工程中有三种方式:特征提取,特征创造和特征选择。仔细观察上面的降维例子和上周我们讲解过的特征 选择,你发现有什么不同了吗?

特征选择是从已存在的特征中选取携带信息最多的,选完之后的特征依然具有可解释性,我们依然知道这个特 征在原数据的哪个位置,代表着原数据上的什么含义。

而PCA,是将已存在的特征进行压缩,降维完毕后的特征不是原本的特征矩阵中的任何一个特征,而是通过某 些方式组合起来的新特征。通常来说,在新的特征矩阵生成之前,我们无法知晓PCA都建立了怎样的新特征向 量,新特征矩阵生成之后也不具有可读性,我们无法判断新特征矩阵的特征是从原数据中的什么特征组合而 来,新特征虽然带有原始数据的信息,却已经不是原数据上代表着的含义了。以PCA为代表的降维算法因此是 特征创造(feature creation,或feature construction)的一种。

可以想见,PCA一般不适用于探索特征和标签之间的关系的模型(如线性回归),因为无法解释的新特征和标 签之间的关系不具有意义。在线性回归模型中,我们使用特征选择。

2、重要参数n_components

n_components是我们降维后需要的维度,即降维后需要保留的特征数量,降维流程中第二步里需要确认的k值, 一般输入[0, min(X.shape)]范围中的整数。K是一个需要我们人为去确认的超参数,并且我们设定的数字会影响到模型的表现。就达不到降维的效果,如果留下的特征太少,那新特征向量可能无法容纳原始数据集中的大部分信息,因此,n_components既不能太大也不能太小。那怎么办呢?

可以先从我们的降维目标说起:如果我们希望可视化一组数据来观察数据分布,我们往往将数据降到三维以下,很 多时候是二维,即n_components的取值为2。

迷你实例(鸢尾花降维可视化)

from sklearn.decomposition import PCA
from matplotlib import pyplot as plt
from sklearn.datasets import load_iris
import pandas as pd
import numpy as npiris = load_iris()
#print(iris)x = iris.data
y = iris.target
#print(x)
#print(y)
#print(pd.DataFrame(x))
#可以了解到鸢尾花数据集一共有4个特征pca = PCA(n_components=2) #实例化
pca = pca.fit(x)          #弥合模型
result = pca.transform(x) #获取新矩阵
#print(result)   #新矩阵只有两个特征值x_dr = PCA(n_components=2).fit_transform(x)
#print(x_dr)    #这两种方法结果是一样的#可视化,将三种鸢尾花的数据分布显示在二维平面坐标系中,对应的两个字符欧标应该是三种鸢尾花降维之后的坐标位置
#选取每一个种类的特征值
#print(x_dr[y == 0, 0]) #选取标签为1的第一列值,第二列也是一个意思的
plt.figure()
plt.scatter(x_dr[y == 0, 0], x_dr[y == 0, 1], color='red', label=iris.target_names[0])
plt.scatter(x_dr[y == 1, 0], x_dr[y == 1, 1], color='black', label=iris.target_names[1])
plt.scatter(x_dr[y == 2, 0], x_dr[y == 2, 1], color='orange', label=iris.target_names[2])
plt.title('pca of IRIS dataset')
plt.legend()
plt.show()#这两种方法效果是一样的,一个不写循环,一个写循环
colors = ['red', 'black', 'yellow']
for i in range(3):plt.scatter(x_dr[y == i, 0], x_dr[y == i, 1], alpha=0.7, color=colors[i],label=iris.target_names[i])plt.legend()
plt.title('PCA of IRIS dataset')
plt.show()

#探索降维后的数据
print(pca.explained_variance_ )
#查看降维后每个特征向量上所带的信息大小(可解释方差的大小)
#[4.22824171 0.24267075]  #就是每个新特征的方差值print(pca.explained_variance_ratio_)  #查看降维后每个新特征向量所占的信息量占原始数据总信息量的百分比
#[0.92461872 0.05306648]print(pca.explained_variance_ratio_.sum())
#0.9776852063187949
pca_line = PCA().fit(x)  #当不填写n_compents的时候,会计算每个特征向量的贡献值
plt.plot([1, 2, 3, 4], np.cumsum(pca_line.explained_variance_ratio_))  #np.cumsum将每个特征信息比例进行累加
plt.xticks([1, 2, 3, 4])  #这是为了限制坐标轴显示为整数
plt.xlabel('number of components after dimension reduction')
plt.ylabel('cumulative explained variance ratio')
plt.show()


最大似然估计自选超参数

pca = PCA(n_components='mle')
#让pca进行选择降维到几维
pca_mle = pca.fit(x)
x_mle = pca_mle.transform(x)

按信息量占比选超参数

pca_f = PCA(n_components=0.97, svd_solver='full')
pca_f.fit(x)
x_f = pca_f.transform(x)
#print(x_f)print(pca_f.explained_variance_ratio_)
#[0.92461872 0.05306648]

3、PCA中的SVD



重要参数svd_solver 与 random_state

参数svd_solver是在降维过程中,用来控制矩阵分解的一些细节的参数。有四种模式可选:“auto”, “full”, “arpack”,“randomized”,默认”auto"。

“auto”:基于X.shape和n_components的默认策略来选择分解器:如果输入数据的尺寸大于500x500且要提 取的特征数小于数据最小维度min(X.shape)的80%,就启用效率更高的”randomized“方法。否则,精确完整 的SVD将被计算,截断将会在矩阵被分解完成后有选择地发生。

“full”:从scipy.linalg.svd中调用标准的LAPACK分解器来生成精确完整的SVD,适合数据量比较适中,计算时 间充足的情况,生成的精确完整的SVD的结构为:

“arpack”:从scipy.sparse.linalg.svds调用ARPACK分解器来运行截断奇异值分解(SVD truncated),分解时就将特征数量降到n_components中输入的数值k,可以加快运算速度,适合特征矩阵很大的时候,但一般用于 特征矩阵为稀疏矩阵的情况,此过程包含一定的随机性。截断后的SVD分解出的结构为:

“randomized”,通过Halko等人的随机方法进行随机SVD。在"full"方法中,分解器会根据原始数据和输入的 n_components值去计算和寻找符合需求的新特征向量,但是在"randomized"方法中,分解器会先生成多个随机向量,然后一一去检测这些随机向量中是否有任何一个符合我们的分解需求,如果符合,就保留这个随 机向量,并基于这个随机向量来构建后续的向量空间。这个方法已经被Halko等人证明,比"full"模式下计算快 很多,并且还能够保证模型运行效果。适合特征矩阵巨大,计算量庞大的情况。

重要属性components_
通常来说,在新的特征矩阵生成之前,我们无法知晓PCA都建立了怎样的新特征向量,新 特征矩阵生成之后也不具有可读性,我们无法判断新特征矩阵的特征是从原数据中的什么特征组合而来,新特征虽 然带有原始数据的信息,却已经不是原数据上代表着的含义了。

但是其实,在矩阵分解时,PCA是有目标的:在原有特征的基础上,找出能够让信息尽量聚集的新特征向量。

如果原特征矩阵是图像,V(k,n)这 个空间矩阵也可以被可视化的话,我们就可以通过两张图来比较,就可以看出新特征空间究竟从原始数据里提取了什么重要的信息。

人脸识别案例

from sklearn.decomposition import PCA
from sklearn.datasets import fetch_lfw_people
from matplotlib import pyplot as plt
import numpy as np
import pandas as pdfaces = fetch_lfw_people(min_faces_per_person=60)  #实例化
#print(faces.images.shape)  #(1348, 62, 47)
#print(faces.data.shape)  #(1348, 2914)  2914 = 62 * 47
x = faces.data #设置特征矩阵#画图,将原特征矩阵进行可视化
fig, axes = plt.subplots(4, 5, figsize=(8, 4), subplot_kw={'xticks': [], 'yticks': []}) #不要显示坐标轴
#print(fig)
#print(axes) ##不难发现,axes中的一个对象对应fig中的一个空格
#print(axes.shape)  #(4, 5) 四行五列图片#二维结构,可以有两种循环方式,一种是使用索引,循环一次同时生成一列上的三个图
#另一种是把数据拉成一维,循环一次只生成一个图
#在这里,究竟使用哪一种循环方式,是要看我们要画的图的信息,储存在一个怎样的结构里
#我们使用 子图对象.imshow 来将图像填充到空白画布上
#而imshow要求的数据格式必须是一个(m,n)格式的矩阵,即每个数据都是一张单独的图
#因此我们需要遍历的是faces.images,其结构是(1277, 62, 47)
#要从一个数据集中取出24个图,明显是一次性的循环切片[i,:,:]来得便利
#因此我们要把axes的结构拉成一维来循环#print(enumerate(axes.flat))
#填充图像
for i, ax in enumerate(axes.flat):ax.imshow(faces.images[i, :, :], cmap='gray')#选择色彩模式
#plt.show()
#print(fig)

#建模降维,提取新特征空间矩阵
pca = PCA(150).fit(x) #将data原来的2914维降到150维
v = pca.components_
#print(v.shape)  #(150, 2914) (新特征维度,原特征维度)#print(v[0, :].reshape(62, 47))
'''
[[-0.00579708 -0.00595363 -0.00615767 ... -0.00813068 -0.00789127-0.00791125][-0.00586497 -0.00604798 -0.00647989 ... -0.00849601 -0.00826257-0.00840366][-0.00622997 -0.00658633 -0.00714348 ... -0.00897475 -0.0085009-0.0089165 ]...[-0.00270353 -0.00276129 -0.00370097 ... -0.01046781 -0.00896865-0.00820496][-0.00298345 -0.003292   -0.00394306 ... -0.01013859 -0.00875235-0.00805416][-0.00329591 -0.00362476 -0.00457148 ... -0.01000113 -0.00901094-0.00813919]]
'''#print(v[0, :]) #取降维后的像素,新的特征将轴进行了变换,我们想看看变换后的图像是什么样的
'''
[-0.00579718 -0.00595365 -0.00615768 ... -0.01000111 -0.00901092-0.00813918]
'''#将新特征空间矩阵可视化
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')
plt.show()


提取的主要特征有光线和眼睛

4、重要接口inverse_transform

from sklearn.datasets import fetch_lfw_people
from sklearn.decomposition import PCA
import numpy as np
import pandas as pd
from matplotlib import pyplot as pltfaces = fetch_lfw_people(min_faces_per_person=60)
x = faces.data
#print(x)
#print(x.shape) #(1348, 2914)pca = PCA(150)
x_dr = pca.fit_transform(x)#print(x_dr)
#print(x_dr.shape)#print(x_dr[0])
x_inverse = pca.inverse_transform(x_dr)
#print(x_inverse)fig, ax = plt.subplots(2, 10, figsize=(10, 2.5), subplot_kw={"xticks": [], "yticks": []})
#plt.show()
#print(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')plt.show()


逆转换之后的图像并没有原来的图像清洗,是因为在经过PVC降维之后去掉了一些噪音,只提取了重要的特征,所以在逆转的过程中并不能逆转已经去掉的信息。

案例:用PCA做噪音过滤

from sklearn.datasets import load_digits
from sklearn.decomposition import PCA
import numpy as np
import pandas as pd
from matplotlib import pyplot as pltdigits = load_digits()
#print(digits)#print(digits.data.shape)#(1797, 64)
#print(digits.images.shape) #(1797, 8, 8)
#print(set(digits.target.tolist())) #{0, 1, 2, 3, 4, 5, 6, 7, 8, 9}
#是一个手写识别分类数据,标签是从0-9def plot_digits(data):fig, axes = plt.subplots(4, 10, figsize=(10, 4), subplot_kw={'xticks': [], 'yticks': []})for i, ax in enumerate(axes.flat):ax.imshow(data[i].reshape(8, 8), cmap="binary")plt.show()plot_digits(digits.data)


给手写数字加噪音,取出一部分服从正太分布的、方差为2的数据

rng = np.random.RandomState(42)
#给原始数据加上噪音digits_noise = rng.normal(digits.data, 2)
#从原始数据集中取出来一个服从正太分布,方差为2的新数据集
#plot_digits(digits_noise)


加了噪音之后非常模糊

利用pca提取使得特征解释率在0.5上的特征即可,经过主要特征的特区进行逆转,逆转之后的图片只体现主要的信息,会稍微清晰一些

pca = PCA(0.5, svd_solver='full').fit(digits_noise)
x_dr = pca.transform(digits_noise)
print(x_dr.shape)  #(1797, 6)x_inverse = pca.inverse_transform(x_dr)
#plot_digits(x_inverse)

5、重要接口,参数和属性总结

6、案例:PCA对手写数字数据集的降维

from sklearn.decomposition import PCA
from sklearn.ensemble import RandomForestClassifier as RFC
from sklearn.neighbors import KNeighborsClassifier as KNN
from sklearn.model_selection import cross_val_score
import matplotlib.pyplot as plt
import numpy as np
import pandas as pd
import timedata = pd.read_csv('digit recognizor.csv')
#print(data.shape)
#print(data.head())
#print(data.info())x = data.iloc[:, 1:] #(42000, 785)
y = data.iloc[:, 0]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()

先通过解释率累加图来寻找一个合理的维度,因为785维实属太高维了!

我们一般拐点处的维度,大概看起来就是在1-101之间

scores = []
#继续缩小最佳维度的范围
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()scores.append(once)
plt.figure(figsize=(10, 8))
plt.plot(range(1, 101, 10), scores)
plt.show()


再次缩小范围

start_time = time.time()
scores = []
#继续缩小最佳维度的范围
for i in range(15, 30):x_dr = PCA(i).fit_transform(x)once = cross_val_score(RFC(n_estimators=10, random_state=0), x_dr, y, cv=5).mean()scores.append(once)
plt.figure(figsize=(10, 8))
plt.plot(range(15, 30), scores)
end_time = time.time()
print(end_time-start_time)
plt.show()


于是,取维度26作为我们降维之后的降维之后的新特征维度,并输入随机森林中

x_dr = PCA(26).fit_transform(x)
score = cross_val_score(RFC(n_estimators=100, random_state=0), x_dr, y, cv=5).mean()
print(score)  #0.9466190476190477

此时,我们想到了KNN比随机森林更适合跑这个数据集,所以我们换一个算法再次验证

x_dr = PCA(26).fit_transform(x)
score_knn = cross_val_score(KNN(), x_dr, y, cv=5).mean()
print(score_knn)  #0.9710238095238095

因为这时的KNN()里面是默认值,所以我们可以寻找一个更好的参数

x_dr = PCA(26).fit_transform(x)
score_1 = []
for i in range(10):once = cross_val_score(KNN(i+1), x_dr, y, cv=5).mean()score_1.append(once)
plt.figure(figsize=(10, 8))
plt.plot(range(10), score_1)
plt.show()


此时,KNN里面的参数取2和4都试试

x_dr = PCA(26).fit_transform(x)
score_knn = cross_val_score(KNN(3), x_dr, y, cv=5).mean()
print(score_knn)  #0.9708571428571429x_dr = PCA(26).fit_transform(x)
score_r = cross_val_score(KNN(5), x_dr, y, cv=5).mean()
print(score_knn)  #0.9708571428571429

发现结果都不如默认的参数,那就还是使用默认参数。

PCA降维算法(内含PCA可视化迷你案例+PCA人脸识别降维案例+PCA逆转降噪案例)相关推荐

  1. python简单的人脸识别系统(PCA+逻辑回归)

    python简单的人脸识别系统(PCA+逻辑回归) 数据集:ORL人脸库 特征提取:PCA降维,将112*92降成30 分类器:逻辑回归 ** 代码: from tkinter import * fr ...

  2. 模式识别作业--人脸识别(python+PCA+pytorch神经网络)

    模式识别作业–人脸识别(python+PCA+pytorch) 1.实验原理 该实验通过PCA降维+BP神经网络的算法实现对人脸数据集中人脸数据的识别 2.实验步骤 1.图片预处理 首先将测试集和训练 ...

  3. 3d人脸识别算法opencv_用Opencv打造自己的人脸识别

    # 用Opencv打造自己的人脸识别 标签: opencv 人脸识别在现在使用的越来越多,所以使用opencv构造一个简单的人脸识别.步骤包括收集及处理数据,构建人脸识别器,进行人脸识别. 收集数据 ...

  4. 【机器学习超详细】机器学习案例之SVM人脸识别技术应用 PCA降维 结果可视化 支持向量机

    基础知识介绍: LFW人脸识别数据集(http://vis-www.cs.umass.edu/lfw/) 该实验可以在JupyterNotebook上运行,也可在其他Python程序上运行.(本人习惯 ...

  5. 【人脸识别】基于PCA+SVM人脸识别(准确率)matlab源码含GUI

    一.简介 1 PCA\ PCA(Principal Component Analysis)是常用的数据分析方法.PCA是通过线性变换,将原始数据变换为一组各维度线性无关的数据表示方法,可用于提取数据的 ...

  6. 【人脸识别】基于PCA和SVM的人脸识别关键技术研究与实现附matlab代码

    1 简介 人脸识别是计算机视觉和图像模式识别领域的一个重要技术.主成分分析(PCA)是人脸图像特征提取的一个重要算法.而支持向量机(SVM)有适合处理小样本问题,高维数及泛化性能强等多方面的优点.文章 ...

  7. 《 Python程序设计项目案例》— 人脸识别考勤可视化分析系统签到打卡记录到Excel表格项目参考代码(课程设计、期末结课大作业、毕业设计)

    声明 本文仅在CSDN发布,其他均为盗版.请支持正版! 正版链接: https://blog.csdn.net/meenr/article/details/107348867 Python课程设计(程 ...

  8. 人脸识别算法_格灵深瞳在人脸识别算法测试(FRVT)中斩获全球第一

    1月6日,美国国家标准与技术研究院(NIST)公布了最新的人脸识别算法测试(FRVT)成果,格灵深瞳再次刷新纪录:在7项测试子任务中,获得2项第一.3项第二,综合排名世界第一的成绩. 过去几个月,很多 ...

  9. 深度学习——Face Verificaton(人脸验证)与Face Recognition(人脸识别)在FaceNet的应用案例

    一.综述 人脸识别领域主要有两个范畴:Face Verificaton(人脸验证)与Face Recognition(人脸识别) 1.Face Verificaton(人脸验证):1:1的匹配问题.如 ...

最新文章

  1. Linq to SQL Dynamic 动态查询
  2. AGV控制器设计与融合
  3. Backbone源码分析-Backbone架构+流程图
  4. VS2010 RTM
  5. C语言关键字 ISO/ANSI C90 C99 C11
  6. 开始使用ASP.NET核心运行状况检查
  7. Java学习——继承和多态
  8. MySQL多表关联查询与存储过程
  9. 老李分享: 全栈工程师? 2
  10. window版GitHub使用
  11. 专业视频压制神器下载——解决会声会影、PR、AE处理视频后过大的问题(三款工具)专业视频压制软件
  12. 嵌入式Linux应用开发
  13. 金融计量学实验报告一
  14. 计算机专业必看电影,IT人士必看的10部电影
  15. 模拟高清和数字高清摄像机的区别,全局快门CMOS 图像传感器,Interline Transfer CCD图像传感器
  16. Sublime安装中文插件
  17. Python导入excel数据
  18. PYQT5 系列(一)——参考自《弗兰克万岁》
  19. Viz-artist常用脚本操作
  20. unpacking of archive failed: cpio: lstat failed - Not a directory

热门文章

  1. 乔磊20155305第二次随笔
  2. 上了这个时代的贼船,就别想活着下去
  3. HBase 在滴滴出行的应用场景和最佳实践
  4. 浅谈开发与研发之差异
  5. 山建大计算机学院,山建大丨历数20年来建大学生作业设计表达的前世今生
  6. Es Bucket聚合(桶聚合) 第一篇(常用桶聚合一览)
  7. vue3+ts使用高德离线地图
  8. Unable to paint on Qt Widget, shows error “paintEngine: Should no longer be called”
  9. 11月24号-11月30号
  10. DevOps生命周期,你想知道的全都在这里了!