目录
4、Principal Component Analysis (PCA)
一、PCA的概念
PCA(Principal Component Analysis),即主成分分析方法,是一种使用最广泛的数据降维算法。PCA的主要思想是将n维特征映射到k维上,这k维是全新的正交特征也被称为主成分,是在原有n维特征的基础上重新构造出来的k维特征。PCA的工作就是从原始的空间中顺序地找一组相互正交的坐标轴,新的坐标轴的选择与数据本身是密切相关的。其中,第一个新坐标轴选择是原始数据中方差最大的方向,第二个新坐标轴选取是与第一个坐标轴正交的平面中使得方差最大的,第三个轴是与第1,2个轴正交的平面中方差最大的。依次类推,可以得到n个这样的坐标轴。通过这种方式获得的新的坐标轴,我们发现,大部分方差都包含在前面k个坐标轴中,后面的坐标轴所含的方差几乎为0。于是,我们可以忽略余下的坐标轴,只保留前面k个含有绝大部分方差的坐标轴。事实上,这相当于只保留包含绝大部分方差的维度特征,而忽略包含方差几乎为0的特征维度,实现对数据特征的降维处理。
二、特征维度约减的概念
PCA的目标就是实现维数约减,即在尽可能保留信息的同时减少数据的维度。通过维数约减,我们可以实现数据压缩节省存储空间,还能加快一些算法的运算速度。
具体来讲,PCA算法要在高维空间中找到一个低维度的面(子空间),使高维空间中的点到自身投影到低维子空间的对应点之间的距离之和(也称投影误差)最小。下面是一些简单的例子,它们可以被可视化,分别是从二维平面投影到一条直线和从三维空间投影到一张平面。
1、为何要维度约减
• 可视化: 高位数据在 2D 或 3D空间中的可视化• 维度约减: 高效的存储与检索• 噪声消除: 提升分类或识别精度
2、维度约减的应用
• 文本挖掘• 人脸识别• 手写体识别• 图像检索• 基因分类• ......
3、常规维度约减方法
• 无监督方法– Latent Semantic Indexing (LSI): truncated SVD– Independent Component Analysis (ICA)– Principal Component Analysis (PCA)– Canonical Correlation Analysis (CCA)• 监督方法– Linear Discriminant Analysis (LDA)• 半监督方法– Research topic
4、Principal Component Analysis (PCA)
•主成分分析 (PCA)基本思路–通过协方差分析,建立高维空间到低维空间的线性映射/矩阵–保留尽可能多的样本信息–压缩后的数据对分类、聚类尽量不产生影响,甚至有所提升•将原始高维向量通过投影矩阵,投射到低维空间–这些向量称为主成分 (PCs), 具有无关性、正交的特点。重要的是这些向量的数量要远小于高维空间的维度
三、主成分的代数定义
我们的目标是找到a1 , 使z1的方差最大。
首先根据z1的方差定义,推导得出:
其中
可以看出,S是维度之间的协方差矩阵, 是样本均值在实际计算中,可以先将样本减去均值使得
假设
根据样本组成的矩阵
有协方差矩阵
可证明S半正定!
四、PCA算法流程
1、PCA算法的过程
(1)数据中心化:对X中的每一行(即一个特征属性)进行零均值化,即减去这一行的均值
(2)求出数据中心化后矩阵X的协方差矩阵(即特征与特征之间的协方差构成的矩阵)
(3)求解协方差矩阵的特征值和特征向量
(4)将特征向量按照特征值从大到小按列进行排列称为矩阵,获取最前面的k列数据形成矩阵W。
(5)利用矩阵W和样本集X进行矩阵的乘法得到降低到k维的最终数据矩阵。
2、PCA算法实施过程所用公式
(1)方差
一个字段的方差可以看做是每个元素与字段均值的差的平方和的均值,即:
由于我们将X中的每一行进行零均值化,因此方差可以直接用每个元素的平方和除以元素个数表示:
我们希望投影后,投影值尽可能分散,而这种分散度可以用数学上的方差来表示
(2)协方差
数学上可以用两个字段的协方差表示其相关性,由于已经让每个字段均值为0,则:
对于上面二维降成一维的问题来说,找到那个使得方差最大的方向就可以了。不过对于更高维,还有一个问题需要解决。考虑三维降到二维问题。与之前相同,首先我们希望找到一个方向使得投影后方差最大,这样就完成了第一个方向的选择,继而我们选择第二个投影方向。如果我们还是单纯只选择方差最大的方向,很明显,这个方向与第一个方向应该是“几乎重合在一起”,显然这样的维度是没有用的,因此,应该有其他约束条件。从直观上说,让两个字段尽可能表示更多的原始信息,我们是不希望它们之间存在(线性)相关性的,因为相关性意味着两个字段不是完全独立,必然存在重复表示的信息。 数学上可以用两个字段的协方差来表示其相关性。
(3) 协方差矩阵
假设我们只有a和b两个字段,那么我们将它们按行组成矩阵X:
然后我们用X乘以X的转置,并乘上系数1/m:这个矩阵对角线上的两个元素分别是两个字段的方差,而其它元素是a和b的协方差。
3、PCA算法简单示例
这里以上文提到的X
为例,我们用PCA方法将这组二维数据其降到一维。因为这个矩阵的每行已经是零均值,这里我们直接求协方差矩阵:
然后求其特征值和特征向量,具体求解方法不再详述,可以参考相关资料。求解后特征值为:
其对应的特征向量分别是:
其中对应的特征向量分别是一个通解,c1和c2可取任意实数。那么标准化后的特征向量为
可以验证协方差矩阵C的对角化:
最后我们用P的第一行乘以数据矩阵,就得到了降维后的表示:
降维投影结果如下图:
五、PCA算法代码实现
以一个二维降一维得栗子来展示,其中数据为x = [2.5, 0.5, 2.2, 1.9, 3.1, 2.3, 2,1,1.5,1.1], y = [2.4, 0.7, 2.9, 2.2, 3, 2.7, 1.6, 1.1, 1.6, 0.9],在坐标系中展示如下:
import numpy as np
import matplotlib.pyplot as plt
x = np.array([2.5,0.5,2.2,1.9,3.1,2.3,2,1,1.5,1.1])
y = np.array([2.4,0.7,2.9,2.2,3,2.7,1.6,1.1,1.6,0.9])
plt.plot(x,y,'o')
plt.show()
#createData
import numpy as np
import matplotlib.pyplot as plt
#数据表示
x = np.array([2.5,0.5,2.2,1.9,3.1,2.3,2,1,1.5,1.1])
y = np.array([2.4,0.7,2.9,2.2,3,2.7,1.6,1.1,1.6,0.9])
x1 = x
y1 = y
data = np.matrix([ [x1[i],y1[i]] for i in range(len(x1)) ])
mean_x = np.mean(x)
mean_y = np.mean(y)
x1 = x - mean_x
y1 = y - mean_y
data = np.matrix([ [x1[i],y1[i]] for i in range(len(x1)) ])
print("求均值之后的数据", data)
#求协方差矩阵(Covariance Matrix)
cov1 = np.cov(x1,y1)
#求协方差矩阵的特征值和特征向量
#用numpy自带的函数计算特征根和特征向量
val,vec = np.linalg.eig(cov1)
#绘制特征向量的图-->垂直的折线
plt.plot(x1,y1,'o')
xmin,xmax = x1.min(),x1.max()
ymin,ymax = y1.min(),y1.max()
dx = (xmax - xmin) * 0.2
dy = (ymax - ymin) * 0.2
plt.xlim(xmin - dx,xmax + dx)
plt.ylim(ymin - dy,ymax + dy)
plt.plot([vec[:,0][0],0],[vec[:,0][1],0],color ='red')
plt.plot([vec[:,1][0],0],[vec[:,1][1],0],color ='red')
plt.show()
#选择主要成分
main_pair = [(np.abs(val[i]) ,vec[:,i]) for i in range(len(val))]
# main_pair = [(0.049, array([-0.735,0.677])) , (1.284, array([-0.678,-0.735]))]
#从main_pair中选取前k个特征向量
#这里是二维数据,取k = 1
feature = main_pair[0][1]
#feature = array([-0.735,0.677])
#原数据 X 特征向量 = 降维后的数据
new_data_reduced = np.transpose(np.dot(feature,np.transpose(data)))
print("降维之后的结果", new_data_reduced)
#可视化
new_data = np.transpose(np.dot(vec,np.transpose(data)))
plt.plot(x1,y1,'o',color = 'red')
plt.plot([vec[:,0][0],0],[vec[:,0][1],0],color = 'red')
plt.plot([vec[:,1][0],0],[vec[:,1][1],0],color = 'blue')
plt.plot(new_data[:,0],new_data[:,1],'^',color = 'blue')
plt.plot(new_data_reduced[:,0],[1.4] * 10,'*',color = 'green')
plt.show()
数据求均值之后矩阵为:
求均值之后的数据 [[ 0.69 0.49]
[-1.31 -1.21]
[ 0.39 0.99]
[ 0.09 0.29]
[ 1.29 1.09]
[ 0.49 0.79]
[ 0.19 -0.31]
[-0.81 -0.81]
[-0.31 -0.31]
[-0.71 -1.01]]
所得特征向量的图示(垂直的折线)
降维之后的矩阵为:
降维之后的结果 [[-0.17511531]
[ 0.14285723]
[ 0.38437499]
[ 0.13041721]
[-0.20949846]
[ 0.17528244]
[-0.3498247 ]
[ 0.04641726]
[ 0.01776463]
[-0.16267529]]
将上述数据可视化如下(其中绿色的五角星表示PCA降维之后得到的一维数据)
1、代码解析
(1)data = np.matrix([ [x1[i],y1[i]] for i in range(len(x1)) ])
np.matrix()将所给数据转化为矩阵的形式,方便调用numpy中的库来进行矩阵的运算
(2) mean_x = np.mean(x)
np.mean()主要是用来求均值,举个栗子
>>> a = np.array([[1, 2], [3, 4]])
>>> a
array([[1, 2],
[3, 4]])
>>> np.mean(a)
2.5
>>> np.mean(a, axis=0) # axis=0,计算每一列的均值
array([ 2., 3.])
>>> np.mean(a, axis=1) # 计算每一行的均值
array([ 1.5, 3.5])
3、cov1 = np.cov(x1,y1)
np.cov()用来求协方差矩阵,举个栗子
>>> X=np.array([[1 ,5 ,6] ,[4 ,3 ,9 ],[ 4 ,2 ,9],[ 4 ,7 ,2]])
>>> np.cov(X)
array([[ 7. , 4.5 , 4. , -0.5 ],
[ 4.5 , 10.33333333, 11.5 , -7.16666667],
[ 4. , 11.5 , 13. , -8.5 ],
[ -0.5 , -7.16666667, -8.5 , 6.33333333]])
4、val,vec = np.linalg.eig(cov1)
np.linalg.eig()用来求矩阵的特征值和特征向量,举个栗子
>>> w, v = LA.eig(np.diag((1, 2, 3)))
>>> w; v
array([ 1., 2., 3.])
array([[ 1., 0., 0.],
[ 0., 1., 0.],
[ 0., 0., 1.]])
5、new_data_reduced = np.transpose(np.dot(feature,np.transpose(data)))
np.transpose()表示矩阵的转置,举个栗子
>>> two=np.arange(16).reshape(4,4)
>>> two
array([[ 0, 1, 2, 3],
[ 4, 5, 6, 7],
[ 8, 9, 10, 11],
[12, 13, 14, 15]])
>>> two.transpose()
array([[ 0, 4, 8, 12],
[ 1, 5, 9, 13],
[ 2, 6, 10, 14],
[ 3, 7, 11, 15]])
np.dot()用来求向量的点积,举个栗子
import numpy as np
x=np.array([0,1,2,3,4])#等价于:x=np.arange(0,5)
y=x[::-1]
print x
print y
print np.dot(x,y)
以上是我对PCA算法的理解,并作出整理,如果有什么理解不对的地方还请指导
六、总结
根据实验结果,可以得出以下结论:
- 主成分分析(PCA)成功将原始数据从4维降至2维,同时保留了大部分数据的信息。
- 经过PCA降维后的新变量能够有效地反映数据的差异性,有助于进行后续的数据分析和处理。
- 通过K-Means聚类算法对PCA降维后的数据进行分类,结果表明该方法能够有效地区分不同类型的鸢尾花。
- 在新变量的基础上,可以进一步探索其他聚类算法或分类模型对数据进行分析和预测,以验证PCA在数据处理中的效果。
综合而言,PCA在数据降维方面取得了良好的效果,为后续的数据分析和建模提供了有力支持。