SVD的应用
利用SVD,我们可以简化数据,使用小很多的数据集来表示原始数据集。这样做,实际上去除了噪声和冗余信息。我们可以把SVD看成是从有噪声的数据中抽取相关特征。下面是SVD的主要应用。
隐性语义索引
SVD最早的应用之一就是信息检索。我们称利用SVD的方法为隐性语义索引(LSI)或隐性语义分析(LSA)。
在LSI中,一个矩阵是由文档和词语共同组成的。当我们在该矩阵上应用SVD的时候,就会构建出多个奇异值。这些奇异值代表了文档中的概念或主题,这一特点可以用于更高效的文档搜索。在词语拼写错误时,只基于词语存在与否的简单搜索方式会遇到问题。当我们查找一个词时,其同义词所在的文档可能不会匹配上。如果我们从上千篇相似的文档中抽取概念,那么同义词就会映射到同一概念。
推荐系统
另一个主要应用就是推荐系统。较为先进的推荐系统先利用SVD从数据中构建一个主题空间,然后再在该空间下计算相似度,以此提高推荐的效果。
矩阵分解
很多情况下,数据中的一小段携带了数据集中的大部分信息。矩阵分解可以将原始矩阵表示成新的易于处理的形式,这种新的形式就是两个或多个矩阵的乘积。
不同的矩阵分解技术具有不同的性质。最常见的一种矩阵分解技术就是SVD,它将原始数据集矩阵DATA分解为三个矩阵 U , Σ , V T U,\Sigma,V^{T} U,Σ,VT。如果原始矩阵是m行n列,那么 U , Σ , V T U,\Sigma,V^{T} U,Σ,VT分别是m行m列,m行n列和n行n列,为了清晰起见,上面的过程可以写作:
D a t a m ∗ n = U m ∗ m Σ m ∗ n V n ∗ n T Data_{m*n}=U_{m*m}\Sigma_{m*n}V^{T}_{n*n} Datam∗n=Um∗mΣm∗nVn∗nT
上述分解中会构建出一个矩阵 Σ \Sigma Σ,该矩阵只有对角元素,其他元素均为0.另一个惯例是, Σ \Sigma Σ的对角元素是从大到小排列的。这些对角元素称为奇异值,他们对应了原始数据Data中的奇异值。和PCA中的特征值一样, Σ \Sigma Σ中的奇异值也体现了数据集中的重要特征。奇异值和特征值是有关系的。这里的奇异值就是矩阵 D a t a ∗ D a t a T Data*Data^{T} Data∗DataT特征值的平方根。
矩阵 Σ \Sigma Σ只有从大到小排列的对角元素,.在科学和工程中,一直存在这样一个普遍事实:在某个奇异值的数目(r个)之后,其他奇异值都置为0。这就意味着数据集中仅有r个重要特征,其余的都是噪声或冗余数据。
利用python实现SVD
python中的Numpy包内有一个linalg的线性工具,可以使用它直接计算SVD的结果,不需要专门研究对应的线性代数的知识,我们举一个例子,有如下这个矩阵:
[ 1 1 7 7 ] \left [ \begin{matrix} 1 &1 \\ 7 & 7 \\ \end{matrix} \right ] [1717]
我们使用该函数来计算它的SVD。
data=[[1,1],[7,7]]
u,sigma,vt=np.linalg.svd(data)
得到如下结果:
u: [[-0.14142136 -0.98994949]
[-0.98994949 0.14142136]]
sigma: [1.00000000e+01 2.82797782e-16]
vt: [[-0.70710678 -0.70710678]
[ 0.70710678 -0.70710678]]
可以看到 Σ \Sigma Σ是以行向量的形式出现,因为该矩阵除了对角元素以外其他元素均为0,这样的格式更节省空间。
接下来再看一个大的数据集,我们建立如下的数据集:
def loadData1():