原理
下面以 从4维降到2维
为例:
如果有一组n个样本的数据,
身高 | 体重 | 变量3 | 变量4 |
---|---|---|---|
x0 | y0 | z0 | w0 |
x1 | y1 | z1 | w1 |
… | … | … | … |
x_(n-1) | y_(n-1) | z_(n-1) | w_(n-1) |
那么可以用一个矩阵表示这组数据 ,为了方便,我们转置一下:
我们的目标是把它降成2维。为什么要降维呢?我们知道,如果数据是一维,我们可以在数轴上标出来,如果数据是二维的,我们可以在平面上画出来,如果是三维以上,就不太好表示了,为了展现数据,我们需要降维。还有另外一个重要的原因是,有些额外的数据可能会影响对建模造成干扰,我们并不需要。以下是我们希望得到的结果:它代表了原数据在两个主要轴向
上的信息。
显然要找到一个变换矩阵W,使得:
下面介绍怎么求这个W矩阵。至于为什么那么求,百度有详细的解释,这里不作介绍。
第一步:是把数据中心化(即让每个维度的均值为0),如下图:
第二步,计算协方差矩阵
因为1/n 对结果没有影响,因此令
第三步:求协方差矩阵
的特征值矩阵。
特征值矩阵就是特征向量构成的矩阵,这里不演示如何求特征值及特征向。
至此,就把需要的变换矩阵求出来了。
示例
以著名的iris数据集为例:
代码:
import numpy as np;
import pandas as pd;
import matplotlib.pyplot as plt;
df = pd.read_excel("iris.xlsx", header = None);
df2 = df.drop(4, axis = 1);
array = df2.to_numpy();
#中心化
array = array.T;
(rows, cols) = array.shape;
for row in range(rows):
array[row] -= (np.sum(array[row]) / cols)
#求协方差矩阵
A = array.dot(array.T);
#求特征值
value,vector = np.linalg.eig(A);
#得到降维的新矩阵
array_new = (vector.T)[0:2,:].dot(array);
#画图
plt.scatter(array_new[0], array_new[1], c = pd.Categorical(df[4]).codes);
plt.show();