- 如果填数字,代表我们降维之后需要保留的维度,即降维后要保留的特征数量。
- 输入的范围在[0.mim(X.shape)],即小于 特征数量和样本数量的最小值
- 累积可解释性方差贡献率曲线可以帮助我们选择合适的n_components
实践:鸢尾花数据集降维可视化
from sklearn.datasets import load_iris
from sklearn.decomposition import PCA
import matplotlib.pyplot as pl
import numpy as np
iris=load_iris()
y=iris.target
X=iris.data
y.shape
(150,)
X.shape
(150, 4)
#降维
pca=PCA(n_components=2)
pca=pca.fit(X)
X_dr=pca.transform(X)
#可视化
colors=['red','black','orange']
plt.figure()
for i in range(3):
plt.scatter(X_dr[y==i,0],
X_dr[y==i,1],
alpha=0.7,
c=colors[i]
,label=iris.target_names[i])
plt.legend()
plt.title('PCA of IRIS dataset')
plt.show()
以下代码中涉及到PCA的两个重要属性:
pca.explained_variance_
#array([4.22824171, 0.24267075])
pca.explained_variance_ratio_
#array([0.92461872, 0.05306648])
pca.explained_variance_ratio_.sum()
#0.9776852063187949
# 累积可解释方差贡献率
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.ylabel("cumulative explained variance ratio")
plt.xlabel("number of components after dimension reduction")
plt.show()
#最大似然估计选择超参数,
pca_mle=PCA(n_components="mle")
pca_mle=pca_mle.fit(X)
X_mle=pca_mle.transform(X)
pca_mle.explained_variance_ratio_.sum()
#0.9947878161267246
n_components中输入浮点数,代表降维到 满足该浮点数信息量的程度即可。
#按信息量占比选择超参数
pca_f=PCA(n_components=0.97,svd_solver='full')
#当n_components的含义为信息量占比时,必须让参数svd_solver="full"
pca_f=pca_f.fit(X)
X_f=pca_f.transform(X)
pca_f.explained_variance_ratio_
#array([0.92461872, 0.05306648])
参数svd_solver是在降维过程中,用来控制矩阵分解的一些细节的参数。有四种模式可选:“auto”, “full”, “arpack”,
“randomized”,默认”auto"。 在实践时,一般用"auto",当计算不出来时,用"randomized"。
“auto”:简单来说就是,数据量小时,用"full"策略;数据量大时,用"randomized"策略
基于X.shape和n_components的默认策略来选择分解器:如果输入数据的尺寸大于500x500且要提
取的特征数小于数据最小维度min(X.shape)的80%,就启用效率更高的”randomized“方法。否则,精确完整
的SVD将被计算,截断将会在矩阵被分解完成后有选择地发生
“full”:适合于数据量适中的情况
从scipy.linalg.svd中调用标准的LAPACK分解器来生成精确完整的SVD,适合数据量比较适中,计算时
间充足的情况,生成的精确完整的SVD的结构为:
“arpack”:适用于特征矩阵为稀疏矩阵的情况,即特征矩阵中为0的元素比非0的元素多得多
“randomized”:适合特征矩阵巨大,计算量庞大的情况
在参数svd_solver的值为"arpack"或"randomized"的时候生效,可以控制这两种SVD模式中的随机模式,通常我们选用“auto”,不必对这个参数纠结太多。
在n维特征矩降维的过程中
- 输入原数据,结构为(m, n),找出原本的n个特征向量构成的n维空间V
- 决定降维后的特征数量: k,
- 通过某种变化,找出n个新的特征向量,以及它们构成的新n维空间V
- 找出原始数据在新特征空间V中的n个新特征向量上对应的值,即**“将数据映射到新空间中”**
- 选取前k个信息量最大的特征,删掉没有被选中的特征,成功将n维空间V降为k维
根据以上的降维过程,参数components_中保存的就是降维后的特征向量V(k,n),这里我们用图像数据来可视化解读V(k.n)
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(min_faces_per_person=60)
faces.images.shape#(1348, 62, 47)
#1348是图像的个数,相当于每一个样本,只是图像特征有两个维度,
#data中2914=62*47
faces.data.shape#(1348, 2914)
X=faces.data
fig,axes=plt.subplots(3,8
,figsize=(8,4)
,subplot_kw={"xticks":[],"yticks":[]})#不显示坐标轴
# fig#生成一张纸
# axes.shape#一个个子图对象
for i,ax in enumerate(axes.flat):
ax.imshow(faces.images[i,:,:]
,cmap="gray"
)
#建模降维
pca=PCA(150).fit(X)
v=pca.components_
v.shape#(150, 2914)
fig,axes=plt.subplots(3,8
,figsize=(8,4)
,subplot_kw={"xticks":[],"yticks":[]})#不显示坐标轴
# fig#生成一张纸
# axes.shape#一个个子图对象
for i,ax in enumerate(axes.flat):
ax.imshow(v[i,:].reshape(62,47)
,cmap="gray"
)
可以发现,新特征空间可视化后的人脸非常模糊。大部分是和五官和亮度相关的向量,说明PCA能够将原始数据集中重要的数据进行聚集。
代码见n_components讲解部分的实践
代码见n_components讲解部分的实践
fit transform fit_transform三个较为熟悉,不多赘述
pca=PCA(150)
X_dr=pca.fit_transform(X)
X_dr.shape#(1348, 150)
X_inverse=pca.inverse_transform(X_dr)
X_inverse.shape#(1348, 2914)
fig,ax=plt.subplots(2,10,figsize=(10,2.5)
,subplot_kw={"xticks":[],"yticks":[]})
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")
#PCA做噪声过滤
from sklearn.datasets import load_digits
from sklearn.decomposition import PCA
import matplotlib.pyplot as plt
import numpy as np
digits=load_digits()
digits.data.shape#(1797, 64)
#定义作图函数
def 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")
plot_digits(digits.data)#原始数据
# 为数据加上噪音
np.random.RandomState(42)
noisy=np.random.normal(digits.data,2)
plot_digits(noisy)#加上噪音后的“原始数据”
#降维
pca=PCA(0.5).fit(noisy)
# pca.explained_variance_ratio_.sum()
X_dr=pca.transform(noisy)
X_dr.shape#(1797, 6)
noisy_inverse=pca.inverse_transform(X_dr)
plot_digits(noisy_inverse)#利用inverse_transform升维除噪后的数据
注:本文内容是本人在学习“菜菜的机器学习课程”过程中的记录、总结和整理,将重点部分整理出来的笔记。此文更侧重用法与实践,关于PCA和SVD、降维原理内容等理论知识没有过多整理。侵删