机器学习sklearn-降维算法

目录

1.PCA(主成分分析)

1.1 参数

2 PCA中的SVD

2.1 人脸识别中属性components_的运用

2.2 用PCA做噪音过滤


1.PCA(主成分分析)

PCA常用于高维数据的降维,可用于提取数据的主要特征分量。 在降维中,PCA 使用的信息量衡量指标,就是样本方差,又称可解释性方 差,方差越大,特征所带的信息量越多

机器学习sklearn-降维算法_第1张图片

Var 代表一个特征的方差, n 代表样本量, xi 代表一个特征中的每个样本取值, xhat 代表这一列样本的均值。

 机器学习sklearn-降维算法_第2张图片

在数学原理中,无论是 PCA SVD 都需要遍历所有的特征和样本来计算信息量指标。并且在矩阵分解的过程之中,会产生比原来的特征矩阵更大的矩阵,比如原数据的结构是(m,n) ,在矩阵分解中为了找出最佳新特征空间 V ,可能需要产生(n,n) (m,m) 大小的矩阵,还需要产生协方差矩阵去计算更多的信息。而现在无论是 Python 还是 R ,或者其他的任何语言,在大型矩阵运算上都不是特别擅长,无论代码如何简化,我们不可避免地要等待计算机去完成这个非常庞大的数学计算过程。因此,降维算法的计算量很大,运行比较缓慢,但无论如何,它们的功能无可替代,它们依然是机器学习领域的宠儿。
特征选择是从已存在的特征中选取携带信息最多的,选完之后的特征依然具有可解释性,我们依然知道这个特征在原数据的哪个位置,代表着原数据上的什么含义。
PCA ,是将已存在的特征进行压缩,降维完毕后的特征不是原本的特征矩阵中的任何一个特征,而是通过某些方式组合起来的新特征。通常来说,在新的特征矩阵生成之前,我们无法知晓 PCA 都建立了怎样的新特征向 量,新特征矩阵生成之后也不具有可读性 ,我们无法判断新特征矩阵的特征是从原数据中的什么特征组合而来,新特征虽然带有原始数据的信息,却已经不是原数据上代表着的含义了。以PCA 为代表的降维算法因此是特征创造(feature creation ,或 feature construction )的一种。

1.1 参数

n_components
n_components 是我们降维后需要的维度,即降维后需要保留的特征数量,降维流程中第二步里需要确认的 k 值,一般输入[0, min(X.shape)] 范围中的整数。一说到 K ,大家可能都会想到,类似于 KNN 中的 K 和随机森林中的n_estimators,这是一个需要我们人为去确认的超参数,并且我们设定的数字会影响到模型的表现。如果留下的特征太多,就达不到降维的效果,如果留下的特征太少,那新特征向量可能无法容纳原始数据集中的大部分信息,因此,n_components 既不能太大也不能太小。
对鸢尾花数据进行可视化。鸢尾花数据集原始存在4个特征,降维为2为进行可视化显示。
机器学习sklearn-降维算法_第3张图片
明显这是一个分簇的分布,并且每个簇之间的分布相对比较明显,也许versicolor和 virginia 这两种花之间会有一些分类错误,但 setosa 肯定不会被分错。这样的数据很容易分类,可以遇
见, KNN ,随机森林,神经网络,朴素贝叶斯, Adaboost 这些分类器在鸢尾花数据集上,未调整的时候都可以有95%上下的准确率。
from sklearn.decomposition import PCA #导入PCA
import matplotlib.pyplot as plt
import numpy as np
import pandas as pd
from sklearn.datasets import load_iris#导入鸢尾花数据集

iris=load_iris()
y=iris.target#标签
x=iris.data #数据
x=pd.DataFrame(x) #转换为dataframe方便处理

#pca建模
pca=PCA(n_components=2) #将4维降低为二维
x_dr=pca.fit_transform(x) #进行矩阵降维 demission reduction
# print(x_dr.shape)

