plainify

给编译器看的注释——「注解」

计算机的世界是由 0 和 1 构成的,为了方便人类与计算机沟通,先贤们发明了编程语言,通过编译器将这些语言翻译成机器可以看懂的机器语言。为了方便人类更好的阅读代码,避免不必要的 996,几乎所有的编程语言都提供「注释」的特性,在某种程度上,这些「注释」的存在就是“废话”,因为编译器在执行到这里的时候是直接忽略的,「注释」虽然是人类写的,却也只是为了给“愚蠢”的人类看的。然而,无论哪个时代都有前行者,他们所做的不过是让我们的代码看起来更简洁,更有时代的进步感,因此必须要让人类与机器的沟通更进一步了,而这就是写给编译器的注释——「注解」。 何为「注解」 所谓注解,英文名 Annotation,是在 Java SE 5.0 版本中开始引入的概念,同class和interface一样,也属于一种类型。很多开发人员认为注解的地位不高,但其实不是这样的。像@Transactional、@Service、@RestController、@RequestMapping、@CrossOrigin 等等这些注解的使用频率越来越高。 说了这么多,到底何为「注解」? 注解是放在 Java 源码的类、方法、字段、参数前的一种特殊“注释”。 话不多说,直接上代码: // 用户请求接口 @RestController public class UserController { @GetMapping(value = "/user") public User getUser() { return new User("闰土",22,"男"); } } 上述是一个十分简单的 SpringBoot 的控制器代码,第 1 行是「注释」,是告诉阅读这行代码的人这是一个用户请求接口;第 2 行和第 4 行是「注解」,是用来编译器,这一个 Restful 接口,请求方法为 Get,匹配的是"/user"路径。 注释会被编译器直接忽略,注解则可以被编译器打包进入 class 文件,因此,注解是一种用作标注的“元数据”。从 JVM 的角度看,注解本身对代码逻辑没有任何影响,如何使用注解完全由工具决定。 「注解」的本质 在探究「注解」的本质之前,我们要先理解一个东西,Annotation 同class和interface一样,也属于一种类型,因此如果想要申明一个注解的话,我们同样需要写一个 java 文件来创建注解。注解的创建方法很简单,见下面的代码 👇 import java.lang.annotation.*; @Target(ElementType.METHOD) @Retention(RetentionPolicy.SOURCE) public @interface TestOverride { } 如上面代码所示,创建了一个名为「TestOverride」的注解,关键词是**「@interface」**,这时有小伙伴肯定就要说了,为什么我创建一个注解前还有注解?不急,这里我们暂且按下不表,之后来解释。...

plainify

从网易云日推浅谈个性化推荐系统--基于内容的协同过滤算法

上篇文章介绍了基于用户的协同过滤算法,该算法在一些网站(如 Facebook)中得到了应用,但该算法有一些缺点。首先,随着网站的用户数目越来越大,计算用户兴趣相似度矩阵将越来越困难,其运算时间复杂度和空间复杂度的增长和用户数的增长近似于平方关系。其次,基于用户的协同过滤很难对推荐结果作出解释。因此,著名的电子商务公司亚马逊提出了另一个算法一基于内容的协同过滤算法。 什么是基于内容的协同过滤算法 在进入本文的正题之前,先打开网易云音乐看下今天的日推: 看了上述的标记,是不是瞬间理解了为啥用网易云听音乐的时候会有上瘾的感觉,因为他给你听的都是你爱听的啊。就跟小时候我妈给我做菜是一样的,今天知道我喜欢吃红烧肉,明天为了照顾我的喜好又为了保证不重样,第二天就给我做了糖醋排骨,久而久之产生了依赖性,体重也开始飙升了。 上述就是 基于内容的协同过滤算法(Item-based collaborative filtering,简称 ItemCF) 在生活中常见的案例,该算法给用户推荐那些和他们之前喜欢的内容相似的内容。比如,该算法会因为你购买过《数据挖掘导论》而给你推荐《机器学习》。不过,ItemCF 算法并不利用内容的内容属性计算内容之间的相似度,它主要通过分析用户的行为记录计算内容之间的相似度。该算法认为,内容 A 和内容 B 具有很大的相似度是因为喜欢内容 A 的用户大都也喜欢内容 B。 事实上,由于人和人之间的差异性远大于内容和内容之间的差异(不然怎么会说你女朋友翻脸比翻书还快呢 🙈),ItemCF 算法算是目前业界应用最多的算法。无论是淘宝首页猜你喜欢,还是网易云音乐、哔哩哔哩、YouTube,其推荐算法的基础都是该算法。 Tips:基于内容的协同过滤算法可以利用用户的历史行为给推荐结果提供推荐解释,比如上图中网易云日推的标签,会告诉你是根据你收藏的某某单曲推荐的。 基于内容的协同过滤算法 如果你理解了我的上一篇文章《从网易云日推浅谈个性化推荐系统(1)–基于用户的协同过滤算法》,那你也很容易就可以联想到想要实现一个基于内容的协同过滤需要有以下两步: 计算内容之间的相似度。 根据内容的相似度和用户的历史行为给用户生成推荐列表。 计算内容之间的相似度 1.确定计算相似度的公式 很显然,步骤(1)的关键就是计算两个内容之间的相似度,亚马逊显示相关内容推荐时的标题是 “Customers Who Bought This Item Also Bought” (购买了该商品的用户也经常购买的其他商品) ,相当于就下了一个定义,根据这个定义,我们可以用下面的公式定义内容的相似度: $$W_{ij}=\frac{\left | N(i)\cap N(j) \right |}{\left | N(i) \right |}$$ 这里,分母$\left | N(i) \right |$是喜欢物品$i$的用户数,而分子$\left | N(i)\cap N(j) \right |$是同时喜欢物品$i$和物品$j$的用户数。因此,上述公式可以理解为喜欢物品$i$的用户中有多少比例的用户也喜欢物品$j$。...

