使用implicit处理稀疏矩阵

背景

对于非常大的稀疏矩阵,直接计算相似度通常是不切实际的,因为这会导致巨大的计算成本。例如,如果直接计算用户之间的相似度或项目之间的相似度,需要遍历整个矩阵,这在数据量很大的情况下几乎是不可能完成的任务。实际应用中经常使用如SVD(奇异值分解)和ALS(交替最小二乘法)这样的方法来处理推荐系统的评分矩阵。这些方法非常适合处理稀疏矩阵,而且能够有效地处理非常大的数据集

推荐系统中确实越来越多地采用了深度学习技术,但这并不意味着传统的算法如SVD(奇异值分解)、ALS(交替最小二乘法)已经被完全淘汰。实际上,各种方法各有优势,在不同的应用场景中仍然有着广泛的应用。

传统推荐算法的优势

  • SVD/ALS 等方法在处理稀疏矩阵方面非常有效,能够很好地处理大型数据集。

  • 这些算法相对简单,易于实现和理解。

  • 对于某些场景,尤其是数据量不是特别大且用户行为模式相对稳定的情况,这些方法的效果依然很好。
    深度学习在推荐系统中的应用

  • 深度学习能够更好地捕捉复杂的非线性关系,这对于处理用户行为和偏好等方面尤其有用。

  • 深度学习模型,如DNN(深度神经网络)、CNN(卷积神经网络)、RNN(循环神经网络)以及Transformer等,可以在用户画像、序列推荐、点击率预测等多个方面发挥重要作用。

  • 深度学习模型可以融合多种类型的数据(如文本、图像、视频等),从而提供更加丰富和个性化的推荐。
    实际应用中的选择:
    在实际应用中,推荐系统采用的是混合策略,即结合多种算法和技术。例如:

  • 数据规模较小:可能更倾向于使用SVD/ALS等传统算法。

  • 数据规模较大且需要处理复杂特征:深度学习模型会更有优势。

  • 多模态数据:结合文本、图像等多种数据源的情况下,深度学习模型能够更好地整合这些信息。

  • 实时推荐:对于需要实时响应的推荐场景,简单的模型或组合模型可能更合适。

implicit介绍

implicit是一个非常强大的Python库,专门用于实现推荐系统中的协同过滤算法,尤其是针对大规模稀疏数据集。它主要支持两种类型的协同过滤方法:基于用户的协同过滤和基于项目的协同过滤。implicit库特别适用于处理显式反馈(如评分数据)和隐式反馈(如点击、浏览等行为数据)

特点

  • 高性能:implicit使用numba和cython进行了优化,能够高效地处理大规模数据集。
  • 易于使用:API简洁明了,易于上手。
  • 多种推荐算法:支持多种矩阵分解算法,如SVD、ALS等。
  • 支持显式和隐式反馈:可以根据数据类型选择合适的模型。
  • 灵活的参数调整:可以轻松调整模型参数以适应不同场景。

安装

pip install implicit
查看版本
在这里插入图片描述

测试

import pandas as pd
from implicit.als import AlternatingLeastSquares
from implicit.nearest_neighbours import bm25_weight
# ratings_df 是一个 DataFrame,包含三列:用户ID、物品ID和评分
# 示例数据
ratings_df = pd.DataFrame({
    'user_id': [1, 1, 1, 2, 2, 3],
    'item_id': [1, 2, 3, 1, 2, 1],
    'rating': [5.0, 3.0, 4.0, 4.0, 5.0, 3.0]
})

# 创建用户-物品评分矩阵
user_item_matrix = ratings_df.pivot(index='user_id', columns='item_id', values='rating').fillna(0)

# 应用BM25权重
user_item_matrix = bm25_weight(user_item_matrix.T).T

# 初始化ALS模型
model = AlternatingLeastSquares(factors=50, regularization=0.01, iterations=20)

# 训练模型
model.fit(user_item_matrix)

# 获取用户推荐
user_id = 1  # 示例用户ID
recommendations = model.recommend(user_id, user_item_matrix[user_id], N=10)

# 输出推荐结果
for item_id, score in recommendations:
    print(f"Item ID: {item_id}, Score: {score}")

解释

