西瓜书
第10章讲解的是降维
和度量学习
的相关内容
维度
对于数组和Series
而言,维度就是shape
返回的数值。shape
中 返回了几个数字,就是几维。
索引以外的数据,不分行列的称之为一维,有行列之分的称之为二维,也称之为表。一张表最多是二维的。
数组中的每张表可以是一个特征矩阵或者一个DataFrame
。行是样本,列是特征。
笔记:维度指的是样本的数量或者特征的数量;一般情况下,指的是特征数量。n个特征就是n维
对于图像而言,维度就是图像中特征向量的数量。特征向量可以理解成坐标轴。
降维decompositon
降维算法中降维指的是:降低特征矩阵中特征的数量。
sklearn
中的降维算法在decomposition
中。模块的本质是矩阵分解模块。代表是SVD
奇异值分解。
主成分分析中的常见的模块:
主成分分析PCA
增量主成分分析IPCA,Incremental PCA
核主成分分析KPCA,Kernel PCA
小批量稀疏主成分分析,MiniBatchSparse PCA
稀疏主成分分析,Sparse PCA
截断的SVD,Truncated SVD
高级矩阵分解
具有在线变分贝叶斯算法的隐含狄利克雷分布,LatenDirichletAllocation
非负矩阵分解,NMF
稀疏编码,SparseCoder
在降维的过程中,会减少特征的数量,则意味着需要删除数据:减少特征数量、保留大部分有效信息
方差过滤
如果一个特征的方差
过小:特征上很可能有很多相同的取值,区分度很低,有效信息少
过大:特征上带有大量的有效信息
笔记:PCA中就是使用样本方差作为信息衡量的指标。样本方差越大,可解释型越强,特征所带的信息越多
Var是特征的方差
n是样本数量
代表的是一个特征中的每个样本取值
代表的是这一列样本的均值
为什么是n-1
为了得到样本方差的无偏估计。为什么样本方差的分母是n-1
降维demo
通过一个二维降低到一维的栗子来说明降维的实现过程
x_1 | x_2 |
---|---|
1 | 1 |
2 | 2 |
3 | 3 |
上面原始数据中,两个特征的均值都是2
,方差都是;总方差都是2
逆时针旋转45
度之后变成了
0 | |
0 | |
0 |
的均值和方差都是0
;的均值是;方差是2
。总方差也是2
笔记:
PCA
中取得是信息量较大的特征,即方差较大,所以特征可以删除,二维变成了一维,保留了原始数据的信息。
降维基本步骤
将二维矩阵和n
维矩阵进行类比,掌握降维算法的基本过程:
过程 | 二维特征矩阵 | n维特征矩阵 |
---|---|---|
1 | 找出2个特征对应的直角坐标系 | 找出原本的n个特征向量构成的n维空间V |
2 | 决定降维之后的特征数量:1 | 决定降维之后的特征数量:k |
3 | 旋转,找出一个新的坐标系; 本质上是找出2个新的特征向量,构成新平面 新特征向量能够被压缩到较少的特征上,总信息量损失不多 | 通过某种变化,找出n个新的特征变量,以及它们构成的新n维空间V |
4 | 将原始数据在新坐标系上的坐标找出来 | 找出原始数据在特征空间V上的对应的值,“将新的数据映射到新空间中” |
5 | 选取方差最大的特征向量,删除没有被选中的特征,降低到1维 | 选取前k个信息量最大的特征,从n维降低k维 |
笔记:步骤3中,找出n个新特征向量,将数据压缩到少数特征上,且总信息量不能损失过多的技术,主要是矩阵分解
PCA
思想
PCA(Principal Component Analysis)是一种常用的数据分析方法,属于一种无监督学习的算法。PCA通过线性变换将原始数据变换为一组各维度线性无关的表示,可用于提取数据的主要特征分量,常用于高维数据的降维。
参考文章PCA数学原理
內积和投影
內积定义
两个维度相同向量(机器学习中一般是指列向量)的內积被定义成
內积将两个向量映射成为一个实数
內积的几何意义
,为它们之前的夹角,投影的矢量长度是表示模,也就是A线段的标量长度。內积的另一种表示形式为
也就是A到B的投影长度乘以B的模。特殊情况下,如果B的模是1,那么內积结果就是A到B的投影长度。
基
基的产生
一个二维向量可以对应二维笛卡尔直角坐标系中从原点出发的一个有向线段。代数中常用线段的终点坐标表示向量,例如下面的(3,2)。
实际上向量(3,2)表示的是在X轴上的投影是3,Y轴上的投影是2。
笔记:投影是矢量,可以是负值,与方向有关。
在二维坐标系中,向量(x,y)实际上表示为线性组合:
那么,(1,0)和(0,1)可以看做是二维空间中的一组基。
笔记:实际上任何两个线性无关的二维向量都可以成为一组基,所谓线性无关在二维平面内可以直观认为是两个不在一条直线上的向量。
例如,(1,1)和(-1,1)也可以成为一组基。一般来说,我们希望基的模是1,因为从内积的意义可以看到,如果基的模是1,那么就可以方便的用向量点乘基而直接获得其在新基上的坐标了。上面的基变成了,即除以了各自的模。
那么(3,2)在这组基下的新坐标为
笔记:一般情况基是正交的,就是说內积为0,直观来说是相互垂直的。
基变换的矩阵表示
矩阵的两行表示两个基,乘以原来的向量,得到新基下的坐标。
一般的,如果我们有M
个N
维向量,想将其变换为由R
个N
维向量表示的新空间中
- 首先将
R
个基按行组成矩阵A
,就是整个P
向量 - 然后将向量按列组成矩阵
B
,就是整个a
向量 - 两矩阵的乘积
AB
就是变换结果,其中AB
的第m
列为A
中第m
列变换后的结果
两个矩阵相乘的意义是:将右边矩阵中的每列列向量变换到左边矩阵中的每一行行向量作为基所表示的空间中去。
笔记:不同的基能够对同一组数据进行不同的表示。基的数量小于向量本身的维数,能够达到降维的效果
方差与协方差矩阵
去中心化
将所有的字段减去字段均值,结果变成了每个字段都变成了均值为0
方差
一个字段的方差可以看做是每个元素与字段均值的差的平方和的均值
由于每个字段的均值变成了0,那么总的方差可以简写成
笔记:将每个方差加起来再除以总样本数m
协方差
数学上可以用两个字段的协方差表示其相关性
当均值为0,上面的协方差公式可以表示为
当样本数较大时,不必在意其是 m 还是 m-1,为了方便计算,我们分母取 m。
笔记:如果只是单纯地选择方差最大的方向,后续的方向应该会和方差最大的方向接近重合,就导致了字段是线性相关的。我们不希望字段之间存在相关性。
当协方差为0,表示两个字段完全独立;为了让协方差为0,第二个基应当在和第一个基正交的方向上(垂直方向)
协方差矩阵
协方差矩阵是
- 对角线上是两个字段的方差
- 其他元素是协方差
协方差矩阵对角化
- 除去对角线上的元素,其他全部变成0
- 对角线上的元素从大到小,从上往下排列
原始的协方差矩阵是C,P是一组基按行组成的矩阵,设Y=PX,Y对应的协方差矩阵是D
由于C是一个对称矩阵,满足:
- 实对称矩阵不同特征值对应的特征向量必然正交
- 设特征向量重数为
r
,则必然存在r
个线性无关的特征向量对应于,因此可以将r
个特征向量单位正交化
e
代表的是单位向量,对于协方差矩阵C
的结论如下:
那么P是协方差矩阵的特征向量单位化后按行排列出的矩阵,
优化目标
- 选择K个基之后最大程度地保留原有的信息
- K个基是单位正交基
- 原始数据映射到这组基上,各个字段之间的协方差为0,字段的总方差尽可能大。
解决方法:希望投影后的投影值尽量地分散。满足的条件是:
- 最近重构性:样本点到投影平面(空间)的距离足够近
- 最大可分性:样本点在投影平面上的投影尽可能的分开
PCA算法
- 输入:样本集D和低维空间维度k
- 具体过程
- 所有样本进行去中心化
- 计算所有样本的协方差矩阵
- 对协方差矩阵做特征值分解
- 取最大的k个特征值所对应的特征向量
- 输出投影矩阵:
PCA实例
比较大,所以使用作为基
sklearn中PCA的使用
重要的参数是n_components
,降维之后需要保留的特征数量,取值在[0, min(X.shape)]
。如果不填写,默认是min(X.shape)
包导入
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
from sklearn.datasets import load_iris
from sklearn.decomposition import PCA # 导入PCA模块
数据导入
iris = load_iris()
X = iris.data
y = iris.target
X.shape # 2维数组
pd.DataFrame(X) # 4维的特征矩阵
PCA降维
# 调用PCA实现降维
pca = PCA(n_components=2) # 实例化
pca = pca.fit(X) # 传入特征矩阵,拟合模型
X_dr = pca.transform(X) # 获取新矩阵
X_dr.shape
# 一步到位的写法:X_dr = PCA(2).fit_transform(X)
可视化
X_dr[y == 0, 0] # 鸢尾花为第0种的第1列特征的数据;X_dr[y == 0, 1] 第2列特征的数据
如何取出每种鸢尾花的两个特征中的数据
plt.figure()
plt.scatter(X_dr[y == 0, 0],X_dr[y == 0, 1],c='red',label=iris.target_names[0])
plt.scatter(X_dr[y == 1, 0],X_dr[y == 1, 1],c='green',label=iris.target_names[1])
plt.scatter(X_dr[y == 2, 0],X_dr[y == 2, 1],c='orange',label=iris.target_names[2])
plt.legend()
plt.title("PCA of IRIS dataset")
plt.show()
# for循环实现
colors = ["red", "green", "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()
降维之后数据的信息探索
主要是两个属性
累计可解释方差
当n_components
中不填写任何值,默认是min.(X.shape)个特征。通过累计可解释性方差贡献率曲线来选择最好的n_components
。曲线横纵坐标分别是:
降维后保留的特征个数
累积可解释性方差贡献率
# numpy中额cumsum来累积计算
pca_line = PCA().fit(X) # PCA后面没有填写n_components值
plt.plot([1,2,3,4], np.cumsum(pca_line.explained_variance_ratio_))
plt.xticks([1,2,3,4]) # 保证横坐标是整数,不会出现1.5
plt.xlabel("Number of components after dimension reduction")
plt.ylabel("Cumulative explained variance")
plt.show()
结果表明选择2个或者3个特征是比较好的
基于极大似然估计MLE的PCA
n_components
中不仅可以填写数字,还可以通过极大似然估计MLE
来自选超参数
按照指定的信息占比选择参数
输入0-1
之间的浮点数,并且配合参数svd_solver="full"
,表示希望降维后的可解释方差占原始数据的信息比例。
pca_f = PCA(n_components=0.97, svd_solver="full")
pca_f = pca_f.fit(X)
X_f = pca_f.transform(X) # 返回降维后的特征矩阵
# 不同的占比
pca_f = PCA(n_components=0.99, svd_solver="full")
pca_f = pca_f.fit(X)
X_f = pca_f.transform(X)
pca_f.explained_variance_ratio_.sum()