一. SVD

1. 基本概念:

(1)定义:提取信息的方法:奇异值分解Singular Value Decomposition(SVD)

(2)优点:简化数据, 去除噪声,提高算法的结果

(3)缺点:数据转换难以想象,耗时,损失特征

(4)适用于:数值型数据

2. 应用:

(1)隐性语义索引(LSI/LSA)

(2)推荐系统

3. 原理——矩阵分解

将原始的数据集矩阵data(m*n)分解成三个矩阵U(m*n), Sigma(n*m), VT(m*n):

对于Sigma矩阵:

  • 该矩阵只用对角元素,其他元素均为零
  • 对角元素从大到小排列。这些对角元素称为奇异值,它们对应了原始数据集矩阵的奇异值
  • 这里的奇异值就是矩阵data特征值的平方根。
  • 在某个奇异值的数目( 1个 )之后,其他的奇异值都置为0。这就意味着数据集中仅有r个重要特征,而其余特征则都是噪声或冗余特征。 
    • 确认r——启发式策略

      • 保留矩阵中90%的能量信息,将奇异值平方和累加加到90%
      • 若有上万奇异值,则保留2-3k

4. 实现:

Numpy中称为linalg的线性代数工具:la.svd()

  1. import numpy as np
  2. from numpy impot linalg as la
  3.  
  4. data = np.array([[4, 4, 0, 2, 2],
  5. [4, 0, 0, 3, 3],
  6. [4, 0, 0, 1, 1],
  7. [1, 1, 1, 2, 0],
  8. [2, 2, 2, 0, 0],
  9. [1, 1, 1, 0, 0],
  10. [5, 5, 5, 2, 0]])
  11.  
  12. U, Sigma, VT = la.svd(data)

二、推荐系统实现

2.1. 基于协同过滤的推荐系统(Collaborate Filtering)

  协同过滤是通过将用户和其他用户的数据进行对比来实现推荐的。

2.1.1 相似度计算

  1. 欧式距离(0~1):

    相似度 = 1/ (1 + 距离)

  2. 皮尔逊相关系数(Pearson correlation):

    

  • 介绍:http://mines.humanoriented.com/classes/2010/fall/csci568/portfolio_exports/sphilip/pear.html
  • 该方法相对于欧氏距离的一个优势在于,它对用户评级的量级并不敏感。比如某个狂躁者对所有物品的评分都是5分 ,而另一个忧郁者对所有物品的评分都是1分,皮尔逊相关系数会认为这两个向量是相等的。
  • 皮尔逊相关系数的计算是由Numpy中的corrcoef()函数,他的取值范围在:(-1~1)
  • 后面我们很快就会用到它了。皮尔逊相关系数的取值范围从-1到+1,
  • 我们通过0.5 + 0 . 5 * corrcoef()把其取值范围归一化到0到 1之间。

3. 余弦相似度(cosine similarity)

    

其中,在Numpy中计算范数的公式:linalg.norm()

  1. def ecludSim(inA,inB):
  2. return 1.0/(1.0 + la.norm(inA - inB)) #计算向量的第二范式,相当于直接计算了欧式距离
  3.  
  4. def pearsSim(inA, inB):
  5. if len(inA) < 3:
  6. return 1.0
  7. return 0.5 + 0.5 * corrcoef(inA, inB, rowvar=0)[0][1]
  8. # corrcoef直接计算皮尔逊相关系数
  9.  
  10. def cosSim(inA, inB):
  11. num = float(inA.T * inB)
  12. denom = la.norm(inA) * la.norm(inB)
  13. return 0.5 + 0.5 * (num/denom)

上面的相似度计算都是假设数据采用了列向量方式进行表示。如果利用上述函数来计算两个行向量的相似度就会遇到问题(我们很容易对上述函数进行修改以计算行向量之间的相似度)。这里采用列向量的表示方法,暗示着我们将利用基于物品的相似度计算方法。

2.1.2 基于物品的相似度还是基于用户的相似度?

行与行之间比较的是基于用户的相似度,列与列之间比较的则是基于物品的相似度。

