在前两篇文章里,我们讨论了两种无监督学习: 

CODE
聚类:发现数据里的结构
异常检测:发现不正常的行为

今天,我们进入一个几乎所有互联网产品都会用到的系统——推荐系统(Recommender System) 。

如果你认真观察,会发现淘宝首页推荐商品、抖音推荐视频、小红书推荐内容、网易云推荐音乐……这些都不是搜索,而是系统主动猜测你会喜欢什么。

而在这些推荐系统背后,最经典、最重要的一种算法,就是协同过滤(Collaborative Filtering)。

推荐系统,其实是很多公司的收入来源

很多人以为,推荐系统只是一个“功能”。但在很多互联网公司,它其实是核心业务引擎。例如:

CODE
电商平台
视频平台
音乐平台
社交媒体
广告系统

很大一部分收入,都来自推荐系统带来的行为转化。

假设你打开一个电商App,你没有搜索任何商品,但首页上能看到:

CODE
猜你喜欢
为你推荐
可能感兴趣

这背后,其实是一个非常明确的问题:这个用户,接下来最可能喜欢什么?

推荐系统的核心问题

我们可以把它抽象成一个表格:

CODE
        商品A   商品B   商品C   商品D
用户1     5      4       ?      1
用户2     5      ?       3      1
用户3     1      2       5      ?
用户4     1      2       ?      5

这里:

CODE
数字 = 评分
? = 还没看过

系统真正要解决的问题只有一个:把这些问号补出来。

也就是,预测用户还没有接触过的内容,会不会喜欢。

传统思路:看内容本身

最早的推荐系统,是这样做的:

CODE
用户喜欢科幻电影
→ 推荐科幻电影

这叫:基于内容推荐(Content-Based Recommendation),比如: 

CODE
电影标签:动作、爱情、喜剧
用户喜欢爱情 → 推荐爱情

这种方式很直观,但有一个致命问题——标签不够用。 

假设两个人都喜欢科幻电影,但一个喜欢烧脑科幻,一个喜欢爆米花科幻,标签一样,但偏好完全不同。

这时候,就需要一种更聪明的方式:看别人。

协同过滤的核心思想

一句话理解协同过滤的思想史:如果两个人过去喜欢的东西相似,那么未来也可能喜欢相似的东西。

这听起来非常像现实生活,假设你喜欢:

CODE
三体
流浪地球
黑客帝国

系统发现另一群人也喜欢这些电影,但他们还喜欢:

CODE
星际穿越

那么系统就会推断你可能也会喜欢《星际穿越》。

注意系统并不知道:

CODE
剧情
演员
标签

它只知道你们行为很像,这就是协同过滤。

协同过滤的优势

协同过滤真正厉害的是自动学出“隐含特征”。

关于 隐含特征(Latent Features),用一个最通俗的方式来解释: 

系统不会真的写:

CODE
爱情程度
动作程度

而是学出: 

CODE
Feature1
Feature2
Feature3

这些特征没有名字,不是人工定义,完全由数据决定,但它们非常有用。 

假设你在做一个内容平台,系统可能自动学出:

CODE
Feature1:节奏快慢
Feature2:信息密度
Feature3:情绪强度

但你从来没有告诉它这些,这就是协同过滤最神奇的地方。

协同过滤到底在做什么?

简单来说,协同过滤同时在学习用户特征和内容特征。也就是说:

CODE
用户有偏好
内容有属性

但这两个东西都是未知的,系统会一起把它们学出来。

这正是协同过滤算法的核心:它会利用多个用户对同一物品的评分数据,自动推断物品的特征,并据此预测其他用户的偏好。

系统过滤的核心公式其实很简单:

CODE
预测评分 = 用户特征 · 物品特征

也就是:

CODE
rating = w · x

你可以把它理解成兴趣匹配程度,如果: 

CODE
用户喜欢动作
电影是动作

匹配度就高。例如下列代码,是关于协同过的一个极简 TensorFlow 示例:

