HOOOS

NMF算法在协同过滤推荐中的应用:原理与实战

0 64 AI算法探险家 NMF协同过滤推荐系统
Apple

NMF算法在协同过滤推荐中的应用:原理与实战

“咦?这个电影我好像没看过,但评分预测还挺高,要不要试试?” 你是不是经常在各种App上遇到类似的情景?这背后,很可能就藏着一种叫做“非负矩阵分解”(Non-negative Matrix Factorization,简称NMF)的算法。

啥是协同过滤?

在聊NMF之前,咱们先得弄明白啥是协同过滤。简单来说,就是“大家觉得好的,我也觉得好;你喜欢的,我也可能喜欢”。

想象一下,一个电影推荐网站,有成千上万的用户和电影。每个用户都给看过的电影打了分(比如1-5星)。现在,我们要给某个用户推荐他没看过的电影。咋办呢?

协同过滤说:“好办!咱们看看跟他口味相似的用户都喜欢啥电影,然后推荐给他不就得了?”

具体来说,协同过滤有两种主要思路:

  1. 基于用户的协同过滤 (User-based CF):找到和你口味相似的用户,看看他们喜欢啥,推荐给你。
  2. 基于物品的协同过滤 (Item-based CF):找到和你喜欢的物品相似的物品,推荐给你。

这两种思路的核心,都是要计算“相似度”。用户之间的相似度,或者物品之间的相似度。怎么算呢?这就要用到各种各样的数学方法了,NMF就是其中一种。

NMF:让矩阵“瘦身”

NMF,非负矩阵分解,顾名思义,就是把一个矩阵拆成两个小矩阵。而且,这两个小矩阵里的所有元素都不能是负数(非负)。

这有啥用呢?咱们还是拿电影推荐来说事儿。

假设咱们有一个用户-电影评分矩阵R,长这样:

电影1 电影2 电影3 ... 电影M
用户1 5 1 ...
用户2 4 ... 2
用户3 1 5 ...
... ... ... ... ... ...
用户N 2 ... 4

其中,问号(?)表示用户还没看过这部电影,也就是我们要预测的评分。

NMF说:“我能把这个大矩阵R,拆成两个小矩阵P和Q。P代表用户对‘潜在特征’的偏好,Q代表电影在‘潜在特征’上的表现。”

啥是“潜在特征”?你可以理解为电影的类型(比如喜剧、动作、爱情),或者更抽象的因素(比如导演风格、演员阵容)。NMF不需要你事先告诉它这些特征是啥,它自己能从数据里学出来。

分解之后,P和Q长这样:

P (用户-潜在特征矩阵):

特征1 特征2 ... 特征K
用户1 0.8 0.2 ... 0.5
用户2 0.1 0.9 ... 0.3
... ... ... ... ...
用户N 0.6 0.4 ... 0.7

Q (潜在特征-电影矩阵):

电影1 电影2 ... 电影M
特征1 0.7 0.3 ... 0.9
特征2 0.2 0.8 ... 0.1
... ... ... ... ...
特征K 0.5 0.6 ... 0.4

然后,我们就可以用P和Q来预测用户对没看过电影的评分了:

预测评分 = P * Q

比如,我们要预测用户1对电影2的评分,就可以这么算:

预测评分 = (0.8 * 0.3) + (0.2 * 0.8) + ... + (0.5 * 0.6)

NMF的数学原理

NMF的目标,是找到两个非负矩阵P和Q,使得它们的乘积尽可能接近原始矩阵R:

R ≈ P * Q

怎么找呢?NMF用了一种叫做“迭代”的方法。就像雕刻家一点一点地雕琢石像,NMF也一步一步地调整P和Q,让它们越来越接近目标。

具体来说,NMF定义了一个“损失函数”,用来衡量PQ和R之间的差距。损失函数越小,说明PQ和R越接近。

常用的损失函数有两种:

  1. 平方损失 (Squared Loss)

    Loss = ||R - P*Q||²

    这个公式的意思是,把R和P*Q里每个对应元素的差的平方加起来。

  2. KL散度 (Kullback-Leibler Divergence)

    Loss = Σ (R * log(R / (PQ)) - R + PQ)

    这个公式看起来有点复杂,但它的核心思想是衡量R和P*Q的“概率分布”之间的差异。KL散度越大,说明两个分布越不相似。

有了损失函数,NMF就可以用各种各样的优化算法(比如梯度下降、乘法更新)来找到让损失函数最小的P和Q。