到底使用哪一种相似度呢?这取决于用户或物品的数目。基于物品相似度计算的时间会随物品数量的增加而增加,基于用户的相似度计算的时间则会随用户数量的增加而增加。如果我们有一个商店,那么最多会有几千件商品。在撰写本书之际,最大的商店大概有100 000件商品。而在\61!«\大赛中,则会有480 000个用户和17 700部电影。如果用户的数目很多,那么我们可能倾向于使用基于物品相似度的计算方法。对于大部分产品导向的推荐引擎而言,用户的数量往往大于物品的数量,即购买商品的用户数会多于出售的商品种类。

2.1.3 推荐系统的评价

  • 采用交叉测试的方法。具体的做法就是,我们将某些已知的评分值去掉,然后对它们进行预测,最后计算预测值和真实值之间的差异。
  • 评价的指标是称为最小均方根误差( RootMeanSquaredError, RMSE ) 的指标。
    • 它首先计算均方误差的平均值然后取其平方根。
    • 如果评级在1星到5星这个范围内,而我们得到的为1.0,那么就意味着我们的预测值和用户给出的真实评价相差了一个星级。

2.1.4 实现:

  1. def loadExData():
  2. return[[4, 4, 0, 2, 2],
  3. [4, 0, 0, 3, 3],
  4. [4, 0, 0, 1, 1],
  5. [1, 1, 1, 2, 0],
  6. [2, 2, 2, 0, 0],
  7. [1, 1, 1, 0, 0],
  8. [5, 5, 5, 2, 0]]
  9.  
  10. def loadExData2():
  11. return[[0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 5],
  12. [0, 0, 0, 3, 0, 4, 0, 0, 0, 0, 3],
  13. [0, 0, 0, 0, 4, 0, 0, 1, 0, 4, 0],
  14. [3, 3, 4, 0, 0, 0, 0, 2, 2, 0, 0],
  15. [5, 4, 5, 0, 0, 0, 0, 5, 5, 0, 0],
  16. [0, 0, 0, 0, 5, 0, 1, 0, 0, 5, 0],
  17. [4, 3, 4, 0, 0, 0, 0, 5, 5, 0, 1],
  18. [0, 0, 0, 4, 0, 4, 0, 0, 0, 0, 4],
  19. [0, 0, 0, 2, 0, 2, 5, 0, 0, 1, 2],
  20. [0, 0, 0, 0, 5, 0, 0, 0, 0, 4, 0],
  21. [1, 0, 0, 0, 0, 0, 0, 1, 2, 0, 0]]
  22.  
  23. # 协同过滤算法
  24. # dataMat 用户数据 user 用户 simMeas 相似度计算方式 item 物品
  25. def standEst(dataMat, user, simMeas, item):
  26. n = shape(dataMat)[1] # 计算列的数量,物品的数量
  27. simTotal = 0.0
  28. ratSimTotal = 0.0
  29. for j in range(n):
  30. userRating = dataMat[user, j]
  31. print(dataMat[user, j])
  32. if userRating == 0:
  33. continue # 如果用户u没有对物品j进行打分,那么这个判断就可以跳过了
  34. overLap = nonzero(logical_and(dataMat[:, item] > 0, dataMat[:, j] > 0))[0] # 找到对物品 j 和item都打过分的用户
  35. if len(overLap) == 0:
  36. similarity = 0
  37. else:
  38. similarity = simMeas(dataMat[overLap, item], dataMat[overLap, j]) # 利用相似度计算两个物品之间的相似度
  39.  
  40. print('the %d and %d similarity is: %f' % (item, j, similarity))
  41. simTotal += similarity
  42. ratSimTotal += similarity * userRating # 待推荐物品与用户打过分的物品之间的相似度*用户对物品的打分
  43. if simTotal == 0:
  44. return 0
  45. else:
  46. return ratSimTotal / simTotal
  47.  
  48. def recommand(dataMat, user, N=3, simMeas=pearsSim, estMethod=standEst):
  49. unratedItem = nonzero(dataMat[user, :]==0)[0]
  50. if len(unratedItem) == 0:
  51. return 'You rated everything'
  52. else:
  53. itemScores=[]
  54. # 对于为评分的item,对他进行评分
  55. for item in unratedItem:
  56. estimatedScore = standEst(dataMat, user, simMeas, item)
  57. itemScores.append((item, estimatedScore))
  58. itemScores = sorted(itemScores, key=lambda jj: jj[1], reverse=True)[:N]
  59. print(itemScores)
  60.  
  61. data = array(loadExData())
  62. recommand(data, 2)

