Featured image of post 数据可视化笔记

数据可视化笔记

数据挖掘中数据可视化的学习笔记

# 主成分分析(PCA)

# 基本思想

PCA顾名思义,就是找出数据里最主要的方面,用数据里最主要的方面来代替原始数据。具体的,假如我们的数据集是n维的,共有m个数据$(x^{(1)},x^{(2)},…,x^{(m)})$。我们希望将这m个数据的维度从n维降到n’维,希望这m个n’维的数据集尽可能的代表原始数据集。

通过计算数据矩阵的协方差矩阵,然后得到协方差矩阵的特征值特征向量,选择特征值最大(即方差最大)的k个特征所对应的特征向量组成的矩阵。这样就可以将数据矩阵转换到新的空间当中,实现数据特征的降维。

由于得到协方差矩阵的特征值特征向量有两种方法:特征值分解协方差矩阵、奇异值分解协方差矩阵,所以PCA算法有两种实现方法:基于特征值分解协方差矩阵实现PCA算法、基于SVD分解协方差矩阵实现PCA算法。

# 特征值分解(EVD)

特征值和特征向量的定义如下:

$$ Ax=\lambda x $$

其中A是一个$n \times n$的实对称矩阵,$x$是一个$n$维向量,则我们说$\lambda$是矩阵A的一个特征值,而$x$是矩阵A的特征值$\lambda$所对应的特征向量。

求出特征值和特征向量有什么好处呢? 就是我们可以将矩阵A特征分解。如果我们求出了矩阵A的$n$个特征值$\lambda_1 \leq \lambda_2 \leq … \leq \lambda_n$,以及这$n$个特征值所对应的特征向量${q_1,q_2,…q_n}$,如果这$n$个特征向量线性无关,那么矩阵A就可以用下式的特征分解表示:$A=Q\Sigma Q^{-1}$ 。

其中,Q是这个矩阵A的特征向量组成的矩阵,Σ是一个对角矩阵,每一个对角线元素就是一个特征值,里面的特征值是由大到小排列的,这些特征值所对应的特征向量就是描述这个矩阵变化方向(从主要的变化到次要的变化排列)。也就是说矩阵A的信息可以由其特征值和特征向量表示。

注意到要进行特征分解,矩阵A必须为方阵。那么如果A不是方阵,即行和列不相同时,我们还可以对矩阵进行分解吗?答案是可以,此时我们的SVD登场了。

# 奇异值分解(SVD)

SVD也是对矩阵进行分解,但是和特征分解不同,SVD并不要求要分解的矩阵为方阵。假设我们的矩阵A是一个$m \times n$的矩阵,那么我们定义矩阵A的SVD为:

$$ A = U\Sigma V^T $$

其中U是一个$m \times m$的矩阵,$\Sigma$是一个$m \times n$的矩阵,除了主对角线上的元素以外全为0,主对角线上的每个元素都称为奇异值,V是一个$n \times n$的矩阵。

计算方法:

  • 我们将A的转置和A做矩阵乘法,那么会得到$n \times n$的一个方阵$A^TA$。对其进行特征值分解,得到n个特征值和对应的n个特征向量$v$了。将$A^TA$的所有特征向量张成一个$n \times n$的矩阵V,就是我们SVD公式里面的V矩阵了。
  • 对$AA^T$进行特征值分解,得到m个特征值和对应的m个特征向量$u$了。将$AA^T$的所有特征向量张成一个$m \times m$的矩阵U,就是我们SVD公式里面的U矩阵了。一般我们将U中的每个特征向量叫做A的左奇异向量。
  • 由于奇异值矩阵$\Sigma$除了对角线上是奇异值其他位置都是0,那我们只需要求出每个奇异值$\sigma$就可以了。求解奇异值可以用$\sigma_i = Av_i / u_i$或$\sigma_i = \sqrt{\lambda_i}$

# 算法过程

输入:n维样本集$D=(x^{(1)}, x^{(2)},…,x^{(m)})$,要降维到的维数n'.

输出:降维后的样本集$D'$

  1. 对所有的样本进行中心化: $x^{(i)} = x^{(i)} - \frac{1}{m}\sum\limits_{j=1}^{m} x^{(j)}$
  2. 计算样本的协方差矩阵$XX^T$
  3. 对矩阵$XX^T$进行特征值分解
  4. 取出最大的n’个特征值对应的特征向量$(w_1,w_2,…,w_{n’})$, 将所有的特征向量标准化后,组成特征向量矩阵W。
  5. 对样本集中的每一个样本$x^{(i)}$,转化为新的样本$z^{(i)}=W^Tx^{(i)}$
  6. 得到输出样本集$D’ =(z^{(1)}, z^{(2)},…,z^{(m)})$

上面是采用EVD,如果采用SVD,在第二第三步时就用SVD进行解决。

# 编程实现

 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
load fisheriris;
X = meas;
%% 中心化
meanX = ones(size(X,1), 1) * mean(X);
centredX = X - meanX;
% 直接调用cov直接计算协方差矩阵即可
C = cov(centredX);
%% 特征值分解
[W, Lambda] = eig(C);
% 提取特征值
ev = (diag(Lambda))';
% eig计算出的特征值是升序的,这里手动倒序(W同理)
ev = ev(:, end:-1:1); 
W = W(:, end:-1:1);
% 提取前两个主成分的特征向量
Wr = W(:, 1:2);
% 新坐标空间的数据点
Tr = centredX * Wr;
%% 作图
figure(1);
scatter(Tr(:,1), Tr(:,2), 130, categorical(species), '.');
colormap(winter);
xlabel('Principal Component 1');
ylabel('Principal Component 2');
%% SVD分解
% 可以检验,W和V完全相同(向量的正负号不影响)
[U, Sigma, V] = svd(X);
% 提取前两个主成分的特征向量
Vr = V(:, 1:2);
% 新坐标空间的数据点
Tr = X * Vr; 
%% 作图
figure(2);
scatter(Tr(:,1), Tr(:,2), 130, categorical(species), '.');
colormap(winter);
xlabel('Principal Component 1');
ylabel('Principal Component 2');

EVD

SVD

# MATLAB三维数据绘图

# 三维线

使用plot3()函数即可绘制三维线,输入应为三个向量

1
2
3
4
5
6
7
8
turns = 40*pi;
t = linspace(0,turns,4000);
x = cos(t).*(turns-t)./turns;
y = sin(t).*(turns-t)./turns;
z = t./turns;
plot3(x,y,z);
grid on;
axis square;

螺旋线

# 三维图形绘制及等高线

我们可以通过使用mesh()命令绘制三维面,使用contour()命令可以绘制三维图形的等高线。 与之前的命令一样,我们也可以通过向其传递不同的参数来改变图形的细节。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
x = -3.5:0.2:3.5; y = -3.5:0.2:3.5;
[X,Y] = meshgrid(x,y);
Z = 10.*X.*exp(-X.^2-Y.^2);

grid on;
axis square;
subplot(1,2,1);
mesh(X,Y,Z);
subplot(1,2,2);
contour(X,Y,Z,'ShowText', 'on', 'LevelStep', 1);

三维图形绘制及等高线

三维图形绘制及等高线

# 参考资料