协同过滤怎么实现?

wen python案例 3

从原理到实战的完整指南

目录导读

  1. 协同过滤的核心思想与分类
  2. 基于用户的协同过滤实现步骤
  3. 基于物品的协同过滤实现步骤
  4. 矩阵分解与隐语义模型
  5. 冷启动与稀疏性问题解决方案
  6. 代码实战:Python实现协同过滤
  7. 常见问题与优化策略(Q&A)
  8. 总结与未来趋势

协同过滤的核心思想与分类

协同过滤(Collaborative Filtering)是推荐系统中最经典的算法,其核心假设是:“过去兴趣相似的用户,未来也会有相似的兴趣”“用户喜欢的物品,其相似物品也会被喜欢”,它不依赖物品本身的属性(如文本、图片),而是通过用户行为数据(评分、点击、购买)挖掘群体智慧。

协同过滤怎么实现?

主要分类:

  • 基于用户(User-Based):找到相似用户,推荐他们喜欢的物品。
  • 基于物品(Item-Based):找到相似物品,推荐目标用户过去喜欢的物品的同类。
  • 模型化方法:如矩阵分解(SVD、NMF)、隐语义模型(LFM)。

FAQ:协同过滤与内容推荐的区别? 推荐基于物品特征(如标签、分类),而协同过滤仅依赖用户行为,协同过滤能发现“隐性关联”,但存在冷启动问题。


基于用户的协同过滤实现步骤

步骤1:构建用户-物品评分矩阵

假设有M个用户,N个物品,形成M×N矩阵,元素 ( r_{ui} ) 表示用户u对物品i的评分(或行为权重)。

步骤2:计算用户相似度

常用算法:

  • 皮尔逊相关系数:衡量两组评分变化的线性相关性,适合处理评分尺度差异。
  • 余弦相似度:计算用户评分向量的夹角余弦,需先减去用户平均分(修正余弦)消除偏差。
  • 杰卡德相似度:适用于二元行为(点击/未点击)。

公式示例(修正余弦): [ \text{sim}(u, v) = \frac{\sum{i \in I{uv}}(r_{ui} - \bar{r}u)(r{vi} - \bar{r}v)}{\sqrt{\sum{i \in I{uv}}(r{ui} - \bar{r}u)^2} \sqrt{\sum{i \in I{uv}}(r{vi} - \bar{r}_v)^2}} ]

步骤3:生成推荐

  • 找到与目标用户u最相似的K个用户(K近邻)。
  • 预测u对未评分物品i的评分: [ \hat{r}_{ui} = \bar{r}u + \frac{\sum{v \in N(u)} \text{sim}(u, v) \cdot (r_{vi} - \bar{r}v)}{\sum{v \in N(u)} |\text{sim}(u, v)|} ]
  • 将预测评分最高的Top-N物品推荐给用户。

代码片段(Python伪代码):

def user_based_cf(ratings_matrix, user_id, k=10, top_n=5):
    sim_dict = compute_user_similarity(ratings_matrix, user_id)
    nearest_neighbors = sorted(sim_dict.items(), key=lambda x: x[1], reverse=True)[:k]
    # 预测评分逻辑...
    return recommended_items

基于物品的协同过滤实现步骤

为什么更常用?

  • 稳定性:用户兴趣变化快,而物品间相似性相对稳定。
  • 可解释性:推荐理由更直观(“因为您喜欢A,所以推荐相似的B”)。

步骤:

  1. 构建用户-物品评分矩阵(同用户版)。
  2. 计算物品相似度:对任意两个物品i、j,计算共同评分用户的评分向量相似度(常用修正余弦、皮尔逊)。
  3. 生成推荐:根据用户已评分物品,加权聚合相似物品的评分: [ \hat{r}{ui} = \frac{\sum{j \in N(i)} \text{sim}(i, j) \cdot r{uj}}{\sum{j \in N(i)} |\text{sim}(i, j)|} ]

注意:需预先计算物品相似度矩阵,避免实时计算,在大规模场景下,可用近似近邻算法(如LSH)加速。


矩阵分解与隐语义模型

SVD(奇异值分解)

将评分矩阵分解为 ( R = U \cdot \Sigma \cdot V^T ),取前k个奇异值降维,再用隐向量点积预测评分: [ \hat{r}_{ui} = U_u \cdot V_i^T ]

FunkSVD(隐语义模型)

