前言

在上篇文章豆瓣电影,电视剧DM实战中提及到,我和室友们产生了剧荒,萌生出要做一个个人用的推荐系统,解决剧荒的问题,经过一轮的死缠烂打,这个个人推荐系统终于成型了。

今天来分享一下心得,对此感兴趣的朋友可以自己对着写一个。

传统推荐系统算法

首先介绍一下传统的推荐系统方法,之所以叫它传统,是因为大部分学习资料上都是用这一个方法。

我们来假设有这么一个矩阵(用python的列表表示):

  [# A B C D E[2,0,0,4,4], #1[5,5,5,3,3], #2[2,4,2,1,2]  #3......]

矩阵的行代表用户,列表示物品,其交点表示用户对该物品的评分。

假设现在用户1需要选商品,推荐系统则假设其会选择并未选择过的商品,因此,系统会在第一行中寻找评分为0的物品,显然会找到B和C。这时,该怎么知道是推荐B还是C呢?(假设用户只需推荐一个),这时则需要计算B、C和用户以前选择过的物品(已评分)的相似度。

仅仅算出相似度还不够,因为你不能判断这到底是好的那一部分相似还是坏的部分相似。所以这时,我们需要引入用户的评分作为相似度计算的权重,评分X相似度得到最后的得分(该得分会一直累加,则B的推荐得分会是B与A,D,E的相似得分的累加和)。这样一来,评分低物品的最后得分自然就低,评分高的物品自然得分就高,这时问题就简化成排序问题了。

显然,上述问题的核心在于如何计算相似度。

这里给出计算相似度的两种方法:

  • 欧式距离法
    以B和A的相似度为例:
    similar = 1/sqrt((0-2)^2 + (5-5)^2 + (4-2)^2 ……) 最后B与A的相似得分还得乘上评分,score = similar * 2

  • 余弦相似度

    costheta=fracAcdotB||A||||B||

    AB为两列向量,||A||表示A的2范数
    特别注意一点的是,cos的取值是-1~1,我们需要将其归一化,即把范围弄成在0~1上。于是相似度计算公司变成0.5 + 0.5*cos

少用户推荐系统的创新

在上述的内容中,我们可以发现传统的方法有一个特出的问题,传统的算法需要大量的用户评分,即矩阵的行数需要较多才能得出的结果才值得参考。这一个需求咋看起来是没什么问题,也符合我们的逻辑,唯有数据量足够,我们才能找到较为准确的规律嘛。

但回到我的需求上来说,这可是一个明显的缺点,在前言我说明的需求上说过这是一个给宿舍甚至是个人使用的推荐系统。

也就是说:

  • 我们无法提供大量数据。

  • 我们很懒,我们最可能是告诉系统我从它的推荐中采纳了哪一部的电影,而不会去评分,我们可能告诉它质量是否可以接受,但不会像豆瓣用户那样给出0~10的准确分数。

因此,传统的推荐算法有很多不适合我需求的地方,但是看问题要看本质。无非就是根据用户的特性,或者根据商品特性,进行与训练好的模型进行相似性比较。抓住这些特点,我做了少少的"创新"

  • 不基于用户的评分作相似度,而是用商品的label做标准
    现在很多商品尤其是音乐或者电影,都会具有自己的label,比如说喜剧悬疑,其次还有主演导演等可以作为其特征。电商平台上也有诸如商品种类衣服,女鞋包包,等,而某些物品,例如衣服,那么衣服的品牌size,都可以作为用户的一个选择的特征。

  • 用户模型是动态更新的
    这一点不难理解,如果一个用户长期使用使用该系统,那么他的选择中很可能已经覆盖了大量的label,这时基于label的推荐系统则很难区分该用户的喜好。这是我们有两个解决方法。第一个是允许用户自定义label,比如SF就可以自定义问题或文章的标签,这样增大了label的多样性。当然,这个解决方案只能算一个缓解的方案,要想彻底解决,我觉得需要给特征选定有效期。
    增加有效期后,用户的选择可以反应出一个时间段内的需求。假设这样一个场景,一名用户准备去旅游了,他可能会大量浏览旅游用品的出售页面,例如一次性牙膏等,这时,就可以向该用户推荐出售旅行用品的网站了。而超过了特征的有效期,例如一周,这时用户已经旅游回来,因为特征已经无效,推荐系统不再推荐旅游用品(这样用户不会觉得莫名其妙。个人经历,现在某些网站就往往会出现明显已经超过我感兴趣时限的推荐),而是开始重新收集用户新一周浏览的特征,动态构建用户模型,推荐用户下一阶段他可能需要的物品

实现上述想法,在python中,我们可以这么做,实现如下字典

record = {"labelName":(weight,time),"labelName2":(weight,time)……
}#labelName是标签名称,在该标签下有一个元组,元组的第一个字段是这个标签的权重。
#权重越大,表示用户越喜欢这个标签。
#第二个字段是创建该标签的起始时间

在实现推荐时,则较为容易实现,给定testList。这时需要:

  • 创建名res的空字典

  • 遍历testList,每一个对象命名为t

  • 遍历t具有的label,根据labelrecord上获取信息。

  • 同时获取当前时间time2,如果time2-time超出了规定时限,则该标签的信息无效,忽略该label,同时删除record里面的对应的字段。

  • 若该标签有效,则t的得分加1,并将t的下标index作为key假如到一个res

  • 遍历完成后,对res字典按value排序

  • 最后,可以根据需要对排序结果进行访问。并入只获取最高的前5名。

这样,一个适合少用户的推荐系统就弄出来啦~

现在正在宿舍投入运行,至于效果如何可能要一段时间才知道了

后话

github 地址

说明一下,github上只是提供了一个实现了上述改进后思路的类recommend.py,并不是一个成型的推荐系统,你可以下载后,根据这个类进行二次开发,比如:

  • 利用flask框架包装成一个web应用

  • 结合该类并利用SMTP协议,弄一个自动往邮箱发信息的脚本,推荐的电影信息

  • 将类实例化,弄出简单的命令行应用

迟下我会上传一个使用falsk封装的一个简单的webserver去github,可以通过web API请求,返回json格式的电影信息。

如有错误,望指正。

from: https://segmentfault.com/a/1190000005152849?utm_source=tuicool&utm_medium=referral

用python写一个简单的推荐系统 1相关推荐

  1. 用python写一个简单的推荐系统

    前言 在上篇文章豆瓣电影,电视剧DM实战中提及到,我和室友们产生了剧荒,萌生出要做一个个人用的推荐系统,解决剧荒的问题的想法,经过一轮的死缠烂打,这个个人推荐系统终于成型了. 今天来分享一下心得,对此 ...

  2. python旅游推荐系统_用python写一个简单的推荐系统

    前言 在上篇文章豆瓣电影,电视剧DM实战中提及到,我和室友们产生了剧荒,萌生出要做一个个人用的推荐系统,解决剧荒的问题的想法,经过一轮的死缠烂打,这个个人推荐系统终于成型了. 今天来分享一下心得,对此 ...

  3. python推荐系统-用python写个简单的推荐系统示例程序

    用python写个简单的推荐系统示例程序 作者:阿俊 发布于:2011-11-26 16:03 Saturday 分类:推荐系统 python这门语言写程序代码量非常少,短短几行就可以把程序写的很清楚 ...

  4. python推荐系统-利用python构建一个简单的推荐系统

    摘要: 快利用python构建一个属于你自己的推荐系统吧,手把手教学,够简单够酷炫. 本文将利用python构建一个简单的推荐系统,在此之前读者需要对pandas和numpy等数据分析包有所了解. 什 ...

  5. 基于python的系统构建_利用python构建一个简单的推荐系统

    摘要: 快利用python构建一个属于你自己的推荐系统吧,手把手教学,够简单够酷炫. 本文将利用python构建一个简单的推荐系统,在此之前读者需要对pandas和numpy等数据分析包有所了解. 什 ...

  6. python推荐_利用Python构建一个简单的推荐系统

    原标题:利用Python构建一个简单的推荐系统 摘要:快利用python构建一个属于你自己的推荐系统吧,手把手教学,够简单够酷炫.在此之前读者需要对pandas和numpy等数据分析包有所了解. 什么 ...

  7. 用python写一个简单的web服务器

    人生苦短,我用python 简洁高效,这才是理想的语言啊 分享一点python的学习经验-----如何用python写一个简单的web服务器 首先,我们需要简单地了解一下网络通信协议,这里用白话介绍一 ...

  8. 利用python写一个简单的双色球彩票系统

    利用python写一个简单的双色球彩票系统 1.设置每次买的号码一样 写一个双色球彩票系统,系统可以随机产生一组数据,一组彩票数据有六位数,这六位数的的取值范围是0和1. 一张彩票是两块钱,用户可以选 ...

  9. python爬虫抢火车票_如何用python写一个简单的12306抢票软件|python 爬火车票 教程...

    python 如果抓取验证码图片 类似12306的登录验证码图片 这个以前做次.最大的麻烦是码的识别算法的识别率太低.12306那种网站登陆错3次就限制你20分钟.所以除非你有33%以上的识别率否则不 ...

最新文章

  1. faster rcnn源码解读(五)之layer(网络里的input-data)
  2. sql 与linq的转换
  3. B15_NumPy 矩阵库(Matrix)(empty(),zeros(),ones(),eye(),identity(),rand())
  4. 设计模式——工厂模式(二)
  5. vue axios springboot 跨域
  6. Microsoft Hololens开发上手(4)
  7. 预训练卷不动,可以卷输入预处理啊!
  8. 单链表(不带头结点)
  9. mysql windows 乱码问题_MySQL:windows中困扰着我们的中文乱码问题
  10. 7-7 12-24小时制 (15 分)
  11. 超融合硬件损坏导致Oracle RAC异常恢复实录
  12. 编程语言----00程序员常用网站
  13. RAID 6 vs. RAID 10
  14. jQuery源码分析系列:.domManip() .buildFragment() .clean()
  15. 分析“HTTP500内部服务器错误”解决方法
  16. 【从理论到代码】旋转矩阵与欧拉角 一
  17. openresty 前端开发序 1
  18. java判断一个数是否为素数/质数
  19. 学计算机物理去戴维斯还是伦斯勒理工学院好,去伦斯勒理工学院留学,优势竟然这么多...
  20. Forest详细介绍

热门文章

  1. 【项目实战】:Python 商铺地址分布数据分析
  2. 在Docker启动Cloudera并开始体验
  3. SpringBoot各种Controller写法
  4. Vue.js(一) Vue.js + element-ui 扫盲
  5. 比特币早期投资家:没有人能够阻止其发展 TechWeb 09-27 09:10 凤凰科技讯 据CNBC网站北京时间9月27日报道,风险投资家、“Social+Capital”基金创始人Chamath
  6. 机器学习入门系列一(关键词:单变量线性回归,梯度下降法)
  7. Learning to Rank 中Listwise关于ListNet算法讲授及实现
  8. java 强制gc_java应用性能调优之详解System的gc垃圾回收方法
  9. 实战SSM_O2O商铺_37【商品】商品列表之View层的实现
  10. Oracle-数据泵expdp/impdp实操