NMF的优缺点

NMF的优点:

  • 可解释性强:P和Q都有明确的含义,可以帮助我们理解用户和物品的潜在特征。
  • 非负约束:非负约束更符合实际情况,比如评分不能是负数,用户对某个特征的偏好也不能是负数。
  • 计算效率高:NMF的计算复杂度相对较低,适合处理大规模数据。

NMF的缺点:

  • 不唯一性:NMF的解不唯一,也就是说,可能存在多组P和Q,它们的乘积都和R很接近。这可能会影响结果的稳定性。
  • 局部最优:NMF的优化算法可能会陷入局部最优,也就是说,找到的P和Q可能不是全局最好的。

NMF实战:Python代码示例

说了这么多,咱们来点实际的。下面是一个用Python实现NMF的简单例子:

import numpy as np
from sklearn.decomposition import NMF

# 构造一个用户-电影评分矩阵R
# 假设有5个用户,4部电影
R = np.array([
    [5, 3, 0, 1],
    [4, 0, 0, 1],
    [1, 1, 0, 5],
    [1, 0, 0, 4],
    [0, 1, 5, 4],
])

# 设置潜在特征的数量K
K = 2

# 创建NMF模型
model = NMF(n_components=K, init='random', random_state=0)

# 训练模型
P = model.fit_transform(R)
Q = model.components_

# 预测评分
R_pred = np.dot(P, Q)

# 打印结果
print("原始评分矩阵R:")
print(R)
print("\n用户-潜在特征矩阵P:")
print(P)
print("\n潜在特征-电影矩阵Q:")
print(Q)
print("\n预测评分矩阵R_pred:")
print(R_pred)

这段代码用到了Python的scikit-learn库,它提供了很多机器学习算法的实现,包括NMF。

代码很简单,主要分这么几步:

  1. 构造数据:创建一个用户-电影评分矩阵R。
  2. 设置参数:设置潜在特征的数量K。
  3. 创建模型:创建一个NMF模型。
  4. 训练模型:用R来训练模型,得到P和Q。
  5. 预测评分:用P和Q来预测评分。
  6. 打印结果:看看原始评分、P、Q和预测评分。

运行这段代码,你会看到类似这样的结果:

原始评分矩阵R:
[[5 3 0 1]
 [4 0 0 1]
 [1 1 0 5]
 [1 0 0 4]
 [0 1 5 4]]

用户-潜在特征矩阵P:
[[1.54945798 0.        ]
 [1.16822662 0.        ]
 [0.         2.1483856 ]
 [0.         1.67837545]
 [0.         2.27297888]]

潜在特征-电影矩阵Q:
[[3.22668274 2.25343576 0.          0.65376682]
 [0.39527218 0.42772463 1.56576383 1.78389136]]

预测评分矩阵R_pred:
[[5.         3.48999645 0.         1.01274996]
 [3.76249182 2.63164876 0.         0.76350288]
 [0.8490933  0.91835042 3.36234882 3.83649456]
 [0.66315155 0.71829491 2.61878986 2.98796719]
 [0.89927479 0.97372456 3.56158555 4.06065387]]

可以看到,预测评分和原始评分已经比较接近了。当然,这只是一个简单的例子,实际应用中还需要考虑很多因素,比如数据的预处理、参数的调优、模型的评估等等。

NMF的扩展和应用

除了基本的NMF,还有很多NMF的扩展,比如:

  • 加权NMF (Weighted NMF):给不同的评分赋予不同的权重,比如更近期的评分权重更高。
  • 稀疏NMF (Sparse NMF):在P和Q上加入稀疏性约束,让它们更稀疏,更容易解释。
  • 图正则化NMF (Graph Regularized NMF):利用用户之间或物品之间的关系(比如社交网络、电影类型)来约束P和Q。

NMF的应用也不仅仅局限于推荐系统,它还可以用于:

  • 图像处理:比如人脸识别、图像分割。
  • 文本挖掘:比如主题提取、文档聚类。
  • 生物信息学:比如基因表达分析、蛋白质相互作用预测。

总之,NMF是一种非常强大且灵活的工具,值得我们深入学习和探索。

希望这篇文章能帮你对NMF有一个更深入的了解。如果你对NMF感兴趣,不妨自己动手试试,相信你会发现更多有趣的用法!

记住,实践出真知!

“实践是检验真理的唯一标准。”

“纸上得来终觉浅,绝知此事要躬行。”

“Just do it!”

点评评价

captcha
健康