日期: 2024 年 6 月 29 日

  • NAML:基于注意力机制的多视角新闻推荐算法

    引言

    在信息过载的时代,个性化新闻推荐显得尤为重要。为了更精准地捕捉用户的兴趣,NAML 算法利用多视角学习,从新闻标题、正文、类别和子类别等多个角度学习新闻表示,并结合用户历史行为学习用户表示,从而实现更精准的新闻推荐。

    NAML 算法原理

    NAML 算法的核心思想是利用注意力机制,从多视角学习新闻表示和用户表示,并根据两者之间的匹配程度预测用户点击新闻的概率。具体来说,NAML 算法包含以下几个步骤:

    1. 新闻编码器:
      • 标题编码器: 使用卷积神经网络 (CNN) 对新闻标题进行编码,得到新闻标题的语义表示向量。
      • 正文编码器: 使用 CNN 对新闻正文进行编码,得到新闻正文的语义表示向量。
      • 类别编码器: 使用嵌入向量表示新闻的类别。
      • 子类别编码器: 使用嵌入向量表示新闻的子类别。
      • 注意力网络: 使用注意力网络对上述四个向量进行加权平均,得到最终的新闻表示向量。
    2. 用户编码器: 使用 GRU 网络对用户浏览过的新闻进行编码,得到用户的兴趣表示向量。
    3. 注意力机制: 使用加性注意力机制分别对新闻表示向量和用户表示向量进行加权,选择重要的词语和新闻,学习更具信息量的新闻表示和用户表示。
    4. 点击率预测: 将新闻表示向量和用户表示向量输入到一个全连接神经网络中,预测用户点击该新闻的概率。

    MIND 数据集

    MIND 数据集是一个大规模英文新闻数据集,包含了 1,000,000 用户、161,013 篇新闻文章和 15,777,377 条点击日志。每篇新闻文章包含丰富的文本内容,包括标题、摘要、正文、类别和实体。每条点击日志包含用户的点击事件、未点击事件以及该用户在该次点击之前的历史点击行为。

    本示例使用 MIND 数据集的子集 MIND demo,包含 5,000 用户、9,432 篇新闻文章和 6,134 条点击日志。由于 MIND 数据集没有发布新闻正文,本示例使用新闻摘要代替正文。

    NAML 模型训练

    首先,需要下载 MIND demo 数据集和预训练的 GloVe 词嵌入文件。

    tmpdir = TemporaryDirectory()
    data_path = tmpdir.name
    
    # ... 定义数据文件路径 ...
    
    mind_url, mind_train_dataset, mind_dev_dataset, mind_utils = get_mind_data_set(MIND_type)
    
    if not os.path.exists(train_news_file):
        download_deeprec_resources(mind_url, os.path.join(data_path, 'train'), mind_train_dataset)
    
    # ... 下载验证集和词嵌入文件 ...

    然后,设置模型超参数,并创建 NAML 模型。

    # 设置超参数
    epochs = 5
    seed = 42
    batch_size = 32
    
    # ...
    
    # 创建 NAML 模型
    hparams = prepare_hparams(yaml_file,
                              wordEmb_file=wordEmb_file,
                              wordDict_file=wordDict_file,
                              userDict_file=userDict_file,
                              vertDict_file=vertDict_file,
                              subvertDict_file=subvertDict_file,
                              batch_size=batch_size,
                              epochs=epochs)
    
    iterator = MINDAllIterator
    model = NAMLModel(hparams, iterator, seed=seed)

    最后,使用训练集和验证集对模型进行训练。

    model.fit(train_news_file, train_behaviors_file, valid_news_file, valid_behaviors_file)

    模型评估

    模型训练完成后,可以使用验证集对模型性能进行评估。

    res_syn = model.run_eval(valid_news_file, valid_behaviors_file)
    print(res_syn)

    评估指标包括 Group AUC、Mean MRR、NDCG@5 和 NDCG@10。

    模型保存

    训练完成后,可以使用 save_weights 方法保存模型参数。

    model_path = os.path.join(data_path, "model")
    os.makedirs(model_path, exist_ok=True)
    
    model.model.save_weights(os.path.join(model_path, "naml_ckpt"))

    总结

    NAML 算法是一种基于注意力机制的多视角新闻推荐算法,能够有效学习新闻的多方面特征和用户的兴趣,从而提升推荐效果。微软 Recommenders 工具提供了 NAML 算法的示例代码,方便用户快速上手并进行实验。

  • LSTUR:兼顾长期和短期兴趣的新闻推荐算法

    引言

    在新闻推荐领域,准确捕捉用户的兴趣至关重要。用户的兴趣可以分为长期兴趣和短期兴趣两类。长期兴趣指的是用户长期以来稳定的偏好,而短期兴趣则指的是用户在短期内表现出的兴趣变化。LSTUR 算法结合了用户的长期兴趣和短期兴趣,能够更精准地为用户推荐新闻。

    LSTUR 算法原理

    LSTUR 算法的核心思想是分别学习用户的长期表示和短期表示,并将两者融合,得到最终的用户表示。具体来说,LSTUR 算法包含以下几个步骤:

    1. 新闻编码器: 使用卷积神经网络 (CNN) 对新闻标题进行编码,得到新闻的语义表示向量。
    2. 用户编码器:
      • 长期表示: 使用用户 ID 的嵌入向量表示用户的长期兴趣。
      • 短期表示: 使用门控循环单元 (GRU) 网络对用户最近浏览过的新闻进行编码,得到用户的短期兴趣表示向量。
    3. 长期和短期表示融合: 将用户的长期表示和短期表示融合,得到最终的用户表示向量。LSTUR 算法提供了两种融合方法:
      • 使用长期表示初始化 GRU 网络的隐藏状态。
      • 将长期表示和短期表示拼接成一个统一的用户向量。
    4. 点击率预测: 将新闻表示向量和用户表示向量输入到一个全连接神经网络中,预测用户点击该新闻的概率。

    MIND 数据集

    MIND 数据集是一个大规模英文新闻数据集,包含了 1,000,000 用户、161,013 篇新闻文章和 15,777,377 条点击日志。每篇新闻文章包含丰富的文本内容,包括标题、摘要、正文、类别和实体。每条点击日志包含用户的点击事件、未点击事件以及该用户在该次点击之前的历史点击行为。

    本示例使用 MIND 数据集的子集 MIND demo,包含 5,000 用户、9,432 篇新闻文章和 6,134 条点击日志。

    LSTUR 模型训练

    首先,需要下载 MIND demo 数据集和预训练的 GloVe 词嵌入文件。

    tmpdir = TemporaryDirectory()
    data_path = tmpdir.name
    
    # ... 定义数据文件路径 ...
    
    mind_url, mind_train_dataset, mind_dev_dataset, mind_utils = get_mind_data_set(MIND_type)
    
    if not os.path.exists(train_news_file):
        download_deeprec_resources(mind_url, os.path.join(data_path, 'train'), mind_train_dataset)
    
    # ... 下载验证集和词嵌入文件 ...

    然后,设置模型超参数,并创建 LSTUR 模型。

    # 设置超参数
    epochs = 5
    seed = 40
    batch_size = 32
    
    # ...
    
    # 创建 LSTUR 模型
    hparams = prepare_hparams(yaml_file,
                              wordEmb_file=wordEmb_file,
                              wordDict_file=wordDict_file,
                              userDict_file=userDict_file,
                              batch_size=batch_size,
                              epochs=epochs)
    
    iterator = MINDIterator
    model = LSTURModel(hparams, iterator, seed=seed)

    最后,使用训练集和验证集对模型进行训练。

    model.fit(train_news_file, train_behaviors_file, valid_news_file, valid_behaviors_file)

    模型评估

    模型训练完成后,可以使用验证集对模型性能进行评估。

    res_syn = model.run_eval(valid_news_file, valid_behaviors_file)
    print(res_syn)

    评估指标包括 Group AUC、Mean MRR、NDCG@5 和 NDCG@10。

    模型保存

    训练完成后,可以使用 save_weights 方法保存模型参数。

    model_path = os.path.join(data_path, "model")
    os.makedirs(model_path, exist_ok=True)
    
    model.model.save_weights(os.path.join(model_path, "lstur_ckpt"))

    总结

    LSTUR 算法是一种兼顾用户长期兴趣和短期兴趣的新闻推荐算法,能够有效提升推荐效果。微软 Recommenders 工具提供了 LSTUR 算法的示例代码,方便用户快速上手并进行实验。

  • LightGBM:电商广告点击率预估利器

    引言

    在电商平台中,广告点击率 (CTR) 预估对于广告投放效果至关重要。准确预测用户点击广告的概率,可以帮助广告主优化广告投放策略,提升广告收益。LightGBM 作为一种高效的梯度提升决策树算法,在 CTR 预估任务中表现出色。本篇文章将以 lightgbm_tinycriteo.ipynb 示例为例,介绍如何使用 LightGBM 训练 CTR 预估模型,并探讨模型优化策略。

    LightGBM 简介

    LightGBM 是微软开源的一种梯度提升框架,它使用基于树的学习算法,并针对分布式计算和高效率进行了优化。LightGBM 具有以下优势:

    • 训练速度快,效率高。
    • 内存占用低。
    • 预测精度高。
    • 支持并行计算和 GPU 加速。
    • 能够处理大规模数据。

    数据准备

    本示例使用 Criteo 数据集,该数据集是 CTR 预估领域的经典基准数据集。原始数据集包含 39 个特征,其中 13 个为数值特征 (I1-I13),26 个为类别特征 (C1-C26)。由于原始数据集规模较大,本示例使用了一个包含约 10 万个样本的子集。

    # 定义特征列和标签列
    nume_cols = ["I" + str(i) for i in range(1, 14)]
    cate_cols = ["C" + str(i) for i in range(1, 27)]
    label_col = "Label"
    
    # 加载数据集
    header = [label_col] + nume_cols + cate_cols
    with TemporaryDirectory() as tmp:
        all_data = criteo.load_pandas_df(size=SIZE, local_cache_path=tmp, header=header)

    将数据集按照时间顺序划分为训练集、验证集和测试集,划分比例为 8:1:1。

    # 划分数据集
    length = len(all_data)
    train_data = all_data.loc[:0.8*length-1]
    valid_data = all_data.loc[0.8*length:0.9*length-1]
    test_data = all_data.loc[0.9*length:]

    模型训练与评估

    基础用法

    对于 LightGBM 的基础用法,只需对类别特征进行简单的顺序编码即可。

    # 顺序编码
    ord_encoder = ce.ordinal.OrdinalEncoder(cols=cate_cols)
    
    # 编码数据
    train_x, train_y = encode_csv(train_data, ord_encoder, label_col)
    valid_x, valid_y = encode_csv(valid_data, ord_encoder, label_col, "transform")
    test_x, test_y = encode_csv(test_data, ord_encoder, label_col, "transform")

    创建 LightGBM 数据集,并设置模型参数。

    # 创建 LightGBM 数据集
    lgb_train = lgb.Dataset(train_x, train_y.reshape(-1), params=params, categorical_feature=cate_cols)
    lgb_valid = lgb.Dataset(valid_x, valid_y.reshape(-1), reference=lgb_train, categorical_feature=cate_cols)
    lgb_test = lgb.Dataset(test_x, test_y.reshape(-1), reference=lgb_train, categorical_feature=cate_cols)
    
    # 训练模型
    lgb_model = lgb.train(params,
                          lgb_train,
                          num_boost_round=NUM_OF_TREES,
                          valid_sets=lgb_valid,
                          categorical_feature=cate_cols,
                          callbacks=[lgb.early_stopping(EARLY_STOPPING_ROUNDS)])
    
    # 预测测试集结果
    test_preds = lgb_model.predict(test_x)
    
    # 计算 AUC 和 Logloss
    auc = roc_auc_score(np.asarray(test_y.reshape(-1)), np.asarray(test_preds))
    logloss = log_loss(np.asarray(test_y.reshape(-1)), np.asarray(test_preds))
    
    print({"auc": auc, "logloss": logloss})

    优化用法

    为了进一步提升模型性能,可以对类别特征进行标签编码和二进制编码,并将数值特征的缺失值填充为均值。

    # 标签编码和二进制编码
    num_encoder = lgb_utils.NumEncoder(cate_cols, nume_cols, label_col)
    train_x, train_y = num_encoder.fit_transform(train_data)
    valid_x, valid_y = num_encoder.transform(valid_data)
    test_x, test_y = num_encoder.transform(test_data)
    
    # 训练模型
    # ...
    
    # 预测测试集结果
    test_preds = lgb_model.predict(test_x)
    
    # 计算 AUC 和 Logloss
    auc = roc_auc_score(np.asarray(test_y.reshape(-1)), np.asarray(test_preds))
    logloss = log_loss(np.asarray(test_y.reshape(-1)), np.asarray(test_preds))
    
    print({"auc": auc, "logloss": logloss})

    模型保存与加载

    训练完成后,可以使用 save_model 方法保存模型,并使用 Booster 类加载模型。

    # 保存模型
    with TemporaryDirectory() as tmp:
        save_file = os.path.join(tmp, "finished.model")
        lgb_model.save_model(save_file)
        loaded_model = lgb.Booster(model_file=save_file)
    
    # 使用加载的模型进行预测
    test_preds = loaded_model.predict(test_x)

    总结

    LightGBM 是一种高效的梯度提升决策树算法,在 CTR 预估任务中表现出色。通过对类别特征进行编码和缺失值填充等优化策略,可以进一步提升模型性能。

  • GeoIMC:融合几何信息的电影推荐算法

    引言

    推荐系统领域中,矩阵分解技术是协同过滤算法的重要分支。传统的矩阵分解方法通常只考虑用户和物品之间的交互信息,而忽略了用户和物品本身的特征。GeoIMC 算法将用户和物品的特征信息融入到矩阵分解过程中,并利用黎曼优化方法求解模型参数,从而提升推荐效果。

    GeoIMC 算法原理

    GeoIMC 算法基于 Jawanpuria 等人 (2019) 的研究成果,将用户和物品的特征信息融入到矩阵分解过程中。以 MovieLens-100K (ML100K) 数据集为例,假设 $X \in R^{m \times d_1}$ 和 $Z \in R^{n \times d_2}$ 分别表示用户和电影的特征矩阵,$M \in R^{m \times n}$ 表示用户对电影的评分矩阵。GeoIMC 算法将评分矩阵建模为 $M = XUBV^TZ^T$,其中 $U \in R^{d_1 \times k}$、$V \in R^{d_2 \times k}$ 和 $B \in R^{k \times k}$ 分别为正交矩阵、正交矩阵和对称正定矩阵。模型参数通过 Pymanopt 工具包进行黎曼优化求解。

    数据准备

    本示例使用 MovieLens 100K 数据集,并使用与 Xin Dong 等人 (2017) 相同的方法生成用户和电影的特征向量。

    # 创建临时目录下载 ML100K 数据集
    dp = tempfile.mkdtemp(suffix='-geoimc')
    movielens.download_movielens(MOVIELENS_DATA_SIZE, f"{dp}/ml-100k.zip")
    with zipfile.ZipFile(f"{dp}/ml-100k.zip", 'r') as z:
        z.extractall(dp)
    
    # 加载数据集和特征
    dataset = ML_100K(
        normalize=normalize,
        target_transform='binarize'
    )
    dataset.load_data(f"{dp}/ml-100k/")

    模型训练

    使用 IMCProblem 类初始化 GeoIMC 问题,并设置正则化参数和模型秩。

    np.random.seed(10)
    prblm = IMCProblem(
        dataset.training_data,
        lambda1=regularizer,
        rank=rank
    )
    
    # 求解优化问题
    prblm.solve(
        max_time,
        max_iters,
        verbosity
    )

    生成推荐结果

    使用 Inferer 类初始化推理器,并使用训练得到的模型参数预测用户对电影的评分。

    # 初始化推理器
    inferer = Inferer(
        method='dot'
    )
    
    # 预测评分
    predictions = inferer.infer(
        dataset.test_data,
        prblm.W
    )

    模型评估

    使用 rmsemae 函数计算模型的均方根误差 (RMSE) 和平均绝对误差 (MAE)。

    # 准备测试集和预测结果数据框
    user_ids = dataset.test_data.get_data().tocoo().row
    item_ids = dataset.test_data.get_data().tocoo().col
    test_df = pd.DataFrame(
        data={
            "userID": user_ids,
            "itemID": item_ids,
            "rating": dataset.test_data.get_data().data
        }
    )
    predictions_df = pd.DataFrame(
        data={
            "userID": user_ids,
            "itemID": item_ids,
            "prediction": [predictions[uid, iid] for uid, iid in list(zip(user_ids, item_ids))]
        }
    )
    
    # 计算 RMSE 和 MAE
    RMSE = rmse(
        test_df,
        predictions_df
    )
    MAE = mae(
        test_df,
        predictions_df
    )
    
    print(f"""
    RMSE: {RMSE}
    MAE: {MAE}
    """)

    总结

    GeoIMC 算法通过将用户和物品的特征信息融入到矩阵分解过程中,并利用黎曼优化方法求解模型参数,能够有效提升推荐效果。本示例展示了如何使用 Recommenders 工具包实现 GeoIMC 算法,并对模型性能进行了评估。

    参考文献

    [1] Pratik Jawanpuria, Arjun Balgovind, Anoop Kunchukuttan, Bamdev Mishra. Learning Multilingual Word Embeddings in Latent Metric Space: A Geometric Approach. Transaction of the Association for Computational Linguistics (TACL), Volume 7, p.107-120, 2019.

    [2] Xin Dong, Lei Yu, Zhonghuo Wu, Yuxia Sun, Lingfeng Yuan, Fangxi Zhang. A Hybrid Collaborative Filtering Model withDeep Structure for Recommender Systems.
    Proceedings of the Thirty-First AAAI Conference on Artificial Intelligence (AAAI-17), p.1309-1315, 2017.

  • FastAI:快速构建电影推荐系统

    引言

    FastAI 作为一个易于使用且功能强大的深度学习库,为推荐系统的构建提供了便捷的工具。本篇文章将以 fastai_movielens.ipynb 示例为例,介绍如何利用 FastAI 框架,快速构建一个基于协同过滤的电影推荐系统,并对模型性能进行评估。

    数据准备

    本示例使用经典的 MovieLens 数据集,该数据集包含用户对电影的评分信息。首先,使用 recommenders.datasets.movielens 模块加载数据集,并确保用户 ID 和电影 ID 以字符串类型加载,避免与嵌入 ID 混淆。

    ratings_df = movielens.load_pandas_df(
        size=MOVIELENS_DATA_SIZE,
        header=[USER,ITEM,RATING,TIMESTAMP]
    )
    
    # 确保 ID 以字符串类型加载
    ratings_df[USER] = ratings_df[USER].astype('str')
    ratings_df[ITEM] = ratings_df[ITEM].astype('str')

    接下来,使用 python_stratified_split 函数将数据集划分为训练集/验证集和测试集,划分比例为 75:25。

    train_valid_df, test_df = python_stratified_split(
        ratings_df,
        ratio=0.75,
        min_rating=1,
        filter_by="item",
        col_user=USER,
        col_item=ITEM
    )
    
    # 从测试集中移除“冷启动”用户
    test_df = test_df[test_df.userID.isin(train_valid_df.userID)]

    模型训练

    FastAI 提供了 collab_learner 函数,用于快速构建协同过滤模型。默认情况下,collab_learner 使用 EmbeddingDotBias 模型,该模型为用户和电影创建嵌入向量,并将它们映射到指定维度的浮点数空间。

    # 设置随机种子以确保结果可复现
    np.random.seed(101)
    torch.manual_seed(101)
    torch.cuda.manual_seed_all(101)
    
    # 创建 CollabDataLoaders
    data = CollabDataLoaders.from_df(train_valid_df,
                                         user_name=USER,
                                         item_name=ITEM,
                                         rating_name=RATING,
                                         valid_pct=0)
    
    # 创建 collab_learner
    learn = collab_learner(data, n_factors=N_FACTORS, y_range=[0,5.5], wd=1e-1)

    collab_learner 中,n_factors 参数表示隐含特征维度,y_range 参数设置评分范围,wd 参数设置权重衰减以进行正则化。

    使用 fit_one_cycle 函数训练模型,并设置学习率和迭代次数。

    with Timer() as train_time:
        learn.fit_one_cycle(EPOCHS, lr_max=5e-3)

    生成推荐结果

    为了生成推荐结果,首先需要获取模型已知的所有用户和电影,以及测试集中的用户。

    # 获取所有用户和电影
    total_users, total_items = learner.dls.classes.values()
    total_items = total_items[1:]
    total_users = total_users[1:]
    
    # 获取测试集中的用户
    test_users = test_df[USER].unique()
    test_users = np.intersect1d(test_users, total_users)

    然后,构建测试集用户和所有已知电影的笛卡尔积,并移除训练集中出现过的用户-电影组合。

    # 构建笛卡尔积
    users_items = cartesian_product(np.array(test_users),np.array(total_items))
    users_items = pd.DataFrame(users_items, columns=[USER,ITEM])
    
    # 移除训练集中出现过的组合
    training_removed = pd.merge(users_items, train_valid_df.astype(str), on=[USER, ITEM], how='left')
    training_removed = training_removed[training_removed[RATING].isna()][[USER, ITEM]]

    最后,使用 score 函数对模型进行评分,并获取 Top-K 推荐结果。

    with Timer() as test_time:
        top_k_scores = score(learner,
                             test_df=training_removed,
                             user_col=USER,
                             item_col=ITEM,
                             prediction_col=PREDICTION)

    模型评估

    使用 recommenders.evaluation.python_evaluation 模块中的评估指标对模型进行评估。

    # 排序指标评估
    eval_map = map(test_df, top_k_scores, col_user=USER, col_item=ITEM,
                   col_rating=RATING, col_prediction=PREDICTION,
                   relevancy_method="top_k", k=TOP_K)
    
    eval_ndcg = ndcg_at_k(test_df, top_k_scores, col_user=USER, col_item=ITEM,
                          col_rating=RATING, col_prediction=PREDICTION,
                          relevancy_method="top_k", k=TOP_K)
    
    # ... 其他排序指标评估 ...
    
    # 评分预测指标评估
    eval_rmse = rmse(test_df, scores, col_user=USER, col_item=ITEM, col_rating=RATING, col_prediction=PREDICTION)
    eval_mae = mae(test_df, scores, col_user=USER, col_item=ITEM, col_rating=RATING, col_prediction=PREDICTION)
    
    # ... 其他评分预测指标评估 ...
    
    # 打印评估指标
    print(f"Model:\t\t{learn.__class__.__name__}\n"
          f"Top K:\t\t{TOP_K}\n"
          f"MAP:\t\t{eval_map:.6f}\n"
          f"NDCG:\t\t{eval_ndcg:.6f}\n"
          # ... 打印其他排序指标 ...
          f"RMSE:\t\t\t{eval_rmse:.6f}\n"
          f"MAE:\t\t\t{eval_mae:.6f}\n"
          # ... 打印其他评分预测指标 ...
         )

    总结

    本篇文章以 fastai_movielens.ipynb 为例,介绍了如何使用 FastAI 快速构建一个基于协同过滤的电影推荐系统。FastAI 提供了简洁的接口和高效的训练方法,使得构建推荐系统变得更加容易。

  • 深度知识感知网络:DKN 新闻推荐算法解析

    引言

    在信息爆炸的时代,如何从海量新闻中为用户推荐感兴趣的内容,成为了推荐系统研究的热点之一。传统的基于 ID 的协同过滤算法往往难以捕捉新闻内容的语义信息,而基于内容的推荐算法则需要人工提取新闻特征,效率低下。深度知识感知网络 (DKN) 算法应运而生,它结合了深度学习和知识图谱的优势,能够自动学习新闻内容的语义表示,并利用知识图谱中的实体信息提升推荐效果。

    DKN 算法原理

    DKN 算法的核心思想是将新闻内容和知识图谱信息融合到一个深度学习模型中,通过联合学习语义级和知识级的新闻表示,实现更精准的推荐。具体来说,DKN 算法主要包含以下几个步骤:

    1. 知识图谱表示学习: 使用 TransX 方法将知识图谱中的实体和关系嵌入到低维向量空间中,得到实体嵌入向量。
    2. 新闻语义表示学习: 使用卷积神经网络 (CNN) 对新闻标题进行编码,得到新闻语义嵌入向量。
    3. 知识感知卷积神经网络 (KCNN): 将实体嵌入向量和新闻语义嵌入向量融合,并使用 KCNN 进行特征提取,得到最终的新闻表示向量。
    4. 注意力机制: 使用注意力机制对用户的历史点击行为进行加权平均,得到用户的兴趣表示向量。
    5. 点击率预测: 将新闻表示向量和用户兴趣表示向量输入到一个全连接神经网络中,预测用户点击该新闻的概率。

    MIND 数据集

    MIND 数据集是一个大规模英文新闻数据集,包含了 1,000,000 用户、161,013 篇新闻文章和 15,777,377 条点击日志。每篇新闻文章包含丰富的文本内容,包括标题、摘要、正文、类别和实体。每条点击日志包含用户的点击事件、未点击事件以及该用户在该次点击之前的历史点击行为。

    本示例使用 MIND 数据集的子集 MIND demo,包含 500 用户、9,432 篇新闻文章和 6,134 条点击日志。

    DKN 模型训练

    首先,需要下载 MIND demo 数据集和预训练的词嵌入、实体嵌入和上下文嵌入文件。

    tmpdir = TemporaryDirectory()
    data_path = os.path.join(tmpdir.name, "mind-demo-dkn")
    
    # ... 定义数据文件路径 ...
    
    if not os.path.exists(yaml_file):
        download_deeprec_resources("https://recodatasets.z20.web.core.windows.net/deeprec/", tmpdir.name, "mind-demo-dkn.zip")

    然后,设置模型超参数,并创建 DKN 模型。

    # 设置超参数
    EPOCHS = 10
    HISTORY_SIZE = 50
    BATCH_SIZE = 500
    
    # 创建 DKN 模型
    hparams = prepare_hparams(yaml_file,
                              news_feature_file = news_feature_file,
                              user_history_file = user_history_file,
                              wordEmb_file=wordEmb_file,
                              entityEmb_file=entityEmb_file,
                              contextEmb_file=contextEmb_file,
                              epochs=EPOCHS,
                              history_size=HISTORY_SIZE,
                              batch_size=BATCH_SIZE)
    
    model = DKN(hparams, DKNTextIterator)

    最后,使用训练集和验证集对模型进行训练。

    model.fit(train_file, valid_file)

    模型评估

    模型训练完成后,可以使用测试集对模型性能进行评估。

    res = model.run_eval(test_file)
    print(res)

    评估指标包括 AUC、Group AUC、Mean MRR、NDCG@5 和 NDCG@10。

    总结

    DKN 算法是一种结合了深度学习和知识图谱的先进新闻推荐算法,能够有效提升推荐效果。微软 Recommenders 工具提供了 DKN 算法的示例代码,方便用户快速上手并进行实验。

  • 基于 PySpark 的电影推荐系统:深入解析 ALS 算法

    引言

    协同过滤算法是推荐系统中应用最广泛的算法之一,而交替最小二乘法 (ALS) 则是协同过滤算法中的一种经典算法。本篇文章将以微软 Recommenders 工具中的 als_movielens.ipynb 示例为例,详细介绍如何使用 PySpark 实现基于 ALS 算法的电影推荐系统,并对模型性能进行评估。

    数据准备

    本示例使用经典的 MovieLens 数据集,该数据集包含了用户对电影的评分信息。首先,需要使用 recommenders.datasets.movielens 模块加载数据集,并指定使用的数据集大小和数据格式。

    # 定义数据格式
    schema = StructType(
        (
            StructField(COL_USER, IntegerType()),
            StructField(COL_ITEM, IntegerType()),
            StructField(COL_RATING, FloatType()),
            StructField(COL_TIMESTAMP, LongType()),
        )
    )
    
    # 加载 MovieLens 100k 数据集
    data = movielens.load_spark_df(spark, size=MOVIELENS_DATA_SIZE, schema=schema)
    data.show()

    接下来,使用 spark_random_split 函数将数据集划分为训练集和测试集,划分比例为 75:25。

    train, test = spark_random_split(data, ratio=0.75, seed=123)

    模型构建

    使用 PySpark MLlib 中的 ALS 模块构建 ALS 模型。

    # 设置模型参数
    als = ALS(
        rank=10,
        maxIter=15,
        implicitPrefs=False,
        regParam=0.05,
        coldStartStrategy='drop',
        nonnegative=False,
        seed=42,
        **header
    )
    
    # 训练模型
    with Timer() as train_time:
        model = als.fit(train)

    在 ALS 模型中,rank 参数表示隐含特征维度,maxIter 参数表示最大迭代次数,regParam 参数表示正则化系数。

    生成推荐结果

    为了避免推荐用户已经评分过的电影,需要将训练集中出现过的用户-电影组合从推荐结果中剔除。

    with Timer() as test_time:
        # 生成所有用户-电影组合
        users = train.select(COL_USER).distinct()
        items = train.select(COL_ITEM).distinct()
        user_item = users.crossJoin(items)
    
        # 预测评分
        dfs_pred = model.transform(user_item)
    
        # 剔除训练集中出现过的用户-电影组合
        dfs_pred_exclude_train = dfs_pred.alias("pred").join(
            train.alias("train"),
            (dfs_pred[COL_USER] == train[COL_USER]) & (dfs_pred[COL_ITEM] == train[COL_ITEM]),
            how='outer'
        )
    
        # 获取最终推荐结果
        top_all = dfs_pred_exclude_train.filter(dfs_pred_exclude_train[f"train.{COL_RATING}"].isNull()) \
            .select('pred.' + COL_USER, 'pred.' + COL_ITEM, 'pred.' + "prediction")
    
        # 触发计算
        top_all.cache().count()

    模型评估

    使用 SparkRankingEvaluationSparkRatingEvaluation 模块对模型进行评估。

    # 排序指标评估
    rank_eval = SparkRankingEvaluation(test, top_all, k = TOP_K, col_user=COL_USER, col_item=COL_ITEM,
                                        col_rating=COL_RATING, col_prediction="prediction",
                                        relevancy_method="top_k")
    
    # 评分预测指标评估
    rating_eval = SparkRatingEvaluation(test, prediction, col_user=COL_USER, col_item=COL_ITEM,
                                        col_rating=COL_RATING, col_prediction="prediction")
    
    # 打印评估指标
    print(f"Model:\tALS\n"
          f"Top K:\t{rank_eval.k}\n"
          f"MAP:\t{rank_eval.map_at_k():.6f}\n"
          f"NDCG:\t{rank_eval.ndcg_at_k():.6f}\n"
          f"Precision@K:\t{rank_eval.precision_at_k():.6f}\n"
          f"Recall@K:\t{rank_eval.recall_at_k():.6f}\n"
          f"RMSE:\t{rating_eval.rmse():.6f}\n"
          f"MAE:\t{rating_eval.mae():.6f}\n"
          f"Explained variance:\t{rating_eval.exp_var():.6f}\n"
          f"R squared:\t{rating_eval.rsquared():.6f}")

    总结

    本篇文章以 als_movielens.ipynb 为例,详细介绍了如何使用 PySpark 实现基于 ALS 算法的电影推荐系统,并对模型性能进行了评估。 ALS 算法原理简单,易于实现,并且可以通过调节参数来控制模型的复杂度,适用于各种规模的数据集。

  • 快速上手推荐系统:微软 Recommenders 示例精解

    引言

    想要快速体验不同推荐算法的魅力,并构建自己的推荐系统原型?微软 Recommenders 工具的 00_quick_start 目录提供了一系列开箱即用的 Jupyter Notebook 示例,涵盖了从数据准备、模型构建到模型评估的完整流程。

    示例概览

    00_quick_start 目录下的示例 Notebook 涵盖了多种经典和先进的推荐算法,并使用了不同的数据集和运行环境,具体如下表所示:

    示例数据集运行环境描述
    alsMovieLensPySpark使用交替最小二乘法 (ALS) 预测电影评分,在 PySpark 环境中运行。
    dknMINDPython CPU, GPU使用深度知识感知网络 (DKN) 进行新闻推荐,利用知识图谱信息,在 Python+GPU (TensorFlow) 环境中运行。
    fastaiMovieLensPython CPU, GPU使用 FastAI 推荐系统预测电影评分,在 Python+GPU (PyTorch) 环境中运行。

    注意: 表格中只列举了部分示例,完整列表请参考 README.md

    示例详解

    下面以 sar_movielens.ipynb 为例,介绍如何使用 Recommenders 快速构建一个简单的推荐系统。

    1. 数据准备

    该示例使用了 MovieLens 数据集,其中包含用户对电影的评分信息。首先,需要使用 recommenders.datasets.movielens 模块加载数据集。

    from recommenders.datasets.movielens import load_pandas_dataframe
    
    # 加载 MovieLens 100k 数据集
    df = load_pandas_dataframe(size='100k')

    2. 模型构建

    该示例使用了简单的推荐算法 (SAR),该算法基于用户历史行为计算物品之间的相似度,并根据相似度进行推荐。

    from recommenders.models.sar import SAR
    
    # 创建 SAR 模型
    model = SAR(
        col_user="userID",
        col_item="itemID",
        col_rating="rating",
        similarity_type="cosine",
        time_decay_coefficient=1.0,
        time_unit="week",
    )
    
    # 训练模型
    model.fit(df)

    3. 模型评估

    模型训练完成后,可以使用 recommenders.evaluation.python_evaluation 模块中的评估指标对模型进行评估。

    from recommenders.evaluation.python_evaluation import map_at_k, ndcg_at_k
    
    # 生成推荐结果
    top_k = 10
    user_ids = df["userID"].unique()
    recommendations = model.recommend_k_items(df, user_ids, top_k=top_k)
    
    # 计算评估指标
    map_value = map_at_k(df, recommendations, col_user="userID", col_item="itemID", col_rating="rating", k=top_k)
    ndcg_value = ndcg_at_k(df, recommendations, col_user="userID", col_item="itemID", col_rating="rating", k=top_k)
    
    print(f"MAP@{top_k}: {map_value:.4f}")
    print(f"NDCG@{top_k}: {ndcg_value:.4f}")

    总结

    微软 Recommenders 提供的快速入门示例可以帮助您快速了解不同推荐算法的原理和使用方法,并构建自己的推荐系统原型。

  • 将 Recommenders 示例无缝迁移到 AzureML 云平台

    引言

    随着推荐系统规模的扩大和对训练效率要求的提高,将本地实验迁移到云平台成为一种趋势。Azure 机器学习服务(AzureML)为开发者提供了一个强大的云端环境,可以用于数据准备、模型训练、测试、部署、管理和跟踪。

    本指南将以 run_notebook_on_azureml.ipynb 为例,介绍如何将 Recommenders 示例 Notebook 提交到 AzureML 计算目标,利用云平台的优势加速推荐系统开发流程。

    AzureML 简介

    AzureML 提供了丰富的功能,包括:

    • 管理云资源,用于监控、记录和组织机器学习实验。
    • 支持本地和云端训练模型,包括 GPU 加速训练。
    • 易于扩展,只需创建并指向新的计算目标即可应对数据集增长。

    准备工作

    使用 AzureML 之前,需要完成以下准备工作:

    • 拥有 Azure 订阅。如果没有,可以创建一个免费帐户,并试用 Azure 机器学习服务的免费或付费版本。
    • 安装 azure.contrib.notebook 包。
    #!pip install "azureml.contrib.notebook>=1.0.21.1"

    连接到 AzureML 工作区

    AzureML 工作区是用于组织和协调机器学习工作流的 Azure 资源,它协调存储、数据库和计算资源,为实验、部署、推理和模型监控提供额外功能。

    以下代码将获取或创建一个 AzureML 工作区,并将配置保存到 aml_config/config.json 文件中。

    ws = Workspace.create(
        name="<WORKSPACE_NAME>",
        subscription_id="<SUBSCRIPTION_ID>",
        resource_group="<RESOURCE_GROUP>",
        location="<WORKSPACE_REGION>"
        exist_ok=True,
    )

    创建或连接 Azure 机器学习计算资源

    Azure 机器学习计算是一种托管计算基础设施,允许用户轻松创建单节点到多节点的计算资源。

    以下代码将创建一个 CPU 集群作为远程计算目标。

    # 远程计算(集群)配置
    VM_SIZE = 'STANDARD_D2_V2'
    MIN_NODES = 0
    MAX_NODES = 2
    
    CLUSTER_NAME = 'cpucluster'
    
    try:
        compute_target = ComputeTarget(workspace=ws, name=CLUSTER_NAME)
        print("找到现有计算目标")
    except:
        print("正在创建新的计算目标...")
        # 指定新集群的配置
        compute_config = AmlCompute.provisioning_configuration(
            vm_size=VM_SIZE,
            min_nodes=MIN_NODES,
            max_nodes=MAX_NODES
        )
        # 使用指定的名称和配置创建集群
        compute_target = ComputeTarget.create(ws, CLUSTER_NAME, compute_config)
        # 等待集群完成,显示输出日志
        compute_target.wait_for_completion(show_output=True, min_node_count=None, timeout_in_minutes=20)

    提交 Notebook

    以下代码将 sar_movielens.ipynb Notebook 提交到 AzureML 计算目标。

    NOTEBOOK_NAME = 'sar_movielens.ipynb'
    experiment_name = NOTEBOOK_NAME.strip(".ipynb")
    # ... 设置运行配置 ...
    
    cfg = NotebookRunConfig(source_directory='../',
                                notebook='notebooks/00_quick_start/' + NOTEBOOK_NAME,
                                output_notebook='outputs/out.ipynb',
                                parameters={"MOVIELENS_DATA_SIZE": "100k", "TOP_K": 10},
                                run_config=run_config)
    
    run = exp.submit(cfg)
    run

    监控运行进度

    可以使用 Jupyter 小部件监控运行进度。小部件会每隔 10-15 秒提供一次实时更新,直到作业完成。

    RunDetails(run).show()

    查看指标

    运行完成后,可以使用 run.get_metrics() 查看记录的指标。

    metrics = run.get_metrics()
    print(metrics)

    释放计算资源

    为避免不必要的费用,请确保在使用后释放创建的计算目标。

    # 删除计算目标
    compute_target.delete()

    总结

    通过将 Recommenders 示例 Notebook 提交到 AzureML 云平台,可以充分利用云计算的优势,加速推荐系统开发流程。AzureML 提供了丰富的功能和灵活的配置选项,可以满足不同规模和需求的推荐系统开发。

  • 微软 Recommenders:推荐系统实战宝典

    引言

    构建一个高效的推荐系统并非易事,需要对数据进行预处理、选择合适的算法、进行模型训练和评估,最终才能将其部署到生产环境。为了帮助开发者和研究人员更好地应对这些挑战,微软开源了 Recommenders 工具,并提供了一系列 Jupyter Notebook 示例和最佳实践,涵盖了推荐系统开发的完整流程。

    示例概览

    Recommenders 的示例 Notebook 按照功能和用途被组织在不同的目录下,具体如下表所示:

    目录是否支持本地运行描述
    00_quick_start快速入门示例,演示如何在本地环境中使用推荐算法构建推荐系统。
    01_prepare_data数据准备示例,为不同的推荐算法准备和加载数据。
    02_model_collaborative_filtering协同过滤算法模型训练和评估示例,深入探讨算法原理和实现细节。

    本地运行示例

    大部分示例 Notebook 都可以在本地 Linux 机器上直接运行,只需按照 说明 正确设置环境即可。

    注意: 某些示例可能需要异构计算实例,例如安装了 Spark 框架的 CPU 机器集群或配备 GPU 设备的机器。因此,建议在 Linux 数据科学虚拟机 (Ubuntu) 上运行这些 Notebook,因为该虚拟机预先配置了单节点 Spark 和/或 GPU 设备。

    Azure 云端增强

    为了提高大规模开发推荐系统的效率,部分示例 Notebook 还使用了 Azure 云产品和服务,例如:

    • Azure 机器学习服务: 用于训练、部署、自动化和管理机器学习模型的云服务,在示例中广泛用于超参数调整、指标跟踪和监控、计算资源扩展以及 Web 服务部署等任务。
    • Azure 数据科学虚拟机: 主要用作远程服务器,用户可以轻松配置本地和云环境以运行示例 Notebook。
    • Azure Cosmos DB: 用于存储数据,例如在模型部署示例中,将模型生成的推荐结果存储在 Cosmos DB 中以实现实时服务。
    • Azure Databricks: 主要用于在分布式计算环境中开发基于 Spark 的推荐系统,例如 Spark ALS 算法。
    • Azure Kubernetes 服务: 用于服务推荐模型或使用推荐结果为应用程序服务。

    将现有 Notebook 提交到 Azure 机器学习

    run_notebook_on_azureml 示例 Notebook 提供了一个框架,可以直接将现有 Notebook 提交到 Azure 机器学习计算目标。设置好计算目标并创建运行配置后,只需替换 Notebook 文件名即可直接提交 Notebook。

    cfg = NotebookRunConfig(source_directory='../',
                                notebook='examples/00_quick_start/' + NOTEBOOK_NAME,
                                output_notebook='outputs/out.ipynb',
                                parameters={"MOVIELENS_DATA_SIZE": "100k", "TOP_K": 10},
                                run_config=run_config)

    所有使用 store_metadata 记录的指标和参数都将作为跟踪指标存储在运行中。最初提交的 Notebook 将作为输出 Notebook out.ipynb 存储在 Azure 门户的输出选项卡中。

    总结

    微软 Recommenders 提供的示例 Notebook 为开发者和研究人员提供了一个宝贵的学习资源,可以帮助他们快速掌握构建高性能推荐系统的最佳实践。无论是本地运行还是借助 Azure 云平台,Recommenders 都能帮助您轻松构建个性化推荐体验。