《Python机器学习》读书笔记(五)特征抽取——PCA

版权声明: https://blog.csdn.net/weixin_40604987/article/details/79598125

Python机器学习读书笔记(五)特征抽取——PCA

说明:

  1. 关于本书: 《Python机器学习》
  2. 本笔记侧重代码调用,只描述了一些简单概念,本书的公式推导不在这里展示
  3. 本页代码

特征抽取 可以将原始数据集变换到一个维度更低的新的特征子空间,在尽可能多地保持相关信息的情况下,对数据进行压缩。

1. 主成份分析 Principle Component Analysis, PCA

1.1 一些博客

1.2 简单介绍

  • 如果我们将矩阵看作物理运动,那么最重要的就是运动方向(特征向量)和速度(特征值)。因为物理运动只需要方向和速度就可以描述,同理矩阵也可以仅使用特征向量和特征值描述。

  • PCA 是一种寻找高维数据(图像等)模式的工具。机器学习实践上经常使用 PCA 对输入神经网络的数据进行预处理。通过聚集、旋转和缩放数据,PCA 算法可以去除一些低方差的维度而达到降维的效果,这样操作能提升神经网络的收敛速度和整体效果。

  • 目标 :在高维数据中找到方差最大的方向,并将数据映射到一个维度不大于原始数据的新的子空间上。
  • 如下图所示: 以新的坐标是相互正交为约束条件,新的子空间上正交的坐标轴可以被解释为方差最大的方向。在这里x1,x2为原始特征的坐标轴,而PC1,PC2为主成份

主成份示例图1

1.3 原理简介

  • 如果使用PCA降维,我们将构建一个dk转换矩阵W,这样就可以将一个样本向量x映射到新的k维子空间上去,且 k<d

x=[x1,x2,...,xd],xRd

xW,WRdk

z=[z1,z2,...,zd],zRk

  • 算法流程:
  1. 对原始的d维数据做标准化处理
  2. 构造样本协方差矩阵
  3. 计算协方差矩阵的特征值和特征向量
  4. 选择与前k个最大特征值对应的特征向量,其中k为新特征空间的维度
  5. 通过前k个特征向量构建映射矩阵W
  6. 通过映射矩阵W将d维的输入数据集X转换到新的k维特征子空间
  • 协方差矩阵(dd)是沿主对角线对称的,该矩阵成对的存储了不同特征之间的协方差。
  • 两个特征之间的协方差若为正,则同时增减,反之两个特征之间的协方差若为负,则朝相反方向变动
  • 协方差矩阵的特征向量代表主成份(最大方差方向),而对应的特征值大小就决定了特征向量的重要性。

1.4 示例

  • 加载数据集
import pandas as pd

df_wine = pd.read_csv('https://archive.ics.uci.edu/ml/'
                      'machine-learning-databases/wine/wine.data',
                      header=None)
  • 划分数据集
if Version(sklearn_version) < '0.18':
    from sklearn.cross_validation import train_test_split
else:
    from sklearn.model_selection import train_test_split

X, y = df_wine.iloc[:, 1:].values, df_wine.iloc[:, 0].values

X_train, X_test, y_train, y_test = \
    train_test_split(X, y, test_size=0.3, random_state=0)
  • 标准化
from sklearn.preprocessing import StandardScaler

sc = StandardScaler()
X_train_std = sc.fit_transform(X_train)
X_test_std = sc.transform(X_test)
  • 构造协方差矩阵,eigen_vals, eigen_vecs分别是协方差向量和协方差矩阵(d*d)
import numpy as np
cov_mat = np.cov(X_train_std.T)
eigen_vals, eigen_vecs = np.linalg.eig(cov_mat)
  • 为了挑选前k个特征向量,绘制特征值的方差贡献率图像。特征值 λj 的方差贡献率是指特征值λj所有特征值的和的比值。使用Numpy的cumsum函数,计算累积方差:
tot = sum(eigen_vals)
var_exp = [(i / tot) for i in sorted(eigen_vals, reverse=True)]
cum_var_exp = np.cumsum(var_exp)


import matplotlib.pyplot as plt

plt.bar(range(1, 14), var_exp, alpha=0.5, align='center',
        label='individual explained variance')
plt.step(range(1, 14), cum_var_exp, where='mid',
         label='cumulative explained variance')
plt.ylabel('Explained variance ratio')
plt.xlabel('Principal components')
plt.legend(loc='best')
plt.tight_layout()
# plt.savefig('./figures/pca1.png', dpi=300)
plt.show()

效果

  • 接着,按特征值的降序排列特征对,并选取两个对应特征值最大的特征向量
eigen_pairs = [(np.abs(eigen_vals[i]), eigen_vecs[:, i])
               for i in range(len(eigen_vals))]
eigen_pairs.sort(key=lambda k: k[0], reverse=True)

w = np.hstack((eigen_pairs[0][1][:, np.newaxis],
               eigen_pairs[1][1][:, np.newaxis]))
  • 将数据映射到子空间
X_train_pca = X_train_std[0].dot(w)
  • 可视化展示新数据:
X_train_pca = X_train_std.dot(w)
colors = ['r', 'b', 'g']
markers = ['s', 'x', 'o']

for l, c, m in zip(np.unique(y_train), colors, markers):
    plt.scatter(X_train_pca[y_train == l, 0], 
                X_train_pca[y_train == l, 1], 
                c=c, label=l, marker=m)

plt.xlabel('PC 1')
plt.ylabel('PC 2')
plt.legend(loc='lower left')
plt.tight_layout()
# plt.savefig('./figures/pca2.png', dpi=300)
plt.show()

效果

1.5 使用sklearn进行主成份分析

使用了前面用到的plot_decision_regions函数

from sklearn.decomposition import PCA

pca = PCA(n_components=2)
X_train_pca = pca.fit_transform(X_train_std)
X_test_pca = pca.transform(X_test_std)

plot_decision_regions(X_train_pca, y_train, classifier=lr)
plt.xlabel('PC 1')
plt.ylabel('PC 2')
plt.legend(loc='lower left')
plt.tight_layout()
# plt.savefig('./figures/pca3.png', dpi=300)
plt.show()

效果

  • n_components=None时,可以保留所有主成份,并且可以通过explained_variance_ratio_属性获得相应的方差贡献率
pca = PCA(n_components=None)
X_train_pca = pca.fit_transform(X_train_std)
pca.explained_variance_ratio_

array([ 0.37329648,  0.18818926,  0.10896791,  0.07724389,  0.06478595,0.04592014,  0.03986936,  0.02521914,  0.02258181,  0.01830924,0.01635336,  0.01284271,  0.00642076])

作者邮箱: mr.yxj@foxmail.com

转载请告知作者,感谢!

没有更多推荐了,返回首页