小言_互联网的博客

四、Sklearn降维算法 PCA 和 SVD

509人阅读  评论(0)

sklearn中降维算法都被包括在模块decomposition中,这个模块本质是一个矩阵分解模块

在过去的十年中,如果要讨论算法进步的先锋,矩阵分解可以说是独树一帜。

矩阵分解可以用在降维,深度学习,聚类分析,数据预处理,低纬度特征学习,推荐系统,大数据分析等领域。

降维算法中的”降维“,指的是降低特征矩阵中特征的数量。上周的课中我们说过,降维的目的是为了让算法运算更
快,效果更好,但其实还有另一种需求:数据可视化

PCA和SVD是两种不同的降维算法,但他们都遵从上面的过程来实现降维,只是两种算法中矩阵分解的方法不同,信息量的衡量指标不同罢了。PCA使用方差作为信息量的衡量指标,并且特征值分解来找出空间V。降维完成之后,PCA找到的每个新特征向量就叫做“主成分”,而被丢弃的特征向量被认为信息量很少,这些信息很可能就是噪音。

SVD使用奇异值分解来找出空间V,其中Σ也是一个对角矩阵,不过它对角线上的元素是奇异值,这也是SVD中用来衡量特征上的信息量的指标。在数学原理中,无论是PCA和SVD都需要遍历所有的特征和样本来计算信息量指标。并且在矩阵分解的过程之中,会产生比原来的特征矩阵更大的矩阵,比如原数据的结构是(m,n),在矩阵分解中为了找出最佳新特征空间V,可能需要产生(n,n),(m,m)大小的矩阵,还需要产生协方差矩阵去计算更多的信息。

一、PCA 和 SVD

在降维过程中,我们会减少特征的数量,这意味着删除数据,数据量变少则表示模型可以获取的信息会变少,模型的表现可能会因此受影响。同时,在高维数据中,必然有一些特征是不带有有效的信息的(比如噪音),或者有一些特征带有的信息和其他一些特征是重复的(比如一些特征可能会线性相关)。我们希望能够找出一种办法来帮助我们衡量特征上所带的信息量,让我们在降维的过程中,能够即减少特征的数量,又保留大部分有效信息——将那些带有重复信息的特征合并,并删除那些带无效信息的特征等等——逐渐创造出能够代表原特征矩阵大部分信息的,特征更少的,新特征矩阵。

PCA具体原理参考:https://blog.csdn.net/s294878304/article/details/101882002

SVD

1、Sklearn中的 PCA

class sklearn.decomposition.PCA (n_components=None, copy=True, whiten=False,
        svd_solver=’auto’, tol=0.0,iterated_power=’auto’, random_state=None)

(1)重要参数n_components

n_components是我们降维后需要的维度,即降维后需要保留的特征数量,我们设定的数字会影响到模型的表现。如果留下的特征太多,就达不到降维的效果,如果留下的特征太少,那新特征向量可能无法容纳原始数据集中的大部分信息,因此,n_components既不能太大也不能太小。那怎么办呢?

1)、高维数据的可视化

import  matplotlib.pyplot as plt
from sklearn.datasets import load_iris
from  sklearn.decomposition import PCA
import pandas as pd

iris = load_iris()
X = iris.data
Y = iris.target
print(X.shape)#(150, 4)
X = pd.DataFrame(X)
# print(X.head(2))
print("==========PCA建模==============")
pca = PCA(n_components=2)
pca.fit(X)
X_dr = pca.transform(X)
# 也可以fit_transform一步到位,X_dr = PCA(2).fit_transform(X)
# print(X_dr)
print("==========可视化==============")
# 要将三种鸢尾花的数据分布显示在二维平面坐标系中,对应的两个坐标(两个特征向量)应该是三种鸢尾花降维后的
# x1和x2,怎样才能取出三种鸢尾花下不同的x1和x2呢?
# 布尔索引,取出X中,Y标签为零的所有行的第0列,即取出降维后的第一个特征
t1 = X_dr[Y == 0, 0]
t2 = X_dr[Y == 0, 1]
# 要展示三中分类的分布,需要对三种鸢尾花分别绘图,可以写成三行代码,也可以写成for循环
color = ['red', 'black', 'orange']
names = iris.target_names
plt.figure()
# alpha=0.7 表示点的颜色深浅
for i in [0, 1, 2]:
    plt.scatter(X_dr[Y == i, 0],
                X_dr[Y == i, 1],
                alpha=0.7, c=color[i], label=names[i])
