博客
关于我
python 实现基于用户的协同过滤算法
阅读量:655 次
发布时间:2019-03-15

本文共 2264 字,大约阅读时间需要 7 分钟。

用户协同过滤算法实现

算法思想

基于用户的协同过滤算法的核心思想是:有相似兴趣的用户可能会喜欢相同的物品。因此,计算用户的相似度成为实现推荐系统的关键步骤。本文采用了下列相似度公式:

[ \omega_{uv} = \frac{N(u) \bigcap N(v)}{\sqrt{N(u) \times N(v)}} ]

其中,( N(u) ) 表示用户 ( u ) 看过的电影数量。

实现思路

本实现使用了 MovieLens 数据集,该数据集包含用户对电影的评分信息。具体步骤如下:

  • 数据集加载:从 ratings.csv 文件中读取数据,将数据按用户-电影-评分-时间戳的格式存储,并整理成物品-用户的倒排表。

  • 变量定义

    • ( N ):记录用户看过的电影数量。
    • ( W ):用户相似度矩阵。
    • ( train ):存储用户交互数据。
    • ( item_users ):存储物品-用户倒排表。
    • ( k ):推荐的相似用户数量。
    • ( n ):每个用户推荐的电影数量。
  • 计算相似度矩阵:遍历倒排表,统计每个用户的交互次数,并计算用户之间的相似度。

  • 推荐算法:为目标用户推荐电影,首先获取其已观看的电影列表,然后基于相似度排序的用户,计算并推荐未观看的电影。

  • 代码实现

    import operatorclass UserBasedCF:    def __init__(self):        self.N = {}  # 记录用户看过的电影数量        self.W = {}  # 用户相似度矩阵        self.train = {}  # 用户交互数据        self.item_users = {}  # 物品-用户倒排表        self.k = 30  # 相似用户数量        self.n = 10  # 每个用户推荐的电影数量    def get_data(self, file_path):        """加载数据集"""        with open(file_path, 'r') as f:            for line in f:                if not line.strip():                    continue                user, item, rating, timestamp = line.split(',')                self.train.setdefault(user, [])                self.train[user].append((item, rating))                self.item_users.setdefault(item, []).append(user)    def similarity(self):        """计算用户相似度矩阵"""        for item, users in self.item_users.items():            for u in users:                self.N[u] = self.N.get(u, 0) + 1                for v in users:                    if u != v:                        self.W.setdefault(u, {})                        self.W[u][v] = self.W.get(u, {}).get(v, 0) + 1        for u in self.W:            for v in self.W[u]:                self.W[u][v] /= (self.N[u] * self.N[v]) ** 0.5    def recommendation(self, user):        """为指定用户推荐电影"""        watched = {item for (item, _) in self.train[user]}        ranked = {}        for v, similarity in sorted(self.W[user].items(), key=operator.itemgetter(1), reverse=True)[:self.k]:            for item, rating in self.train[v]:                if item not in watched:                    ranked[item] = ranked.get(item, 0) + similarity * float(rating)        return sorted(ranked.items(), key=operator.itemgetter(1), reverse=True)[:self.n]

    运行结果

    程序随机选择一位用户,基于其最相似的 30 个用户,为其推荐 10 部电影。推荐结果包括电影 ID 和加权评分,具体结果请参考运行环境中的输出。

    参考资料

    《推荐系统实践》——项亮

    转载地址:http://sezmz.baihongyu.com/

    你可能感兴趣的文章
    Plotly 绘制表面 3D 未显示
    查看>>
    Plotly-Dash 存在未知问题并创建“加载依赖项时出错“;通过使用 Python-pandas.date_range
    查看>>
    Plotly-Dash:如何过滤具有多个数据框列的仪表板?
    查看>>
    Plotly:如何为 x 轴上的时间序列设置主要刻度线/网格线的值?
    查看>>
    Plotly:如何从 x 轴删除空日期?
    查看>>
    Plotly:如何从单条迹线制作堆积条形图?
    查看>>
    Plotly:如何以 Root 样式绘制直方图,仅显示直方图的轮廓?
    查看>>
    Plotly:如何使用 Plotly Express 组合散点图和线图?
    查看>>
    Plotly:如何使用 plotly.graph_objects 和 plotly.express 定义图形中的颜色?
    查看>>
    Plotly:如何使用 Python 对绘图对象条形图进行颜色编码?
    查看>>
    Plotly:如何使用 updatemenus 更新一个特定的跟踪?
    查看>>
    Plotly:如何使用长格式或宽格式的 pandas 数据框制作线图?
    查看>>
    Plotly:如何向烛台图添加交易量
    查看>>
    Plotly:如何在 plotly express 中找到趋势线的系数?
    查看>>
    Plotly:如何在桑基图中设置节点位置?
    查看>>
    Plotly:如何处理重叠的颜色条和图例?
    查看>>
    Plotly:如何手动设置 plotly express 散点图中点的颜色?
    查看>>
    Plotly:如何结合 make_subplots() 和 ff.create_distplot()?
    查看>>
    Plotly:如何绘制累积的“步骤“;直方图?
    查看>>
    Quartz进一步学习与使用
    查看>>