博客

  • Mobile-Agent-v2:多智能体协作让手机操作更智能

    近日,人工智能手机操作助手Mobile-Agent迎来了重大升级。其团队发布了全新的Mobile-Agent-v2,通过引入多智能体协作架构,大幅提升了手机操作的智能化水平。本文将为您详细解读Mobile-Agent-v2的创新之处及其强大功能。

    Mobile-Agent的发展历程

    Mobile-Agent于今年年初首次亮相,凭借出色的自动化手机操作能力,迅速引起业界广泛关注。短短5个月时间,其GitHub仓库就收获了2000多个Star。

    Mobile-Agent采用纯视觉方案,通过视觉感知和操作工具实现智能体在手机上的自主操作,无需依赖系统级UI文件。借助强大的中枢模型,Mobile-Agent可以即插即用,无需额外训练。

    Mobile-Agent-v2的重大升级

    最新发布的Mobile-Agent-v2在原有基础上实现了几项关键突破:

    1. 保留纯视觉方案
    2. 引入多智能体协作架构
    3. 增强任务拆解、跨应用操作和多语言能力

    目前,Mobile-Agent-v2的论文和代码均已开源发布。

    多智能体协作架构

    Mobile-Agent-v2最大的创新在于引入了多智能体协作架构,包括三个关键角色:

    1. 规划智能体(Planning Agent):生成任务进度,使操作历史导航更高效。
    2. 决策智能体(Decision Agent):执行具体操作,并更新记忆单元中的关键信息。
    3. 反思智能体(Reflection Agent):观察每次操作的结果,处理可能出现的错误。

    这一架构有效解决了单智能体方案面临的两大挑战:

    1. 任务进度导航:随着操作次数增加,操作历史序列变得冗长,给智能体追踪进度带来困难。
    2. 焦点内容导航:纯文本的任务进度会导致屏幕信息丢失,智能体无法获取关键信息。

    为应对这些挑战,Mobile-Agent-v2做出了如下设计:

    • 规划智能体将冗长的操作历史转化为简洁的纯文本任务进度。
    • 引入记忆单元,由决策智能体负责更新其中的任务关键信息。
    • 反思智能体负责监测操作前后的屏幕状态变化,判断操作正确性。

    强大的跨应用操作能力

    从团队公布的演示视频可以看出,Mobile-Agent-v2展现了出色的跨应用操作能力。

    例如,在一个跨应用任务中,用户要求Mobile-Agent-v2查看聊天软件中的未读消息,然后按照消息要求完成任务。Mobile-Agent-v2成功打开WhatsApp查看了指定联系人的消息,随后按要求打开TikTok搜索宠物视频并分享。整个过程涉及多个应用切换,Mobile-Agent-v2都能准确完成。

    另一个例子展示了Mobile-Agent-v2在社交媒体平台X(原Twitter)上的操作能力。它能够精准地搜索指定用户、关注并评论,即使遇到推荐用户弹窗等干扰也能灵活应对。

    此外,Mobile-Agent-v2还展示了在YouTube、小红书、微信等复杂应用中的操作能力,包括搜索视频、发表评论、回复消息等。这些操作都需要理解复杂的UI布局和上下文信息,Mobile-Agent-v2都能出色完成。

    性能评估

    论文中采用了动态评估方法,选择10个应用(5个系统应用和5个第三方应用)进行测试,涵盖英文和非英文场景。每个应用设计了2条基础指令和2条进阶指令,另外还设计了4条跨应用操作指令。

    评估结果显示,Mobile-Agent-v2在各项指标上都实现了全面提升:

    1. 在英文应用中,基础指令完成率从73.7%提升至84.2%,进阶指令从57.9%提升至68.4%。
    2. 在非英文应用中,基础指令完成率从63.2%提升至78.9%,进阶指令从47.4%提升至63.2%。
    3. 跨应用操作的完成率从50.0%大幅提升至75.0%。

    通过引入额外的操作知识,Mobile-Agent-v2的性能还能进一步提升。

    技术创新的价值

    Mobile-Agent-v2的多智能体协作架构为解决长序列操作中的挑战提供了新思路。分析失败案例发现,Mobile-Agent的失败操作大多集中在任务后期,而Mobile-Agent-v2的失败则分布更均匀,说明新架构有效缓解了长序列操作的困难。

    这一技术突破使得Mobile-Agent-v2能够更好地应对复杂的跨应用场景,为老年人和视障群体提供便利。例如,通过简单的语音指令就能帮助用户完成复杂的打车任务。

    未来展望

    Mobile-Agent-v2的出色表现为智能手机操作助手的发展开辟了新天地。未来,我们可以期待看到更多基于此技术的创新应用,例如:

    1. 针对特定人群的定制化智能助手
    2. 更复杂的跨设备、跨平台操作能力
    3. 与其他AI技术的深度融合,如语音交互、AR等

    总之,Mobile-Agent-v2展现了AI在智能手机操作领域的巨大潜力,相信随着技术的不断进步,未来会有更多令人惊叹的应用场景被开发出来。

    参考文献

    1. Wang, J., Xu, H., Jia, H., Zhang, X., Yan, M., Shen, W., … & Sang, J. (2024). Mobile-Agent-v2: Mobile Device Operation Assistant with Effective Navigation via Multi-Agent Collaboration. arXiv preprint arXiv:2406.01014.
    2. X-PLUG. (2024). MobileAgent: The Powerful Mobile Device Operation Assistant Family. GitHub repository. https://github.com/X-PLUG/MobileAgent
    3. ModelScope. (2024). ModelScope-Agent: An agent framework connecting models in ModelScope with the world. GitHub repository. https://github.com/modelscope/modelscope-agent
  • Slim: 一键缩小容器镜像大小的神器

    引言

    在当今云原生时代,容器技术已经成为了开发和部署应用的主流方式。然而,随着应用复杂度的增加,容器镜像的体积也在不断膨胀,这不仅会增加存储成本,还会影响镜像的传输效率和应用的启动速度。如何在不影响功能的前提下,有效地减小容器镜像的体积,成为了许多开发者和运维人员面临的一大挑战。今天,我们将为大家介绍一个强大的工具——Slim,它能够自动分析并缩小容器镜像,而无需修改镜像中的任何内容。

    Slim简介

    Slim是一个开源的命令行工具,其主要特点是能够将容器镜像缩小多达30倍,对于编译语言,缩小幅度甚至可能更大。它的工作原理是通过智能分析镜像内容,移除不必要的文件和依赖,从而实现镜像体积的大幅缩减。

    Slim的GitHub项目地址为:https://github.com/slimtoolkit/slim

    该项目目前已经获得了超过18.4K的Star,可见其受欢迎程度之高。

    Slim的优势

    1. 自动化优化: Slim能够自动分析镜像内容,无需手动干预。
    2. 保持原有功能: 在缩小镜像体积的同时,不会改变容器的功能。
    3. 兼容性强: 可以处理各种语言的应用镜像,如Node.js, Python, Ruby, Go, Rust, Java, PHP等。
    4. 安全性提升: 通过移除不必要的组件,减少了潜在的攻击面。
    5. 易于使用: 提供交互式CLI,使用简单直观。

    Slim的工作原理

    Slim的工作流程大致如下:

    1. 分析原始镜像结构
    2. 运行容器并监控其行为
    3. 识别必要的文件和依赖
    4. 构建最小化的镜像
    5. 生成安全配置文件(如AppArmor和Seccomp)

    Slim的安装

    Slim的安装非常简单,主要是下载对应操作系统的二进制文件并放置到正确的目录中。以Linux系统为例:

    # 下载最新的Linux二进制文件
    curl -L -o ds.tar.gz https://github.com/slimtoolkit/slim/releases/download/1.40.11/dist_linux.tar.gz
    
    # 解压并移动到bin目录
    tar -xvf ds.tar.gz
    mv dist_linux/slim /usr/local/bin/
    mv dist_linux/slim-sensor /usr/local/bin/

    也可以使用一键安装脚本:

    curl -sL https://raw.githubusercontent.com/slimtoolkit/slim/master/scripts/install-slim.sh | sudo -E bash -

    Slim的使用

    Slim的基本使用语法如下:

    slim [global flags] [command] [command-specific flags] <IMAGE_ID_OR_NAME>

    常用的命令包括:

    • xray: 对目标容器镜像执行静态分析
    • build: 分析、优化容器镜像,生成安全配置文件
    • profile: 执行基本的容器镜像分析和动态容器分析
    • run: 运行容器
    • vulnerability: 执行漏洞相关的分析

    实际案例:优化Nginx镜像

    让我们以一个实际的例子来展示Slim的强大功能。我们将优化一个Nginx镜像:

    # 查看原始Nginx镜像大小
    docker images | grep nginx
    # 输出:nginx  latest  4f67c83422ec   3 weeks ago     188MB
    
    # 使用Slim优化镜像
    slim build 52f6af495b48
    
    # 查看优化后的镜像大小
    docker images | grep nginx
    # 输出:
    # nginx.slim    latest   f9ce92b996ba   44 seconds ago   13.3MB
    # nginx         latest   4f67c83422ec   3 weeks ago      188MB

    从输出可以看到,Nginx镜像从原来的188MB缩小到了13.3MB,缩小了约14倍!

    优化后镜像的使用

    优化后的镜像可以像普通镜像一样使用。例如,我们可以用优化后的Nginx镜像启动一个HTTPS网站:

    docker run -d -p 443:443 \
      -v /opt/https-nginx/etc/nginx.conf:/etc/nginx/nginx.conf \
      -v /opt/https-nginx/index.html:/usr/share/nginx/html/index.html \
      -v /opt/https-nginx/cert/:/etc/nginx/ssl/ \
      --name https-nginx nginx.slim:latest

    通过查看日志,我们可以确认容器启动正常:

    docker logs -f https-nginx
    # 输出:
    # /docker-entrypoint.sh: Launching /docker-entrypoint.d/30-tune-worker-processes.sh
    # /docker-entrypoint.sh: Configuration complete; ready for start up

    结语

    Slim工具为我们提供了一种简单而有效的方法来优化容器镜像。它不仅能大幅减小镜像体积,还能提高应用的安全性和启动速度。最重要的是,Slim的使用不需要我们改变现有的构建流程或修改Dockerfile,这使得它能够无缝集成到现有的开发和部署环境中。

    在容器技术日益普及的今天,Slim无疑是一个值得每个开发者和运维人员掌握的强大工具。它能帮助我们构建更小、更安全、更高效的容器化应用,从而在竞争激烈的云原生世界中占得先机。

    参考文献

    1. Slim GitHub项目: https://github.com/slimtoolkit/slim
  • 深入解析 Spark 协同过滤(ALS)

    Spark MLlib 提供了一种协同过滤算法,可用于训练矩阵分解模型,该模型预测用户对物品的显式或隐式评分,从而进行推荐。本文将深入探讨 Spark 的协同过滤算法。

    1 矩阵分解算法

    1.1 协同过滤问题的矩阵分解

    矩阵分解是推荐任务中常用的一种技术。基本上,矩阵分解算法试图找到表示用户和物品内在属性的潜在因子,即:

    $$\hat r_{u,i} = q_{i}^{T}p_{u}$$

    其中,$\hat r_{u,i}$ 是用户 $u$ 对物品 $i$ 的预测评分,$q_{i}^{T}$ 和 $p_{u}$ 分别是物品和用户的潜在因子。矩阵分解问题的挑战在于找到 $q_{i}^{T}$ 和 $p_{u}$,这可以通过矩阵分解方法实现。为了尽量接近观察到的评分,开发了一种学习方法。此外,为了避免过拟合问题,学习过程被正则化。例如,基本形式的矩阵分解算法表示如下:

    $$\min \sum (r_{u,i} – q_{i}^{T}p_{u})^2 + \lambda (||q_{i}||^2 + ||p_{u}||^2)$$

    其中,$\lambda$ 是正则化参数。

    在没有显式评分的情况下,可以使用用户与物品的历史交互(如点击、浏览、购买等)来推断隐式评分。为了考虑这些隐式评分,原始矩阵分解算法可以表示为:

    $$\min \sum c_{u,i}(p_{u,i} – q_{i}^{T}p_{u})^2 + \lambda (||q_{i}||^2 + ||p_{u}||^2)$$

    其中,$c_{u,i}=1+\alpha r_{u,i}$,如果 $r_{u,i}>0$ 则 $p_{u,i}=1$,否则 $p_{u,i}=0$。$r_{u,i}$ 是用户偏好的数值表示(例如点击次数等)。

    1.2 交替最小二乘法(ALS)

    由于 $q_{i}^{T}p_{u}$ 项的存在,损失函数是非凸的。可以应用梯度下降法,但这将导致昂贵的计算成本。为此,开发了一种交替最小二乘法(ALS)算法来解决这个问题。

    ALS 的基本思想是每次学习 $q$ 和 $p$ 中的一个进行优化,而将另一个保持不变。这使得每次迭代的目标函数都是凸的且可解的。当交替迭代收敛到最优解时,过程停止。值得注意的是,这种迭代计算可以并行化和/或分布式处理,这使得该算法在数据集很大且用户-物品评分矩阵非常稀疏的推荐场景中非常理想。关于 ALS 及其分布式计算的全面讨论,请参见这里

    2 Spark Mllib 实现

    矩阵分解算法在 Spark ml DataFrame 和 Spark mllib RDD 中均可用作为 ALS 模块提供。

    • ALS 实现的独特之处在于它使用“交替最小二乘法”来分布式地训练矩阵分解模型。
    • 在训练方法中,可以选择一些参数来控制模型性能。
    • Spark ALS 模型支持显式和隐式评分。

    3 基于 Spark ALS 的 MovieLens 推荐系统

    以下代码使用 MovieLens-100K 数据集来演示 Spark 中的 ALS 算法。

    注意:此笔记本需要一个 PySpark 环境才能正常运行。请按照 SETUP.md 中的步骤安装 PySpark 环境。

    import warnings
    warnings.simplefilter(action='ignore', category=FutureWarning)
    
    import sys
    from matplotlib import pyplot as plt
    import numpy as np
    import pandas as pd
    import seaborn as sns
    
    import pyspark
    from pyspark.sql import SparkSession
    from pyspark.ml.recommendation import ALS
    import pyspark.sql.functions as F
    from pyspark.sql.functions import col
    from pyspark.ml.tuning import CrossValidator
    from pyspark.sql.types import StructType, StructField
    from pyspark.sql.types import FloatType, IntegerType, LongType
    
    from recommenders.datasets import movielens
    from recommenders.utils.spark_utils import start_or_get_spark
    from recommenders.evaluation.spark_evaluation import SparkRankingEvaluation, SparkRatingEvaluation
    from recommenders.tuning.parameter_sweep import generate_param_grid
    from recommenders.datasets.spark_splitters import spark_random_split
    
    print(f"System version: {sys.version}")
    print(f"Pandas version: {pd.__version__}")
    print(f"PySpark version: {pyspark.__version__}")

    3.1 加载和准备数据

    数据从 CSV 文件读取到 Spark DataFrame 中。

    MOVIELENS_DATA_SIZE = "100k"
    
    COL_USER = "UserId"
    COL_ITEM = "MovieId"
    COL_RATING = "Rating"
    COL_PREDICTION = "prediction"
    COL_TIMESTAMP = "Timestamp"
    
    schema = StructType(
        (
            StructField(COL_USER, IntegerType()),
            StructField(COL_ITEM, IntegerType()),
            StructField(COL_RATING, FloatType()),
            StructField(COL_TIMESTAMP, LongType()),
        )
    )
    
    dfs = movielens.load_spark_df(spark=spark, size=MOVIELENS_DATA_SIZE, schema=schema)
    dfs.show(5)

    数据按 80-20 比例随机分为训练集和测试集。

    dfs_train, dfs_test = spark_random_split(dfs, ratio=0.75, seed=42)

    3.2 训练 MovieLens 模型

    值得注意的是,Spark ALS 模型允许删除冷用户,以便对测试数据进行稳健评估。如果存在冷用户,Spark ALS 实现允许用户删除冷用户,以确保对预测结果的评估是合理的。

    RANK = 10
    MAX_ITER = 15
    REG_PARAM = 0.05
    
    als = ALS(
        maxIter=MAX_ITER,
        rank=RANK,
        regParam=REG_PARAM,
        userCol=COL_USER,
        itemCol=COL_ITEM,
        ratingCol=COL_RATING,
        coldStartStrategy="drop"
    )
    
    model = als.fit(dfs_train)

    3.3 使用模型进行预测

    训练好的模型可以用来预测给定测试数据的评分。

    dfs_pred = model.transform(dfs_test).drop(COL_RATING)

    使用预测结果,可以评估模型性能。

    evaluations = SparkRatingEvaluation(
        dfs_test,
        dfs_pred,
        col_user=COL_USER,
        col_item=COL_ITEM,
        col_rating=COL_RATING,
        col_prediction=COL_PREDICTION
    )
    
    print(
        "RMSE score = {}".format(evaluations.rmse()),
        "MAE score = {}".format(evaluations.mae()),
        "R2 score = {}".format(evaluations.rsquared()),
        "Explained variance score = {}".format(evaluations.exp_var()),
        sep="\n"
    )

    通常,数据科学家对排名指标也感兴趣。通常,排名指标适用于推荐一组物品的场景。在我们的例子中,推荐的物品应该与用户已经评分的物品不同。

    users = dfs_train.select(COL_USER).distinct()
    items = dfs_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(
        dfs_train.alias("train"),
        (dfs_pred[COL_USER] == dfs_train[COL_USER]) & (dfs_pred[COL_ITEM] == dfs_train[COL_ITEM]),
        how='outer'
    )
    
    dfs_pred_final = dfs_pred_exclude_train.filter(dfs_pred_exclude_train["train.Rating"].isNull()) \
        .select('pred.' + COL_USER, 'pred.' + COL_ITEM, 'pred.' + "prediction")
    
    evaluations = SparkRankingEvaluation(
        dfs_test,
        dfs_pred_final,
        col_user=COL_USER,
        col_item=COL_ITEM,
        col_rating=COL_RATING,
        col_prediction=COL_PREDICTION,
        k=K
    )
    
    print(
        "Precision@k = {}".format(evaluations.precision_at_k()),
        "Recall@k = {}".format(evaluations.recall_at_k()),
        "NDCG@k = {}".format(evaluations.ndcg_at_k()),
        "Mean average precision = {}".format(evaluations.map_at_k()),
        sep="\n"
    )

    3.4 微调模型

    Spark ALS 模型的预测性能通常受参数影响。

    参数描述默认值备注
    rank潜在因子的数量10潜在因子越多,分解模型中考虑的内在因素越多。
    regParam正则化参数1.0值需要根据经验选择,以避免过拟合。
    maxIter最大迭代次数10迭代次数越多,模型收敛到最优点的效果越好。

    通常的做法是从默认参数值开始构建模型,然后在一定范围内调整参数,以找到最佳参数组合。以下参数集用于训练 ALS 模型进行比较研究。

    param_dict = {
        "rank": [10, 15, 20],
        "regParam": [0.001, 0.1, 1.0]
    }
    
    param_grid = generate_param_grid(param_dict)
    rmse_score = []
    
    for g in param_grid:
        als = ALS(
            userCol=COL_USER,
            itemCol=COL_ITEM,
            ratingCol=COL_RATING,
            coldStartStrategy="drop",
            **g
        )
        model = als.fit(dfs_train)
        dfs_pred = model.transform(dfs_test).drop(COL_RATING)
        evaluations = SparkRatingEvaluation(
            dfs_test,
            dfs_pred,
            col_user=COL_USER,
            col_item=COL_ITEM,
            col_rating=COL_RATING,
            col_prediction=COL_PREDICTION
        )
        rmse_score.append(evaluations.rmse())
    
    rmse_score = [float('%.4f' % x) for x in rmse_score]
    rmse_score_array = np.reshape(rmse_score, (len(param_dict["rank"]), len(param_dict["regParam"])))
    
    rmse_df = pd.DataFrame(data=rmse_score_array, index=pd.Index(param_dict["rank"], name="rank"),
                           columns=pd.Index(param_dict["regParam"], name="reg. parameter"))
    
    fig, ax = plt.subplots()
    sns.heatmap(rmse_df, cbar=False, annot=True, fmt=".4g")

    从这个可视化中可以看出,随着潜在因子数量的增加,RMSE 先减少后增加,这是由于过拟合。当潜在因子数量为 20,正则化参数为 0.1 时,模型达到了最低的 RMSE 分数。

    3.5 Top K 推荐

    3.5.1 为所有用户(物品)生成前 K 个推荐

    dfs_rec = model.recommendForAllUsers(10)
    dfs_rec.show(10)

    3.5.2 为选定的用户(物品)生成前 K 个推荐

    users = dfs_train.select(als.getUserCol()).distinct().limit(3)
    dfs_rec_subset = model.recommendForUserSubset(users, 10)
    dfs_rec_subset.show(10)

    3.5.3 Top-K 推荐的运行时考虑

    值得注意的是,通常对所有用户进行 Top-K 推荐计算是整个管道(模型训练和评分)的瓶颈。这是因为:

    • 从所有用户-物品对中获取 Top-K 需要交叉连接,这通常计算量很大。
    • 用户-物品对的内积是逐个计算的,而不是利用某些现代计算加速库(如 BLAS)中可用的矩阵块乘法特性。

    关于 Spark 中 Top-K 推荐的可能优化的更多详细信息,请参见这里

    # cleanup spark instance
    spark.stop()

    参考文献

    1. Yehuda Koren, Robert Bell, and Chris Volinsky, “Matrix Factorization Techniques for Recommender Systems”, ACM Computer, Vol. 42, Issue 8, pp 30-37, Aug., 2009.
    2. Yifan Hu, Yehuda Koren, and Chris Volinsky, “Collaborative Filtering for Implicit Feedback Datasets”, Proc. IEEE ICDM, 2008, Dec, Pisa, Italy.
    3. Apache Spark. url: https://spark.apache.org/docs/latest/ml-collaborative-filtering.html
    4. Seaborn. url: https://seaborn.pydata.org/
    5. Scaling collaborative filtering with PySpark. url: https://engineeringblog.yelp.com/2018/05/scaling-collaborative-filtering-with-pyspark.html
    6. Matrix Completion via Alternating Least Square (ALS). url: http://stanford.edu/~rezab/classes/cme323/S15/notes/lec14.pdf
  • 长短期兴趣分离:推荐系统的新突破

    在这个信息爆炸的时代,推荐系统在我们的日常生活中扮演着越来越重要的角色。无论是新闻推送、电商购物还是短视频推荐,都离不开推荐系统的支持。然而,传统的推荐算法往往无法很好地区分用户的长期兴趣和短期兴趣,这严重影响了推荐的准确性。最近,清华大学和快手科技的研究人员提出了一种新的方法,通过对比学习框架实现长短期兴趣的分离,大大提升了推荐效果。让我们一起来看看这项突破性的研究。

    长短期兴趣:用户偏好的两个维度

    在推荐系统中,准确把握用户兴趣至关重要。但用户的兴趣是复杂多变的,通常可以分为两个方面:

    • 长期兴趣:反映用户相对稳定的偏好,可能会持续较长时间。例如,一个用户长期以来都喜欢浏览电子产品。
    • 短期兴趣:体现用户近期的动态偏好,变化较快。比如用户最近突然对服装产生了兴趣。

    准确区分和建模这两种兴趣,对提高推荐效果至关重要。然而,现有的方法往往将长短期兴趣混杂在一起建模,难以真正分离开来。这不仅影响了推荐的准确性,也使得推荐结果难以解释。

    现有方法的局限性

    目前主流的推荐算法大致可以分为以下几类:

    1. 基于协同过滤的方法:主要捕捉用户的长期兴趣,但忽视了序列特征,难以建模动态的短期兴趣。
    2. 序列模型:利用CNN或RNN等网络学习序列特征,但往往只关注短期记忆,容易忽视长期兴趣。
    3. 混合方法:结合协同过滤和序列模型,试图同时捕捉长短期兴趣。但由于缺乏显式的监督,学到的长短期兴趣表示往往还是纠缠在一起的。

    这些方法的共同问题在于:没有针对长短期兴趣设计独立的建模机制,也没有专门的监督信号来指导长短期兴趣的分离。这就导致了学到的兴趣表示难以真正区分长短期特征。

    CLSR:基于对比学习的长短期兴趣分离框架

    为了解决上述问题,研究人员提出了一种新的对比学习框架CLSR(Contrastive Learning for Short and Long-term interests in Recommendation)。该框架的核心思想是:通过自监督的方式,利用用户的交互序列构建长短期兴趣的代理表示,并通过对比学习实现长短期兴趣的有效分离。具体来说,CLSR包含以下几个关键组件:

    1. 独立的长短期兴趣编码器

    CLSR设计了两个独立的编码器,分别用于捕捉长期兴趣和短期兴趣:

    • 长期兴趣编码器:采用注意力池化机制,从用户的全部历史交互中提取长期兴趣表示。
    • 短期兴趣编码器:基于RNN和注意力机制,从用户最近的交互序列中捕捉动态变化的短期兴趣。

    这种设计使得长短期兴趣可以被独立地建模,为后续的分离奠定了基础。

    2. 基于交互序列的自监督

    CLSR的一大创新在于,它利用用户的交互序列自动构建长短期兴趣的代理表示,作为自监督的信号。具体而言:

    • 长期兴趣代理:用户全部历史交互的平均表示
    • 短期兴趣代理:用户最近k个交互的平均表示

    这些代理表示虽然简单,但能很好地反映长短期兴趣的特征,为后续的对比学习提供了有效的监督信号。

    3. 对比学习任务

    有了代理表示作为”伪标签”,CLSR设计了成对的对比学习任务:

    • 使长期兴趣编码器的输出与长期兴趣代理更相似
    • 使短期兴趣编码器的输出与短期兴趣代理更相似

    这种对比学习机制能有效地引导模型学习到更好地分离的长短期兴趣表示。

    4. 自适应融合网络

    为了在最终预测时合理利用长短期兴趣,CLSR设计了一个基于注意力的融合网络。该网络能根据目标物品和用户历史,自适应地调整长短期兴趣的重要性,从而做出更准确的预测。

    实验结果:显著提升推荐效果

    研究人员在电商和短视频推荐两个大规模真实数据集上进行了实验。结果表明,CLSR在各项指标上都显著优于现有的最先进方法:

    • AUC和GAUC提升超过0.02
    • NDCG提升超过10.7%

    这样的提升幅度在推荐系统领域是非常可观的。

    更重要的是,研究人员还通过反事实分析验证了CLSR在长短期兴趣分离方面的效果。他们人为地干预用户的历史交互序列,阻断长期或短期兴趣的信息。结果显示,CLSR能够稳定地实现更强的长短期兴趣分离,远超现有方法。

    总结与展望

    CLSR框架巧妙地利用对比学习和自监督,解决了长短期兴趣分离这一关键问题。它不仅显著提升了推荐效果,还为推荐系统的可解释性和可控性开辟了新的方向。

    未来的研究可以在以下几个方面进一步拓展:

    1. 设计更复杂的长短期兴趣代理表示,进一步提升自监督效果
    2. 将CLSR框架应用到更多推荐场景,如新闻、音乐等领域
    3. 探索如何利用分离的长短期兴趣实现更精细的推荐控制和解释

    总的来说,CLSR为推荐系统的发展提供了一个全新的范式,相信会激发出更多创新性的工作。

    参考文献

    https://arxiv.org/pdf/2202.13090.pdf

  • 序列推荐系统的性能比较:CLSR与SLi_Rec在点击和购买预测上的表现

    在推荐系统中,准确预测用户的点击和购买行为对于提升用户体验和增加平台收益至关重要。本文将比较两种序列推荐模型——CLSR(基于对比学习的序列推荐模型)和SLi_Rec(结合长短期偏好的自适应用户建模个性化推荐模型)在点击和购买预测上的表现。

    1. 模型简介

    1.1 CLSR

    CLSR是一种基于对比学习的序列推荐模型,通过对比学习方法提升推荐性能。其主要特点包括:

    • 通过对比学习方法捕捉用户行为的序列模式;
    • 利用用户的历史行为和当前行为进行建模;
    • 采用多层神经网络进行推荐。

    1.2 SLi_Rec

    SLi_Rec是一种结合长短期偏好的自适应用户建模个性化推荐模型。其主要特点包括:

    • 采用注意力机制的“非对称SVD”范式进行长期建模;
    • 在LSTM的门控逻辑中考虑时间和语义的不规则性;
    • 使用注意力机制动态融合长期和短期组件。

    2. 性能比较

    根据ResearchGate上的研究数据,我们可以看到CLSR和SLi_Rec在点击和购买预测上的性能比较。以下为两种模型在不同指标下的表现:

    指标CLSRSLi_Rec
    点击预测准确率(Accuracy)0.850.82
    点击预测AUC0.870.85
    购买预测准确率(Accuracy)0.780.75
    购买预测AUC0.800.78

    从表中可以看出,CLSR在点击和购买预测的准确率和AUC(曲线下面积)上均优于SLi_Rec,尤其是在点击预测上表现更为突出。

    3. 模型分析

    3.1 CLSR模型的优势

    1. 对比学习方法:CLSR通过对比学习方法有效捕捉用户行为序列中的模式,提高了模型的泛化能力和推荐性能。
    2. 多层神经网络:采用多层神经网络对用户行为进行建模,增强了模型的表达能力。

    3.2 SLi_Rec模型的优势

    1. 注意力机制:SLi_Rec通过注意力机制动态融合用户的长期和短期偏好,能够更好地捕捉用户的兴趣变化。
    2. 时间和语义不规则性:在LSTM的门控逻辑中考虑时间和语义的不规则性,使得模型在处理复杂用户行为序列时表现更好。

    4. 结论

    虽然CLSR在点击和购买预测上的表现优于SLi_Rec,但这并不意味着SLi_Rec模型的劣势。SLi_Rec在捕捉用户长期和短期偏好方面具有独特的优势,适用于需要综合考虑用户长期兴趣和短期需求的应用场景。而CLSR则在对比学习和多层神经网络的加持下,能够更有效地捕捉用户行为模式,适用于需要高精度点击和购买预测的推荐系统。

    参考文献

    1. Zeping Yu, Jianxun Lian, Ahmad Mahmoody, Gongshen Liu, Xing Xie. Adaptive User Modeling with Long and Short-Term Preferences for Personailzed Recommendation. In Proceedings of the 28th International Joint Conferences on Artificial Intelligence, IJCAI’19, Pages 4213-4219. AAAI Press, 2019.
    2. ResearchGate. Comparison between CLSR and SLi_Rec on predicting click and purchase. 链接.

    以上内容通过对比CLSR和SLi_Rec模型在点击和购买预测上的表现,分析了两种模型的优劣势,为推荐系统的选择和应用提供了参考。希望本文对您了解序列推荐系统的性能比较有所帮助。

  • xDeepFM:极深度因子分解机在推荐系统中的应用

    在当今信息爆炸的时代,推荐系统已成为帮助用户从海量信息中快速找到所需内容的重要工具。然而,如何更好地捕捉特征之间的交互关系,一直是推荐系统研究的重点和难点。本文将为您介绍一种新颖的深度学习模型——xDeepFM(极深度因子分解机),它在有效学习特征交互方面取得了显著进展。

    1. xDeepFM模型简介

    xDeepFM是由Lian等人在2018年提出的一种深度学习模型,旨在同时捕捉低阶和高阶特征交互,以提高推荐系统的精确度。该模型具有以下几个关键特性:

    1. 显式特征交互:xDeepFM包含一个名为CIN(Compressed Interaction Network)的组件,它以向量级别学习特征交互,使得特征间的关系更加明确。
    2. 隐式特征交互:模型还包含传统的DNN(Deep Neural Network)组件,在比特级别隐式学习特征交互。
    3. 高度可配置:通过设置不同的超参数,如use_Linear_partuse_FM_partuse_CIN_partuse_DNN_part,我们可以启用模型的不同子组件。例如,仅启用use_Linear_partuse_FM_part,就可以得到经典的FM(因子分解机)模型。

    2. xDeepFM的模型结构

    xDeepFM的模型结构主要包含以下几个部分:

    1. 线性部分(Linear part):捕捉一阶特征交互。
    2. FM部分(Factorization Machine part):学习二阶特征交互。
    3. CIN部分(Compressed Interaction Network part):显式学习高阶特征交互。
    4. DNN部分(Deep Neural Network part):隐式学习高阶特征交互。

    模型的总体结构可以表示为:

    y = w_linear * x + w_FM * FM(x) + w_CIN * CIN(x) + w_DNN * DNN(x)

    其中,x是输入特征,w_linear、w_FM、w_CIN和w_DNN是各个部分的权重。

    3. xDeepFM在Criteo数据集上的实践

    为了展示xDeepFM的实际效果,我们将使用Criteo数据集进行实验。Criteo数据集是一个广泛用于CTR(点击率)预测任务的工业基准数据集。

    3.1 数据准备

    xDeepFM使用FFM(Field-aware Factorization Machine)格式作为数据输入。每行代表一个实例,格式如下:

    <label> <field_id>:<feature_id>:<feature_value>

    其中,<label>是二进制值,1表示正例,0表示负例。特征被划分为不同的字段,字段索引和特征索引都从1开始。

    3.2 模型配置

    我们使用以下配置来初始化xDeepFM模型:

    hparams = prepare_hparams(yaml_file,
                              FEATURE_COUNT=2300000,
                              FIELD_COUNT=39,
                              cross_l2=0.01,
                              embed_l2=0.01,
                              layer_l2=0.01,
                              learning_rate=0.002,
                              batch_size=4096,
                              epochs=10,
                              cross_layer_sizes=[20, 10],
                              init_value=0.1,
                              layer_sizes=[20,20],
                              use_Linear_part=True,
                              use_CIN_part=True,
                              use_DNN_part=True)

    这里我们启用了线性部分、CIN部分和DNN部分,设置了特征数量、字段数量、学习率等超参数。

    3.3 模型训练与评估

    在训练之前,我们首先检查模型的初始性能:

    print(model.run_eval(test_file))
    # 输出: {'auc': 0.4728, 'logloss': 0.7113}

    然后开始训练模型:

    model.fit(train_file, valid_file)

    训练过程中,我们可以观察到模型性能的逐步提升:

    at epoch 1
    train info: logloss loss:744.3602104187012
    eval info: auc:0.6637, logloss:0.5342
    ...
    at epoch 10
    train info: logloss loss:1.0249397866427898
    eval info: auc:0.747, logloss:0.491

    最后,我们在测试集上评估模型的最终性能:

    result = model.run_eval(test_file)
    print(result)
    # 输出: {'auc': 0.7356, 'logloss': 0.5017}

    4. 实验结果分析

    通过观察实验结果,我们可以得出以下几点结论:

    1. 模型性能显著提升:从初始的AUC 0.4728提升到最终的0.7356,说明xDeepFM模型成功学习到了有效的特征交互。
    2. 快速收敛:在短短10个epoch内,模型就达到了较好的性能,这表明xDeepFM具有良好的收敛速度。
    3. 稳定性:从训练过程中可以看出,模型的性能随着训练的进行稳步提升,没有出现明显的过拟合现象。
    4. 实用性:在Criteo这样的大规模数据集上,xDeepFM能够在合理的时间内完成训练(约4分钟),显示了其在实际应用中的潜力。

    5. xDeepFM的优势与应用前景

    1. 特征交互的全面捕捉:通过结合显式和隐式特征交互学习,xDeepFM能够更全面地捕捉特征间的复杂关系。
    2. 减少人工特征工程:模型能够自动学习有效的特征组合,大大减少了人工特征工程的工作量。
    3. 灵活性:模型的高度可配置性使其能够适应不同的应用场景和数据特点。
    4. 性能优越:在多个基准数据集上,xDeepFM都展现出了优于传统模型的性能。
    5. 可解释性:相比纯粹的深度学习模型,xDeepFM的CIN部分提供了一定程度的可解释性。

    6. 结论

    xDeepFM作为一种新型的深度学习推荐模型,通过巧妙地结合显式和隐式特征交互学习,在捕捉复杂特征关系方面取得了显著进展。我们的实验结果表明,该模型在Criteo数据集上展现出了优秀的性能和稳定性。

    xDeepFM不仅在推荐系统中具有广阔的应用前景,还为我们思考如何更好地设计深度学习模型以捕捉特征交互提供了新的思路。以下是对xDeepFM未来发展的几点展望:

    7. 未来展望

    1. 模型优化:尽管xDeepFM已经表现出色,但仍有进一步优化的空间。例如,可以探索更高效的CIN结构,或者引入注意力机制来增强模型的表达能力。
    2. 大规模应用:虽然在本实验中xDeepFM表现良好,但在更大规模的数据集和实际在线系统中的表现还需要进一步验证。未来可以探索如何在保持模型性能的同时,提高其在大规模数据上的计算效率。
    3. 跨领域迁移:xDeepFM在CTR预测任务上表现出色,未来可以尝试将其应用到其他领域,如自然语言处理或计算机视觉中的特征交互学习任务。
    4. 可解释性研究:虽然xDeepFM比纯粹的深度学习模型更具可解释性,但如何更好地理解和解释模型学到的特征交互仍是一个值得深入研究的方向。
    5. 与其他技术的结合:可以探索将xDeepFM与其他先进技术(如强化学习、图神经网络等)结合,以应对更复杂的推荐场景。
    6. 动态适应:研究如何使xDeepFM能够更好地适应用户兴趣和市场趋势的动态变化,提高模型的实时性和适应性。
    7. 隐私保护:随着数据隐私越来越受到重视,如何在保护用户隐私的同时利用xDeepFM进行有效推荐是一个重要的研究方向。

    综上所述,xDeepFM作为一种强大的特征交互学习模型,不仅在当前的推荐系统中发挥着重要作用,还有望在更广泛的机器学习应用中产生影响。它的出现为我们提供了一个新的视角来思考如何更好地建模复杂的特征关系,相信随着进一步的研究和优化,xDeepFM将在推荐系统和相关领域发挥更大的作用。

    参考文献

    [1] Lian, J., Zhou, X., Zhang, F., Chen, Z., Xie, X., & Sun, G. (2018). xDeepFM: Combining Explicit and Implicit Feature Interactions for Recommender Systems. In Proceedings of the 24th ACM SIGKDD International Conference on Knowledge Discovery & Data Mining.

    [2] Guo, H., Tang, R., Ye, Y., Li, Z., & He, X. (2017). DeepFM: A Factorization-Machine based Neural Network for CTR Prediction. In Proceedings of the 26th International Joint Conference on Artificial Intelligence.

    [3] Cheng, H. T., Koc, L., Harmsen, J., Shaked, T., Chandra, T., Aradhye, H., … & Shah, H. (2016). Wide & Deep Learning for Recommender Systems. In Proceedings of the 1st Workshop on Deep Learning for Recommender Systems.

  • SASRec模型在亚马逊数据集上的应用

    在当今的电子商务领域,推荐系统扮演着越来越重要的角色。它能够帮助用户快速发现感兴趣的商品,提升用户体验;同时也能够帮助平台提高销售转化率,增加收入。本文将介绍一种先进的序列推荐模型SASRec,并展示其在亚马逊数据集上的应用实例。

    SASRec模型简介

    SASRec(Self-Attentive Sequential Recommendation)是一种基于自注意力机制的序列推荐模型。它由Kang等人于2018年提出,能够有效捕捉用户的长期和短期兴趣,在多个数据集上取得了优异的性能。

    SASRec模型的核心思想是:

    1. 将用户的历史行为序列作为输入
    2. 使用自注意力机制来学习不同行为之间的关系
    3. 预测用户下一个可能的行为

    相比传统的RNN或CNN模型,SASRec具有以下优势:

    • 可以同时建模长期和短期依赖关系
    • 计算效率高,易于并行化
    • 模型可解释性强

    在亚马逊数据集上的应用

    接下来,我们将展示如何使用Microsoft Recommenders库在亚马逊电子产品数据集上应用SASRec模型。

    环境准备

    首先,我们需要安装必要的依赖包:

    !pip install --upgrade recommenders

    然后导入所需的库:

    import sys
    import os
    import numpy as np
    import pandas as pd
    import matplotlib.pyplot as plt
    from recommenders.models.sasrec.sasrec_tf import SASRec
    from recommenders.datasets.amazon_reviews import download_and_extract, data_preprocessing
    from recommenders.evaluation.python_evaluation import (
        map_at_k,
        ndcg_at_k,
        precision_at_k,
        recall_at_k,
    )
    from recommenders.utils.timer import Timer
    from recommenders.utils.constants import SEED
    
    print("System version: {}".format(sys.version))
    print("Recommenders version: {}".format(recommenders.__version__))

    数据准备

    我们使用亚马逊电子产品数据集。首先下载并解压数据:

    data_path = download_and_extract(r'https://recommenders.blob.core.windows.net/datasets/amazon_reviews_electronics_5core.json')

    然后对数据进行预处理:

    data = data_preprocessing(data_path, threshold=5, col_names=['userID', 'itemID', 'rating', 'timestamp'])

    将数据集分为训练集和测试集:

    train, test = data.random_split(0.75)

    模型训练

    接下来,我们创建SASRec模型实例并进行训练:

    model = SASRec(
        item_num=data['item_num'],
        max_seq_length=50,
        num_blocks=2,
        embedding_dim=100,
        attention_dim=100,
        learning_rate=0.001,
        batch_size=128,
        num_epochs=100,
        seed=SEED
    )
    
    model.fit(train)

    模型评估

    训练完成后,我们使用多个指标对模型进行评估:

    k = 10
    eval_metrics = {
        "MAP": map_at_k,
        "NDCG": ndcg_at_k,
        "Precision": precision_at_k,
        "Recall": recall_at_k
    }
    
    with Timer() as test_time:
        predictions = model.predict(test)
    
    print("Took {} seconds for prediction.".format(test_time.interval))
    
    for metric_name, metric_func in eval_metrics.items():
        score = metric_func(test, predictions, k=k)
        print("{:<11} @ {}: {:.4f}".format(metric_name, k, score))

    结果分析

    通过上述步骤,我们成功地在亚马逊电子产品数据集上应用了SASRec模型。模型的性能可以通过MAP、NDCG、准确率和召回率等指标来评估。这些指标反映了模型在不同方面的推荐质量。

    例如,NDCG@10的值反映了模型在前10个推荐结果中的排序质量。MAP@10则衡量了模型检索相关项目的能力。准确率和召回率分别反映了推荐结果的精确性和完整性。

    通过分析这些指标,我们可以对SASRec模型在亚马逊电子产品数据集上的表现有一个全面的了解。如果需要进一步提升模型性能,可以考虑调整模型参数,如嵌入维度、注意力层数等,或者尝试更复杂的模型结构。

    结论

    SASRec模型作为一种先进的序列推荐算法,在亚马逊电子产品数据集上展现出了良好的性能。它能够有效捕捉用户的长期和短期兴趣,为用户提供个性化的推荐。通过Microsoft Recommenders库,我们可以方便地实现和评估SASRec模型,为推荐系统的研究和应用提供了有力的工具支持。

    在实际应用中,还需要考虑模型的效率、可解释性以及商业目标等因素。未来的研究方向可以包括将SASRec与其他模型进行集成,探索更有效的特征表示方法,以及在更大规模的数据集上进行验证。

    参考文献

    1. Kang, W. C., & McAuley, J. (2018). Self-attentive sequential recommendation. In 2018 IEEE International Conference on Data Mining (ICDM) (pp. 197-206). IEEE.
    2. Microsoft Recommenders. (n.d.). GitHub repository. https://github.com/recommenders-team/recommenders

    SASRec模型在亚马逊数据集上的应用

    在当今互联网时代,推荐系统已经成为各大电商平台必不可少的一部分。亚马逊作为全球最大的电商平台之一,如何通过先进的推荐系统为用户提供个性化的购物体验,成为其竞争力的重要来源之一。本文将介绍一种最新的推荐系统模型——SASRec,并探讨它在亚马逊数据集上的应用。

    什么是SASRec?

    SASRec,全称为Self-Attentive Sequential Recommendation,是一种基于自注意力机制的序列推荐模型。该模型通过捕捉用户行为序列中的复杂模式,来预测用户未来可能感兴趣的商品。

    模型结构

    SASRec的核心在于其自注意力机制。自注意力机制可以理解为一种加权平均的计算方法,它能够根据序列中的各个元素之间的关系来调整它们的权重。具体来说,SASRec模型主要由以下几部分组成:

    1. Embedding层:将用户和商品的ID映射到一个低维度的向量空间。
    2. 自注意力层:通过多头自注意力机制来捕捉用户行为序列中的模式。
    3. 位置编码:加入位置编码信息,帮助模型理解序列中的顺序信息。
    4. 输出层:将自注意力层的输出进行处理,最终预测用户的下一次行为。

    公式上,SASRec的自注意力机制可以表示为:
    [ \text{Attention}(Q, K, V) = \text{softmax}\left(\frac{QK^T}{\sqrt{d_k}}\right)V ]
    其中,(Q)、(K)和(V)分别代表查询矩阵、键矩阵和值矩阵,(d_k)是矩阵的维度。

    SASRec在亚马逊数据集上的应用

    亚马逊数据集包含了用户的购买记录、浏览历史、商品评价等丰富的信息,这为SASRec模型的训练提供了良好的数据基础。

    数据预处理

    在实际应用中,首先需要对亚马逊的数据进行预处理。具体步骤如下:

    1. 数据清洗:去除缺失值和异常值,确保数据的质量。
    2. 数据分割:将数据划分为训练集、验证集和测试集,以便模型的训练和评估。
    3. 序列生成:将每个用户的行为记录按照时间顺序排列,生成用户行为序列。

    模型训练

    在完成数据预处理后,可以开始训练SASRec模型。在训练过程中,需要设置一些超参数,例如学习率、批量大小、嵌入维度等。此外,还需要选择适当的优化器(如Adam)来加速模型的收敛。

    模型评估

    为了评估SASRec模型的性能,可以使用多个评价指标,例如精确率(Precision)、召回率(Recall)和F1-Score等。这些指标可以帮助我们全面了解模型的推荐效果。

    实验结果

    在亚马逊数据集上进行实验,SASRec模型展示了其强大的推荐能力。与传统的协同过滤方法相比,SASRec在多个评价指标上均取得了显著的提升。例如,在Top-N推荐任务中,SASRec的Precision和Recall都明显优于基线模型。

    结论

    SASRec模型通过引入自注意力机制,有效地捕捉了用户行为序列中的复杂模式,从而提高了推荐系统的性能。通过在亚马逊数据集上的实际应用,我们可以看到SASRec在推荐任务中的巨大潜力。未来,随着更多数据和更强计算能力的加入,SASRec有望在电商平台上发挥更大的作用。

    参考文献

    1. Kang, W.-C., & McAuley, J. (2018). Self-Attentive Sequential Recommendation. arXiv preprint arXiv:1808.09781.
    2. He, X., Liao, L., Zhang, H., Nie, L., Hu, X., & Chua, T.-S. (2017). Neural Collaborative Filtering. In Proceedings of the 26th International Conference on World Wide Web (pp. 173-182).

    SASRec模型在亚马逊数据集上的应用

    简介

    在当今快速发展的电子商务平台上,推荐系统已经成为提升用户体验的重要工具。本文将介绍一种基于Transformer的序列推荐模型——SASRec,并探讨其在亚马逊数据集上的应用。

    SASRec模型简介

    SASRec,全称为Self-Attentive Sequential Recommendation,是一种基于自注意力机制的序列推荐模型。与传统的CNN(如Caser)或RNN(如GRU、SLI-Rec)不同,SASRec依赖于Transformer编码器来生成用户行为序列的新表示。

    模型变体

    在本文中,我们将介绍两种基于Transformer的推荐模型:

    1. SASRec:基于vanilla Transformer,仅建模商品序列。
    2. SSE-PT:基于Stochastic Shared Embedding的个性化Transformer,既建模用户也建模商品。

    数据预处理

    亚马逊的电子产品数据集包含用户的购买记录。我们将对这些数据进行预处理,以便输入到SASRec模型中。数据集需要经过以下步骤的预处理:

    1. 下载并读取数据:获取亚马逊电子产品的用户评论数据。
    2. 过滤数据:过滤掉交互次数少于10次的用户和商品。
    3. 编码用户和商品:将用户ID和商品ID转换为从1开始的整数。
    4. 排序和分割:按用户ID和时间排序,并将数据划分为训练集、验证集和测试集。

    数据示例

    预处理后的数据格式如下所示:

    userID  itemID
    30449   2771
    30449   61842
    30449   60293
    30449   30047
    30449   63296
    30449   22042
    30449   6717
    30449   75780

    模型训练

    模型参数

    在训练模型之前,需要设置一些模型参数:

    • num_epochs:训练轮数
    • batch_size:批量大小
    • lr:学习率
    • maxlen:序列的最大长度
    • num_blocks:Transformer块的数量
    • hidden_units:注意力计算的隐藏单元数量
    • num_heads:注意力头的数量
    • dropout_rate:dropout率
    • l2_emb:L2正则化系数
    • num_neg_test:每个正样本的负样本数量

    模型构建

    根据选择的模型(SASRec或SSE-PT),可以构建相应的模型:

    if model_name == 'sasrec':
        model = SASREC(item_num=data.itemnum,
                       seq_max_len=maxlen,
                       num_blocks=num_blocks,
                       embedding_dim=hidden_units,
                       attention_dim=hidden_units,
                       attention_num_heads=num_heads,
                       dropout_rate=dropout_rate,
                       conv_dims=[100, 100],
                       l2_reg=l2_emb,
                       num_neg_test=num_neg_test
        )
    elif model_name == "ssept":
        model = SSEPT(item_num=data.itemnum,
                      user_num=data.usernum,
                      seq_max_len=maxlen,
                      num_blocks=num_blocks,
                      user_embedding_dim=10,
                      item_embedding_dim=hidden_units,
                      attention_dim=hidden_units,
                      attention_num_heads=num_heads,
                      dropout_rate=dropout_rate,
                      conv_dims=[110, 110],
                      l2_reg=l2_emb,
                      num_neg_test=num_neg_test
        )
    else:
        print(f"Model-{model_name} not found")

    采样器

    采样器用于在每个批次中从训练数据中创建负样本:

    sampler = WarpSampler(data.user_train, data.usernum, data.itemnum, batch_size=batch_size, maxlen=maxlen, n_workers=3)

    训练步骤

    定义损失函数并进行模型训练:

    with Timer() as train_time:
        t_test = model.train(data, sampler, num_epochs=num_epochs, batch_size=batch_size, lr=lr, val_epoch=6)
    
    print('Time cost for training is {0:.2f} mins'.format(train_time.interval/60.0))

    评估结果

    训练完成后,评估模型在测试集上的性能:

    res_syn = {"ndcg@10": t_test[0], "Hit@10": t_test[1]}
    print(res_syn)

    结论

    通过在亚马逊数据集上的实验,我们看到SASRec模型在推荐任务中表现出色。其基于自注意力机制的设计,使其能够有效地捕捉用户行为序列中的复杂模式,从而提高推荐准确性。未来,可以通过结合更多数据和优化算法,进一步提升模型性能。

    参考文献

    1. Wang-Cheng Kang, Julian McAuley: Self-Attentive Sequential Recommendation, arXiv preprint arXiv:1808.09781 (2018)
    2. Ashish Vaswani, et al. Attention is all you need. In Advances in Neural Information Processing Systems.
    3. Jiaxi Tang, Ke Wang. Personalized top-n sequential recommendation via convolutional sequence embedding.
    4. Kyunghyun Cho, et al. Learning Phrase Representations using RNN Encoder-Decoder for Statistical Machine Translation.
    5. Zeping Yu, et al. Adaptive User Modeling with Long and Short-Term Preferences for Personalized Recommendation.
    6. Liwei Wu, et al. SSE-PT: Sequential Recommendation Via Personalized Transformer.
  • 揭秘AI写作背后的数学:大型语言模型如何计算误差?

    在这个AI快速发展的时代,ChatGPT等大型语言模型(LLMs)的出现让许多人惊叹不已。这些模型似乎能够理解我们的指令,生成连贯的文本,甚至创作诗歌和故事。但你是否曾想过,这些模型是如何学习和改进的?今天,让我们一起揭开AI写作背后的数学秘密,探讨大型语言模型是如何计算和减少误差的。

    模型输出:概率的艺术

    想象一下,当你在写一篇文章时,每写下一个词,你的大脑都在预测下一个最合适的词。大型语言模型也是如此工作的。每当模型需要生成下一个词时,它会输出一个概率分布,这个分布包含了词汇表中每个词被选为下一个词的可能性。

    例如,假设模型正在生成一个句子:”今天天气真…”。它可能会给出如下的概率分布:

    • 好: 40%
    • 晴朗: 30%
    • 糟糕: 15%
    • 热: 10%
    • 其他词: 5%

    这个概率分布反映了模型对下一个词的”猜测”。

    真实标签:理想与现实的对比

    在训练过程中,模型需要知道它的”猜测”有多准确。这就需要用到”真实标签”。真实标签是一个叫做”one-hot”编码的向量,它只在实际出现的词的位置标记为1,其他位置都是0。

    继续上面的例子,如果实际的下一个词是”晴朗”,那么真实标签就会是:

    [0, 1, 0, 0, …, 0]

    这个向量在词汇表中”晴朗”对应的位置是1,其他位置都是0。

    损失函数:衡量差距的尺子

    为了量化模型预测与实际情况的差距,我们需要一个衡量标准,这就是损失函数。在语言模型中,最常用的是交叉熵损失(Cross-Entropy Loss)。

    交叉熵损失的数学表达式看起来可能有点复杂:

    $L = -\sum_i y_i \log(P_i)$

    但别被吓到!让我们用通俗的语言来解释它:

    1. 对于每个可能的词,我们将模型预测的概率取对数。
    2. 然后,我们只关注实际出现的词(即真实标签中为1的那个位置)。
    3. 我们取这个概率的负对数值作为损失。

    为什么要用对数?这是因为对数能够将乘法转化为加法,使计算更加方便,同时也能够处理非常小的概率值。

    在我们的例子中,如果”晴朗”是正确的下一个词,而模型给它的预测概率是30%(0.3),那么损失就是:

    $L = -\log(0.3) \approx 1.2$

    损失越小,表示模型的预测越准确。

    批量处理:提高效率的秘诀

    在实际训练中,为了提高效率,模型通常不会一次只处理一个词,而是处理一批(batch)数据。这时,我们会计算这批数据的平均损失。

    假设我们有一个包含100个词的批次,我们会:

    1. 对每个词计算损失
    2. 将所有损失加起来
    3. 除以100得到平均损失

    这样做不仅能提高计算效率,还能让模型学习更加稳定。

    反向传播:模型学习的核心

    有了损失,模型就知道了自己的预测有多不准确。但知道还不够,它还需要改进。这就是反向传播算法的作用。

    反向传播的过程可以简单理解为:

    1. 计算损失函数关于模型各个参数的梯度(即参数变化对损失的影响)。
    2. 根据这些梯度,微调模型的参数,使得损失变小。

    这个过程就像是模型在不断”调整”自己,以便下次能做出更准确的预测。

    超越文本:多样化的评估方法

    虽然交叉熵损失是训练语言模型的核心指标,但在实际应用中,我们还需要其他方法来全面评估模型的性能。一些常用的指标包括:

    • BLEU(Bilingual Evaluation Understudy):主要用于评估机器翻译的质量。
    • ROUGE(Recall-Oriented Understudy for Gisting Evaluation):常用于评估自动摘要的质量。
    • Perplexity(困惑度):衡量模型对语言的建模能力,值越低越好。

    这些指标从不同角度评估模型的性能,帮助研究人员全面了解模型的优缺点。

    结语:数学与创造力的完美结合

    通过了解大型语言模型如何计算和减少误差,我们可以看到,在看似神奇的AI写作背后,是严谨的数学原理和精巧的算法设计。这种将数学精确性与语言创造力相结合的方法,正是推动AI技术不断进步的动力。

    随着技术的不断发展,未来的语言模型可能会采用更加复杂和高效的误差计算方法。但无论技术如何发展,理解这些基本原理都将帮助我们更好地理解和利用AI技术,在人工智能时代保持竞争力。

    参考文献:

    1. Goodfellow, I., Bengio, Y., & Courville, A. (2016). Deep learning. MIT press.
    2. Jurafsky, D., & Martin, J. H. (2021). Speech and language processing. Pearson.

    深入解析大型语言模型的计算误差:从概率分布到损失函数

    在人工智能和自然语言处理领域,大型语言模型(如 GPT 系列)已经成为了研究和应用的热点。这些模型能够生成流畅自然的文本,但它们是如何评估和改进自身的表现呢?本文将深入探讨大型语言模型的计算误差机制,从概率分布到损失函数,一步步揭示其中的奥秘。

    模型输出:概率分布的魔力

    大型语言模型的核心任务是预测下一个词。想象一下,当你开始写一个句子”今天天气真…”,模型会根据已有的上下文,为每个可能的后续词赋予一个概率。这个概率分布就是模型的输出。

    例如,模型可能会给出如下的概率分布:

    • “好”:0.6
    • “糟糕”:0.2
    • “晴朗”:0.15
    • 其他词:0.05

    这个分布反映了模型对下一个词的预测信心。

    真实标签:One-Hot 编码的精确表示

    在训练过程中,模型需要知道实际出现的词是什么。这就是”真实标签”的作用。真实标签通常采用”one-hot”编码,这是一种只有一个位置为 1,其余全为 0 的向量。

    假设词汇表有 10000 个词,如果实际的下一个词是”好”,且”好”在词汇表中的索引是 42,那么真实标签就是一个长度为 10000 的向量,其中第 42 个位置为 1,其余均为 0。

    损失函数:交叉熵损失的应用

    为了衡量模型预测与实际情况的差距,我们需要一个损失函数。在语言模型中,最常用的是交叉熵损失(Cross-Entropy Loss)。

    交叉熵损失的数学表达式如下:

    ![L = -\sum_i y_i \log(P_i)][]

    其中,![y_i][] 是真实标签中的值(0 或 1),![P_i][] 是模型预测的概率。

    由于真实标签是 one-hot 编码,上述公式可以简化为:![L = -\log(P_y)][]

    其中,![P_y][] 是模型对实际出现的词的预测概率。

    计算步骤:从理论到实践

    让我们通过一个具体例子来理解这个过程:

    1. 假设模型预测”好”的概率为 0.6。
    2. 实际上,下一个词确实是”好”。
    3. 那么,损失值为:![L = -\log(0.6) \approx 0.51][]

    这个损失值告诉我们,虽然模型的预测方向是对的,但还有改进的空间。损失值越小,表示模型的预测越准确。

    批量处理:提高效率的关键

    在实际训练中,我们通常不会对每个词单独计算损失,而是采用批量处理的方法。假设我们有一个包含 64 个样本的批次,我们会计算这 64 个样本的平均损失:![L_{batch} = \frac{1}{64} \sum_{i=1}^{64} L_i][]

    这种方法不仅提高了计算效率,还能使损失值更加稳定。

    反向传播:模型优化的核心

    计算出损失后,下一步就是通过反向传播来优化模型参数。这个过程包括:

    1. 计算损失函数关于模型各个参数的梯度。
    2. 使用优化算法(如随机梯度下降)更新参数。
    3. 重复这个过程,直到模型性能达到预期或停止改善。

    通过这种方式,模型能够逐步减少预测误差,提高生成文本的质量。

    结语:超越单词预测虽然我们主要讨论了单词预测的误差计算,但大型语言模型的应用远不止于此。在实际应用中,我们还需要考虑模型在各种自然语言处理任务中的表现,如文本生成、理解等。

    为此,研究者们开发了多种评估指标,如 BLEU(用于机器翻译)、ROUGE(用于文本摘要)和 Perplexity(困惑度,用于评估语言模型的泛化能力)等。这些指标从不同角度衡量模型的性能,为进一步改进模型提供了方向。

    通过深入理解大型语言模型的计算误差机制,我们不仅能够更好地优化现有模型,还能为开发下一代更强大的语言模型奠定基础。随着技术的不断进步,我们期待看到更多令人惊叹的自然语言处理应用,为人类的沟通和知识获取带来革命性的变化。

    参考文献

    1. Goodfellow, I., Bengio, Y., & Courville, A. (2016). Deep Learning. MIT Press.
    2. Vaswani, A., et al. (2017). Attention Is All You Need. Advances in Neural Information Processing Systems.
    3. Brown, T. B., et al. (2020). Language Models are Few-Shot Learners. arXiv preprint arXiv:2005.14165.
  • Suri: 多约束指令遵循的长文本生成新突破

    在人工智能和自然语言处理领域,如何让大型语言模型(LLM)更好地遵循复杂指令并生成高质量长文本,一直是一个重要而富有挑战性的研究方向。近日,来自马萨诸塞大学阿默斯特分校的研究团队在这一领域取得了重要突破,他们提出了一种名为Suri的新数据集和训练方法,显著提升了LLM在多约束条件下生成长文本的能力。本文将详细介绍这项研究的主要内容、创新点及其潜在影响。

    研究背景与动机

    现有的指令遵循研究主要集中在简单指令和短回复任务上。然而,在实际应用中,用户往往需要LLM能够遵循包含多个复杂约束的指令,并生成长篇幅、高质量的文本输出,如详细的技术报告或引人入胜的小说。

    为了探索这一挑战,研究团队开展了首个针对多约束指令下长文本生成的深入研究。他们创建了Suri数据集,并提出了一种名为I-ORPO的新型对齐方法,以提升LLM在这类任务中的表现。

    Suri数据集的构建

    Suri数据集是该研究的核心基础。它包含20,000个配对样本,每个样本由以下三部分组成:

    1. 人工撰写的长文本响应(y): 从ChapterBreak、Books3和RedPajama-Data-v2等现有数据集中采样,长度在2,048到5,024个单词之间。
    2. 反向翻译指令(xw): 使用GPT-4-turbo模型,将人工撰写的文本反向生成相应的指令。每个指令包含一个主要目标和约10个语义和风格约束。
    3. corrupted指令(xl): 通过对xw中的约束进行最小化编辑,生成部分违反原始约束但仍忠实于整体主要目标的corrupted指令。

    研究团队采用了多项措施来确保数据集的质量和多样性:

    • 对采样的文本进行了清洗和过滤,去除无关元数据。
    • 人工评估验证了反向翻译指令与原始文本的一致性,约87%的约束被完全满足。
    • 分析了指令中约束的类型分布,确保了语义、风格、广泛和具体约束的平衡。

    I-ORPO: 创新的对齐方法

    研究团队提出了Instructional Odds Ratio Preference Optimization (I-ORPO)方法,这是对ORPO算法的改进和适应。I-ORPO的主要创新点在于:

    1. 利用corrupted指令(xl)作为负面反馈,避免了为长文本获取人工偏好判断的困难。
    2. 修改了ORPO的损失函数,使模型学习区分正确指令和corrupted指令: $L_{I-ORPO} = E_{(x_w,x_l,y)}[L_{SFT} + \lambda \cdot L_{I-OR}]$ 其中, $L_{I-OR} = – \log \sigma \left(\log \frac{odds_\theta(y|x_w)}{odds_\theta(y|x_l)}\right)$
    3. 通过观察训练曲线,验证了模型成功学习到了正确指令和corrupted指令之间的差异。

    实验结果与评估

    研究团队使用Suri数据集对Mistral-7B-Instruct-v0.2模型进行了微调,得到了Suri-I-ORPO和Suri-SFT两个模型版本。主要评估结果包括:

    1. 生成长度: Suri-I-ORPO和Suri-SFT能生成平均约5,000个token的长文本,远超基线模型的1,100-1,500个token。
    2. 重复度: 尽管生成长度显著增加,但微调后的模型并未出现严重的重复内容问题。
    3. 指令区分能力: Suri-I-ORPO在区分正确指令和corrupted指令方面表现优异,比基线模型提高了至少10%。
    4. 人工评估: 评估者注意到,微调后的模型能有效遵循给定约束,其中I-ORPO模型在约束的连贯、信息丰富和引人入胜的整合方面更受青睐。

    研究意义与展望

    这项研究的重要性主要体现在以下几个方面:

    1. 首次系统研究了多约束指令下的长文本生成问题,填补了现有研究的空白。
    2. 提出了Suri数据集,为后续相关研究提供了宝贵资源。
    3. 开发了I-ORPO方法,为长文本生成任务中的模型对齐提供了新思路。
    4. 显著提升了LLM在长文本生成和复杂指令遵循方面的能力,为实际应用提供了新的可能性。

    未来研究可以进一步探索:

    • 扩大Suri数据集的规模和多样性
    • 改进I-ORPO方法,提高其在更大规模模型上的效果
    • 将Suri和I-ORPO应用于更多领域和任务类型

    总之,这项研究为提升LLM在复杂指令下生成高质量长文本的能力开辟了新的道路,有望推动自然语言生成技术在创意写作、技术文档撰写等领域的应用和发展。

    参考文献

    1. Pham, C. M., Sun, S., & Iyyer, M. (2024). Suri: Multi-constraint Instruction Following for Long-form Text Generation. arXiv:2406.19371v1.
    2. Hong, J., et al. (2024). Odds Ratio Preference Optimization.
    3. Li, X., et al. (2023). Instruction Backtranslation for Large Language Models.

    长文本指令遵循:Suri 数据集与 I-ORPO 算法

    近年来,大型语言模型(LLM)在指令遵循方面取得了显著进展,但现有研究主要集中在简单指令和短文本生成任务上。对于包含复杂多约束指令的长文本生成任务,LLM 仍面临挑战。本文将介绍一种名为 Suri 的新数据集,以及一种基于 ORPO 算法的指令对齐方法 I-ORPO,旨在提升 LLM 在长文本指令遵循方面的能力。

    Suri 数据集:长文本指令遵循的基石

    Suri 数据集包含 20,000 个长文本,每个文本都配有一条由 LLM 生成的包含多个复杂约束的指令。这些指令涵盖了语义和风格方面的约束,例如:

    • 语义约束: 描述一个支持母亲和缺席父亲的家庭;
    • 风格约束: 使用短句强调语气;
    • 混合约束: 以热情的语气讨论印象派艺术。

    Suri 数据集的构建利用了指令反向翻译技术,即使用 LLM 将人类撰写的长文本(例如小说章节)转化为相应的指令。为了训练模型区分正确指令和错误指令,Suri 数据集还包含了由 LLM 生成的错误指令,这些指令对原始指令中的约束进行了微调,使其部分违反,但仍然与指令的总体目标保持一致。

    I-ORPO 算法:利用合成错误指令进行模型对齐

    由于对长文本进行人工偏好标注的难度和成本很高,传统的偏好调整算法(如 DPO)并不适用于 Suri 数据集。为此,本文提出了指令 ORPO(I-ORPO) 算法。I-ORPO 算法利用合成错误指令作为负反馈,而不是依赖人类对不同文本的偏好判断。

    I-ORPO 算法将原始指令和错误指令分别作为正负样本,并利用 Odds Ratio Preference Optimization(ORPO)目标函数进行模型训练。模型学习将正确指令与错误指令区分开来,从而提升其对指令的敏感度,并生成更符合指令要求的文本。

    实验结果:Suri 数据集与 I-ORPO 算法的有效性

    本文对 Mistral-7b-Instruct-v0.2 模型进行了监督微调和 I-ORPO 微调,分别得到 Suri-SFT 和 Suri-I-ORPO 模型。实验结果表明:

    • Suri-SFT 和 Suri-I-ORPO 模型生成的文本长度显著增加,平均长度超过 5,000 个词元,远超基线模型。
    • Suri-I-ORPO 模型在区分正确指令和错误指令方面表现出色,其排名准确率比基线模型高出至少 10%。
    • Suri-I-ORPO 模型生成的文本在语义连贯性和信息量方面优于 Suri-SFT 模型,人类评估结果表明,Suri-I-ORPO 模型生成的文本更易读、更有趣。

    结论与展望

    Suri 数据集和 I-ORPO 算法为长文本指令遵循任务提供了新的解决方案。实验结果表明,Suri 数据集能够有效提升 LLM 在长文本指令遵循方面的能力,而 I-ORPO 算法则为模型对齐提供了新的思路。

    未来研究方向包括:

    • 将 Suri 数据集和 I-ORPO 算法应用于其他 LLM 模型。
    • 研究指令长度、指令与文本信息重叠程度等因素对 I-ORPO 算法性能的影响。
    • 探索 Suri 数据集和 I-ORPO 算法在短文本生成任务上的应用。

    参考文献

    • Pham, C. M., Sun, S., & Iyyer, M. (2024). Suri: Multi-constraint Instruction Following for Long-form Text Generation. arXiv preprint arXiv:2406.19371.

    Suri: 开启AI长文本创作新纪元

    在人工智能迅速发展的今天,大型语言模型(LLMs)已经展现出惊人的能力。然而,当面对复杂的多约束指令和长篇幅文本生成任务时,这些模型仍然存在明显的短板。来自马萨诸塞大学阿默斯特分校的研究团队近期发表的论文《Suri: Multi-constraint Instruction Following for Long-form Text Generation》,为解决这一难题提供了创新性的解决方案。

    突破性贡献

    这项研究的主要贡献可以概括为三个方面:

    1. Suri数据集: 创建了一个包含20,000篇人类撰写长文本的数据集,每篇文本都配有LLM生成的多约束反向翻译指令。这为研究长文本生成和复杂指令遵循提供了宝贵的资源。
    2. I-ORPO方法: 提出了一种名为指令性优势比偏好优化(I-ORPO)的新型对齐方法。该方法巧妙地利用合成的指令扰动作为负反馈,解决了长文本生成任务中难以获得人类偏好判断的问题。
    3. 高性能模型: 通过对Mistral7b-Instruct-v0.2模型进行微调,得到了能够生成约5,000个token长度文本的Suri-SFT和Suri-I-ORPO模型,大幅提升了模型在长文本生成和多约束指令遵循方面的能力。

    方法创新与实验设计

    研究团队的方法设计和实验安排都体现了深思熟虑:

    1. 数据集构建: 通过反向翻译技术,从人类撰写的长文本中提取复杂指令,确保了数据的真实性和多样性。
    2. I-ORPO算法: 通过比较模型在正确指令和扰动指令下生成文本的概率,引导模型更好地遵循复杂指令。这一方法有效规避了长文本人工评估的巨大成本。
    3. 多维度评估: 研究采用了自动评估和人工评估相结合的方式,从文本长度、重复率、指令遵循度等多个角度全面评估模型性能。

    关键发现与启示

    这项研究的结果令人振奮:

    1. 长文本生成突破: Suri-SFT和Suri-I-ORPO模型能够生成平均长度约5,000个token的文本,远超基线模型的1,100-1,500个token,且没有出现明显的质量下降。
    2. 指令遵循能力提升: 微调后的模型在遵循复杂指令方面表现出色,Suri-I-ORPO在约束的连贯整合和信息丰富度方面尤为突出。
    3. LLM评估局限性: 研究发现,在评估长文本生成任务时,即使是先进的LLM(如GPT-4)也存在一定局限性,这为未来的评估方法研究提供了重要启示。

    未来研究方向

    这项研究为AI长文本创作开辟了新的可能性,同时也指明了几个值得进一步探索的方向:

    1. 将Suri数据集和I-ORPO方法应用于其他大型语言模型,探索其泛化能力。
    2. 研究表面特征(如指令长度、信息重叠度)对I-ORPO性能的影响。
    3. 探索模型在不同长度要求任务中的表现,提高其灵活性。
    4. 改进评估指标,更全面地衡量长文本生成的质量。
    5. 深入研究长文本生成技术的伦理影响和社会责任。

    结语

    Suri项目的成功,标志着AI在长文本创作和复杂指令遵循方面迈出了重要一步。这不仅为学术研究提供了新的思路和工具,也为AI在创意写作、技术文档撰写等领域的实际应用铺平了道路。随着技术的进一步发展和完善,我们有理由期待AI在不久的将来能够成为人类在长篇创作中的得力助手,为内容创作带来新的革命。

  • SAR算法在MovieLens数据集上的应用

    推荐系统是现代互联网应用中不可或缺的一部分。无论是电子商务、社交媒体还是内容平台,都在使用各种推荐算法来为用户提供个性化的体验。今天,我们将深入探讨一种简单而有效的推荐算法——简单算法推荐(Simple Algorithm for Recommendation, SAR),并通过在著名的MovieLens数据集上的实践来展示其应用。

    SAR算法简介

    SAR是一种基于用户交互历史的快速、可扩展的个性化推荐算法。它的主要特点包括:

    1. 生成易于解释和理解的推荐结果
    2. 能够处理”冷启动物品”和”半冷启动用户”的场景
    3. 属于基于邻域的算法,旨在为每个用户推荐最合适的物品

    SAR的核心思想是推荐与用户已有偏好相似的物品。这里的”相似”指的是:如果用户与物品A交互,那么他们也很可能与物品B交互;而”偏好”则指用户在过去与某个物品有过交互。

    SAR的优势

    1. 高准确度:虽然算法简单,但能达到很好的推荐效果
    2. 训练速度快:只需要进行简单的计数就可以构建预测时使用的矩阵
    3. 预测速度快:预测过程仅涉及相似度矩阵与偏好向量的乘法运算

    SAR的使用注意事项

    1. 由于不使用物品或用户特征,在某些场景下可能不如使用这些特征的算法
    2. 内存消耗大:需要创建一个m×m的稀疏方阵(m为物品数量)
    3. SAR更适合隐式评分场景,不适合预测具体评分值

    数据准备

    我们使用MovieLens数据集来演示SAR算法的应用。MovieLens是一个包含用户对电影评分的数据集,非常适合用来测试推荐算法。

    首先,我们加载所需的库和数据:

    import sys
    import logging
    import numpy as np
    import pandas as pd
    from recommenders.datasets import movielens
    from recommenders.models.sar import SAR
    from recommenders.datasets.python_splitters import python_stratified_split
    
    # 加载MovieLens 100k数据集
    data = movielens.load_pandas_df(size="100k")
    data["rating"] = data["rating"].astype(np.float32)

    接下来,我们将数据集分为训练集和测试集:

    train, test = python_stratified_split(data, ratio=0.75, col_user="userID", col_item="itemID", seed=42)

    这里我们使用了分层抽样的方法,保证每个用户的75%评分进入训练集,25%进入测试集。

    模型训练与预测

    现在,我们可以开始训练SAR模型了:

    model = SAR(
        col_user="userID",
        col_item="itemID",
        col_rating="rating",
        col_timestamp="timestamp",
        similarity_type="jaccard",
        time_decay_coefficient=30,
        timedecay_formula=True,
        normalize=True
    )
    
    model.fit(train)

    在这个过程中,SAR会计算物品之间的共现矩阵,然后基于Jaccard相似度计算物品相似度矩阵。同时,它还会计算用户-物品亲和度矩阵,捕捉用户与物品之间关系的强度。

    训练完成后,我们可以为测试集中的用户生成Top-K推荐:

    TOP_K = 10
    top_k = model.recommend_k_items(test, top_k=TOP_K, remove_seen=True)

    模型评估

    为了评估SAR的性能,我们使用了几个常见的排序指标:

    1. 平均精度均值(MAP)
    2. 归一化折损累积增益(NDCG)
    3. 准确率(Precision)
    4. 召回率(Recall)

    同时,我们还计算了一些评分指标:

    1. 均方根误差(RMSE)
    2. 平均绝对误差(MAE)
    3. R方(R-squared)
    4. 可解释方差(Explained Variance)
    eval_map = map(test, top_k, col_user="userID", col_item="itemID", col_rating="rating", k=TOP_K)
    eval_ndcg = ndcg_at_k(test, top_k, col_user="userID", col_item="itemID", col_rating="rating", k=TOP_K)
    eval_precision = precision_at_k(test, top_k, col_user="userID", col_item="itemID", col_rating="rating", k=TOP_K)
    eval_recall = recall_at_k(test, top_k, col_user="userID", col_item="itemID", col_rating="rating", k=TOP_K)
    
    eval_rmse = rmse(test, top_k, col_user="userID", col_item="itemID", col_rating="rating")
    eval_mae = mae(test, top_k, col_user="userID", col_item="itemID", col_rating="rating")
    eval_rsquared = rsquared(test, top_k, col_user="userID", col_item="itemID", col_rating="rating")
    eval_exp_var = exp_var(test, top_k, col_user="userID", col_item="itemID", col_rating="rating")

    这些指标能够全面地评估SAR算法在MovieLens数据集上的表现。

    结论

    通过在MovieLens数据集上的实验,我们展示了SAR算法的实际应用。SAR作为一种简单而有效的推荐算法,在许多场景下都能取得不错的效果。它的快速训练和预测特性使其特别适合需要实时推荐的应用场景。

    然而,SAR也有其局限性。例如,它不能利用物品或用户的特征信息,这在某些场景下可能会限制其性能。此外,对于大规模数据集,其内存消耗可能会成为一个挑战。

    总的来说,SAR是推荐系统工具箱中的一个有力工具。在实际应用中,我们需要根据具体的业务需求和数据特征,选择适合的算法或者多种算法的组合。

    参考文献

    1. Recommenders contributors. (2023). SAR Single Node on MovieLens (Python, CPU). GitHub. https://github.com/recommenders-team/recommenders/blob/main/examples/00_quick_start/sar_movielens.ipynb
    2. Aggarwal, C. C. (2016). Recommender Systems: The Textbook. Springer International Publishing.
    3. Harper, F. M., & Konstan, J. A. (2015). The MovieLens Datasets: History and Context. ACM Transactions on Interactive Intelligent

    这篇文章将介绍如何使用简单算法推荐(SAR)模型对MovieLens数据集进行协同过滤推荐。SAR是一种基于用户交互历史的快速可扩展的个性化推荐算法,具有易于解释和处理冷启动问题的优势。让我们一步步来看SAR模型的实现过程。

    1. 数据准备

    首先,我们加载MovieLens数据集并进行预处理:

    data = movielens.load_pandas_df(size="100k")
    data["rating"] = data["rating"].astype(np.float32)

    这里我们使用了MovieLens 100k数据集,包含10万条用户对电影的评分记录。

    接下来,我们将数据集分为训练集和测试集:

    train, test = python_stratified_split(data, ratio=0.75, col_user="userID", col_item="itemID", seed=42)

    我们使用了分层抽样的方法,保留75%的数据作为训练集,25%作为测试集。这种分割方法可以确保每个用户在训练集和测试集中都有数据。

    2. SAR模型训练

    SAR模型的核心思想是基于用户的历史交互来推荐相似的物品。我们首先实例化SAR模型:

    model = SAR(
        col_user="userID",
        col_item="itemID",
        col_rating="rating",
        col_timestamp="timestamp",
        similarity_type="jaccard",
        time_decay_coefficient=30,
        timedecay_formula=True,
        normalize=True
    )

    这里我们使用了Jaccard相似度,并启用了时间衰减和归一化。

    然后我们开始训练模型:

    model.fit(train)

    SAR模型的训练过程主要包括以下步骤:

    1. 计算物品共现矩阵
    2. 基于共现矩阵计算物品相似度矩阵
    3. 计算用户-物品亲和度矩阵

    训练完成后,我们可以为测试集中的用户生成Top-K推荐:

    top_k = model.recommend_k_items(test, top_k=TOP_K, remove_seen=True)

    3. 模型评估

    为了评估SAR模型的性能,我们使用了多个常用的推荐系统评估指标:

    eval_map = map(test, top_k, col_user="userID", col_item="itemID", col_rating="rating", k=TOP_K)
    eval_ndcg = ndcg_at_k(test, top_k, col_user="userID", col_item="itemID", col_rating="rating", k=TOP_K)
    eval_precision = precision_at_k(test, top_k, col_user="userID", col_item="itemID", col_rating="rating", k=TOP_K)
    eval_recall = recall_at_k(test, top_k, col_user="userID", col_item="itemID", col_rating="rating", k=TOP_K)

    这些指标包括平均精度均值(MAP)、归一化折损累积增益(NDCG)、精确率和召回率。

    此外,我们还计算了一些评分预测相关的指标:

    eval_rmse = rmse(test, top_k, col_user="userID", col_item="itemID", col_rating="rating")
    eval_mae = mae(test, top_k, col_user="userID", col_item="itemID", col_rating="rating")
    eval_rsquared = rsquared(test, top_k, col_user="userID", col_item="itemID", col_rating="rating")
    eval_exp_var = exp_var(test, top_k, col_user="userID", col_item="itemID", col_rating="rating")

    这些指标包括均方根误差(RMSE)、平均绝对误差(MAE)、R方和解释方差。

    4. 结果分析

    在MovieLens 100k数据集上,SAR模型的表现如下:

    • MAP: 0.106959
    • NDCG: 0.379533
    • Precision@K: 0.331071
    • Recall@K: 0.176837
    • RMSE: 1.229246
    • MAE: 1.033912

    这些结果表明,SAR模型在推荐相关性和排序质量方面表现不错,但在评分预测方面还有提升空间。

    我们还可以查看特定用户的推荐结果:

    user_id = 54
    ground_truth = test[test["userID"] == user_id].sort_values(by="rating", ascending=False)[:TOP_K]
    prediction = model.recommend_k_items(pd.DataFrame(dict(userID=[user_id])), remove_seen=True)
    df = pd.merge(ground_truth, prediction, on=["userID", "itemID"], how="left")

    这让我们能够直观地比较模型的推荐结果和用户的实际偏好。

    5. 总结与展望

    SAR模型作为一种简单高效的协同过滤算法,在MovieLens数据集上展现了不错的性能。它的优势在于:

    1. 训练和预测速度快
    2. 可解释性强
    3. 能够处理冷启动问题

    然而,SAR模型也存在一些局限性:

    1. 不使用用户和物品特征,可能在某些场景下处于劣势
    2. 对于大规模数据集,内存消耗较大

    未来的改进方向可以包括:

    1. 结合内容特征,构建混合推荐系统
    2. 使用更高级的相似度计算方法
    3. 探索模型集成,如将SAR与矩阵分解方法结合

    总的来说,SAR模型为协同过滤推荐系统提供了一个简单而有效的baseline,值得在实际应用中尝试和优化。


    简单算法推荐 (SAR) 在 MovieLens 数据集上的应用

    简单算法推荐 (SAR) 是一种快速且可扩展的个性化推荐算法,它基于用户交易历史进行推荐。SAR 生成的推荐易于解释和理解,并能处理“冷启动物品”和“半冷启动用户”场景。SAR 属于一种基于邻域的算法,如 Aggarwal 的推荐系统 中所述,旨在为每个用户排名最顶级的物品。有关 SAR 的更多详细信息,请参阅 深入研究笔记本

    SAR 推荐与用户已有 亲和力 的物品最 相似 的物品。如果与一个物品交互的用户也可能与另一个物品交互,则这两个物品是 相似 的。如果用户过去与某个物品交互过,则该用户对该物品具有 亲和力

    SAR 的优势:

    • 对于易于训练和部署的算法,具有很高的准确性。
    • 快速训练,只需要简单的计数来构建预测时使用的矩阵。
    • 快速评分,只需要将相似度矩阵与亲和度向量相乘。

    正确使用 SAR 的注意事项:

    • 由于它不使用物品或用户特征,因此在与使用特征的算法相比可能处于劣势。
    • 它需要大量的内存,需要创建一个 $mxm$ 的稀疏方阵(其中 $m$ 是物品的数量)。这对于许多矩阵分解算法来说也是一个问题。
    • SAR 倾向于隐式评分场景,它不预测评分。

    本篇文章将以 Python 在 CPU 上为例,展示如何使用和评估 SAR。

    1. 加载数据

    SAR 旨在用于以下模式的交互:<用户 ID>, <物品 ID>,<时间>,[<事件类型>], [<事件权重>]

    每行代表用户和物品之间的一次交互。这些交互可能是电子商务网站上不同类型的事件,例如用户点击查看物品、将物品添加到购物车、点击推荐链接等等。每个事件类型可以分配不同的权重,例如,我们可以将“购买”事件的权重分配为 10,而“查看”事件的权重可能只有 1。

    MovieLens 数据集格式良好,包含用户对电影的评分(电影评分用作事件权重)——我们将使用它作为本篇文章的示例。

    1.1 下载并使用 MovieLens 数据集

    # top k 个推荐的物品
    TOP_K = 10
    
    # 选择 MovieLens 数据集大小:100k、1m、10m 或 20m
    MOVIELENS_DATA_SIZE = "100k"
    
    # 下载并加载 MovieLens 数据集
    data = movielens.load_pandas_df(
        size=MOVIELENS_DATA_SIZE
    )
    
    # 将浮点精度转换为 32 位以减少内存消耗
    data["rating"] = data["rating"].astype(np.float32)

    1.2 使用实用程序提供的 Python 随机拆分器拆分数据

    我们将完整数据集拆分为 traintest 数据集,以评估算法在训练期间未见过的保留集上的性能。由于 SAR 根据用户偏好生成推荐,因此测试集中所有用户也必须存在于训练集中。在这种情况下,我们可以使用提供的 python_stratified_split 函数,该函数从每个用户中保留一定比例(在本例中为 25%)的物品,但确保所有用户都存在于 traintest 数据集中。dataset.python_splitters 模块中提供了其他选项,可以更详细地控制拆分方式。

    train, test = python_stratified_split(data, ratio=0.75, col_user="userID", col_item="itemID", seed=42)

    2. 训练 SAR 模型

    2.1 实例化 SAR 算法并设置索引

    我们将使用 SAR 的单节点实现,并指定列名以匹配我们的数据集(时间戳是一个可选列,如果您的数据集不包含它,可以删除)。

    其他选项用于控制算法的行为,如 深入研究笔记本 中所述。

    logging.basicConfig(level=logging.DEBUG,
                        format='%(asctime)s %(levelname)-8s %(message)s')
    
    model = SAR(
        col_user="userID",
        col_item="itemID",
        col_rating="rating",
        col_timestamp="timestamp",
        similarity_type="jaccard",
        time_decay_coefficient=30,
        timedecay_formula=True,
        normalize=True
    )

    2.2 在我们的训练数据上训练 SAR 模型,并为我们的测试数据获取 top-k 推荐

    SAR 首先计算一个物品到物品的 共现矩阵。共现表示两个物品在任何给定用户中同时出现的次数。一旦我们有了共现矩阵,我们就可以通过给定指标(本例中为 Jaccard 相似度)重新缩放共现来计算 物品相似度矩阵

    我们还计算一个 亲和度矩阵 来捕获每个用户与每个物品之间关系的强度。亲和度由不同的类型(如 评分观看 电影)以及事件发生的时间驱动。

    推荐是通过将亲和度矩阵 $A$ 与相似度矩阵 $S$ 相乘来实现的。结果是一个 推荐评分矩阵 $R$。我们在下面看到的 recommend_k_items 函数中计算了 test 数据集中每个用户的 top-k 结果。

    SAR 算法的完整演练可以在这里找到 here

    with Timer() as train_time:
        model.fit(train)
    
    print("Took {} seconds for training.".format(train_time.interval))
    
    with Timer() as test_time:
        top_k = model.recommend_k_items(test, top_k=TOP_K, remove_seen=True)
    
    print("Took {} seconds for prediction.".format(test_time.interval))

    2.3 评估 SAR 的性能

    我们评估 SAR 在 python_evaluation 模块中提供的几个常见排名指标上的性能。我们将考虑平均平均精度 (MAP)、归一化折损累积增益 (NDCG)、精确度和召回率,这些指标是针对我们使用 SAR 计算的每个用户的 top-k 物品。用户、物品和评分列名在每个评估方法中都已指定。

    # 排名指标
    eval_map = map(test, top_k, col_user="userID", col_item="itemID", col_rating="rating", k=TOP_K)
    eval_ndcg = ndcg_at_k(test, top_k, col_user="userID", col_item="itemID", col_rating="rating", k=TOP_K)
    eval_precision = precision_at_k(test, top_k, col_user="userID", col_item="itemID", col_rating="rating", k=TOP_K)
    eval_recall = recall_at_k(test, top_k, col_user="userID", col_item="itemID", col_rating="rating", k=TOP_K)
    
    # 评分指标
    eval_rmse = rmse(test, top_k, col_user="userID", col_item="itemID", col_rating="rating")
    eval_mae = mae(test, top_k, col_user="userID", col_item="itemID", col_rating="rating")
    eval_rsquared = rsquared(test, top_k, col_user="userID", col_item="itemID", col_rating="rating")
    eval_exp_var = exp_var(test, top_k, col_user="userID", col_item="itemID", col_rating="rating")
    
    positivity_threshold = 2
    test_bin = test.copy()
    test_bin["rating"] = binarize(test_bin["rating"], positivity_threshold)
    
    top_k_prob = top_k.copy()
    top_k_prob["prediction"] = minmax_scale(top_k_prob["prediction"].astype(float))
    
    eval_logloss = logloss(
        test_bin, top_k_prob, col_user="userID", col_item="itemID", col_rating="rating"
    )
    print("Model:\t",
          "Top K:\t%d" % TOP_K,
          "MAP:\t%f" % eval_map,
          "NDCG:\t%f" % eval_ndcg,
          "Precision@K:\t%f" % eval_precision,
          "Recall@K:\t%f" % eval_recall,
          "RMSE:\t%f" % eval_rmse,
          "MAE:\t%f" % eval_mae,
          "R2:\t%f" % eval_rsquared,
          "Exp var:\t%f" % eval_exp_var,
          "Logloss:\t%f" % eval_logloss,
          sep='\n')
    # 现在让我们看看特定用户的结果
    user_id = 54
    
    ground_truth = test[test["userID"] == user_id].sort_values(
        by="rating", ascending=False
    )[:TOP_K]
    prediction = model.recommend_k_items(
        pd.DataFrame(dict(userID=[user_id])), remove_seen=True
    )
    df = pd.merge(ground_truth, prediction, on=["userID", "itemID"], how="left")
    df.head(10)

    上面,我们看到测试集中评分最高的物品之一被模型的 top-k 推荐所恢复,但其他物品则没有。离线评估很困难,因为它们只能使用测试集中以前看到的内容,可能无法代表用户在整个物品集中的实际偏好。对数据拆分方式、算法使用方式和超参数的调整可以改善这里的结果。

    参考文献

    希望这篇文章能帮助您更好地理解 SAR 算法及其在 MovieLens 数据集上的应用。

    recommenders/examples/00_quick_start/sar_movielens.ipynb at main · recommenders-team/recommenders · GitHub