SVD(single value Decomposition,奇异值分解)在机器学习中经常出现,是一类用来降维的方法,在图像处理方面,是一类用来降噪降秩的方法,在推荐系统中,发展成为一系列基于矩阵分解类模型。
笔者经历尚浅,暂时认为降维降秩和推荐系统中的一系列算法在应用上不应该混为一谈。
数学中的SVD
SVD是应用广泛 的数学方法,属于 矩阵分析 的范畴,它代表一种矩阵分解的方式——一个m*n的矩阵分解成两个酉矩阵和一个对角线矩阵(酉矩阵即即满足 矩阵的转置*矩阵== I单位矩阵)。
直观的看,SVD分解就是下图中的步骤:
SVD分解的详细证明过程可见 《矩阵分析(第四版)》P84。
刘建平的博客中有SVD计算的例子:https://www.cnblogs.com/pinard/p/6251584.html
-------------------------------------------------------------------------------------------------------------------------------------
图像处理中的SVD——降秩降噪
SVD方法本质上只是将一个矩阵分解成了三个矩阵,而要做到降噪降秩则是利用了SVD的一些性质:
首先我们要知道,SVD分解出来的三个矩阵,分别代表了什么。
设A为原矩阵,U、∑、VT为分解出来的三个矩阵。
U实质上是A*AT的特征向量的堆叠,V是AT*A这个矩阵的特征向量的堆叠,∑的对角线上则是特征值。
SVD有这样一条性质:∑对角线上的特征值所对应特征向量包含的能量,从左上往右下是一个递减过程,而且还是跨度极大的递减。一般前面很少几个特征值能能量总和就包含了整体能量的百分之九十。
有了这条性质,我们就知道降噪降秩是怎么玩的了——将前面那些包含大部分能量的拿出来用,其他的舍弃掉。
降秩降噪
将原本的三个矩阵(下标代表矩阵的shape)裁剪成。
由裁剪后的乘起来得到的结果与A矩阵不同,但是保留了A矩阵百分之九十(九十是自己算的,求∑矩阵里面的元素平方占所有对角线元素的百分比)的能量,去除了许多无用的信息,这就是用于图片降噪的原理(当然前提是我们知道图片可以用矩阵来表示)。
有一点值得注意,也是我一直误解的地方,当初想当然的认为得到的结果与原矩阵A相比维度降低了,但是仔细看一下,其实它的结果矩阵与矩阵A,两者shape是一样的,这个操作是降噪降秩,并没有降维。
-------------------------------------------------------------------------------------------------------------------------------------
机器学习中的SVD
机器学习降维方法中的SVD应该称之为 截断SVD(Truncated Single Value Decomposition),事实上,sikit-learn中就是这么命名的。
我们已经知道了三个矩阵各自怎么来的,大概了解代表了怎么样的意义,并且知道它如何做到了降噪,那么降维,也不难理解。
降维
截断svd只是使用U矩阵和 ∑矩阵 的一部分相乘得到的。
即 结果 = ,这样求得的矩阵显然是将列维度降到了k。
如果需要压缩样本数量,同样可以使用 ∑矩阵右乘VT矩阵,不使用U矩阵,即 。
至于为什么可以用来近似结果而舍弃V,我暂时的理解是U和V都是A和AT的特征向量矩阵,其代表的信息是相同的,只取一边即可,深一点的原因暂时没有了解到。
-------------------------------------------------------------------------------------------------------------------------------------
推荐系统中的SVD
重点来了,推荐系统的SVD系列算法,这个系列的算法来自于NLP领域的隐语义模型LFM的LSI算法,虽然是叫着SVD,但是用起来一点儿也感觉不到矩阵分解的存在,真的(网上也找不到这个问题的答案,有过路大佬还望指点)。
首先提一下在《机器学习实战》中,提出的推荐系统中SVD的用法还是最原始的用法,大概是这样的:
对用户-物品的评分矩阵进行SVD,将物品映射到低维空间,然后计算相似度,无论是用户相似度还是物品相似度,只要有了,就可以推荐了。
但是,这种做法一般是没有什么意义的,因为一般(绝大部分)推荐系统中的用户-物品评分矩阵都是极其极其稀疏的,简单地仅仅使用很少的已知信息很容易导致过拟合。而我们又没有好的方法去填充缺失值的部分。
Funk SVD
就是从它开始,让我对这个名字产生了怀疑。
funk SVD原理是这样的: 将原本的用户-物品评分矩阵 用 两个矩阵 Q 和 P的乘积来近似,如何近似?用梯度下降之类的优化算法。
公式来表示: , Q和P的shape分别了m*f、f*n,f为超参,代表了隐含主题数(如电影推荐系统,Q中每一行代表用户u对喜剧、恐怖等元素的喜爱程度,而P中每一行代表了电影i含有的喜剧、恐怖等元素的比例)。
用A矩阵中的每一个评分来表示:
解释一下:一个评分的预测的根据是 该用户对各种主题元素的喜爱程度以及该电影拥有的这些主题元素的比例。
可以发现,整个P矩阵和Q矩阵都是需要拟合的参数,下一步该考虑的就是怎么拟合,怎么创造出这两个矩阵?
回到机器学习的套路中来,损失函数闪亮登场:
, 即.
通过最小化损失函数来求解,一般LFM使用SGD和交替最小二乘法来迭代参数。
随机梯度下降SGD计算如下:
, α为超参。
Basic SVD
Basci SVD在Funk SVD之上做了优化,加入了“基准”。
什么是“基准”?对于一个用户来说,他对物品评分的标准(如一个人最好只给四星,最差只给两星,另一个人却只给五星和一星)。对于一个物品来说,也有基准,是所有评分过的用户对这个物品的平均喜好。
用来表示整体平均分,用表示用户u所有评分与的偏差,表示物品i所有评分与的偏差,则得到Basic SVD公式:
SVD++
SVD++在Basic SVD的基础上,又考虑了隐式数据的反馈。
先上公式: , 代表用户u已有的隐式反馈数据集合。
什么是隐式反馈数据? 其实有很多,比如一个电影推荐系统,一个用户虽然没有评论某个电影,但是他搜索过这个电影或者打开过这个电影,这些交互行为并没有显示的告诉我们用户对电影的评价,但是我们可以认为用户对这个电影可能有兴趣。
上式中的即可以这样理解:无论用户对该电影评分多少,他都有打开这一电影看的这一行为,那么说明他对这部电影的某种主题或者某些主题感兴趣。SVD++要做的,就是从这种隐式反馈中发现用户感兴趣的元素。
当然,如果隐式反馈数据不止一种,我们变换公式形式就可以了,如下: