主成分分析(PCA)

目标

实现一个PCA模型,能够对给定数据进行降维(即找到其中的主成分)

实验准备

降维的必要

多重共线性–预测变量之间相互关联。多重共线性会导致解空间的不稳定,从而可能导致结果的不连贯。

高维空间本身具有稀疏性。一维正态分布有68%的值落于正负标准差之间,而在十维空间上只有0.02%。

过多的变量会妨碍查找规律的建立。

仅在变量层面上分析可能会忽略变量之间的潜在联系。例如几个预测变量可能落入仅反映数据某一方面特征的一个组内。

降维的目的

  • 减少预测变量的个数
  • 确保这些变量是相互独立的
  • 提供一个框架来解释结果
  • 降维的方法
  • 主成分分析
  • 因子分析
  • 用户自定义复合

有关PCA

PCA概念

主成分分析 ( Principal Component Analysis , PCA )或者主元分析。是一种掌握事物主要矛盾的统计分析方法,它可以从多元事物中解析出主要影响因素,揭示事物的本质,简化复杂的问题。计算主成分的目的是将高维数据投影到较低维空间。给定 n 个变量的 m 个观察值,形成一个 n * m 的数据矩阵, n 通常比较大。对于一个由多个变量描述的复杂事物,人们难以认识,那么是否可以抓住事物主要方面进行重点分析呢?如果事物的主要方面刚好体现在几个主要变量上,我们只需要将这几个变量分离出来,进行详细分析。但是,在一般情况下,并不能直接找出这样的关键变量。这时我们可以用原有变量的线性组合来表示事物的主要方面, PCA 就是这样一种分析方法。

PCA作用范围

PCA 主要用于数据降维,对于一系列例子的特征组成的多维向量,多维向量里的某些元素本身没有区分性,比如某个元素在所有的例子中都为1,或者与1差距不大,那么这个元素本身就没有区分性,用它做特征来区分,贡献会非常小。所以我们的目的是找那些变化大的元素,即方差大的那些维,而去除掉那些变化不大的维,从而使特征留下的都是“精品”,而且计算量也变小了。 对于一个K维的特征来说,相当于它的每一维特征与其他维都是正交的(相当于在多维坐标系中,坐标轴都是垂直的),那么我们可以变化这些维的坐标系,从而使这个特征在某些维上方差大,而在某些维上方差很小。

PCA的算法步骤

  1. 设有m条n维数据。

  2. 将原始数据按列组成n行m列矩阵X

  3. 将X的每一行(代表一个属性字段)进行零均值化,即减去这一行的均值

  4. 求出协方差矩阵C=1/mXX’

  5. 求出协方差矩阵的特征值及对应的特征向量

  6. 将特征向量按对应特征值大小从上到下按行排列成矩阵,取前k行组成矩阵P

  7. Y=PX即为降维到k维后的数据

小结

PCA的应用分析

对于一个训练集,100个对象模板,特征是10维,那么它可以建立一个100*10的矩阵,作为样本。求这个样本的协方差矩阵,得到一个10*10的协方差矩阵,然后求出这个协方差矩阵的特征值和特征向量,应该有10个特征值和特征向量,我们根据特征值的大小,取前四个特征值所对应的特征向量,构成一个10*4的矩阵,这个矩阵就是我们要求的特征矩阵,100*10的样本矩阵乘以这个10*4的特征矩阵,就得到了一个100*4的新的降维之后的样本矩阵,每个特征的维数下降了。当给定一个测试的特征集之后,比如1*10维的特征,乘以上面得到的10*4的特征矩阵,便可以得到一个1*4的特征,用这个特征去分类。所以做PCA实际上是求得这个投影矩阵,用高维的特征乘以这个投影矩阵,便可以将高维特征的维数下降到指定的维数。

在进行基因表达数据分析时,一个重要问题是确定每个实验数据是否是独立的,如果每次实验数据之间不是独立的,则会影响基因表达数据分析结果的准确性。对于利用基因芯片所检测到的基因表达数据,如果用 PCA 方法进行分析,可以将各个基因作为变量,也可以将实验条件作为变量。当将基因作为变量时,通过分析确定一组“主要基因元素”,它们能够很好地说明基因的特征,解释实验现象;当将实验条件作为变量时,通过分析确定一组“主要实验因素”,它们能够很好地刻画实验条件的特征,解释基因的行为。

PCA作为基础的数学分析方法,其实际应用十分广泛,比如人口统计学、数量地理学、分子动力学模拟、数学建模、数理分析等学科中均有应用,是一种常用的多变量分析方法。

PCA优缺点

优点

  • 以方差衡量信息的无监督学习,不受样本标签限制;
  • 各主成分之间正交,可消除原始数据成分间的相互影响;
  • 可减少指标选择的工作量;
  • 用少数指标代替多数指标,利用PCA降维是最常用的算法;
  • 计算方法简单,易于实现。

缺点

  • 主成分解释其含义往往具有一定的模糊性,不如原始样本完整;
  • 贡献率小的主成分往往可能含有对样本差异的重要信息;
  • 特征值矩阵的正交向量空间是否唯一有待讨论;
  • 属于无监督学习。

代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
Created on Tue Nov 29 15:51:25 2016
@author: kuangmeng
"""
import numpy as np
import matplotlib.pyplot as plt
#全局变量定义区
XLabel = list()
YLabel = list()
phi = [0., 0.]
#自己定义的矩阵转换函数
def Transport(matrix):
temp = list()
for i in range(len(matrix[0])):
temp.append(list())
for j in range(len(matrix)):
temp[i].append(matrix[j][i])
return temp
#加载文件(可以通过更改文件名来加载不同的测试数据)
data_set = open('testSet.txt', 'r')
for line in data_set.readlines():
data_line = line.strip().split()
tmpx = float(data_line[0])
tmpy = float(data_line[1])
phi[0] += tmpx
phi[1] += tmpy
XLabel.append(tmpx)
YLabel.append(tmpy)
phi[0] = phi[0]/100.0
phi[1] = phi[1]/100.0
data_set.close()
#加载结束
temp_x = list()
for i in range(100):
temp_x.append([XLabel[i]-phi[0], YLabel[i]-phi[1]])
temp_x_ = Transport(temp_x)
sigma = np.dot(temp_x_, temp_x)
D,V= np.linalg.eig(sigma)
for i in range(2):
for j in range(2):
V.real[i][j] *= -1
temp_v_ = Transport(V.real)
tr1 = list()
tr1.append(XLabel)
tr1.append(YLabel)
tr1 = Transport(tr1)
xr1 = np.dot(tr1, temp_v_[0])
xr2 = np.dot(phi, temp_v_[1])
xr = tr1
# print xr
for i in range(len(XLabel)):
xr[i][0] = np.dot(xr1[i], V.real[0][0])+np.dot(xr2, V.real[0][1])
xr[i][1] = np.dot(xr1[i], V.real[1][0])+np.dot(xr2, V.real[1][1])
# print xr
plt.plot(XLabel, YLabel, 'r+')
temp_xr = Transport(xr)
plt.plot(temp_xr[0], temp_xr[1], 'b*')
for i in range(len(XLabel)):
plt.plot([XLabel[i],xr[i][0]], [YLabel[i],xr[i][1]])
plt.axis([-8,6,-5,5])
plt.xlabel = 'x'
plt.ylabel = 'y'
plt.show()



The link of this page is https://blog.nooa.tech/articles/6c0d033f/ . Welcome to reproduce it!

© 2018.02.08 - 2024.05.25 Mengmeng Kuang  保留所有权利!

:D 获取中...

Creative Commons License