user_item_matrix = bm25_weight(user_item_matrix.T).T

bm25_weight函数,该函数接收一个评分矩阵作为输入,并返回一个经过BM25加权处理后的矩阵。由于user_item_matrix是以用户作为行索引,物品作为列索引的,所以在传入bm25_weight之前,我们先转置了矩阵,使得物品成为行索引,用户成为列索引。这是因为bm25_weight默认处理的是物品-用户矩阵。
加权处理后,我们再次转置矩阵,以便保持用户-物品的原始结构。这样做的原因是后续训练AlternatingLeastSquares模型时需要保持用户-物品的结构不变。

BM25

BM25(Best Match
25)是一种信息检索中常用的文本相关性评分函数。它最初是为了文档检索设计的,用于评估查询和文档的相关性。在推荐系统中,BM25可以用来对用户-物品评分矩阵中的评分进行加权处理,以反映物品的流行程度和用户的评分习惯。

BM25的作用:

  • 增加热门物品的重要性:如果一个物品被很多用户评分,那么这个物品的评分会被认为更加重要。
  • 减少冷门物品的影响:如果一个物品只被少数用户评分,那么它的评分会被适当降低权重,以避免过高地估计其受欢迎程度。
  • 虑用户的评分行为:不同用户可能会有不同的评分习惯。例如,一些用户倾向于给较高的分数,而另一些则相反。BM25可以帮助调整这些差异,使评分更具可比性。

数据量大的处理方式

实际使用中数据量都非常大,需要做一些处理
比如

  • 压缩稀疏矩阵
  • 增量更新
  • 并行(多核)批处理
  • 数据预处理 提前进行一些数据预处理,比如去重、排序等,可以减少训练时的数据处理开销

上述代码优化

import pandas as pd
import numpy as np
from scipy.sparse import csr_matrix
from implicit.als import AlternatingLeastSquares
from implicit.nearest_neighbours import bm25_weight

# 示例数据
ratings_df = pd.DataFrame({
    'user_id': [1, 1, 1, 2, 2, 3],
    'item_id': [1, 2, 3, 1, 2, 1],
    'rating': [5.0, 3.0, 4.0, 4.0, 5.0, 3.0]
})

# 数据预处理
# 去除重复评分
ratings_df = ratings_df.drop_duplicates(subset=['user_id', 'item_id'])

# 创建用户-物品评分矩阵
# 使用稀疏矩阵表示
n_users = ratings_df['user_id'].max() + 1
n_items = ratings_df['item_id'].max() + 1
user_item_matrix = csr_matrix((ratings_df['rating'], (ratings_df['user_id'] - 1, ratings_df['item_id'] - 1)), shape=(n_users, n_items))

# 应用BM25权重
# 注意:这里假设物品ID是从0开始的连续整数
user_item_matrix = bm25_weight(user_item_matrix.T).T

# 初始化ALS模型
model = AlternatingLeastSquares(factors=50, regularization=0.01, iterations=20, use_gpu=True)  # 如果有GPU,可以设置use_gpu=True

# 训练模型
model.fit(user_item_matrix)

# 获取用户推荐
user_id = 1  # 示例用户ID
recommendations = model.recommend(user_id - 1, user_item_matrix[user_id - 1], N=10)

# 输出推荐结果
for item_id, score in recommendations:
    print(f"Item ID: {item_id + 1}, Score: {score}")

代码说明

ratings_df['user_id'].max() + 1 最大uid加1

csr_matrix:
csr_matrix是scipy.sparse模块中的一个类,用于创建压缩稀疏行矩阵(Compressed Sparse Row matrix)。这是一种高效的稀疏矩阵表示方式,特别适合处理大型稀疏矩阵。
参数说明:
第一个参数是一个元组,其中包含:
数据:ratings_df['rating'],这是一个包含评分值的数组。
索引:一个包含两个元组的元组,分别是:
(ratings_df['user_id'] - 1):用户ID数组,减1是因为索引是从0开始的。
(ratings_df['item_id'] - 1):物品ID数组,同样减1以适应从0开始的索引。
shape=(n_users, n_items):定义了矩阵的形状,即行数和列数。这里n_users和n_items分别是用户总数和物品总数。
  • 24
    点赞
  • 18
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值