一篇长文学懂入门推荐算法库:surprise


一篇长文学懂入门推荐算法库:surprise

文章插图
不知不觉写完了七篇文章来分析这个推荐算法库 surprise,基本上我们从头到尾所有代码都自己完成,并且可以成功 run 起来一个基于邻域的协同过滤算法 。是哪个算法这件事其实我觉得不重要,surprise 支持的每个算法本身思路并不复杂,代码也不晦涩难懂,我们主要的目的是理解它的架构,学习框架各个部分的交互 。
按理之前的文章写完后,这个系列就可以算是初步完成了 。但是我自己回头再看的时候,发现七篇文章缺乏一个总体性的视角,这可能会导致有的同学读起来觉得前后不太连贯 。
文章的顺序是按照我自己在学习源码过程中的顺序编排的,但是如果没有告诉读者我的思维过程,读者可能不能很好的理解这其中的关系 。
所以这篇文章是想从一个整体的视角,以我当初的思路为主线进行介绍,观察并思考如何一步一步的让模型 run 起来 。至于某些具体的细节部分,我们给出之前写的对应文章链接,大家可以回头再去看相应的文章来了解 。
 
1 先搞个模型跑起来我们首先从一个总体性的代码看一下,很简单的几行代码,开始我们的 surprise 之旅 。
一篇长文学懂入门推荐算法库:surprise

文章插图
这里需要导入的部分,我都已经重写过了,但是大家可以在自己本地的代码上尝试一下,直接利用 surprise 库就可以运行一个简单的 KNN 算法,本质上也就是基于邻域的协同过滤算法 。按照我在代码上标注出来的红线部分,分别给对应的四个 import 模块,前面加上 surpris. 的路径就可以从 surprise 中进行导入 。
这里需要提一下,我用的是自己之前已经在 movielens 官网下载的数据集,大家可以自己直接下载,也可以在网上找一下教程,surprise 支持自动下载 movielens 的数据集 。
接下来我们只看 surprise_code 函数,这个函数就是我们需要学习的所有内容,从这个例子开始,我们要去一步步深扒 surprise 的执行过程 。
def surprise_code: reader = Reader(line_format="user item rating", sep=',', skip_lines=1) data = https://www.isolves.com/it/cxkf/yy/Python/2020-05-28/Dataset.load_from_file('./ml-latest-small/ratings.csv', reader) algo = KNNBasic perf = cross_validate(algo, data, measures=['RMSE', 'MAE'], cv=2, verbose=0) for keys in perf: print(keys, ": ", perf[keys])对核心的 surprise_code 函数,可以分为两个部分来看:数据载入,算法执行并检测结果 。
数据载入,由 Reader 和 Dataset 两个类来提供功能,具体的思路是由 Reader 提供读取数据的格式,然后 Dataset 按照 Reader 的设置来完成对数据的载入 。
算法执行并检测结果,这里由一个 cross_validate 来完成,提前导入需要执行的算法并实例化,然后将数据,算法,要检测的指标等都传入 cross_validate,它会完成对算法的训练拟合,然后进行预测结果,再对结果进行验证,最终返回目标的检测指标对应的结果 。
所以我们可以看到直接调用接口是很容易跑起来一个模型的,仅这么几行简单的代码就可以将一个算法完整的运行起来 。但是如果要深入到代码的执行细节上,就需要捋顺它们的关系,然后抽丝剥茧一点点展开 。
在【第一篇文章:推荐实践(1):从零开始写一个自己的推荐算法库】中,我们将上面的算法执行并检测结果分成了两部分,也就是将整个工作流程划分为三部分:数据载入,算法设计,结果评估 。这样子更加细化的一步当然没问题,逻辑上这样子也更容易理解 。
现在捋顺了算法的执行思路以后,我们开始从数据集的载入开始去分析源码 。
trick:在正式细节代码前,分享一些关于我学习源码的方法,不一定适合所有人,也不一定适合所有源码,仅供大家参考:
首先,要像我们一样完成一个非常简单的 demo,如这一小节的标题一样,先搞个模型跑起来 。至少我们得会用它,能用起来,这样子我们才能分析下去 。
其次,我们再捋顺模型的流程,划分为几个主要的部分,按照这个逻辑顺序,从最初的部分开始,尝试自己完成该模块的功能 。导入自己写的部分,替代掉源码的那一部分,看看前面的 demo 能不能继续运行,检查结果是否一致 。
最后,不要在分析的时候,拘泥于细节,先完成该模块的主要功能 。如果这部分功能与其它模块相关,可以先导入相关的模块,直接使用 。不要尝试一步将某一个模块写的尽善尽美 。


推荐阅读