只分解用户和物品的隐向量,通过最小化平方误差学习: [ \min \sum{(u,i) \in Train} (r{ui} - U_u V_i^T)^2 + \lambda(|U_u|^2 + |V_i|^2) ] 使用随机梯度下降(SGD)更新参数。

优点:可处理稀疏性,泛化能力强;缺点:不可解释。


冷启动与稀疏性问题

冷启动问题

  • 新用户:无历史行为 → 使用热门推荐、人口统计学信息或内容特征。
  • 新物品:无用户交互 → 基于物品元数据(如类别、标签)做内容相似推荐。

稀疏性问题

  • 降维:矩阵分解压缩特征。
  • 正则化:防止过拟合。
  • 多模态融合:引入用户画像、物品属性、社交关系等侧信息。

QA:协同过滤的稀疏性阈值?
通常用户-物品矩阵密度 < 1% 即高度稀疏,Amazon使用物品协同过滤,因为物品集合相对稳定,相似度可离线计算。


代码实战:Python实现基于用户的协同过滤

import numpy as np
from sklearn.metrics.pairwise import cosine_similarity
class UserBasedCF:
    def __init__(self, k=10):
        self.k = k
        self.ratings = None
        self.user_ids = None
        self.item_ids = None
    def fit(self, ratings_df):
        """ratings_df: columns=['user_id', 'item_id', 'rating']"""
        self.ratings = ratings_df.pivot(index='user_id', columns='item_id', values='rating').fillna(0)
        self.user_ids = self.ratings.index.tolist()
        self.item_ids = self.ratings.columns.tolist()
    def predict(self, user_id, item_id):
        user_idx = self.user_ids.index(user_id)
        item_idx = self.item_ids.index(item_id)
        if self.ratings.iloc[user_idx, item_idx] != 0:
            return self.ratings.iloc[user_idx, item_idx]  # 已有评分
        # 计算相似用户
        user_vec = self.ratings.iloc[user_idx].values.reshape(1, -1)
        sims = cosine_similarity(user_vec, self.ratings.values)[0]
        nearest = np.argsort(sims)[-self.k-1:-1][::-1]
        # 加权预测
        sum_sim = 0
        sum_rating = 0
        for idx in nearest:
            if sims[idx] > 0 and self.ratings.iloc[idx, item_idx] != 0:
                sum_sim += sims[idx]
                sum_rating += sims[idx] * self.ratings.iloc[idx, item_idx]
        return sum_rating / sum_sim if sum_sim > 0 else 0
    def recommend(self, user_id, top_n=5):
        user_idx = self.user_ids.index(user_id)
        preds = [self.predict(user_id, item) for item in self.item_ids]
        rec_indices = np.argsort(preds)[::-1][:top_n]
        return [self.item_ids[i] for i in rec_indices]

常见问题与优化策略(Q&A)

Q1:K值怎么选?
A:通过交叉验证,观察不同K下的推荐准确率(如RMSE、Precision@k),通常K=10~50效果较好。

Q2:为什么基于物品的协同过滤比基于用户的更受欢迎?
A:物品相似度矩阵可离线存储,在线推荐计算快;且适合大规模用户场景(用户数远大于物品数时)。

Q3:如何处理用户评分偏差?
A:使用“归一化”或“中心化”,如减去用户平均分后再计算相似度,预测时再加回。

Q4:协同过滤适合新闻推荐吗?
A:新闻时效性强,用户兴趣变化快,物品(文章)易冷启动,通常采用混合推荐:协同过滤+内容特征+热度。

Q5:如何提升实时性?
A:使用增量计算(如增量矩阵分解)、离线预计算相似度、或采用图神经网络(GNN)等方案。


总结与未来趋势

协同过滤仍是推荐系统的基石,但其局限(冷启动、稀疏性)需通过融合上下文、社交关系、深度学习(如神经协同过滤)来突破,未来趋势包括:

  • 图神经网络:将用户-物品交互建模为图,捕捉高阶关系。
  • 多模态协同:整合文本、图像、时序特征。
  • 联邦学习:在保护隐私的情况下实现跨设备协同。

最后强调:实现一个生产级协同过滤系统,需要关注离线评估(A/B测试)工程化性能(如使用Spark、Faiss) 以及业务可解释性,从简单模型开始,逐步迭代优化效果。

抱歉,评论功能暂时关闭!