CODE
import tensorflow as tf
import numpy as np
# 用户-电影评分矩阵
ratings = np.array([
    [5, 4, 0],
    [5, 0, 3],
    [1, 2, 5]
])
num_users = 3
num_items = 3
num_features = 2
# 随机初始化
user_features = tf.Variable(
    tf.random.normal([num_users, num_features])
)
item_features = tf.Variable(
    tf.random.normal([num_items, num_features])
)
def predict():
    return tf.matmul(user_features,
                     item_features,
                     transpose_b=True)
optimizer = tf.keras.optimizers.Adam(0.01)
for step in range(200):
    with tf.GradientTape() as tape:
        prediction = predict()
        loss = tf.reduce_mean(
            (prediction - ratings) ** 2
        )
    grads = tape.gradient(
        loss,
        [user_features, item_features]
    )
    optimizer.apply_gradients(
        zip(grads,
            [user_features, item_features])
    )
print(predict())

你只需要理解一件事:

CODE
系统不断调整用户特征和物品特征,
直到预测结果最接近真实行为

现实世界里,大多数推荐不是评分,而是行为

很多人以为,推荐系统依赖 1~5 星评分。但实际上,大多数系统用的是:

CODE
点击
浏览
停留时间
购买
点赞

也就是 0 或 1,例如:

CODE
用户点击 → 1
用户没点击 → 0

这叫二分类推荐(Binary Recommendation)。现实中非常常见,比如:

CODE
是否点击广告
是否购买商品
是否播放视频
是否点赞内容

很多推荐系统就是预测用户会不会做这个动作。

推荐系统,本质不是算法问题是数据问题

假设你的数据是: 

CODE
用户1 看了10秒
用户2 看了30秒
用户3 看了5秒

那么系统只能学到:

CODE
停留时间

但如果你再增加: 

CODE
是否点赞
是否转发
是否收藏

系统的判断能力会立刻提升。

所以推荐系统的上限,取决于数据质量,而不是模型复杂度。


今天这篇文章,你只需要记住三件事:

1、协同过滤的核心思想是相似的人喜欢相似的东西;

2、系统同时学习两件事:用户特征和内容特征。而且都是自动学出来的;

3、推荐系统最重要的不是算法,而是用户行为数据。

在很多技术讨论里,我们习惯把推荐系统理解为一种优化工具:通过更精准的算法,提高点击率,提高转化率,提高停留时间。

但如果把时间拉长一点,你会发现推荐系统真正改变的,不是指标,而是系统理解用户的方式。

过去,产品是围绕功能设计的,用户需要什么,就主动去搜索,系统只负责把结果呈现出来。

而今天,越来越多的系统开始承担另一种角色——在用户还没有表达需求之前,就尝试理解他。

协同过滤的意义,也正是在这里。它并不依赖复杂的标签,也不需要完全理解内容本身,而是通过大量用户的行为,逐渐建立起一种关于偏好的共识。

这种共识,不是某一个人的判断,而是很多人的经验,很多次选择,以及很多次相似行为慢慢叠加出来的结果。

所以,从某种意义上说,推荐系统并不是在预测未来。它只是把过去无数人的选择,整理成了一种可以被复用的经验。

而一个成熟的系统,也不需要完美地理解每一个用户。它只需要持续学习一件事情——什么样的人,在什么样的情境下,会做出什么样的选择。

这,就是协同过滤真正的价值。

附录:本文涉及的专有名词中英文对照(标红为最核心)

中文
English
一句话说明
推荐系统
Recommender System
根据用户历史行为预测其可能喜欢的内容
协同过滤
Collaborative Filtering
利用多个用户的行为共同推断用户偏好
用户
User
使用系统的人
物品
Item
被推荐的对象,如商品、视频或文章
评分矩阵
Rating Matrix
用户对物品的评分或行为记录表
特征
Feature
描述用户或物品的隐藏属性
隐含特征
Latent Feature
系统自动学习出来的潜在偏好或属性
预测
Prediction
估计用户未来可能的行为
正则化
Regularization
防止模型过度拟合数据的方法
二分类标签
Binary Label
用 0 或 1 表示用户是否喜欢或点击