plt.legend()
plt.title('PCA of IRIS dataset')
plt.show()

2)探索降维后的数据

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

3)、选择最好的 n_components:

a、累积可解释方差贡献率曲线

当参数components中不填写任何值,则默认返回min(X.shape)个特征(即样本矩阵行数和列数中最小的值),一般来说,样本量都会大于特征数目,所以什么都不填就相当于转换了新特征空间,但没有减少特征的个数。一般来说,不会使用这种输入方式。但我们却可以使用这种输入方式来画出累计可解释方差贡献率曲线,以此选择最好的n_components的整数取值。

累积可解释方差贡献率曲线是一条以降维后保留的特征个数为横坐标,降维后新特征矩阵捕捉到的可解释方差贡献率为纵坐标的曲线,能够帮助我们决定n_components最好的取值。

import  matplotlib.pyplot as plt
from sklearn.datasets import load_iris
from sklearn.decomposition import PCA
import pandas as pd
import numpy as np
iris = load_iris()
X = iris.data
Y = iris.target
print(X.shape)# (150, 4)
X = pd.DataFrame(X)

pca_line = PCA()
pca_line.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")
plt.show()

b、最大似然估计自选超参数

除了输入整数,n_components还有哪些选择呢?之前我们提到过,矩阵分解的理论发展在业界独树一慧的数学大神Minka, T.P.在麻省理工学院媒体实验室做研究时找出了让PCA用最大似然估计(maximumestimation)自选超参数的方法,输入“mle”作为n_components的参数输入,就可以调用这种方法。
 

import matplotlib.pyplot as plt
from sklearn.datasets import load_iris
from sklearn.decomposition import PCA
import pandas as pd
import numpy as np
iris = load_iris()
X = iris.data
Y = iris.target
print(X.shape)# (150, 4)
X = pd.DataFrame(X)

pca_mle = PCA(n_components="mle")
pca_mle.fit(X)
X_mle = pca_mle.transform(X)
# print(X_mle)
# 可以发现,mle为我们自动选择了3个特征
print(pca_mle.explained_variance_ratio_.sum())
# 得到了比设定2个特征时更高的信息含量,对于鸢尾花这个很小的数据集来说,3个特征对应这么高的信息含量,并不
# 需要去纠结于只保留2个特征,毕竟三个特征也可以可视化
m, n = X_mle.shape
row = np.arange(0, n, 1)
print(row)
plt.plot(row, np.cumsum(pca_mle.explained_variance_ratio_))
plt.xticks(row) # 这是为了限制坐标轴显示为整数
plt.xlabel("number of components after dimension reduction")
plt.ylabel("cumulative explained variance")
plt.show()

c、按信息量占比选超参数

输入[0,1]之间的浮点数,并且让参数svd_solver =='full',表示希望降维后的总解释性方差占比大于n_components指定的百分比,即是说,希望保留百分之多少的信息量。比如说,如果我们希望保留97%的信息量,就可以输入n_components = 0.97,PCA会自动选出能够让保留的信息量超过97%的特征数量。

import matplotlib.pyplot as plt
from sklearn.datasets import load_iris
from sklearn.decomposition import PCA
import pandas as pd
import numpy as np
iris = load_iris()
X = iris.data
Y = iris.target
print(X.shape)# (150, 4)
X = pd.DataFrame(X)

pca_f = PCA(n_components=0.97, svd_solver="full")
pca_f.fit(X)
X_f = pca_f.transform(X)
print(pca_f.explained_variance_ratio_)

# 得到了比设定2个特征时更高的信息含量,对于鸢尾花这个很小的数据集来说,3个特征对应这么高的信息含量,并不
# 需要去纠结于只保留2个特征,毕竟三个特征也可以可视化
m, n = X_f.shape
row = np.arange(0, n, 1)
print(row)
plt.plot(row, np.cumsum(pca_f.explained_variance_ratio_))
plt.xticks(row) # 这是为了限制坐标轴显示为整数
plt.xlabel("number of components after dimension reduction")
plt.ylabel("cumulative explained variance")
plt.show()

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 


转载:https://blog.csdn.net/s294878304/article/details/101881937
查看评论
* 以上用户言论只代表其个人观点,不代表本网站的观点或立场