降维技术

对数据进行简化降维的原因:

  • 使得数据更易使用
  • 使得数据更易可视化
  • 降低很多算法的开销
  • 去除噪声
  • 使得结果易懂

数据降维方法主要有三种:

  • 主成分分析(Principal Component Analysis, PCA)
    在PCA中,数据从原来的坐标系转换到了新的坐标系,新坐标系的选择由原始数据本身决定。第一个新坐标轴选择的是原始数据中方差最大的方向,第二个新坐标轴的选择是和第一个坐标轴正交而且具有最大方差的方向。此过程一直反复,重复次数为原始数据中的特征数目。
    大部分方差都包含在最前面的几个新坐标轴中。
  • 因子分析(Factor Analysis)
    在因子分析中,假设在观察数据的生成中有一些观察不到的隐变量(latent variable)。假设观察数据是这些隐变量和某些噪声的线性组合。那么隐变量的数据可能比观察数据的数目少,即通过找到隐变量就可以实现数据降维。
  • 独立成分分析(Independent Component Analysis, ICA)
    ICA假设数据是从N个数据源生成的,这一点和因子分析有些类似。假设数据为多个数据源的混合观察结果,这些数据源之间在统计上是相互独立的,而在PCA中只假设数据是不相关的。同因子分析一样,数据源数目少于观察数据数目时,即可实现降维。

PCA

将数据转换成前N个主成分的PCA伪代码如下:

去除平均值
计算协方差矩阵
计算协方差矩阵的特征值和特征向量
将特征值从大到小排序
保留最上面的N个特征向量
将数据转换到上述N个特征向量构建的空间中
In [2]:
import pca
In [3]:
import numpy as np
In [4]:
dataMat = pca.loadDataSet('testSet.txt')
In [5]:
lowDMat, reconMat = pca.pca(dataMat, 1)
In [6]:
np.shape(lowDMat)
Out[6]:
(1000, 1)
In [7]:
import matplotlib.pyplot as plt
In [8]:
fig = plt.figure()
In [9]:
ax = fig.add_subplot(111)
In [10]:
ax.scatter(dataMat[:,0].flatten().A[0], dataMat[:,1].flatten().A[0], marker='^', s=20)
Out[10]:
<matplotlib.collections.PathCollection at 0x9002b70>
In [11]:
ax.scatter(reconMat[:,0].flatten().A[0], reconMat[:,1].flatten().A[0], marker='o', s=10, c='red')
Out[11]:
<matplotlib.collections.PathCollection at 0x8fe8330>
In [12]:
plt.show()
In [13]:
lowDMat, reconMat = pca.pca(dataMat, 2)
In [14]:
fig = plt.figure()
In [15]:
ax = fig.add_subplot(111)
In [16]:
ax.scatter(dataMat[:,0].flatten().A[0], dataMat[:,1].flatten().A[0], marker='^', s=20)
Out[16]:
<matplotlib.collections.PathCollection at 0x48d2d50>
In [17]:
ax.scatter(reconMat[:,0].flatten().A[0], reconMat[:,1].flatten().A[0], marker='o', s=10, c='red')
Out[17]:
<matplotlib.collections.PathCollection at 0x9143a70>
In [18]:
plt.show()
In [19]:
reload(pca)
Out[19]:
<module 'pca' from 'pca.pyc'>
In [20]:
dataMat = pca.replaceNanWithMean()
In [21]:
meanVals = np.mean(dataMat, axis=0)
In [22]:
meanRemoved = dataMat - meanVals
In [23]:
covMat = np.cov(meanRemoved, rowvar=0)
In [24]:
print type(covMat)
<type 'numpy.ndarray'>
In [25]:
eigVals, eigVects = np.linalg.eig(np.mat(covMat))
In [26]:
eigVals[:20]
Out[26]:
array([ 53415197.85687523,  21746671.90465922,   8248376.61529075,
         2073880.85929397,   1315404.38775829,    467693.55734419,
          290863.55541773,    283668.60065106,    237155.82977109,
          208513.83582176,    196098.84856314,    186856.54901859,
          152422.35398714,    113215.03198428,    108493.84818587,
          102849.53283606,    100166.16423586,     83347.37616028,
           81585.05905974,     77656.05239293])