📜  light fm 冷启动问题 - Python (1)

📅  最后修改于: 2023-12-03 15:02:41.110000             🧑  作者: Mango

Light FM 冷启动问题 - Python

简介

在推荐系统中,冷启动问题一直是一个挑战。当一个新用户或新项目加入系统时,我们无法依靠历史数据来进行个性化推荐。Light FM 是一个基于矩阵分解的推荐系统模型,可以帮助我们解决这个问题。

Light FM

Light FM 是由 Maciej Kula 开发的基于矩阵分解的推荐系统模型。它是基于无偏见的光栅分解的,因此可以处理真正的隐式和显式反馈数据,并且将内容特征合并到模型中。

Light FM 主要集成了两种类型的算法:

  • 基于矩阵分解的推荐
  • 点积

这些算法允许 Light FM 自适应学习特征之间的交互,从而生成个性化推荐。

冷启动问题

当我们面对新用户或新项目时,由于没有历史数据,我们不能依靠协同过滤或基于内容推荐。这个冷启动问题很难解决,但通过 Light FM,我们可以使用主观特征(例如描述、标签或分类)来进行个性化推荐。

解决方案

使用主观特征的过程可以简述如下:

  1. 收集项目的主观特征,例如标签或分类。
  2. 将这些特征转换为洗牌后的二进制列表。
  3. 使用 Light FM 学习这些二进制列表和用户行为之间的关系。
  4. 根据用户行为和特征,生成个性化推荐。

例如,在电影推荐系统中,我们可以将电影的主观特征(例如导演、演员、类型)转换为二进制列表。同时,我们可以将用户历史观看记录转换为二进制列表。这些列表可以传入 Light FM 中作为模型的输入,以生成个性化推荐。

实现

Light FM 是用 Python 编写的,因此我们可以通过 Python 模块来实现它。我们可以使用以下命令来安装模块:

pip install lightfm

首先,我们需要加载数据集并将其转换为 Light FM 使用的格式。具体来说,我们需要将每一行(每次购买、查看或评分)表示为三元组(用户、项目、分数)。

import numpy as np
from lightfm.datasets import fetch_movielens
from lightfm import LightFM

# 加载 MovieLens 100k 数据集 (使用评分数据)
data = fetch_movielens(min_rating=4.0)

# 打印训练集和测试集的形状
print(repr(data['train']))
print(repr(data['test']))

接下来,我们可以构建 Light FM 模型并使用 SGD 训练它。

# 创建模型,使用默认参数
model = LightFM(loss='warp')

# 训练模型
model.fit(data['train'], epochs=30, num_threads=2)

在训练完成后,我们可以获得对新项目的推荐。首先,我们需要将项目的主观特征转换为二进制列表。

# 获取所有电影的名称和ID
item_ids = data['item_labels']
item_ids = np.array([i.decode("utf-8") for i in item_ids])

# 打印前10个项目的名称
print(item_ids[:10])

# 获取特定电影的ID
def get_movie_id(movie_name):
    idx = np.where(item_ids == movie_name)[0][0]
    return idx

# 获取电影的主观特征 (类型和年份)
def get_movie_features(movie_id):
    movie_genres = data['item_features'][movie_id]
    feature_names = data['item_feature_labels']
    movie_features = []
    for feature_id, val in zip(movie_genres.indices, movie_genres.data):
        feature_name = feature_names[feature_id]
        movie_features.append(feature_name)
    return ', '.join(movie_features)

# 获取特定电影的主观特征
def get_movie_features_by_name(movie_name):
    idx = get_movie_id(movie_name)
    return get_movie_features(idx)

# 打印特定电影的主观特征
print(get_movie_features_by_name('Toy Story (1995)'))

然后,我们可以使用 Light FM 的 predict_rank 方法来获取推荐列表。

# 获取电影的推荐
def get_movie_recommendations(model, positives, item_ids):
    # 在模型中获取项目和特征
    n_items, n_features = model.item_embeddings.shape
    features = np.eye(n_items, n_features)
    feature_bias = np.zeros(n_items)
    item_biases = model.item_biases[positives]
    user_features = np.zeros((1, n_features))

    # 预测排名
    scores = model.predict_rank(features,
                                feature_bias,
                                item_biases,
                                user_features,
                                evaluate_candidates=range(n_items))

    # 排序并返回最高分的项目
    top_items = item_ids[np.argsort(-scores)]
    return top_items

# 获取推荐列表
movie_id = get_movie_id('Toy Story (1995)')
recommendations = get_movie_recommendations(model, [movie_id], item_ids)

# 打印最高分的10个推荐
print("推荐:")
for r in recommendations[:10]:
    print(get_movie_features_by_name(r))
结论

通过 Light FM,我们可以使用主观特征来解决冷启动问题。具体来说,我们可以将项目的主观特征转换为二进制列表,并将其与用户行为一起传递到 Light FM 模型中。该模型可以自适应学习特征之间的交互,并生成个性化推荐。