2.2 利用SVD实现推荐

2.2.1 选取Sigma奇异值个数r:

  1. # 获取数据:
  2. data = np.array(loadExData2())
  3.  
  4. # SVD 分解
  5. U, Sigma, VT = la.svd(data)
  6.  
  7. # 计算取几个奇异值
  8. # 计算90%能量:487.83
  9. Sig2 = Sigma ** 2
  10. s = sum(Sig2) * 0.9
  11.  
  12. # 计算前两个奇异值包含能量:378(<487.83)
  13. sum(Sig2[:2])
  14.  
  15. # 计算前三个奇异值包含能量:500(>487)
  16. sum(Sig2[:3])
  17. #所以选择前三个就可以了

2.2.2 用SVD实现推荐系统:

  1. # 利用SVD实现推荐系统
  2. def svdEst(dataMat, user, simMeas, item):
  3. n = shape(dataMat)[1]
  4. simTotal = 0.0
  5. ratsimTotal = 0.0
  6. U, Sigma, VT = la.svd(dataMat)
  7. Sig4 = array(eye(4) * Sigma[:4])
  8. xformedItems = dot(dot(dataMat.T, U[:, :4]), Sig4)
  9.  
  10. for j in range(n):
  11. userRating = dataMat[user, j]
  12. if userRating == 0 or j == item:
  13. continue
  14. similarity = simMeas(xformedItems[item, :].T, xformedItems[j, :].T)
  15. simTotal += similarity
  16. ratsimTotal += userRating * similarity
  17. if simTotal == 0:
  18. return 0
  19. else:
  20. return ratsimTotal/simTotal
  21.  
  22. def recommand(dataMat, user, N=3, simMeas=pearsSim, estMethod=standEst):
  23. unratedItem = nonzero(dataMat[user, :]==0)[0]
  24. if len(unratedItem) == 0:
  25. return 'You rated everything'
  26. else:
  27. itemScores=[]
  28. # 对于为评分的item,对他进行评分
  29. for item in unratedItem:
  30. estimatedScore = svdEst(dataMat, user, simMeas, item)
  31. itemScores.append((item, estimatedScore))
  32. itemScores = sorted(itemScores, key=lambda jj: jj[1], reverse=True)[:N]
  33. print(itemScores)
  34.  
  35. data = array(loadExData())
  36. recommand(data, 2)

最后结果:

2.3 冷启动问题

推荐引擎面临的另一个问题就是如何在缺乏数据时给出好的推荐。这称为冷启动问题,处理起来十分困难。

冷启动问题的解决方案,就是将推荐看成是搜索问题。在内部表现上,不同的解决办法虽然有所不同,但是对用户而言却都是透明的。为了将推荐看成是搜索问题,我们可能要使用所需要推荐物品的属性。在餐馆菜肴的例子中,我们可以通过各种标签来标记菜肴,比如素食、美式88、价格很贵等。同时,我们也可以将这些属性作为相似度计算所需要的数据,这被称为基于内容(content-based)的推荐。可能,基于内容的推荐并不如我们前面介绍的基于协同过滤的推荐效果好 ,但我们拥有它,这就是个良好的开始。

  

