Python AI 教学|SVD(Singular Value Decomposition)算法及应用

2019-10-18 15:41:25 浏览数 (1)

1 SVD简介

1.1 特征值分解

如果一个向量v是方阵A的特征向量,则将其可以表示为Av=λv。λ被称为特征向量v对应的特征值。

特征值分解是将一个矩阵分解成下面的形式:

Q是这个矩阵A的特征向量组成的矩阵,Σ是一个对角矩阵,每一个对角线上的元素就是一个特征值。一个矩阵的一组特征向量是一组正交向量。

1.2奇异值分解

提取数据背后因素的方法称为奇异值分解(SVD),SVD使能够用小得多的数据集来表示原始数据集,这样做去除了噪声和冗余信息,我们可以把SVD看成是从噪声数据中抽取相关特征。

(1)奇异值分解定义

奇异值分解指将一个矩阵A(m*n)分解为如下形式:

(其中,U是左奇异矩阵,由左奇异向量组成;V是右奇异矩阵,由右奇异向量组成。)

下图是一个对角矩阵,其除了对角线上的元素外,其余均为0。形如:

该矩阵的对角元素便是奇异值(singular value),一般情况下奇异值是按从大到小排列的。为了节省存储空间,在奇异值分解算法中,只存储σ 值,而不是一个对角矩阵。

(2)奇异值特性

奇异值σ 的减少特别的快,在很多情况下,前10%甚至1%的奇异值的和就占了全部的奇异值之和的99%以上了,则也可以用前r大的奇异值来近似描述矩阵:

(3)奇异值分解与特征值分解的关系

将矩阵A(m*n)和其转置相乘,将得到一个方阵,对这个方阵求特征值可以得到:

v就是矩阵A(m*n)的进行SVD的右奇异向量,同时还有:

σ就是矩阵A(m*n)的奇异值,u则是左奇异向量。

2 SVD算法实现

2.1分解过程

【1】算法实现:

【2】运行结果(python3):

2.2重构过程

由上图可知Sigma的值中,前两个比后面两个大了很多,我们可以将最后两个值去掉,则原始数据集就可以用如下结果来近似:

【1】重构过程示意图:

(其中浅灰色区域是原始数据,深黑色区域是矩阵近似计算仅需要的数据)

【2】重构算法:

【3】运行结果:

(补充:确定要保留的奇异值的数目有很多启发式的策略,其中一个做法就是保留矩阵中90%的能量信息,先将所有的奇异值求其平方和计算出总能量信息,再按照从大到小的顺序将奇异值的平方和累加到大于等于总值的90%为止。举个例子,比如某矩阵分解后得到10个奇异值,这些奇异值的总平方和为500,500*90%=450,则需要累加的奇异值能量和至少为450。按顺序累加,前3个奇异值平方和为100,前5个奇异值的平方为400,前6个平方和为460,则经过计算,重构矩阵的时候,取前6个奇异值。)

函数说明(一)

【1】mat函数

将输入解释为矩阵

语法:numpy.mat(data, dtype=None)

等价于matrix(data, copy=False)

算法示例:

3 SVD应用

SVD在数据压缩(如PCA)、推荐算法、矩阵补全、潜在语义索引(LSI)等领域都有着广泛的应用,这里将详细介绍基于SVD的推荐引擎实现。推荐系统存在于我们生活的各个角落,比如淘宝会给我们推荐我们可能感兴趣的物品,网易云音乐有每日推荐的20首歌,大众点评也会给我们推荐餐厅等。相关的推荐算法有基于内容推荐、协同过滤、关联规则、混合推荐等等。

3.1 基于协同过滤的推荐引擎

协同过滤(collaborative filtering)指通过将用户和其他用户的数据进行对比实现推荐。比如要判断是否给某个用户推荐一部他还没有看过的电影,则可以先将这部电影与用户看过的电影进行比较,如果相似度很高则认为用户会喜欢这部电影,则进行推荐;反之则不推荐。

(1)相似度

假设有一个用户和电影的数据集,我们可以将用户和电影的对应关系看成一个矩阵,如下图所示,行代表用户,列表示电影,矩阵的元素中0表示用户没有看过,1-5表示用户对这部电影的喜爱程度,值越大代表用户越喜欢这部电影。

【1】欧氏距离

电影“一”和“三”的欧氏距离为:

电影“二”和“三”的欧氏距离为:

相似度= ,当距离为0时候,相似度为1,随着距离的增大,相似度减小。

算法实现:

【2】皮尔逊相关系数(Pearson correlation)

