【ArchSummit架构师峰会】探讨数据与人工智能相互驱动的关系>>> 了解详情
写点什么

歌曲推荐系统实践:Pandas、SciPy 和 D3.js

  • 2015-05-07
  • 本文字数:1997 字

    阅读完需:约 7 分钟

时至今日,虽然海量数据、大数据、数据挖掘、个性化等名词术语已耳熟能详,仿佛谁人两两遇到都可以轻易写个挖掘系统出来,但情况真的是这样么? Flipboard 数据产品部门的工程师 Ben Frederickson 在与友人的讨论中就发现,写个推荐系统并没有那么轻而易举,为此他专门写了一篇博文来记录自己实现的整个过程,利用的工具是数据挖掘领域很热门的 Pandas SciPy 函数库,最后使用 D3.js 进行交互和可视化,相关的代码都放在了 GitHub 上。

具体来讲,一个推荐系统包括数据的获取和存储,相似度的计算以及最终结果的可视化,下面分别阐述。

数据获取

Ben 的推荐系统是针对 Last.fm 用户的,所用数据集是通过 Last.fm 的 API 获取的大约 36 万用户对歌手的喜爱程度。程度以用户对该歌手的播放次数为指标,数据集大小在 1 千 7 百万左右。想要在程序中使用这个数据集,ben 通过 Python 数据挖掘工具 Pandas 的 read_table 将 csv 格式的数据导入成为表格。

复制代码
data = pandas.read_table("usersha1-artmbid-artname-plays.tsv",
usecols=[0, 2, 3],
names=['user', 'artist', 'plays'])

将数据加载为表格以后,剩下的任务就是计算相似度了,ben 给出了三种相似度的计算方法,分别是简单的相似度计算,余弦相似度和来自信息学的相似度计算,并给出了各类方法最后的可视化比较。

简单相似度

简单相似度计算,顾名思义,是最简单的相似度计算方法,用来计算两个歌手的相似程度。这种计算方法,忽略歌手被用户播放的次数,只是简单计算两个歌手重叠的用户数目。

复制代码
def overlap(a, b):
return len(a.intersection(b))

这种计算方法的问题在于,那些流行的歌手的存在,会极大影响相似度的准确性。例如几乎每个用户都听过 Radiohead、Coldplay 和披头士,这使得简单相似度方法给出的答案里面,越是流行的歌手越相似。

为了解决这个问题,ben 引入了新的相似度定义, Jaccard 相似度,利用数据挖掘中常用的正则化(Normalize)手段,将简单相似度正则化,消除用户数目对歌手相似度的影响,具体计算方法如下:

复制代码
def jaccard(a, b):
intersection = float(len(a.intersection(b)))
return intersection / (len(a) + len(b) - intersection)

类似的正则化方法还有很多,比如 Dice 正则和 Ochiai 正则等,从一定程度上改善了相似度计算的准确性,但也带来了一点问题,即集合大小相近的歌手会更加相似,ben 觉得这样也并不合理,因此进一步提出了使用余弦相似度。

余弦相似度

上文中提到的简单相似度抛弃了用户对歌手播放次数这一重要信息,实际上它代表了用户对该歌手的喜爱程度,细想一下是非常有道理的,一个披头士的重度听众怎么能够跟听过寥寥几曲的听众一样呢?那么,利用上播放次数这一信息最直接的办法,就是余弦相似度方法,计算公式如下:

复制代码
def cosine(a, b):
return dot(a, b.T)[0, 0] / (norm2(a) * norm2(b))

通过上面公式,我们就可以将播放次数引入到相似度的计算中。公式中的 a 和 b 分别代表歌手的听众向量,通过下面的代码构造生成:

复制代码
# map each username to a unique numeric value
userids = defaultdict(lambda: len(userids))
data['userid'] = data['user'].map(userids.__getitem__)
# map each artist to a sparse vector of their users
artists = dict((artist, csr_matrix(
(group['plays'], (zeros(len(group)), group['userid'])),
shape=[1, len(userids)]))
for artist, group in data.groupby('artist'))

来自信息学的相似度

除了单纯利用播放次数以外,ben 还介绍了来自信息学的,确切来讲是来自搜索引擎中常用的自然语言处理技术,来计算歌手之间的相似度,即词频 - 逆文档频率(TF-IDF)作为向量的相似度计算方法。

这种相似度的发明,来自搜索引擎对检索结果排序的需求,即计算检索关键词与检索返回的文档之间的相似程度。具体来讲,如果某个词语在一个描述语句中出现的频率很高(TF 很高),而在其他描述语句中很少出现(IDF 很高),则认为该词语具有很好的区分文档的能力,其 TF-IDF 值就比较高,那么对应到歌曲推荐这个任务来讲,ben 将用户(听众)看作一个个的单词,来进一步考虑特定用户对相似度准确性的影响,可谓是三种方法中比较准确的一个了,ben 还在原文中用 D3.js 给出了几种相似度的效果对比分析。

