You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

基于用户/物品画像的个性化Collaborative Filtering(CF) Python实现咨询

嘿,这个思路很棒啊——用深度用户/物品画像替代传统的评分相似度做协同过滤,刚好能验证画像对推荐性能的提升作用。我来一步步给你拆解Python实现的方案,分用户侧和物品侧两块来讲:

核心逻辑梳理

不管是用户侧还是物品侧,你的需求核心都是先基于画像相似度锁定「同类群体」,再从同类里选K近邻,最后用协同过滤的方式生成推荐。和传统CF的区别是:传统CF靠评分矩阵算相似度,而你这里靠画像特征算相似度,先圈定典型群体再选近邻,更贴合个性化的画像维度。

第一步:画像相似度计算

首先得把用户/物品画像转化为可计算相似度的向量,不同类型的画像特征对应不同的相似度算法:

  • 数值型特征(比如年龄、消费金额、物品价格):用余弦相似度或欧氏距离
  • 类别/标签型特征(比如用户兴趣标签、物品分类):用Jaccard相似度,或者先做One-Hot编码转数值再用余弦

下面是两种常见场景的实现代码:

import numpy as np
from sklearn.metrics.pairwise import cosine_similarity
from sklearn.preprocessing import StandardScaler

# 1. 数值型画像的余弦相似度计算
def calc_numerical_similarity(target_vec, all_vecs):
    # 确保输入是二维数组(适配sklearn的接口)
    target = target_vec.reshape(1, -1)
    # 计算余弦相似度,返回每个样本与目标的相似度数组
    similarities = cosine_similarity(target, all_vecs)[0]
    return similarities

# 2. 标签型画像的Jaccard相似度计算
def calc_jaccard_similarity(target_tags, all_user_tags):
    similarities = []
    target_set = set(target_tags)
    for user_tags in all_user_tags:
        user_set = set(user_tags)
        intersection = len(target_set & user_set)
        union = len(target_set | user_set)
        sim = intersection / union if union != 0 else 0
        similarities.append(sim)
    return np.array(similarities)
第二步:用户侧个性化CF实现

按照你的需求,分三个阶段完成:

阶段1:匹配典型用户画像

这里有两种落地方式,你可以根据数据规模选:

  • 预聚类典型画像:先对所有用户画像做聚类,把每个簇的中心作为「典型画像」,找到目标用户所属的簇
  • 直接锁定同类用户:跳过聚类,直接找和目标用户画像相似度Top N的用户作为同类群体

这里以聚类方式为例:

from sklearn.cluster import KMeans

# 假设user_portraits是标准化后的数值矩阵,形状为(用户数, 画像特征数)
# 先聚类得到典型用户群(簇数可以用肘部法则确定,这里暂设为10)
kmeans = KMeans(n_clusters=10, random_state=42)
user_cluster_labels = kmeans.fit_predict(user_portraits)
typical_portraits = kmeans.cluster_centers_  # 每个簇的中心就是典型画像

# 找到目标用户所属的簇
target_user_idx = 0  # 替换成你的目标用户索引
target_cluster = user_cluster_labels[target_user_idx]
# 获取同簇内所有用户的索引
same_cluster_users = np.where(user_cluster_labels == target_cluster)[0]

阶段2:从同类中选K近邻

在同簇内,用画像相似度选出Top K个最相似的用户(排除目标用户自己):

k = 5  # 你要的近邻数
target_portrait = user_portraits[target_user_idx]
# 计算同簇内用户与目标用户的画像相似度
cluster_similarities = calc_numerical_similarity(target_portrait, user_portraits[same_cluster_users])

# 按相似度从高到低排序,排除自己后取Top K
sorted_indices = np.argsort(cluster_similarities)[::-1]
top_k_user_indices = [
    same_cluster_users[i] 
    for i in sorted_indices 
    if same_cluster_users[i] != target_user_idx
][:k]

阶段3:生成推荐

收集Top K近邻用户的高分物品,排除目标用户已经交互过的物品:

# 假设user_item_matrix是用户-物品评分矩阵(行=用户,列=物品,0表示未交互)
user_item_matrix = np.array([...])  # 替换成你的真实评分数据

# 收集近邻用户的高分物品(比如评分>=4)
recommended_items = set()
for user_idx in top_k_user_indices:
    high_rated_items = np.where(user_item_matrix[user_idx] >= 4)[0]
    recommended_items.update(high_rated_items)

# 排除目标用户已经交互过的物品
target_rated_items = np.where(user_item_matrix[target_user_idx] > 0)[0]
final_recs = [item for item in recommended_items if item not in target_rated_items]

print("用户侧CF推荐结果:", final_recs)
第三步:物品侧个性化CF实现

逻辑和用户侧完全对称,只是把用户换成物品:

阶段1:匹配典型物品画像

# 对物品画像聚类,得到典型物品群
item_kmeans = KMeans(n_clusters=8, random_state=42)
item_cluster_labels = item_kmeans.fit_predict(item_portraits)
typical_item_portraits = item_kmeans.cluster_centers_

# 假设目标用户感兴趣的物品是item_idx=10
target_item_idx = 10
target_item_cluster = item_cluster_labels[target_item_idx]
# 获取同簇内所有物品的索引
same_cluster_items = np.where(item_cluster_labels == target_item_cluster)[0]

阶段2:从同类中选K近邻物品

k = 5
target_item_portrait = item_portraits[target_item_idx]
# 计算同簇内物品与目标物品的画像相似度
cluster_item_similarities = calc_numerical_similarity(target_item_portrait, item_portraits[same_cluster_items])

# 按相似度排序,排除自己后取Top K
sorted_item_indices = np.argsort(cluster_item_similarities)[::-1]
top_k_item_indices = [
    same_cluster_items[i] 
    for i in sorted_item_indices 
    if same_cluster_items[i] != target_item_idx
][:k]

阶段3:生成推荐

给目标用户推荐这些同类物品(排除已交互的):

# 找目标用户未交互的物品
target_unrated_items = np.where(user_item_matrix[target_user_idx] == 0)[0]
item_recs = [item for item in top_k_item_indices if item in target_unrated_items]

print("物品侧CF推荐结果:", item_recs)
第四步:性能验证

要验证画像的作用,需要把你的新方法和传统CF(surprise库的用户/物品CF)做对比,常用的评估指标:

  • 评分预测任务:MAE、RMSE
  • Top-N推荐任务:Precision@K、Recall@K、NDCG

这里给你一个Precision@K的实现示例:

def precision_at_k(recommended_items, true_liked_items, k):
    # true_liked_items是用户实际喜欢的物品(比如评分>=4的)
    rec_k = recommended_items[:k]
    hits = len(set(rec_k) & set(true_liked_items))
    return hits / k if k > 0 else 0

# 分别计算两种方法的Precision@K
true_items = np.where(user_item_matrix[target_user_idx] >=4)[0]
your_precision = precision_at_k(final_recs, true_items, k=5)
# 传统CF的precision需要你用surprise库跑出来后计算
一些优化建议
  • 如果画像混合了数值、类别、标签特征,可以用加权融合的方式计算相似度(比如数值特征占60%权重,标签特征占40%)
  • 聚类的簇数别瞎选,用肘部法则或轮廓系数确定最优簇数
  • 数据量大时,用近似最近邻算法(比如Annoy、FAISS)加速相似度计算,避免O(n)的时间开销
  • 后期可以尝试把画像相似度和评分相似度加权结合,说不定能得到更好的效果

内容的提问来源于stack exchange,提问作者Geek88

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.29 06:48:34