它度量的是两个向量之间的相似度。该方法相对于欧氏距离的一个优势在于,它对用户评级的量级并不敏感。皮尔逊相关系数的取值范围从-1到 1,通过0.5 0.5*corrcoef()这个函数把其取值范围归一化到0-1之间。

算法实现:

【3】余弦相似度(cosine similarity )

计算的是两个向量夹角的余弦值,两个向量之间的夹角为:

余弦相似度的取值范围也在-1到 1之间,因此借助0.5 0.5*()也将它归一化到0到1之间。

算法实现:

函数说明(二)

【1】 norm函数

用来计算向量或矩阵范数的函数,同svd一样属于numpy库中的linalg。

语法:numpy.linalg.norm(x,p)

【注释:①x表示向量或者矩阵;②p表示范数的种类:p=1计算1-范数;p=2计算2-范数,同norm(x);p=inf计算无穷范数;p='fro',计算Frobenius范数】

算法示例:

【2】 corrcoef函数

用来计算皮尔逊相关系数

语法:numpy.corrcoef(x, y=None, rowvar=True)

【注释:x为矩阵或者向量,y和x的shape一样】

算法示例:

(2)基于电影内容的相似度计算

【1】数据生成

【2】调取数据

【3】运行结果

(补充:除了上述基于物品(item-based)的相似度外,还可以基于用户(user-based)的相似度计算,使用哪一种相似度取决于用户或物品的数目。因为观看电影人数远远高于电影的数目,所以基于电影的推荐会比基于人的推荐花费更短的时间,但是这种基于item推荐的缺点在于对用户历史喜好数据的量及准确性依赖较强,对小众喜好的用户,推荐效果不佳;)

(3)基于电影内容的推荐引擎

目的是构建一个推荐引擎,寻找到用户没有观看过的电影,算法需要实现的事情包括:①寻找用户没有观看过的电影——矩阵中的0值②在上述没看过的电影中对每部电影预计一个用户可能给予的等级——基于相似度计算③对这些电影的评分从高到低进行排序,返回前N个item。

【1】估计评分

【2】推荐电影

【3】调取数据

【4】运行结果

结果表明用户3(从0开始数,数字2对应于第3个用户)对电影3的评分为2.3(因为用户3只有一部电影没有评级,因此算法只返回一个结果)。

使用另两种相似度计算实现对未观看电影的评级:

函数说明(三)

【1】range函数

是一个python自带的来创建包含算术级数的列表。它最常用于for循环。

语法:range(start, stop[, step])

【注释:①start,是列表起始值,省略时默认为0;②stop,是列表最大能够达到的值,列表最后一个元素小于等于stop值;③step是步长】

算法示例:

【2】append函数

用于在列表末尾添加新的对象

语法:list.append(obj)

【注释:obj表示添加到列表末尾的对象】

算法示例:

【3】logcal_and函数

逻辑与

语法:numpy.logical_and(x1, x2)

逻辑函数包括:

算法示例:

3.2 基于SVD的推荐引擎

现实生活中的数据集会比前文协同过滤用到的矩阵稀疏得多,因为观众不可能看过近乎全部的电影,所以需要通过SVD来减少特征空间并提高推荐的效果。详情可以查阅Netflix推荐算法大赛,里面用到了很多的比较复杂推荐算法,而且推荐准确率也很高。

【1】数据生成

同样保存在“svdRec.py”中

【2】SVD过程

运行结果:

截止第5个奇异值累加能量和高于总能量的90%,于是我们可以将一个11维的矩阵转换成一个5维的矩阵。

【3】推荐实现

这里还是用到了协同过滤里面的推荐算法,只是将相似度的计算模块替换成了基于SVD的相似度计算模块。

运行结果:

基于默认的余弦相似度进行推荐top-3:

基于皮尔逊相关系数进行推荐top-3:

函数说明(四)

【1】eye函数

生成对角矩阵

语法:numpy.eye(M, k)

【注释:①M方阵的规模,即行数、列数;②k默认为0,输出对角线全“1”,其余全“0”的方阵;k为正整数,右上方第k条对角线全“1”其余全“0”; k为负整数,左下方第k条对角线全“1”其余全“0”】

算法示例:

责编 | 罗 栾 申

指导 | 老薛

指导教授简介:

薛巍立,男,博士,东南大学经济管理学院教授,博士生导师,国家自然科学基金优秀青年基金项目获得者。博士毕业于中国香港中文大学系统工程与工程管理系,主要从事供应链物流管理、运营风险管理和医疗服务运作管理等。主要成果发表在Operations Research、Production and Operations Management、Transportation Science、European Journal of Operational Research、Operations Research Letters等期刊上。

0 人点赞