数据科学流程之维数约简

当数据集中包含大量特征时:

  - 有些特征包含丰富的预测信息;

  - 有些特征之间具有一定的相关性;

  - 有些特征只包含噪声或不相关信息;

  只保留有意义的特征不仅可以使数据集易于管理,而且可以使预测结果不受数据中噪声的影响,预测精度更好。

维数约简

消除输入数据集的某些特征,创建一个有限特征的数据集(包含所有需要的信息),以更有效的方式预测目标变量。

注:多维数组约简算法的一个主要假设:数据包含加性高斯白噪声。(加性高斯白噪声可以从我们的数据集中分离出来,它是一个线性噪声。)

  ps:关于加性高斯白噪声指路博客:https://www.cnblogs.com/jiangkejie/p/10289876.html

  维数约简可以减少噪声的集合跨度,以此减少噪声的能量。

一. 协方差矩阵

1. 协方差

协方差是对两个随机变量联合分布线性相关程度的一种度量。

  - 两个随机变量越线性相关,协方差越大;

  - 线性无关,协方差为零。

随机变量X,Y的协方差:

  cov(X,Y) = E[(X-E[X])(Y-E[Y])]

  cov(X,Y) = cov(Y,X)  (协方差对称)

随机变量X与自身的协方差就是X的方差:

  cov(X,X) = E[(X-E[X])(X-E[X])]

  var(X) = cov(X,X) = E[(X-E[X])²]

2. 相关系数

相关系数(Correlation coefficient)是按积差方法计算,同样以两变量与各自平均值的离差为基础,通过两个离差相乘来反映两变量之间相关程度。

  - 相关系数取值在-1到1之间;

  - 相关系数为0时,称两个变量不相关;

  - 相关系数为1时,称两个变量完全相关,即具有线性关系;

  - 越接近于0说明两个变量的相似度越小;

  - 越接近于1说明两个变量的相似度越大。

一般地,相关系数>0.8称为高度相关,相关系数<0.3称为低度相关,其他称为中度相关。

      (一.2)

1 from sklearn.datasets import load_iris #载入鸢尾花数据
2 iris = load_iris()
3 print(iris.feature_names)
4 print(iris.data.shape)
['sepal length (cm)', 'sepal width (cm)', 'petal length (cm)', 'petal width (cm)']
(150, 4)
1 import numpy as np
2 cov_data = np.cov(iris.data.T)
3 print(cov_data)
[[ 0.68569351 -0.042434    1.27431544  0.51627069]
 [-0.042434    0.18997942 -0.32965638 -0.12163937]
 [ 1.27431544 -0.32965638  3.11627785  1.2956094 ]
 [ 0.51627069 -0.12163937  1.2956094   0.58100626]]
1 import numpy as np
2 cov_data = np.corrcoef(iris.data.T)
3 print(cov_data)
[[ 1.         -0.11756978  0.87175378  0.81794113]
 [-0.11756978  1.         -0.4284401  -0.36612593]
 [ 0.87175378 -0.4284401   1.          0.96286543]
 [ 0.81794113 -0.36612593  0.96286543  1.        ]]

输出矩阵的第一行第一个是数据集的'sepal length'和本身的协方差/相关系数;第一行第二个是数据集的'sepal length'和'sepal width'的协方差/相关系数;第二行第一个是数据集的
'sepal length'和'sepal width'的协方差/相关系数;第二行第三个是数据集的'sepal width'和'petal length'的协方差/相关系数。。。以此类推,所以会对称。

注:使用协方差矩阵和相关系数矩阵计算相关性的话,cov()和corrcoef()内输入数据必须每行是一个变量(特征),每列是一个样本,所以需要把数据进行转置。(具体算法参考例 一.2 )

  cov()/corrcoef()是协方差/相关系数矩阵,是对称矩阵,每个元素是各个向量元素之间的协方差/相关系数。

3. 热力图

 矩阵图形化表示——heatmap() 热力图

1 import seaborn as sns #导入seaborn包和可视化绘图工具
2 import matplotlib.pyplot as plt
3 sns.heatmap(cov_data,annot = True)
<matplotlib.axes._subplots.AxesSubplot at 0x27a0f0822e0>
1 sns.heatmap(cov_data,annot = True,cmap = 'rainbow')
<matplotlib.axes._subplots.AxesSubplot at 0x27a0f3715e0>

参数annot(annotate标注的缩写)默认取值False;如果是True,在热力图每个方格写入矩阵对应位置数据。

参数cmap从数字到色彩空间的映射。

发现:

- 主对角线元素为1,因为变量自相关系数为1

- 第1和第3,第1和第4,第3和第4特征之间具有高度相关性;

- 第2特征与其他特征相关度较低。潜在特征量应该为2.

相关特征可能包含相似属性,因而可以约简高度相关特征。

维数约减算法很多,如PCA,LFA,LDA,LSA,ICA,T-SNE等。

 

二. 主成分分析

1.主成分分析

  主成分分析(Principal component Analysis, PCA),又称主元分析,主分量分析,旨在利用降维的思想简化数据。

  PCA的主要思想是通过对原始变量相关矩阵内部结构的关系研究,找出影响效果某一要素的几个综合指标,使综合指标为原来变量的线性拟合

  将n维特征映射到p维上,这p维是新的正交特征,被称为主成分。

  p维特征是在原有m维特征的基础上重新构造出来的,不仅保留了原始变量的主要信息,且彼此间不相关,又比原始变量具有某些更优越的性质。              ——抓住主要矛盾

注:p维是从协方差矩阵上提取出来的,因而具有正交属性

2.PCA算法步骤

PCA(n_components=None, copy=True, whiten=False, svd_solver='full')

参数:

n_components: 所要保留的主成分个数n,缺省时默认为None。赋值为int,如n_components=1,将把原始数据降到一个维度;赋值为string,如n_components='mle',将自动选取特征个数n,使得满足所要求的方差百分比。

copy: 表示是否在运行时将原始训练数据复制一份,缺省时默认为True。若为True,则在原始数据副本上进行运算,原始数据不改变。若为False,则在运行PCA算法后,原始训练数据的值改变。

whiten: 白化,使得每个特征具有相同的方差,缺省时默认False。

svd_solver: 指定奇异值分解SVD的方法,缺省时默认auto。有四个可选择的值:{'auto','full','arpack','randomized'}

返回值:

n_components_: 返回所保留的成分个数n;

components_: 返回具有最大方差的成分;

explained_variancce_ratio_: 返回保留的n个成分各自的方差百分比。

2.1 特征分解

特征分解是奇异值分解的一个特例,一般PCA库都是基于SVD实现。

svd_solver参数:

  指定奇异值分解SVD的方法:’auto‘,'full','arpack','randomized'

  'full':传统意义上的SVD,使用scipy库对应的SVD实现。

  'randomized'和'arpack':一般适用于数据量大,数据维度多,同时主城分数比例又较低的PCA降维,使用了加快SVD的随机算法。

    区别:randomized使用scikit-learn的SVD实现;

       arpack使用scipy库的sparse的SVD实现。

  'auto':PCA算法自行在前面三种中做权衡,选择一个合适的SVD算法来降维。

  一般来说,使用默认值就够了。

2.2 Randomized PCA

  scikit-learn提供了一种基于随机SVD(Randomized SVD)的更快的算法,它是一种更轻的,近似迭代分解的方法。

  虽然使用随机SVD进行满秩重建并不十分理想,其基向量在每次迭代过程中会被局部优化,但是做矩阵分解时,随机SVD比经典SVD算法速度更快,只需要几个步骤就能与经典算法结果极其近似。因此,当训练数据集很大时,它是一个很好的选择。

  当数据集的规模非常小时,Randomized PCA输出结果与经典PCA相当接近,但当这两种算法应用于大数据集时,其对比结果会显著不同。

1 from sklearn.decomposition import PCA
2 pca_2c = PCA(n_components=2)#初始化PCA,降为2维
3 X_pca_2c = pca_2c.fit_transform(iris.data)#把数据集里'data'部分进行标准化拟合,得到约简后的数据
4 X_pca_2c.shape
(150, 2)
1 plt.scatter(X_pca_2c[:,0],X_pca_2c[:,1],c=iris.target,alpha=0.8,
        s=60,marker='o',edgecolors='white') #plt.scatter参数x,y:表示的是大小为(n,)的数组,也就是我们即将绘制散点图的数据点;c:可以是'color'也可以是一个二维数组(一行的那种);

                              alpha:0-1之间的实数;s:是一个实数或者是一个数组大小为(n,),这个是一个可选的参数;marker:数据点的形状,默认为'o'(圆点);
                              edgecolors:数据点边缘颜色
2 plt.show()

 

 

1 pca_2c.explained_variance_ratio_
array([0.92461872, 0.05306648])
pca_2c.explained_variance_ratio_.sum()
0.9776852063187949
pca_2c.components_
array([[ 0.36138659, -0.08452251,  0.85667061,  0.3582892 ],
       [ 0.65658877,  0.73016143, -0.17337266, -0.07548102]])
1 pca_2cw = PCA(n_components=2,whiten=True)#初始化PCA,降为2维并且白化
2 X_pca_2cw = pca_2cw.fit_transform(iris.data)
3 plt.scatter(X_pca_2cw[:,0],X_pca_2cw[:,1],c=iris.target,alpha=0.8,
4            s=60,marker='o',edgecolors='white')
5 plt.show()#数值范围变为2倍
6 pca_2cw.explained_variance_ratio_.sum()

0.9776852063187949
1 pca_1c = PCA(n_components=1)#初始化PCA,降为1维
2 X_pca_1c = pca_1c.fit_transform(iris.data)
3 plt.scatter(X_pca_1c[:,0],np.zeros(X_pca_1c.shape),c=iris.target,alpha=0.8,
4            s=60,marker='o',edgecolors='white')
5 plt.show()
6 pca_1c.explained_variance_ratio_.sum()

0.924618723201727
1 pca_95pc = PCA(n_components=0.95)#初始化PCA
2 X_pca_95pc = pca_95pc.fit_transform(iris.data)
3 print(pca_95pc.explained_variance_ratio_.sum())
4 print(X_pca_95pc.shape)
0.9776852063187949
(150, 2)
posted on 2020-04-03 15:09  CC陈三愿  阅读(773)  评论(0编辑  收藏  举报