plainify

从网易云日推浅谈个性化推荐系统--基于用户的协同过滤算法

这是 2019 年的第一篇文章,因为最近导师给了一个新的任务,有关某 app 的个性化推荐的,正好自己也是第一次学习这方面的知识,便想着汇总整理下。前人栽树,后人乘凉,因为篇幅原因,这一部分准备分开来叙述,本篇主要和大家介绍基于用户的协同过滤算法,希望可以对大家有所帮助,如有谬误,还望指正! 什么是个性化推荐系统? 其实个性化推荐系统早已渗透进我们的生活了,网易云音乐的“每日推荐”,淘宝的”猜你喜欢“,这些都是生活中非常常见的个性化推荐的案例。如今,随着大数据的发展,个性化推荐早已涉及诸多领域,比如电子商务(京东淘宝)、电影和电视网站(youtube)、个性化音乐网络电台(网易云音乐)、社交网络(QQ)、个性化阅读(微信读书)、基于位置的个性化服务(美团)等。推荐算法的本质是通过一定的方式将用户和物品联系起来,而不同的推荐系统也会根据实际情况采取不同的推荐方式。 一般来说一个完整的推荐系统一般包括以下三个参与方: 被推荐对象 推荐物品的提供者 提供推荐系统的网站 以网易云音乐的日推为例: 首先,推荐系统需要满足用户的需求,给用户推荐那些令他们感兴趣的音乐。其次,推荐系统要尽量让各个歌手的歌都能够被推荐给对其感兴趣的用户,而不是只推荐几个大流量歌手的歌。最后, 好的推荐系统设计,能够让推荐系统本身收集到高质量的用户反馈,不断完善推荐的质量,增加用户和网站的交互,提高网站的收入。如下图所示: 什么是好的推荐系统? 想要评判一个东西好不好,一定要有个标准。那么推荐系统好坏的标准是什么呢?试想一下为什么大家都喜欢网易云音乐的每日推荐而不喜欢今日头条的每日推送呢?最直观的感受就是网易云的日推歌曲你爱听,而头条的推送你很讨厌。所以说预测准确度是推荐系统领域的重要指标(没有之一)。 好的推荐系统不仅仅能够准确预测用户的行为,而且能够扩展用户的视野,帮助用户发现那些他们可能会感兴趣,但却不那么容易发现的东西(比如网易云音乐经常给你推送那些非常好听但是比较冷门的歌曲)。同时,推荐系统还要能够帮助商家将那些被埋没在长尾中的好商品介绍给可能会对它们感兴趣的用户。 协同过滤(Collaborative Filtering) 为了让推荐结果符合用户口味,我们需要深入了解用户。如何才能了解一个人呢?《论语·公冶长》中说“听其言,观其行”,也就是说可以通过用户留下的文字和行为了解用户兴趣和需求。 实现个性化推荐的最理想情况是用户能主动告诉系统他喜欢什么,比如很久之前注册网易云音乐的时候会让用户选择喜欢什么类型的歌曲,但这种方法有 3 个缺点:首先,现在的自然语言理解技术很难理解用户用来描述兴趣的自然语言;其次,用户的兴趣是不断变化的,但用户不会不停地更新兴趣描述;最后,很多时候用户并不知道自己喜欢什么,或者很难用语言描述自己喜欢什么。 因此,我们需要通过算法自动发掘用户行为数据,从用户的行为中推测出用户的兴趣,从而给用户推荐满足他们兴趣的物品。 基于用户行为分析的推荐算法是个性化推荐系统的重要算法,学术界一般将这种类型的算法称为协同过滤算法(Collaborative Filtering Algorithm)。顾名思义,协同过滤就是指用户可以齐心协力,通过不断地和网站互动,使自己的推荐列表能够不断过滤掉自己不感兴趣的物品,从而越来越满足自己的需求。 既然是基于用户的行为分析,就必须要将用户的行为表示出来,下表给出了一种用户行为的表示方式(当然,在不同的系统中,每个用户所产生的行为也是不一样的),它将个用户行为表示为 6 部分,即产生行为的用户和行为的对象、行为的种类、产生行为的上下文、行为的内容和权重。 表示 备注 user id 产生行为的用户的唯一标识 item id 产生行为的对象的唯一标识 behavior type 行为的种类(比如说是点赞还是收藏) context 产生行为的上下文,包括时间和地点等信息 behavior weight 行为的权重(如果是听歌的行为,那么权重可以是听歌时常) behavior content 行为的内容(如果是评论行为,那么就是评论的文本) 随着学术界的大佬们对协同过滤算法的深入研究,他们提出了很多方法,比如基于邻域的方法(neighborhood-based)、隐语义模型(latent factor model)、基于图的随机游走算法(random walk on graph) 等。在这些方法中,最著名的、在业界得到最广泛应用的算法是基于邻域的方法,而基于邻域的方法主要包含下面两种算法:...