总结

在专业术语充斥耳畔的今天,能够有耐心真正自己去尝试一些想当然的东西、算法甚至系统,是非常难能可贵的精神,而收获也是非常丰富的。Ben 以 Python 中常用的 Pandas 和 SciPy 等工具,展现了从头实现一个推荐系统的方法,正是这种精神的实践典范。


感谢崔康对本文的审校。

给InfoQ 中文站投稿或者参与内容翻译工作,请邮件至 editors@cn.infoq.com 。也欢迎大家通过新浪微博( @InfoQ @丁晓昀),微信(微信号: InfoQChina )关注我们,并与我们的编辑和其他读者朋友交流(欢迎加入 InfoQ 读者交流群)。

公众号推荐:

跳进 AI 的奇妙世界,一起探索未来工作的新风貌!想要深入了解 AI 如何成为产业创新的新引擎?好奇哪些城市正成为 AI 人才的新磁场?《中国生成式 AI 开发者洞察 2024》由 InfoQ 研究中心精心打造,为你深度解锁生成式 AI 领域的最新开发者动态。无论你是资深研发者,还是对生成式 AI 充满好奇的新手,这份报告都是你不可错过的知识宝典。欢迎大家扫码关注「AI前线」公众号,回复「开发者洞察」领取。

2015-05-07 08:094373
用户头像

发布了 268 篇内容, 共 118.1 次阅读, 收获喜欢 24 次。

关注

评论

发布
暂无评论
发现更多内容

用户身份标识与账号体系实践

Java 架构 业务设计 IDMapping 数据映射

高效能7个习惯学习笔记

JefferLiu

高效能人士的七个习惯

12代酷睿处理器+2.8K OLED华硕好屏,灵耀14 2022影青釉商务轻薄本

科技热闻

专访 | 软通动力高级副总裁秦张波:开源驱动创新,推动操作系统产业生态建设

kk-OSC

开放原子全球开源峰会

elasticsearch实战三部曲之一:索引操作

程序员欣宸

Java elasticsearch 7月月更

怎么样的框架对于开发者是友好的?

MASA技术团队

.net 云原生 软件架构

又快又稳!Alibaba出品Java性能优化高级笔记(全彩版)震撼来袭

冉然学Java

编程 程序员 分布式 性能优化 java 14

开放原子开源基金会黄金捐赠人优博讯携手合作伙伴,助力OpenHarmony破圈!

Geek_2d6073

重磅 | 基金会为白金、黄金、白银捐赠人授牌

kk-OSC

开放原子全球开源峰会

centos8快速安装mongdb6.0

技能实验室

React Fragment

程序员海军

7月月更

CSP直通车 | 在线直播认证培训双周末班 火热报名中

ShineScrum捷行

Scrum 敏捷 CSP-SM 敏捷专家 敏捷大师

重磅 | 2022 开放原子全球开源峰会在北京开幕

kk-OSC

开放原子全球开源峰会

SiC功率半导体产业高峰论坛成功举办

Geek_2d6073

开放原子开源基金会秘书长孙文龙 | 凝心聚力,共拓开源

kk-OSC

开放原子全球开源峰会

聊聊性能测试环境搭建

老张

性能测试 环境搭建

专访 | 阿里巴巴首席技术官程立:云 + 开源共同形成数字世界的可信基础

kk-OSC

开放原子全球开源峰会

2022必会的前端面试手写题

buchila11

敢看系列?Python字体反爬实战案例之实习那僧,继续挖坑

梦想橡皮擦

Python 爬虫 7月月更

重磅 | 开放原子校源行活动正式启动

kk-OSC

开放原子全球开源峰会

重磅 | 开放原子算法大赛拉开帷幕

kk-OSC

开放原子全球开源峰会

开源峰会抢先看 | 7 月 29 日分论坛 & 活动议程速览

kk-OSC

开放原子全球开源峰会

如何消减敏捷开发协作中的「认知偏差」?| 敏捷之道

LigaAI

程序人生 产品经理 LigaAI 敏捷开发流程 研发协作

架构实战营模块八作业

Geek_Q

JAVA编程规范之二方库依赖

源字节1号

软件开发 程序员‘

一键搭建博客:如何使用WordPress插件搭建专属博客

hum建应用专家

Wordpress 部署 Wordpress 博客部署

C# 之 volatile关键字解析

陈言必行

7月月更

C# 使用数据库对ListView控件数据绑定

IC00

C# 7月月更

原型链继承和构造函数继承的 “毛病”

掘金安东尼

JavaScript 前端 设计模式 7月月更

转转push的演化之路

转转技术团队

push

推荐算法的三大研究热点

博文视点Broadview

歌曲推荐系统实践:Pandas、SciPy和D3.js_语言 & 开发_张天雷_InfoQ精选文章