#可视化
# print(iris.target_names)
colors = ['red', 'black', 'orange']
plt.figure(figsize=(20,8),dpi=80)
for i in range(3):
    #鸢尾花总共有三种类别  x_dr[y==i,0]表示取第i种鸢尾花的第一个特征 x_dr[y==i1]表示取第i种鸢尾花的第二个特征
    plt.scatter(x_dr[y==i,0],x_dr[y==i,1],c=colors[i],alpha=0.8,label=iris.target_names[i])

plt.xlabel('feature1')
plt.ylabel('feature2')
plt.legend(loc='best')
plt.title('PCA of IRIS dataset')
plt.show()



通过属性explained_variance_查看PCA降维以后每个特征所带信息量大小(可解释性方差)。

通过属性explained_variance_ratio,查看降维后每个新特征向量所占的信息量占原始数据总信息量的百分比,又叫做可解释方差贡献率。

可以发现大部分信息都被有效地集中在了第一个特征上 。

除了输入整数, n_components 还有哪些选择呢?Minka, T.P.在麻省理工学院媒体实验室做研究时找出了让 PCA 用最大似然估计 (maximum likelihood estimation)自选超参数的方法,输入 “mle” 作为 n_components 的参数输入,就可以调用这种方法。
按信息量占比选超参数
输入 [0,1] 之间的浮点数,并且让参数 svd_solver =='full' ,表示希望降维后的总解释性方差占比大于 n_components 指定的百分比,即是说,希望保留百分之多少的信息量。比如说,如果我们希望保留97% 的信息量,就可以输入n_components = 0.97, PCA 会自动选出能够让保留的信息量超过 97% 的特征数量。

2 PCA中的SVD

svd_solver 是奇异值分解器的意思,为什么 PCA 算法下面会有有关奇异值分解的参数?不是两种算法么?我们之前曾经提到过,PCA SVD 涉及了大量的矩阵计算,两者都是运算量很大的模型,但
其实, SVD 有一种惊人的数学性质,即是 它可以跳过数学神秘的宇宙,不计算协方差矩阵,直接找出一个新特征向 量组成的 n 维空间 ,而这个 n 维空间就是奇异值分解后的右矩阵V的转置。
简而言之, SVD 在矩阵分解中的过程比 PCA 简单快速,虽然两个算法都走一样的分解流程,但 SVD 可以作弊耍赖直接算出V 。但是遗憾的是, SVD 的信息量衡量指标比较复杂,要理解 奇异值 远不如理解 方差 来得容易,因此,sklearn将降维流程拆成了两部分:一部分是计算特征空间 V ,由奇异值分解完成,另一部分是映射数据和求解新特征矩阵,由主成分分析完成,实现了用SVD 的性质减少计算量,却让信息量的评估指标是方差。
通过 SVD PCA 的合作,sklearn实现了一种计算更快更简单,但效果却很好的 合作降维 。很多人理解 SVD ,是把 SVD 当作 PCA 的一种求解方法,其实指的就是在矩阵分解时不使用PCA 本身的特征值分解,而使用奇异值分解来减少计算量。这种方法确实存在,但在sklearn 中,矩阵 U Σ 虽然会被计算出来(同样也是一种比起 PCA 来说简化非常多的数学过程,不产生协方差矩阵),但完全不会被用到,也无法调取查看或者使用,因此我们可以认为,U Σ fifit 过后就被遗弃了。奇
异值分解追求的仅仅是 V ,只要有了 V ,就可以计算出降维后的特征矩阵。在 transform 过程之后, fifit 中奇异值分解的结果除了V(k,n) 以外,就会被舍弃,而 V(k,n) 会被保存在属性 components_ 当中,可以调用查看。
在矩阵分解时, PCA 是有目标的:在原有特征的基础上,找出能够让信息尽量聚集的新特征向量。在sklearn使用的 PCA SVD 联合的降维方法中,这些新特征向量组成的新特征空间其实就是 V(k,n) 。当 V(k,n) 是数字时,我们无法判断V(k,n) 和原有的特征究竟有着怎样千丝万缕的数学联系。但是,如果原特征矩阵是图像, V(k,n) 这个空间矩阵也可以被可视化的话,我们就可以通过两张图来比较,就可以看出新特征空间究竟从原始数据里提取了什么重要的信息。

