不知道大家平时喜不喜欢看电影来消遣时光,我是比较喜欢看电影的。对我而言,当我看完一部电影,觉得很好看的时候,我就会寻找类似这部电影的其他电影。刚好有这么一个数据集,包含了很多部的电影,于是打算对其进行一波简单的分析并尝试建一个简单的“推荐系统”,一起来看一下吧~~
库:
Pandas,Numpy,Re
工具:
Ipython Notebook
这边插一句,小密圈曾经有一篇文章大家一起讨论了常用的5种Python开发工具,Notebook做数据分析并且记录笔记非常不错!
1.数据集
本文使用的数据集来自于https://grouplens.org/datasets/movielens/,上面有多种版本,主要区别在于数据集的大小(即收录的电影和用户信息的多少),这里使用的是最小的一个数据集:
image
2.数据初探
数据集里包含了4个文件,本文只用到了其中的两个:电影信息movies.csv,用户对电影的评分ratings.csv,先来看看这两个文件长什么样:
import pandas as pd
movies_data=pd.read_csv('movies.csv')
ratings_data=pd.read_csv('ratings.csv')
print (movies_data)
1).看一下movies_data里的数据
image
2).看一下用户评分的数据:
image
显然,如果单纯从单个文件里来分析的话似乎得不到什么有用或者是直观的信息,但是我们可以把这两个数据帧(DataFrame)结合起来,合成新的,把用户评分和电影信息结合起来,方便我们后续的分析处理
3).合并两个数据集
"#合并
data=pd.merge(movies_data,ratings_data)
"#删除列,可写可不写,不会产生影响
data.drop('timestamp',1,inplace=True)
image
好了,完成了这一步,我们把重要的信息都结合在一起了,可以开始我们真正的数据分析或探索了,接着看看那些电影收到的评分最多,我们只需一句(value_counts()是我在pandas里最喜欢的一个函数之一)
4).看看评价最多的20名电影
image
嗯,经典就是经典,评价最多的前几部都是有名的电影(阿甘正传、低俗小说、肖申克的救赎、沉默的羔羊、星球大战……)
看完评价最多的电影,但大多数人更加关心的是电影究竟好不好看,于是乎,我们就把目光转向评分这里. 那接着就来统计下用户对每一部电影的平均评分吧
5).电影的平均评分
image
其中size是每部电影参评人数,mean是平均分.
6).继续找一下评分最高的top5:
image
咦,我们可以看到,虽然评分是5分,但是……评分只有1人啊,这样绝不是我们想看到的,因为不是很客观,于是,我们再来改进下
这次我们把评价人数大于150人的电影找出来,在进行统计:
image
哈哈哈,这样就客观多了吗,top5分别是:教父、肖申克的救赎、非常嫌疑犯、辛德勒的名单、冰血暴,都是经典电影(大家都看过没有呢)
3.简单的推荐系统
当我们看完一部觉得好看电影,是不是会有这样的感觉,立马看有没有续集,没有的话就会找相似的电影。
是的,这里是基于这样思想,当我们输入一部电影,就找同样的类型的电影,然后返回给我们结果
用代码实现也不多,主要思想是:我们输入电影名或关键词,我们就从数据帧里匹配,然后找到这部电影的类型,再找出与其相同类型的电影,最后返回结果,具体代码为:
image
看看和Toy Story(玩具总动员)类似的动画片有哪些
image
比如找一下星球大战类似的电影:
image
限于篇幅没有完全截图
结论:
正如前文刚刚提到过一样,这个数据集还是比较小的,只有九千多条电影记录,当然网站上可以下载更多的数据和更多有趣的信息。另外这个“推荐系统”比较简单,各位小伙伴可以根据自身的要求,再进一步的优化升级,这里就当做是抛砖引玉吧!
文章底部简短的给大家推荐一个新东西:PrettyPrinter
PrettyPrinter是Python 3.6 及以上版本中的一个功能强大、支持语法高亮、描述性的美化打印包。它使用了改进的Wadler-Leijen布局算法,和Haskell打印美化库中的prettyprinter以及anti-wl-pprint、 JavaScript的Prettier、Ruby的prettypreinter.rb 以及 IPython的Ipython.lib.pretty类似。Python的PrettyPrinter集以上众家之所长,并在此基础上继续改进,因此也成为目前Python最强大的美化输出工具。
以下是使用PrettyPrinter输出结果的截图:
为什么Python还需要额外的美化打印包呢?
无论是IDE还是开发者手动运行命令,将数据打印到屏幕上是程序运行过程中程序员和数值交互的最基础的界面。改进该界面有助于提升开发体验和生产效率。Python本身和第三方库都提供了一些工具来达到此目的:__repr__和__str__两个下划线方法返回普通字符串。__repr__应该尽可能返回语法正确的Python表达式,断言判断失败及控制台计算结果打印最常用的就是该方法。由于其完全基于字符串格式化,因此并不具备美化打印的功能。
标准库中的pprint模块为dicts, lists, tuples, sets, and frozensets等内置数据类型提供了美化打印的功能。它将__repr__方法应用在用户自定义的类实例上。然而,它使用了非常贪婪的布局算法,导致在很多情况下的美化打印出现问题。由于自定义的美化打印受__repr__所限制,pprint的作用也就限制于内置数据类型了。
第三方库pprintpp是对pprint的改进及替代方案,也可以对输出进行优化,不过和pprint一样受限于__repr__使用的代码美化定义。
IPython中默认的打印模块IPython.lib.pretty的目标是pprint更进阶的替代方案。和pprint相比,它在很多方面都表现得更好:大多数情况下算法都能对输出进行美化,而且提供了针对用户自定义类型美化输出的定义工具,能和输出的其他部分实现比较好的结合。不过,为了实现你自己的美化打印方式,你需要对布局算法有所了解。另外,该API 也有一些与生俱来的副作用:调用美化打印工具将数据直接推送至布局缓冲区,不允许原始布局对数据进行初步检测。
以上所有工具都达不到我对美化打印体验的要求,因此我开始做以下几点改进:实现一个能尽可能多的美化打印的算法,即便在效率上做出一些牺牲。花十分之一秒对输出结果进行美化是非常划算的,因为当你需要在结果中寻找自己需要的数据时它将为你节约两秒钟的时间。
实现一个超级简单、描述性的接口来实现用户自定义的美化打印工具。Python成员几乎不会重写__repr__方法,因为这很痛苦;几乎没有人愿意为用户定义的类型编写整齐打印规则,除非类型非常简单。
实现不会在无效Python语法上中断的语法高亮显示。并不是所有__repr__方法都会返回有效的语法,一旦发生语法错误会打断正常的语法高亮。
新的代码美化包的使用体验令我非常惊讶。算法运行的很出色,效率也满足需求。而用户自定义美化规则的方法也很简单,仅仅需要了解两个描述性的函数 register_pretty和pretty_call即可。语法高亮看上去非常漂亮,且不会被无效语法处中断。特别是语法高亮,会使你很难再回到普通的美化打印工具,它大大提升了程序员的开发体验。
最有趣的改进是描述性API,下面是它的工作原理。
简单、描述性的API
在PrettyPrinter中定义输出美化方法主要基于(创建)函数调用。所有非字符的Python值都需要用函数结果表示。该库的主力函数是pretty_call, 它允许你来描述PrettyPrinter应该输出何种类型的函数调用。下面就是pretty_call调用的一个例子:
PrettyPrinter处理原始布局的过程类似于以下语句:
(第一个参数ctx允许用户控制案例中[5,3,6,1]列表中嵌套的数据,reverse参数的True值依据此进行渲染。大部分情况都直接使用默认值即可。)
上面介绍了如何使用Pretty_call,接下来定义我们自己的类型。
使用register_pretty修饰符,可以为MyClass类定义美化方式:
cpprint的输出如下:
点击 the PrettyPrinter definition code for standard library types,查看更多案例。
带状态实例的表示
调用函数的一个缺陷是无法很好的表示带状态的实例。通常你想要额外输出一些信息来表示实例的状态。PrettyPrinter使用解释性评论解决了这一问题,我对这一强大的特性颇为满意。使用评论来标注Python值(或者表示Python值的原始布局),该评论将神奇的出现在输出的结果中。
假如我们定义了一个包含其连接与断开两个状态的Connection类:
如果想得到以下输出:
可以通过如下定义来实现:
结论
我非常享受将PrettyPrinter作为开发工具包的一部分。单独一篇文章只能粗略分享一些点,还有很多有趣的部分等待你去探索,强烈推荐大家尝试一下!在IPython中使用效果更佳,因为交互式解释器环境中的所有结果都可以自动使用PrettyPrinter打印输出。文档中有对该命令的设置的说明。
点击source code on GitHub查看该项目的源码,文档在documentation on readthedocs.io(目前可能还略显简陋)。包中内置了针对Django模型、QuerySets以及使用attrs包创建的所有类的现成的定义。因此如果你恰好也用到了其中的某个,毫无疑问你会想马上试试它的!
本文经来自网络和自己整理,如有侵权,请联系删除。
如果我的分享对你有帮助,还请你多多转发,收藏,点赞,让更多热爱Python者受益。