《机器学习实战》学习笔记——第14章 利用SVD简化数据的更多相关文章

  1. 【机器学习实战】第14章 利用SVD简化数据

    第14章 利用SVD简化数据 SVD 概述 奇异值分解(SVD, Singular Value Decomposition): 提取信息的一种方法,可以把 SVD 看成是从噪声数据中抽取相关特征.从生 ...

  2. 《机器学习实战》学习笔记第十四章 —— 利用SVD简化数据

    相关博客: 吴恩达机器学习笔记(八) —— 降维与主成分分析法(PCA) <机器学习实战>学习笔记第十三章 —— 利用PCA来简化数据 奇异值分解(SVD)原理与在降维中的应用 机器学习( ...

  3. 机器学习实战 - 读书笔记(14) - 利用SVD简化数据

    前言 最近在看Peter Harrington写的"机器学习实战",这是我的学习心得,这次是第14章 - 利用SVD简化数据. 这里介绍,机器学习中的降维技术,可简化样品数据. 基 ...

  4. 机器学习——利用SVD简化数据

    奇异值分解(Singular Value Decompositon,SVD),可以实现用小得多的数据集来表示原始数据集. 优点:简化数据,取出噪声,提高算法的结果 缺点:数据的转换可能难以理解 适用数 ...

  5. 《机器学习实战》学习笔记第十三章 —— 利用PCA来简化数据

    相关博文: 吴恩达机器学习笔记(八) —— 降维与主成分分析法(PCA) 主成分分析(PCA)的推导与解释 主要内容: 一.向量內积的几何意义 二.基的变换 三.协方差矩阵 四.PCA求解 一.向量內 ...

  6. 【机器学习实战学习笔记(1-1)】k-近邻算法原理及python实现

    笔者本人是个初入机器学习的小白,主要是想把学习过程中的大概知识和自己的一些经验写下来跟大家分享,也可以加强自己的记忆,有不足的地方还望小伙伴们批评指正,点赞评论走起来~ 文章目录 1.k-近邻算法概述 ...

  7. 【机器学习实战学习笔记(2-2)】决策树python3.6实现及简单应用

    文章目录 1.ID3及C4.5算法基础 1.1 计算香农熵 1.2 按照给定特征划分数据集 1.3 选择最优特征 1.4 多数表决实现 2.基于ID3.C4.5生成算法创建决策树 3.使用决策树进行分 ...

  8. thinking in java学习笔记:14章 类型信息

    14.2 Class 对象 https://github.com/zhaojiatao/javase 1.什么是Class对象,Class对象是用来做什么的? Class对象是java程序用来创建类的 ...

  9. 【机器学习实战学习笔记(1-2)】k-近邻算法应用实例python代码

    文章目录 1.改进约会网站匹配效果 1.1 准备数据:从文本文件中解析数据 1.2 分析数据:使用Matplotlib创建散点图 1.3 准备数据:归一化特征 1.4 测试算法:作为完整程序验证分类器 ...

随机推荐

  1. 程序跳转到访问一个确定的地址0x100000

    用函数指针 把这个确定的地址转化成一个函数指针 这就明白了程序中调用函数的意义 测试代码如下: #include <stdio.h> void getMemory() { printf(& ...

  2. Nginx-ngx_lua模块原理和内置函数

    ngx_lua模块的原理: 1.每个worker(工作进程)创建一个Lua VM,worker内所有协程共享VM:2.将Nginx I/O原语封装后注入 Lua VM,允许Lua代码直接访问:3.每个 ...

  3. <script>标签应该放到</body>标签之前

    著作权归作者所有. 商业转载请联系作者获得授权,非商业转载请注明出处. 作者:贺师俊 链接:http://www.zhihu.com/question/20027966/answer/13727164 ...

  4. Windows Service 开发,安装与调试

    Visual Studio.net 2010 Windows Service 开发,安装与调试 本示例完成一个每隔一分钟向C:\log.txt文件写入一条记录为例,讲述一个Windows Servic ...

  5. android学习笔记57——Service_2

    Service生命周期 参考:http://codingnow.cn/android/515.html 应用程序启动服务的方式不同,其生命周期也有所不同. startService生命周期如下左图: ...

  6. I18N、L10N、G11N

    I18N --是“Internationalization” 的缩写,由于 “Internationalization” 单词较长,所以为了书写简便,通常缩写为“I18N” .中间的 18 代表在首字 ...

  7. src与href属性的区别

    src和href之间存在区别,能混淆使用.src用于替换当前元素,href用于在当前文档和引用资源之间确立联系. src是source的缩写,指向外部资源的位置,指向的内容将会嵌入到文档中当前标签所在 ...

  8. 114、Android禁止ViewPager的左右滑动

    有时候在开发中会遇到一些“诡异”的要求,比如在ViewPager中嵌入ListView,或者再嵌入一个ViewPager,那么在滑动的时候就会造成被嵌入的XXView不能滑动了,那么现在就把最外层的V ...

  9. 【cl】Json学习

    http://www.cnblogs.com/java-pan/archive/2012/04/07/2436507.html

  10. win7安装xampp,提示windows找不到-n文件(安装成功后,443端口占用,apache服务器无法正常启动)

    1. 环境:win7 64位安装xampp 32位. xampp下载地址:https://www.apachefriends.org/download.html 2. 安装过程最后,报错,提示wind ...