2.1 人脸识别中属性components_的运用

机器学习sklearn-降维算法_第4张图片

机器学习sklearn-降维算法_第5张图片 

比起降维前的数据,新特征空间可视化后的人脸非常模糊,这是因为原始数据还没有被映射到特征空间中。但是可以看出,整体比较亮的图片,获取的信息较多,整体比较暗的图片,却只能看见黑漆漆的一块。在比较亮的图片中,眼睛,鼻子,嘴巴,都相对清晰,脸的轮廓,头发之类的比较模糊。

这说明,新特征空间里的特征向量们,大部分是 " 五官 " " 亮度 " 相关的向量,所以新特征向量上的信息肯定大部分是由原数据中和" 五官 " " 亮度 " 相关的特征中提取出来的。到这里,我们通过可视化新特征空间 V ,解释了一部分降维后的特征:虽然显示出来的数字看着不知所云,但画出来的图表示,这些特征是和” 五官 以及 亮度 有关的。这也再次证明了,PCA 能够将原始数据集中重要的数据进行聚集。
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) #每个人需要60张脸图

#查看数据
# print(faces)
# print(faces.images.shape)#3维数据 1348:图像数量 ;62:每个图片的行;47:列

X=faces.data

#可视化 图像数据和数字数据可视化的方式不一样 图像第一个维度是图像个数
#fig 生成的画布; axes子图对象 后期就针对对象进行操作 
# fig, axes = plt.subplots(3,8,figsize=(20,8),dpi=80,
#                                         subplot_kw={'xticks':[],'yticks':[]})#不显示坐标轴 
# #利用枚举同时遍历数字和对象
# for i,ax in enumerate(axes.flat):
#     ax.imshow(faces.images[i,:,:],cmap='gray')

#PCA降维 提取新的特征矩阵V 以图片形式查看
pca=PCA(300).fit(X) #降维到300未
V=pca.components_
print(V.shape)
fig, axes = plt.subplots(3,8,figsize=(20,8),dpi=80,subplot_kw = {"xticks":[],"yticks":[]})
for i, ax in enumerate(axes.flat):
    ax.imshow(V[i,:].reshape(62,47),cmap="gray") #将降维以后图片还原为原本大小

plt.show()

2.2 用PCA做噪音过滤

原始数据

机器学习sklearn-降维算法_第6张图片

 加上噪声后的机器学习sklearn-降维算法_第7张图片

降噪后

机器学习sklearn-降维算法_第8张图片 

from string import digits
from sklearn.datasets import load_digits
from sklearn.decomposition import PCA
import matplotlib.pyplot as plt
import numpy as np

digits=load_digits()
# print(digits)

#手写数字绘图函数
def plot_digits(data):
    fig, axes = plt.subplots(4,10,figsize=(20,8),dpi=80,subplot_kw = {"xticks":[],"yticks":[]})
    for i,ax in enumerate(axes.flat):
        ax.imshow(data[i].reshape(8,8),cmap="binary")

#给数据加上噪声
np.random.RandomState(40)
#两个参数,分别是指定的数据集,和抽取出来的正太分布的方差 方差越大 抽取出来的数据越混乱
nosiy=np.random.normal(digits.data,2)#在指定的数据集中,随机抽取服从正态分布的数据    

#降维
pca=PCA(0.5).fit(nosiy) #去掉一半特征
X_dr=pca.transform(nosiy)
#逆转降噪结果 实现降噪
without_nosiy=pca.inverse_transform(X_dr)
plot_digits(without_nosiy)

# plot_digits(digits.data)
# plot_digits(nosiy)


plt.show()

 

 

你可能感兴趣的:(sklearn,机器学习,算法)