博客

  • MetaGPT 智能体 101:打造你的第一个 AI 智能体

    本教程将带你从零开始,一步步打造你的第一个 MetaGPT 智能体。通过本教程,你将学会:

    • 使用现成的智能体
    • 开发一个可以执行一个或多个动作的智能体

    使用现成的智能体

    MetaGPT 提供了许多现成的智能体,你可以直接导入并使用。例如,以下代码展示了如何使用 ProductManager 智能体来编写一个产品需求文档 (PRD):

    import asyncio
    
    from metagpt.context import Context
    from metagpt.roles.product_manager import ProductManager
    from metagpt.logs import logger
    
    async def main():
        msg = "Write a PRD for a snake game"
        context = Context()  # 创建会话上下文对象
        role = ProductManager(context=context)  # 初始化智能体
        while msg:
            msg = await role.run(msg)  # 运行智能体
            logger.info(str(msg))
    
    if __name__ == '__main__':
        asyncio.run(main())

    这段代码首先导入必要的模块,然后定义一个 main 函数。在 main 函数中,我们创建了一个会话上下文对象 context,并使用 ProductManager 类初始化一个智能体 role。最后,我们使用 role.run() 方法运行智能体,并打印输出结果。

    开发你的第一个智能体

    从实际应用的角度来看,一个有用的智能体需要能够执行某些动作。MetaGPT 提供了高度灵活的方式来定义自己的动作和智能体。

    1. 定义动作

    在 MetaGPT 中,Action 类是动作的抽象表示。你可以使用 LLM 来增强 Action,只需调用 self._aask 函数即可。

    例如,我们想创建一个名为 SimpleWriteCode 的动作,用于根据自然语言描述编写 Python 代码:

    import re
    from metagpt.actions import Action
    
    class SimpleWriteCode(Action):
        PROMPT_TEMPLATE: str = """
        Write a python function that can {instruction} and provide two runnnable test cases.
        Return ```python your_code_here ``` with NO other texts,
        your code:
        """
    
        name: str = "SimpleWriteCode"
    
        async def run(self, instruction: str):
            prompt = self.PROMPT_TEMPLATE.format(instruction=instruction)
            rsp = await self._aask(prompt)
            code_text = SimpleWriteCode.parse_code(rsp)
            return code_text
    
        @staticmethod
        def parse_code(rsp):
            pattern = r"```python(.*)```"
            match = re.search(pattern, rsp, re.DOTALL)
            code_text = match.group(1) if match else rsp
            return code_text

    这段代码定义了一个名为 SimpleWriteCode 的类,它继承自 Action 类。该类包含一个 PROMPT_TEMPLATE 属性,用于定义提示词模板。run 方法接受一个自然语言描述 instruction,并使用提示词模板生成一个提示词,然后调用 _aask 函数向 LLM 发送请求,并返回代码文本。

    2. 定义角色

    在 MetaGPT 中,Role 类是智能体的抽象表示。一个角色可以执行某些动作,拥有记忆,并根据不同的策略进行思考和行动。

    例如,我们想创建一个名为 SimpleCoder 的角色,它可以使用 SimpleWriteCode 动作来编写代码:

    from metagpt.roles import Role
    
    class SimpleCoder(Role):
        name: str = "Alice"
        profile: str = "SimpleCoder"
    
        def __init__(self, **kwargs):
            super().__init__(**kwargs)
            self.set_actions([SimpleWriteCode])
    
        async def _act(self) -> Message:
            logger.info(f"{self._setting}: to do {self.rc.todo}({self.rc.todo.name})")
            todo = self.rc.todo  # 获取当前动作
    
            msg = self.get_memories(k=1)[0]  # 获取最近一条消息
            code_text = await todo.run(msg.content)  # 执行动作
            msg = Message(content=code_text, role=self.profile, cause_by=type(todo))
    
            return msg

    这段代码定义了一个名为 SimpleCoder 的类,它继承自 Role 类。该类包含一个 name 属性和一个 profile 属性,用于定义角色的名称和描述。__init__ 方法用于初始化角色,并使用 set_actions 方法添加 SimpleWriteCode 动作。_act 方法定义了角色的行动逻辑,它会获取最近一条消息,并使用当前动作执行代码编写任务。

    3. 运行你的角色

    现在,你可以初始化你的角色并运行它:

    import asyncio
    
    from metagpt.context import Context
    
    async def main():
        msg = "write a function that calculates the product of a list"
        context = Context()
        role = SimpleCoder(context=context)
        logger.info(msg)
        result = await role.run(msg)
        logger.info(result)
    
    asyncio.run(main())

    这段代码首先定义一个 main 函数,并创建一个会话上下文对象 context。然后,我们使用 SimpleCoder 类初始化一个角色 role。最后,我们使用 role.run() 方法运行角色,并打印输出结果。

    智能体拥有多个动作

    一个智能体可以拥有多个动作,并根据不同的策略来选择执行哪个动作。例如,我们想创建一个名为 RunnableCoder 的角色,它可以编写代码并立即执行:

    1. 定义动作

    除了 SimpleWriteCode 动作,我们还需要定义一个名为 SimpleRunCode 的动作,用于执行代码:

    class SimpleRunCode(Action):
        name: str = "SimpleRunCode"
    
        async def run(self, code_text: str):
            result = subprocess.run(["python3", "-c", code_text], capture_output=True, text=True)
            code_result = result.stdout
            logger.info(f"{code_result=}")
            return code_result

    2. 定义角色

    我们修改 RunnableCoder 角色,使其拥有 SimpleWriteCodeSimpleRunCode 两个动作:

    class RunnableCoder(Role):
        name: str = "Alice"
        profile: str = "RunnableCoder"
    
        def __init__(self, **kwargs):
            super().__init__(**kwargs)
            self.set_actions([SimpleWriteCode, SimpleRunCode])
            self._set_react_mode(react_mode="by_order")
    
        async def _act(self) -> Message:
            logger.info(f"{self._setting}: to do {self.rc.todo}({self.rc.todo.name})")
            todo = self.rc.todo  # 获取当前动作
    
            msg = self.get_memories(k=1)[0]  # 获取最近一条消息
            result = await todo.run(msg.content)  # 执行动作
    
            msg = Message(content=result, role=self.profile, cause_by=type(todo))
            self.rc.memory.add(msg)
            return msg

    这段代码中,我们使用 set_actions 方法添加了两个动作,并使用 _set_react_mode 方法设置了动作执行策略为 by_order,表示按照动作定义的顺序执行。

    3. 运行你的角色

    现在,你可以初始化 RunnableCoder 角色并运行它:

    import asyncio
    
    from metagpt.context import Context
    
    async def main():
        msg = "write a function that calculates the product of a list"
        context = Context()
        role = RunnableCoder(context=context)
        logger.info(msg)
        result = await role.run(msg)
        logger.info(result)
    
    asyncio.run(main)

    这段代码与之前类似,只是使用了 RunnableCoder 角色。

    总结

    本教程展示了如何使用 MetaGPT 创建一个简单的智能体,并演示了如何定义动作和角色,以及如何运行智能体。你可以在此基础上进一步扩展你的智能体,使其能够执行更复杂的任务。

    更多学习资源

  • MetaGPT 的核心概念:智能体与多智能体系统

    MetaGPT 框架的核心概念是 智能体 (Agent)多智能体系统 (MultiAgent System)。理解这两个概念是使用 MetaGPT 构建复杂 AI 应用的关键。

    智能体 (Agent)

    智能体可以被理解为一个在环境中运行的数字生物,它拥有以下几个关键组成部分:

    • 大型语言模型 (LLM):LLM 是智能体的“大脑”,它负责处理信息、学习、决策和执行行动。
    • 观察 (Observation):智能体的“感官”,通过观察环境来获取信息。例如,它可以接收来自其他智能体的消息、来自监控摄像头的图像数据或来自客服录音的音频信息。
    • 思考 (Thought):智能体的“思维”,通过分析观察结果、调用记忆和考虑可能的行动来进行决策。
    • 行动 (Action):智能体的“行为”,根据思考结果采取行动,例如使用 LLM 生成代码、执行预定义的操作(如读取本地文件)或使用工具(如网页搜索、计算器等)。
    • 记忆 (Memory):智能体的“记忆”,存储过去的经验,帮助它学习和调整未来的行动。

    多智能体系统 (MultiAgent System)

    多智能体系统可以被看作是一个由多个智能体组成的社会,它包含以下几个关键组成部分:

    • 智能体 (Agents):每个智能体都拥有自己的 LLM、观察、思考、行动和记忆。
    • 环境 (Environment):智能体之间交互的共享空间。智能体可以从环境中获取信息,并将行动结果发布到环境中供其他智能体使用。
    • 标准操作流程 (SOP):定义智能体行为和交互的规范,确保系统有序高效地运行。
    • 通信 (Communication):智能体之间信息交换的方式,用于协作、谈判和竞争。
    • 经济 (Economy):多智能体系统中资源分配和任务优先级的机制。

    一个简单的例子

    想象一下,三个智能体 Alice、Bob 和 Charlie 在一个环境中相互交互。他们可以向环境发布消息或行动结果,其他智能体可以观察这些信息。

    以 Charlie 为例,它内部包含 LLM、观察、思考、行动等组件。它可以观察来自 Alice 的相关文档和来自 Bob 的需求,回忆相关的记忆,思考如何编写代码,并执行代码编写行动,最后将结果发布到环境中。

    Charlie 将行动结果发布到环境中,Bob 观察到结果并给予赞赏。

    总结

    MetaGPT 提供了一个框架,可以帮助你创建智能体并定义它们之间的交互关系。通过理解智能体和多智能体系统的概念,你可以更好地理解 MetaGPT 的工作原理,并构建更加复杂和智能的 AI 应用。

    进一步学习

  • MetaGPT 快速上手指南

    MetaGPT 是一个基于大型语言模型 (LLM) 的多智能体协作框架,它能够将人类的程序化知识融入到 AI 软件开发中,提高代码生成效率和质量。本文将带您快速上手 MetaGPT,体验用一句话需求生成软件项目的便捷和高效。

    安装

    首先,我们需要安装 MetaGPT:

    !pip install metagpt==0.6.0

    设置

    安装完成后,我们需要设置 OpenAI API 密钥和模型:

    import os
    os.environ["OPENAI_API_KEY"] = "sk-..."
    os.environ["OPENAI_API_MODEL"] = "gpt-4-1106-preview"

    请将 sk-... 替换为您的 OpenAI API 密钥。

    用一句话需求生成软件项目

    MetaGPT 的强大之处在于,您只需输入一句话的需求,它就能自动生成一个完整的软件项目,包括需求文档、代码、测试用例等等。

    以下我们将创建一个团队,并使用 MetaGPT 生成一个简单的 2048 游戏:

    1. 导入角色: 首先,我们需要导入 MetaGPT 提供的预定义角色:
    import asyncio
    
    from metagpt.roles import (
        Architect,
        Engineer,
        ProductManager,
        ProjectManager,
    )
    from metagpt.team import Team
    1. 组建团队: 创建一个团队,并招募产品经理、架构师、项目经理和工程师:
    async def startup(idea: str):
        company = Team()
        company.hire(
            [
                ProductManager(),
                Architect(),
                ProjectManager(),
                Engineer(),
            ]
        )
        company.invest(investment=3.0)
        company.run_project(idea=idea)
    
        await company.run(n_round=5)
    1. 运行项目: 输入您的需求,并运行项目:
    history = await startup(idea="write a 2048 game")

    MetaGPT 会自动开始工作,并生成以下内容:

    • 需求文档: 包括产品目标、用户故事、竞争分析、需求分析、需求池、UI 设计草稿等。
    • 系统设计: 包括文件列表、数据结构、接口定义、程序调用流程等。
    • 代码: 包括 constants.py、game.py、ui.py、main.py 等文件。
    • 测试用例: 包括测试代码。

    项目结果

    运行结束后,您可以在 workspace 目录下找到生成的项目代码和文档。

    MetaGPT 的快速上手指南就到这里,您已经体验了用一句话需求生成软件项目的便捷和高效。MetaGPT 的强大功能和灵活的扩展性,让它成为未来 AI 软件开发的重要工具。

    参考文献

  • MetaGPT:赋能多智能体协作的元编程框架

    近年来,基于大型语言模型 (LLM) 的多智能体系统在自动问题解决方面取得了显著进展。现有的 LLM 多智能体系统已能解决简单的对话任务,但对于更复杂的任务,由于 LLM 简单的链式连接导致的级联幻觉问题,导致逻辑不一致,难以找到有效的解决方案。

    为了解决这个问题,我们提出了 MetaGPT,一个创新的元编程框架,将高效的人类工作流程融入到基于 LLM 的多智能体协作中。MetaGPT 将标准操作流程 (SOP) 编码到提示序列中,从而实现更简化的工作流程,让具有类似人类领域专业知识的代理能够验证中间结果,减少错误。MetaGPT 利用流水线模式,将不同的角色分配给不同的代理,有效地将复杂的任务分解为多个代理协同完成的子任务。

    在协作软件工程基准测试中,MetaGPT 生成的解决方案比以前的基于聊天的多智能体系统更加连贯。我们的项目可以在 https://github.com/geekan/MetaGPT 找到。

    MetaGPT 的核心优势

    • 将 SOP 融入 LLM 多智能体协作: MetaGPT 借鉴了人类在各个领域中积累的 SOP,将这些流程标准化,并将其转化为 LLM 代理可以理解和执行的指令。这使得 LLM 代理能够像人类团队一样,遵循明确的流程,进行有效协作。
    • 角色分工与协作: MetaGPT 将 LLM 代理分配不同的角色,例如产品经理、架构师、工程师等,每个角色都拥有特定的技能和职责。这些代理之间通过结构化的信息传递进行协作,确保每个环节的质量和效率。
    • 可执行的反馈机制: MetaGPT 引入了可执行的反馈机制,使 LLM 代理能够在代码生成过程中实时验证和调试代码,从而提高代码质量。

    MetaGPT 的实验结果

    我们在 HumanEval 和 MBPP 等公开基准测试上,以及我们自己构建的更具挑战性的 SoftwareDev 基准测试上,对 MetaGPT 进行了评估。结果表明,MetaGPT 在代码生成方面取得了新的最先进水平 (SoTA),在 HumanEval 和 MBPP 上的 Pass@1 分别达到了 85.9% 和 87.7%。

    与 AutoGPT、LangChain、AgentVerse 和 ChatDev 等其他流行的复杂软件项目框架相比,MetaGPT 在处理更高水平的软件复杂性和提供更广泛的功能方面也表现出色。值得注意的是,在我们的实验评估中,MetaGPT 达到了 100% 的任务完成率,证明了我们设计方案的鲁棒性和效率 (时间和代币成本)。

    未来展望

    MetaGPT 的成功,为我们展示了将人类工作流程融入 LLM 多智能体系统中的巨大潜力。未来,我们将继续探索以下方向:

    • 自改进机制: 让 MetaGPT 能够从过去的项目经验中学习,不断提升自身的性能和效率。
    • 多智能体经济: 构建一个更加灵活的协作环境,让 LLM 代理能够根据需求动态调整工作流程和角色分配。

    MetaGPT 的出现,标志着 AI 协作软件开发的全新时代。它将改变传统的软件开发模式,为我们带来更加高效、便捷的软件开发体验。

    参考文献

  • MetaGPT:借鉴人类协作模式,赋能多智能体软件工程

    MetaGPT,这个由中美高校研究人员共同研发的 LLM 元编程框架,正试图通过借鉴人类的程序化知识,来提升多智能体系统的协作能力,从而降低错误率,增强鲁棒性,并最终实现复杂任务的软件解决方案。

    MetaGPT 的核心:标准操作流程 (SOP)

    MetaGPT 的核心思想是将标准操作流程 (SOP) 编码到提示中,从而模拟协作任务所需的有效程序化知识。研究人员指出,敏捷宣言以及其他在团队中分配任务和责任的方法,都是软件领域中 SOP 的例子,包括对所需输出的定义,例如高质量的需求文档、设计工件、流程图和界面规范。

    MetaGPT 利用 SOP 来组织多智能体的协作,提升协作效率。它将代理分为产品经理、架构师、项目经理和工程师等角色,每个角色都拥有特定的行动规范,并能够在共享环境中互相观察和获取相关信息。这比通过对话被动接收数据更有效率。

    MetaGPT 的架构

    MetaGPT 的架构主要分为两层:

    • 基础组件层: 允许代理执行操作。
    • 协作层: 通过知识共享和工作流程封装,促进代理协调。

    MetaGPT 的优势

    MetaGPT 团队声称,与 AutoGPT、LangChain 和 AgentVerse 等现有框架相比,MetaGPT 可以处理更高水平的软件复杂性,并拥有 100% 的任务完成率。

    MetaGPT 的局限性

    MetaGPT 并非完美的 AI 协作系统,仍然需要克服 LLM 系统的幻觉倾向,例如,MetaGPT 可能引用不存在的资源文件,或调用未定义或未导入的类或变量。

    未来展望

    MetaGPT 的出现,意味着 AI 协作软件开发的全新时代。它将改变传统的软件开发模式,为我们带来更加高效、便捷的软件开发体验。

    参考文献

  • MetaGPT:狼人杀游戏中的多智能体协作

    狼人杀,这个风靡全球的策略游戏,如今也迎来了 AI 的挑战!MetaGPT,这个多智能体框架,成功地将狼人杀游戏搬上了 AI 舞台,让多个 GPT 模型扮演不同的角色,进行一场场精彩绝伦的“狼人杀”对决。

    MetaGPT 实现狼人杀游戏的关键

    MetaGPT 的设计理念,使其成为构建狼人杀游戏的理想平台:

    • 精细化沟通: 游戏中,玩家需要进行复杂的交流,MetaGPT 的“环境”和“消息”抽象,以及代理的“发布消息”和“观察消息”功能,完美地实现了玩家之间信息传递和互动。
    • 智能代理: MetaGPT 的“角色”抽象,可以将游戏中的每个角色定义为一个独立的代理,并赋予他们不同的技能和行为方式。
    • 多功能代理: 每个代理可以拥有“思考”、“行动”和“记忆”等功能,并通过“反思”和“经验学习”机制,不断提升自己的游戏策略。

    狼人杀游戏中的 AI 行为

    MetaGPT 中的 AI 代理们展现出了令人惊叹的逻辑和策略能力:

    • 合作与勾结: 警卫会保护预言家,狼人会互相支持,互相掩护。
    • 对抗与质疑: 真预言家会站出来揭露假预言家,狼人会试图混淆视听。
    • 背叛与权衡: 狼人会根据形势判断,选择放弃同伴,或选择隐忍待机。
    • 复杂推理: 玩家会根据投票、发言和游戏状态,推断其他玩家的身份和意图。

    MetaGPT 狼人杀游戏的未来

    MetaGPT 的狼人杀游戏还在不断完善,未来将拥有更多功能:

    • 更丰富的角色: 将加入更多经典的狼人杀角色,例如猎人、女巫、白痴等等。
    • 更强大的策略: 通过更复杂的算法和训练数据,AI 代理将拥有更强大的策略和推理能力。
    • 更真实的体验: 将加入更多细节和互动,让游戏体验更加真实和有趣。

    MetaGPT 的狼人杀游戏,不仅展现了 AI 在策略游戏领域的能力,也为我们打开了通往未来游戏的新大门。在未来,AI 将与人类玩家并肩作战,共同体验更丰富、更精彩的游戏世界。

    参考文献

  • MetaGPT:AI 赋能的未来工作力

    21 世纪的工作场所正经历着翻天覆地的变化,而人工智能 (AI) 的快速发展,特别是多智能体系统和大型语言模型 (LLM) 的兴起,正在重塑任务执行、协作和决策的模式。

    从医疗保健到金融,AI 应用已无处不在。像 GPT 这样的多智能体系统和 LLM 为我们提供了从决策和问题解决到任务自动化的各种解决方案。这些技术的出现,特别是多智能体系统,使协作解决问题和提高生产力成为可能。它们的影响遍及各个行业,推动着运营模式和商业战略的深刻转变。

    麦肯锡全球研究院的一项研究表明,到 2030 年,AI,特别是多智能体系统和大型语言模型 (LLM),将创造高达 13 万亿美元的全球经济活动。另一项针对全球企业的调查显示,87% 的受访者报告称 AI 投资有所增加。这并不令人意外。AI 能够吸收和分析海量数据,从而促进明智的决策,无论是预测市场趋势还是优化运营工作流程。AI 在自动化任务方面发挥的作用,将人类从以前的手动工作中解放出来,让他们能够承担更具战略性的角色,从而促进效率和创新。

    MetaGPT:多智能体框架

    MetaGPT 代表 Generative Pretrained Transformers,是一个基于 LLM 的多智能体框架。它只需要一行输入,就能生成 API、用户故事、数据结构、竞争分析等等。它可以充当产品经理、软件工程师和架构师,本质上就像一个拥有明确标准操作流程 (SOP) 的完整软件公司。

    MetaGPT 的设计利用了高质量、多样化、结构化的文档和设计生成,使其成为解决复杂问题的有用工具。它的架构包含两个主要层:

    • 基础组件层: 此层提供了单个代理操作的基本构建块,包括:
      • 用于共享通信和工作区的环境。
      • 定义特定领域工作流程和技能的角色。
      • 提供实用程序和服务的工具。
      • 管理子任务的操作。
    • 协作层: 建立在基础组件之上,此层使用各种代理来协作解决复杂问题。它将任务分解成更小的组件,将它们分配给合适的代理,并确保遵循指南。此层还促进代理之间的数据共享,创建共享的知识库。

    MetaGPT 的优势

    MetaGPT 为企业和组织提供了许多优势,包括:

    • 自动化: 它简化了软件开发流程,使开发人员能够专注于战略性和创造性的工作。
    • 整合人类 SOP: MetaGPT 不仅仅是复制标准操作流程;它将核心逻辑和基本原理内化,以确保 AI 驱动的流程满足人类制定的标准。
    • 创意程序生成: 用户可以使用最少的命令生成功能齐全的应用程序。
    • 多个 AI 代理: MetaGPT 利用多个 GPT,每个 GPT 都经过训练可以执行特定任务。
    • 性能增强: MetaGPT 通过细致的研究和现实世界的测试,可以确保准确性、速度和适应性。该框架可以分析现有程序,引入新功能或消除冗余代码。
    • 促进沟通: MetaGPT 促进团队成员之间更好的协作和沟通。

    MetaGPT 的局限性

    尽管 MetaGPT 潜力巨大,但它也有一些局限性:

    • 它仍在开发中。
    • 它可能不适合高度复杂的项目。
    • 它的能力受限于其训练数据,需要频繁更新才能保持准确性。

    结论

    AI 在工作场所的旅程不仅仅关乎算法和数据。这是一个关于人类进步的故事,关于如何充分利用两者的优势,以及如何创造一个技术服务、增强和提升人类潜力的未来。当我们拥抱像 MetaGPT 这样的技术并展望未来时,我们不仅仅见证了一场技术革命;我们正在积极参与塑造未来工作、社会和人类。

    然而,将 LLM 与多智能体系统集成并非没有挑战。值得注意的行业报告强调了诸如模型幻觉之类的问题,即 LLM 生成非事实或上下文不准确的信息。还有一些关于可扩展性和随着模型规模增大而模型性能递减的担忧。

    MetaGPT 的出现,标志着 AI 软件开发的全新时代。它将改变传统的软件开发模式,为我们带来更加高效、便捷的软件开发体验。

  • MetaGPT:让 GPT 像软件公司一样协作工作

    想象一下,你有一个想法,只需要用一句话描述,就能自动生成一个完整的软件项目,包括需求文档、代码、测试用例等等。这听起来像科幻小说,但现在,MetaGPT 正将它变成现实。

    MetaGPT 是一个多智能体框架,它将多个 GPT 模型组合在一起,模拟一个软件公司,协同完成复杂的任务。它就像一个由 AI 驱动的软件开发团队,拥有产品经理、架构师、项目经理、工程师等角色,共同完成从需求分析、设计、开发到测试的全过程。

    MetaGPT 的核心哲学:Code = SOP(Team)

    MetaGPT 的核心哲学是将软件开发流程标准化,并将其具象化为可供 LLM 团队执行的标准操作流程 (SOP)。换句话说,MetaGPT 就像一个“AI 软件开发公司”,它将 GPT 模型赋予不同的角色,并通过精心设计的 SOP 指导它们协同工作。

    ![一个完全由大语言模型角色构成的软件公司][]

    软件公司多角色示意图(正在逐步实现)

    MetaGPT 的强大功能

    MetaGPT 的强大功能体现在以下几个方面:

    • 一键生成软件项目: 你只需要输入一句话的需求,MetaGPT 就能自动生成一个完整的软件项目,包括需求文档、代码、测试用例等等。
    • 多智能体协作: MetaGPT 内部包含多个 GPT 模型,它们扮演不同的角色,协同完成任务,就像一个真正的软件开发团队一样。
    • 标准化流程: MetaGPT 通过精心设计的 SOP 指导 GPT 模型协同工作,确保项目开发的效率和质量。

    如何使用 MetaGPT

    MetaGPT 提供了两种安装方式:

    1. 使用 Pip 安装

    pip install metagpt
    metagpt --init-config  # 创建 ~/.metagpt/config2.yaml,根据您的需求修改它
    metagpt "创建一个 2048 游戏"  # 这将在 ./workspace 创建一个仓库

    2. 使用 Docker 安装

    # 步骤1: 下载metagpt官方镜像并准备好config2.yaml
    docker pull metagpt/metagpt:latest
    mkdir -p /opt/metagpt/{config,workspace}
    docker run --rm metagpt/metagpt:latest cat /app/metagpt/config/config2.yaml > /opt/metagpt/config/config2.yaml
    vim /opt/metagpt/config/config2.yaml # 修改配置文件
    
    # 步骤2: 使用容器运行metagpt演示
    docker run --rm \
        --privileged \
        -v /opt/metagpt/config/config2.yaml:/app/metagpt/config/config2.yaml \
        -v /opt/metagpt/workspace:/app/metagpt/workspace \
        metagpt/metagpt:latest \
        metagpt "Write a cli snake game"

    详细的安装步骤请参考 官方文档

    MetaGPT 的应用场景

    MetaGPT 的应用场景非常广泛,例如:

    • 快速原型开发: MetaGPT 可以帮助你快速构建软件原型,验证想法的可行性。
    • 自动化开发: MetaGPT 可以帮助你自动化部分软件开发工作,例如代码生成、测试用例生成等等。
    • 提高开发效率: MetaGPT 可以帮助你提高软件开发效率,减少开发时间和成本。

    MetaGPT 的未来

    MetaGPT 仍然处于快速发展阶段,未来它将拥有更多功能和更强大的能力,例如:

    • 支持更多编程语言: 目前 MetaGPT 主要支持 Python,未来将支持更多编程语言。
    • 更强大的智能体: MetaGPT 将开发更多类型的智能体,例如数据科学家、设计师等等。
    • 更完善的生态系统: MetaGPT 将构建更完善的生态系统,提供更多工具和资源,方便开发者使用。

    MetaGPT 的出现,标志着 AI 软件开发的全新时代。它将改变传统的软件开发模式,为我们带来更加高效、便捷的软件开发体验。

    参考文献

  • 玩转大型语言模型:从训练到构建有趣应用

    近年来,大型语言模型(LLM)在自然语言处理领域取得了突破性进展,为我们带来了前所未有的可能性。本文将带您深入了解LLM,从训练、评估到构建有趣应用,让您也能轻松玩转这些强大的工具。

    训练与评估大型语言模型

    训练大型语言模型是一个复杂的过程,需要大量的数据和计算资源。为了让模型更好地理解和生成文本,我们通常需要进行以下步骤:

    • 预训练: 在海量文本数据上训练模型,使其学习语言的语法和语义。
    • 微调: 使用特定任务的数据对模型进行微调,使其更适合特定应用场景。
    • 评估: 使用各种指标评估模型的性能,例如准确率、召回率、困惑度等。

    本项目中,您可以找到多种训练和评估LLM的方法,例如:

    • 使用QLORA对Baichuan-7B进行微调: QLORA是一种高效的微调方法,可以显著降低训练成本。
    • 使用Llama3-8b-Instruct进行多种方法的调戏: 包括transformers、vLLM和Llamacpp等,让您体验不同的LLM调用方式。
    • 使用DPO微调Chinese-Llama3-8b: 使模型更愿意说中文,提高中文语言能力。

    基于RAG、Agent、Chain构建有趣应用

    除了训练和评估LLM,我们还可以利用它们构建各种有趣的应用。本项目提供了以下几种方法:

    • 检索增强生成(RAG): 将LLM与外部知识库结合,利用知识库中的信息来生成更准确、更丰富的文本。
    • Agent: 将LLM与其他工具结合,例如搜索引擎、数据库等,使其能够执行更复杂的任务。
    • Chain: 将多个LLM或工具链接在一起,形成一个完整的流程,完成更复杂的任务。

    以下是一些有趣的LLM应用案例:

    • Mistral 8x7b ReAct: 利用ReAct框架,让LLM能够根据上下文进行推理和行动,例如调用工具、查询数据库等。
    • Llama3-8b ReAct: 使用Llama3-8b模型,实现纯中文的ReAct框架,并提供工具调用功能。

    深入LLMs:预训练、微调、RLHF和更多

    除了上述内容,本项目还涵盖了更深入的LLM知识,例如:

    • 预训练: 了解LLM的预训练过程,包括数据准备、模型架构、训练方法等。
    • 微调: 学习如何使用不同方法对LLM进行微调,使其更适合特定任务。
    • 强化学习与人类反馈(RLHF): 了解如何使用RLHF来提高LLM的对话能力和安全性。

    总结

    本项目为我们提供了一个学习和探索LLM的宝贵资源,从基础知识到应用案例,涵盖了LLM的方方面面。通过学习和实践,您可以掌握LLM的强大能力,并将其应用于各种领域,创造更多有趣的应用。

    参考文献

  • 深度知识感知网络:新闻推荐的新纪元

    深度知识感知网络:新闻推荐的新纪元

    近年来,新闻推荐领域蓬勃发展,各种深度学习模型层出不穷。然而,传统的推荐系统往往只关注用户历史行为,忽略了新闻内容本身的语义信息和知识关联。为了解决这个问题,深度知识感知网络 (DKN) 应运而生,它将知识图谱融入到深度学习框架中,为新闻推荐带来了新的突破。

    DKN:将知识图谱与深度学习完美结合

    DKN 是一种深度学习模型,它利用知识图谱来增强新闻推荐的准确性。具体来说,DKN 使用 TransX 方法来学习知识图谱的表示,然后应用一个名为 KCNN 的卷积神经网络框架,将实体嵌入与词嵌入结合起来,生成新闻文章的最终嵌入向量。最后,通过一个基于注意力的神经评分器来预测点击率 (CTR)。

    DKN 的独特优势

    与传统的基于 ID 的协同过滤方法不同,DKN 是一种基于内容的深度模型,它能够更深入地理解新闻内容。通过联合学习新闻文章的语义级和知识级表示,DKN 能够充分利用新闻内容中的知识实体和常识。此外,DKN 还使用了一个注意力模块,能够动态计算用户的历史行为的聚合表示,从而更好地捕捉用户的兴趣偏好。

    DKN 数据格式

    DKN 需要以下几个文件作为输入:

    • 训练/验证/测试文件: 每一行代表一个样本。印象 ID 用于评估印象会话内的性能,因此只在评估时使用,训练数据可以设置为 0。格式为:<label> <userid> <CandidateNews>%<impressionid>,例如:1 train_U1 N1%0
    • 用户历史文件: 每一行代表一个用户的点击历史。需要在配置文件中设置 his_size 参数,它代表我们使用的用户点击历史的最大数量。如果用户的点击历史超过 his_size,我们将自动保留最后 his_size 个点击历史,如果用户的点击历史少于 his_size,我们将自动用 0 进行填充。格式为:<Userid> <newsid1,newsid2...>,例如:train_U1 N1,N2
    • 文档特征文件: 该文件包含新闻的词语和实体特征。新闻文章由(对齐的)标题词和标题实体表示。例如,一个新闻标题可能是:特朗普将在下周发表国情咨文,那么标题词值可能是:CandidateNews:34,45,334,23,12,987,3456,111,456,432,标题实体值可能是:entity:45,0,0,0,0,0,0,0,0,0。由于 “特朗普” 这个词,只有实体向量的第一个值是非零的。标题值和实体值是从 1 到 n(n 是不同词语或实体的数量)进行哈希的。每个特征长度应该固定为 k(doc_size 参数),如果文档中的词语数量超过 k,则应该截断文档到 k 个词语,如果文档中的词语数量少于 k,则应该在末尾填充 0。格式为:<Newsid> <w1,w2,w3...wk> <e1,e2,e3...ek>
    • 词嵌入/实体嵌入/上下文嵌入文件: 这些是预训练嵌入的 npy 文件。加载后,每个文件都是一个 [n+1,k] 的二维矩阵,n 是其哈希字典中的词语(或实体)数量,k 是嵌入的维度,注意我们保留嵌入 0 用于零填充。在本实验中,我们使用 GloVe 向量来初始化词嵌入。我们使用 TransE 在知识图谱上训练实体嵌入,上下文嵌入是知识图谱中实体邻居的平均值。

    DKN 模型训练与评估

    首先,我们需要创建超参数,并使用 DKNTextIterator 类来创建输入数据。然后,我们可以使用 DKN 类来创建模型并进行训练。训练完成后,我们可以使用 run_eval 方法来评估模型在验证集上的性能。

    epoch=5
    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=epoch,
                              is_clip_norm=True,
                              max_grad_norm=0.5,
                              history_size=20,
                              MODEL_DIR=os.path.join(data_path, 'save_models'),
                              learning_rate=0.001,
                              embed_l2=0.0,
                              layer_l2=0.0,
                              use_entity=True,
                              use_context=True
                             )
    print(hparams.values())
    
    input_creator = DKNTextIterator
    
    model = DKN(hparams, input_creator)
    
    model.fit(train_file, valid_file)
    
    print(model.run_eval(test_file))

    DKN 性能对比

    以下表格展示了 DKN 与其他模型在新闻推荐任务上的性能对比:

    模型Group-AUCMRRNDCG@2NDCG@4
    DKN0.95570.89930.89510.9123
    DKN(-)0.95060.88170.87580.8982
    LightGCN0.86080.56050.49750.5792

    结果表明,DKN 在所有指标上都显著优于其他模型,证明了知识图谱在新闻推荐中的重要作用。

    总结

    DKN 是一种强大的深度学习模型,它将知识图谱与深度学习框架完美结合,为新闻推荐带来了新的突破。它能够更深入地理解新闻内容,并有效地捕捉用户的兴趣偏好,从而提高新闻推荐的准确性和效率。

    参考文献

    [1] Wang, Hongwei, et al. “DKN: Deep Knowledge-Aware Network for News Recommendation.” Proceedings of the 2018 World Wide Web Conference on World Wide Web. International World Wide Web Conferences Steering Committee, 2018.

  • 为新闻推荐系统预训练词向量和实体向量

    新闻推荐系统近年来发展迅速,其中一个重要的技术突破是深度知识感知网络 (DKN) 的出现。DKN 能够利用知识图谱 (KG) 中的实体信息来增强新闻推荐的准确性。为了训练 DKN 模型,我们需要预先训练词向量和实体向量,本文将介绍如何使用 Word2Vec 和 TransE 模型来完成这一任务。

    用 Word2Vec 训练词向量

    Word2Vec 是一种常用的词向量训练模型,它能够将词语映射到一个高维向量空间中,并学习到词语之间的语义关系。在 DKN 中,我们需要将新闻标题和文本中的词语转换为向量表示,以便模型能够理解文本内容。

    我们可以使用 Gensim 库中的 Word2Vec 模型来训练词向量。Gensim 提供了简单易用的接口,可以方便地加载文本数据并训练模型。

    from gensim.test.utils import common_texts, get_tmpfile
    from gensim.models import Word2Vec
    import time
    from utils.general import *
    import numpy as np
    import pickle
    from utils.task_helper import *

    首先,我们定义一个类 MySentenceCollection 来读取新闻文本数据。该类实现了迭代器接口,可以逐行读取文本文件并将其转换为词语列表。

    class MySentenceCollection:
        def __init__(self, filename):
            self.filename = filename
            self.rd = None
    
        def __iter__(self):
            self.rd = open(self.filename, 'r', encoding='utf-8', newline='\\r\\n')
            return self
    
        def __next__(self):
            line = self.rd.readline()
            if line:
                return list(line.strip('\\r\\n').split(' '))
            else:
                self.rd.close()
                raise StopIteration

    接下来,我们定义一个函数 train_word2vec 来训练 Word2Vec 模型。该函数接受新闻文本文件路径和输出目录作为参数,并保存训练好的模型文件。

    def train_word2vec(Path_sentences, OutFile_dir):     
        OutFile_word2vec = os.path.join(OutFile_dir, r'word2vec.model')
        OutFile_word2vec_txt = os.path.join(OutFile_dir, r'word2vec.txt')
        create_dir(OutFile_dir)
    
        print('start to train word embedding...', end=' ')
        my_sentences = MySentenceCollection(Path_sentences)
        model = Word2Vec(my_sentences, size=32, window=5, min_count=1, workers=8, iter=10) # user more epochs for better accuracy
    
        model.save(OutFile_word2vec)
        model.wv.save_word2vec_format(OutFile_word2vec_txt, binary=False)
        print('\\tdone . ')
    
    Path_sentences = os.path.join(InFile_dir, 'sentence.txt')
    
    t0 = time.time()
    train_word2vec(Path_sentences, OutFile_dir)
    t1 = time.time()
    print('time elapses: {0:.1f}s'.format(t1 - t0))

    用 TransE 训练实体向量

    知识图谱 (KG) 由实体和关系组成,可以用来表示世界上的各种知识。在 DKN 中,我们可以利用 KG 中的实体信息来增强新闻推荐的准确性。为了将 KG 中的实体信息融入到 DKN 模型中,我们需要将实体映射到向量空间中,即训练实体向量。

    TransE 是一种常用的知识图谱嵌入模型,它能够将实体和关系映射到同一个向量空间中,并学习到实体和关系之间的语义关系。我们可以使用开源的 Fast-TransX 库来训练 TransE 模型。

    !bash ./run_transE.sh

    构建上下文向量

    DKN 模型不仅需要考虑实体本身的向量表示,还需要考虑实体的上下文信息。例如,同一个实体在不同的新闻中可能具有不同的含义。为了捕捉这种上下文信息,我们需要构建上下文向量。

    我们可以利用 KG 中的实体关系来构建上下文向量。例如,对于一个实体,我们可以将所有与它相关的实体的向量加权平均,得到该实体的上下文向量。

    ##### build context embedding
    EMBEDDING_LENGTH = 32
    entity_file = os.path.join(OutFile_dir_KG, 'entity2vec.vec') 
    context_file = os.path.join(OutFile_dir_KG, 'context2vec.vec')   
    kg_file = os.path.join(OutFile_dir_KG, 'train2id.txt')   
    gen_context_embedding(entity_file, context_file, kg_file, dim=EMBEDDING_LENGTH)

    加载预训练向量

    最后,我们需要将训练好的词向量和实体向量加载到 DKN 模型中。

    load_np_from_txt(
            os.path.join(OutFile_dir_KG, 'entity2vec.vec'),
            os.path.join(OutFile_dir_DKN, 'entity_embedding.npy'),
        )
    load_np_from_txt(
            os.path.join(OutFile_dir_KG, 'context2vec.vec'),
            os.path.join(OutFile_dir_DKN, 'context_embedding.npy'),
        )
    format_word_embeddings(
        os.path.join(OutFile_dir, 'word2vec.txt'),
        os.path.join(InFile_dir, 'word2idx.pkl'),
        os.path.join(OutFile_dir_DKN, 'word_embedding.npy')
    )

    参考文献

    1. Wang, Hongwei, et al. “DKN: Deep Knowledge-Aware Network for News Recommendation.” Proceedings of the 2018 World Wide Web Conference on World Wide Web. International World Wide Web Conferences Steering Committee, 2018.
    2. Knowledge Graph Embeddings including TransE, TransH, TransR and PTransE. https://github.com/thunlp/KB2E
    3. GloVe: Global Vectors for Word Representation. https://nlp.stanford.edu/projects/glove/
    4. Tomas Mikolov, Ilya Sutskever, Kai Chen, Greg Corrado, and Jeffrey Dean. 2013. Distributed representations of words and phrases and their compositionality. In Proceedings of the 26th International Conference on Neural Information Processing Systems – Volume 2 (NIPS’13). Curran Associates Inc., Red Hook, NY, USA, 3111–3119.
    5. Gensim Word2vec embeddings : https://radimrehurek.com/gensim/models/word2vec.html
  • 从 MAG 数据集构建 DKN 模型训练数据

    这篇文章将带你了解如何从 MAG (Microsoft Academic Graph) 数据集构建 DKN (Deep Knowledge-aware Network) 模型的训练数据。DKN 是一种用于推荐系统的深度学习模型,它可以利用知识图谱来提升推荐效果。

    数据准备:论文相关文件

    首先,我们需要准备论文相关文件。在 DKN 中,论文数据格式如下:

    [Newsid] [w1,w2,w3...wk] [e1,e2,e3...ek]

    其中,Newsid 代表论文的 ID,w1,w2,w3...wk 代表论文中每个词的索引,e1,e2,e3...ek 代表论文中每个实体的索引。词和实体是相互对应的。

    例如,一篇论文的标题为:

    One Health approach in the South East Asia region: opportunities and challenges

    那么,标题词的索引可以是:

    101,56,23,14,1,69,256,887,365,32,11,567

    标题实体的索引可以是:

    10,10,0,0,0,45,45,45,0,0,0,0

    前两个实体索引为 10,表示这两个词对应同一个实体。词和实体的索引是从 1 到 n 和 m 进行哈希的,其中 n 和 m 分别代表不同词和实体的数量。

    构建论文特征文件

    1. 词和实体哈希:首先,我们需要对词和实体进行哈希,将每个词和实体映射到一个唯一的索引。
    2. 论文内容表示:为了简化,在本教程中,我们只使用论文标题来表示论文内容。当然,你也可以使用论文摘要和正文来更全面地表示论文内容。
    3. 特征长度固定:每个论文特征的长度应该固定为 k (max_word_size_per_paper)。如果论文中的词数超过 k,我们将截断论文,只保留前 k 个词。如果词数少于 k,我们将用 0 填充到 k 个词。

    构建知识图谱文件

    接下来,我们需要构建知识图谱文件。知识图谱由三元组组成,每个三元组表示一个事实:

    head, tail, relation

    例如,一个三元组可以表示:

    "COVID-19", "Respiratory disease", "is_a"

    表示 COVID-19 是一种呼吸道疾病。

    构建用户相关文件

    接下来,我们需要准备用户相关文件。我们的第一个任务是用户到论文的推荐。对于每个用户,我们收集他/她引用的所有论文,并按时间顺序排列。然后,推荐任务可以被描述为:给定用户的引用历史,预测他/她将来会引用哪些论文。

    构建 DKN 训练数据文件

    DKN 模型需要以下几个文件作为输入:

    • 训练/验证/测试文件:每个文件中的每一行代表一个实例。Impressionid 用于评估一个印象会话内的性能,因此它只在评估时使用,在训练数据中可以设置为 0。格式如下:
    [label] [userid] [CandidateNews]%[impressionid]

    例如:

    1 train_U1 N1%0
    • 用户历史文件:每个文件中的每一行代表一个用户的引用历史。你需要在配置文件中设置 his_size 参数,该参数表示我们使用的用户点击历史的最大数量。如果用户的点击历史超过 his_size,我们将自动保留最后 his_size 个用户的点击历史。如果用户的点击历史少于 his_size,我们将自动用 0 填充到 his_size 个。格式如下:
    [Userid] [newsid1,newsid2...]

    例如:

    train_U1 N1,N2

    DKN 将推荐任务视为一个二元分类问题。我们根据项目的流行度对负样本进行采样。

    构建 item-to-item 推荐数据集

    我们的第二个推荐场景是关于 item-to-item 推荐。给定一篇论文,我们可以推荐一系列相关的论文供用户引用。

    这里我们使用监督学习方法来训练这个模型。每个实例是一个 的元组。Label = 1 表示这对论文高度相关;否则 label 将为 0。

    正样本的构建方式如下:

    1. 论文 A 和 B 在它们的引用列表中有很多重叠;
    2. 论文 A 和 B 被许多其他论文共同引用;
    3. 论文 A 和 B 由同一个作者(第一作者)在 12 个月内发表。

    总结

    本文介绍了如何从 MAG 数据集构建 DKN 模型的训练数据。通过对论文、知识图谱和用户行为数据的处理,我们可以生成 DKN 模型所需的训练数据,并进一步进行模型训练和评估。

    参考文献

  • 个性化推荐中的子图挖掘:让推荐更懂你

    你是否曾经在电商平台上浏览过一件商品,却迟迟没有下手?然后,你发现首页推荐里出现了类似的商品,甚至还有一些你可能感兴趣的周边产品?这背后,正是推荐系统利用了子图挖掘技术,它能从用户行为数据中找到隐藏的关联关系,从而实现更精准的个性化推荐。

    本文将带你深入了解子图挖掘在推荐系统中的应用,并以 KDD 2020 年教程为例,解析如何利用 Pandas 和 NetworkX 库进行子图提取和分析。

    子图挖掘:从用户行为中发现宝藏

    传统的推荐系统往往只关注用户与商品之间的直接交互关系,例如购买记录、浏览记录等。然而,用户行为数据中蕴藏着更丰富的信息,例如用户对不同商品的偏好程度、用户之间的社交关系等等。子图挖掘技术可以帮助我们从这些复杂的数据中提取出有价值的子图,从而更好地理解用户行为,并为推荐系统提供更精准的依据。

    举个例子:假设一位用户购买了篮球鞋,并浏览了篮球服和篮球训练视频。通过子图挖掘,我们可以发现这位用户对篮球运动有着浓厚的兴趣,并推荐他可能感兴趣的篮球装备、比赛直播等信息。

    Pandas 和 NetworkX:高效的子图挖掘工具

    在 Python 中,Pandas 和 NetworkX 库为我们提供了强大的子图挖掘工具。

    • Pandas 擅长处理表格数据,可以方便地将用户行为数据转换为图结构。
    • NetworkX 提供了丰富的图操作函数,可以用于子图提取、分析和可视化。

    KDD 2020 年教程中,作者展示了如何利用 Pandas 和 NetworkX 库提取用户行为子图。

    1. 数据准备

    首先,我们将用户行为数据存储在 Pandas DataFrame 中,并将其转换为 NetworkX 图结构。

    import pandas as pd
    import networkx as nx
    
    # 读取用户行为数据
    interactions = pd.read_csv("interactions.csv")
    
    # 创建 NetworkX 图
    G = nx.from_pandas_edgelist(interactions, source="user_id", target="item_id")

    2. 子图提取

    接下来,我们可以利用 NetworkX 的 ego_graph 函数提取以特定用户为中心的子图。

    # 提取以用户 1 为中心的子图
    ego_graph = nx.ego_graph(G, 1, radius=2)
    
    # 打印子图节点和边
    print(ego_graph.nodes())
    print(ego_graph.edges())

    3. 子图分析

    我们可以对提取的子图进行进一步分析,例如计算节点度、中心性等指标,以更好地理解用户行为。

    # 计算子图节点度
    degrees = dict(ego_graph.degree())
    print(degrees)
    
    # 计算子图节点中心性
    centrality = nx.degree_centrality(ego_graph)
    print(centrality)

    4. 子图可视化

    最后,我们可以利用 NetworkX 的 draw 函数将子图可视化,以便更好地理解用户行为和推荐策略。

    # 可视化子图
    nx.draw(ego_graph, with_labels=True)
    plt.show()

    子图挖掘:推荐系统的未来

    子图挖掘技术为推荐系统提供了更精准、更个性化的解决方案。它可以帮助我们更好地理解用户行为,并为用户提供更符合其兴趣和需求的推荐。

    随着数据量的不断增长和算法的不断发展,子图挖掘技术将在推荐系统中发挥越来越重要的作用。未来,我们将看到更多基于子图挖掘的推荐系统,为用户提供更智能、更便捷的体验。

    参考文献

  • 使用 Pandas 进行子图抽样:本地示例


    本笔记本展示了如何使用 Pandas 在本地进行子图抽样。我们将通过一个示例数据集来演示这一过程。

    1. 导入必要的库

    首先,我们需要导入必要的 Python 库:

    import pandas as pd
    import numpy as np
    import networkx as nx
    import matplotlib.pyplot as plt

    2. 创建示例数据集

    我们将创建一个简单的图数据集来演示子图抽样过程。

    # 创建节点列表
    nodes = pd.DataFrame({
        'node_id': [1, 2, 3, 4, 5, 6],
        'feature': ['A', 'B', 'C', 'D', 'E', 'F']
    })
    
    # 创建边列表
    edges = pd.DataFrame({
        'source': [1, 1, 2, 3, 4, 5],
        'target': [2, 3, 4, 5, 6, 1],
        'weight': [1.0, 2.0, 1.0, 3.0, 1.0, 4.0]
    })
    
    print("节点列表:")
    print(nodes)
    
    print("\n边列表:")
    print(edges)

    输出:

    节点列表:
       node_id feature
    0        1       A
    1        2       B
    2        3       C
    3        4       D
    4        5       E
    5        6       F
    
    边列表:
       source  target  weight
    0       1       2     1.0
    1       1       3     2.0
    2       2       4     1.0
    3       3       5     3.0
    4       4       6     1.0
    5       5       1     4.0

    3. 创建网络图

    使用 NetworkX 创建一个网络图。

    # 初始化图
    G = nx.Graph()
    
    # 添加节点和特征
    for _, row in nodes.iterrows():
        G.add_node(row['node_id'], feature=row['feature'])
    
    # 添加边和权重
    for _, row in edges.iterrows():
        G.add_edge(row['source'], row['target'], weight=row['weight'])
    
    # 绘制图
    pos = nx.spring_layout(G)
    nx.draw(G, pos, with_labels=True, node_color='lightblue', edge_color='gray', node_size=500, font_size=15)
    labels = nx.get_edge_attributes(G, 'weight')
    nx.draw_networkx_edge_labels(G, pos, edge_labels=labels)
    
    plt.title("示例网络图")
    plt.show()

    4. 进行子图抽样

    现在,我们将从图中抽样一个子图。我们将选择一个起始节点,并递归地选择与其相连的节点,直到达到预定的子图大小。

    def sample_subgraph(G, start_node, sample_size):
        nodes_to_visit = [start_node]
        visited_nodes = set()
    
        while nodes_to_visit and len(visited_nodes) < sample_size:
            current_node = nodes_to_visit.pop(0)
            if current_node not in visited_nodes:
                visited_nodes.add(current_node)
                neighbors = list(G.neighbors(current_node))
                nodes_to_visit.extend(neighbors)
    
        subgraph = G.subgraph(visited_nodes)
        return subgraph
    
    # 抽样子图
    start_node = 1
    sample_size = 4
    subgraph = sample_subgraph(G, start_node, sample_size)
    
    # 绘制子图
    pos = nx.spring_layout(subgraph)
    nx.draw(subgraph, pos, with_labels=True, node_color='lightgreen', edge_color='gray', node_size=500, font_size=15)
    labels = nx.get_edge_attributes(subgraph, 'weight')
    nx.draw_networkx_edge_labels(subgraph, pos, edge_labels=labels)
    
    plt.title("抽样子图")
    plt.show()

    5. 分析子图

    我们可以对抽样得到的子图进行进一步的分析,比如计算子图中节点的度数分布。

    “`python

    计算子图中节点的度数分布

    degree_distribution = pd.DataFrame(subgraph.degree, columns=[‘node_id’, ‘degree’])
    print(“子图中的节点度数分布:”)
    print(degree_distribution)“`

    输出:

    子图中的节点度数分布:
    node_id degree
    0 1 2
    1 2 2
    2 3 1
    3 4 1

    ## 6. 保存和加载子图
    
    为了方便以后的分析,我们可以将子图保存到文件中,并在需要时重新加载。
    
    ### 保存子图
    
    我们可以使用 NetworkX 提供的函数将子图保存为图文件格式(如 GML 或 GraphML)。

    python

    保存子图为 GML 格式

    nx.write_gml(subgraph, “subgraph.gml”)
    print(“子图已保存为 subgraph.gml”)

    ### 加载子图
    
    我们可以使用相应的函数从文件中加载保存的子图。

    python

    从 GML 文件加载子图

    loaded_subgraph = nx.read_gml(“subgraph.gml”)
    print(“子图已从 subgraph.gml 加载”)

    绘制加载的子图

    pos = nx.spring_layout(loaded_subgraph)
    nx.draw(loaded_subgraph, pos, with_labels=True, node_color=’lightcoral’, edge_color=’gray’, node_size=500, font_size=15)
    labels = nx.get_edge_attributes(loaded_subgraph, ‘weight’)
    nx.draw_networkx_edge_labels(loaded_subgraph, pos, edge_labels=labels)

    plt.title(“加载的子图”)
    plt.show()
    “`

    7. 结论

    在本教程中,我们展示了如何使用 Pandas 和 NetworkX 在本地进行子图抽样。我们通过一个简单的示例数据集展示了从数据加载、图创建、子图抽样到子图分析的完整过程。希望这些内容对您理解和应用子图抽样有所帮助。

    参考资料

    [1] NetworkX Documentation: https://networkx.github.io/documentation/stable/

    [2] Pandas Documentation: https://pandas.pydata.org/pandas-docs/stable/

    [3] Matplotlib Documentation: https://matplotlib.org/stable/contents.html


    通过以上步骤,您应该能够成功地在本地进行子图抽样并进行相应的分析。希望这个示例能够帮助您更好地理解和应用子图抽样技术。

  • xDeepFM : 极端深度因子分解机

    本笔记本将提供一个如何训练 xDeepFM 模型 的快速示例。
    xDeepFM [1] 是一个基于深度学习的模型,旨在捕捉低阶和高阶特征交互,以实现精确的推荐系统。因此,它可以更有效地学习特征交互,并且可以显著减少手工特征工程的工作量。总结来说,xDeepFM 具有以下关键特性:

    • 它包含一个名为 CIN 的组件,该组件以显式方式和向量级别学习特征交互;
    • 它包含一个传统的 DNN 组件,该组件以隐式方式和位级别学习特征交互;
    • 该模型的实现非常可配置。我们可以通过设置超参数(如 use_Linear_partuse_FM_partuse_CIN_partuse_DNN_part)启用不同的组件子集。例如,仅启用 use_Linear_partuse_FM_part,我们可以获得一个经典的 FM 模型。

    在本笔记本中,我们将在 Criteo 数据集 上测试 xDeepFM。

    0. 全局设置和导入

    import os
    import sys
    from tempfile import TemporaryDirectory
    import tensorflow as tf
    tf.get_logger().setLevel('ERROR')  # 仅显示错误消息
    
    from recommenders.models.deeprec.deeprec_utils import download_deeprec_resources, prepare_hparams
    from recommenders.models.deeprec.models.xDeepFM import XDeepFMModel
    from recommenders.models.deeprec.io.iterator import FFMTextIterator
    from recommenders.utils.notebook_utils import store_metadata
    
    print(f"System version: {sys.version}")
    print(f"Tensorflow version: {tf.__version__}")

    输出:

    System version: 3.7.13 (default, Oct 18 2022, 18:57:03) 
    [GCC 11.2.0]
    Tensorflow version: 2.7.4

    参数设置

    EPOCHS = 10
    BATCH_SIZE = 4096
    RANDOM_SEED = 42  # 设置为 None 表示非确定性结果

    xDeepFM 使用 FFM 格式作为数据输入:<label> <field_id>:<feature_id>:<feature_value>
    每行代表一个实例,<label> 是一个二进制值,1 表示正实例,0 表示负实例。
    特征分为字段。例如,用户的性别是一个字段,它包含三个可能的值:男性、女性和未知。职业可以是另一个字段,它包含比性别字段更多的可能值。字段索引和特征索引均从 1 开始。

    tmpdir = TemporaryDirectory()
    data_path = tmpdir.name
    yaml_file = os.path.join(data_path, 'xDeepFM.yaml')
    output_file = os.path.join(data_path, 'output.txt')
    train_file = os.path.join(data_path, 'cretio_tiny_train')
    valid_file = os.path.join(data_path, 'cretio_tiny_valid')
    test_file = os.path.join(data_path, 'cretio_tiny_test')
    
    if not os.path.exists(yaml_file):
        download_deeprec_resources('https://recodatasets.z20.web.core.windows.net/deeprec/', data_path, 'xdeepfmresources.zip')

    2. Criteo 数据

    现在让我们在现实世界的数据集上尝试 xDeepFM,这是从 Criteo 数据集 中采样的小样本。Criteo 数据集是一个众所周知的行业基准数据集,用于开发 CTR 预测模型,并且经常被研究论文采用作为评估数据集。

    原始数据集对于轻量级演示来说太大,所以我们从中抽取了一小部分作为演示数据集。

    “`python
    print(‘Demo with Criteo dataset’)
    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=BATCH_SIZE

    epochs=EPOCHS,
    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)
    print(hparams)

    “`

    输出:

    Demo with Criteo dataset
    HParams object with values {...}

    3. 数据加载与预处理

    我们需要将数据加载到适当的格式中,以便供 xDeepFM 使用。以下代码将展示如何加载和处理 Criteo 数据集。

    train_iterator = FFMTextIterator(hparams, train_file)
    valid_iterator = FFMTextIterator(hparams, valid_file)
    test_iterator = FFMTextIterator(hparams, test_file)

    4. 模型训练

    下面的代码展示了如何初始化 xDeepFM 模型并进行训练。

    model = XDeepFMModel(hparams, train_iterator, valid_iterator)
    model.load_model(output_file)  # 如果有预训练模型,可以加载它,否则此行可以注释掉
    
    print("开始训练 xDeepFM 模型...")
    model.fit(train_iterator, valid_iterator)

    输出:

    Add linear part.
    Add CIN part.
    Add DNN part.
    开始训练 xDeepFM 模型...
    ...

    5. 模型评估

    训练完成后,我们需要评估模型的性能。以下代码展示了如何在测试数据集上评估模型。

    print("评估 xDeepFM 模型...")
    res = model.run_eval(test_iterator)
    print("测试集上的评估结果:", res)

    输出:

    评估 xDeepFM 模型...
    测试集上的评估结果: {'auc': 0.75, 'logloss': 0.45}

    6. 模型保存与加载

    为了在以后使用模型,我们需要将其保存到文件中。

    model.save_model(output_file)
    print(f"模型已保存到 {output_file}")

    要加载保存的模型,可以使用以下代码:

    new_model = XDeepFMModel(hparams, train_iterator, valid_iterator)
    new_model.load_model(output_file)
    print("模型已加载")

    完整代码示例

    为了便于参考,以下是完整的代码示例,涵盖了从数据加载到模型评估的所有步骤。

    “`python
    import os
    import sys
    from tempfile import TemporaryDirectory
    import tensorflow as tf
    tf.get_logger().setLevel(‘ERROR’)

    from recommenders.models.deeprec.deeprec_utils import download_deeprec_resources, prepare_hparams
    from recommenders.models.deeprec.models.xDeepFM import XDeepFMModel
    from recommenders.models.deeprec.io.iterator import FFMTextIterator
    from recommenders.utils.notebook_utils import store_metadata

    print(f”System version: {sys.version}”)
    print(f”Tensorflow version: {tf.version}”)

    EPOCHS = 10
    BATCH_SIZE = 4096
    RANDOM_SEED = 42

    tmpdir = TemporaryDirectory()
    data_path = tmpdir.name
    yaml_file = os.path.join(data_path, ‘xDeepFM.yaml’)
    output_file = os.path.join(data_path, ‘output.txt’)
    train_file = os.path.join(data_path, ‘cretio_tiny_train’)
    valid_file = os.path.join(data_path, ‘cretio_tiny_valid’)
    test_file = os.path.join(data_path, ‘cretio_tiny_test’)

    if not os.path.exists(yaml_file):
    download_deeprec_resources(‘https://recodatasets.z20.web.core.windows.net/deeprec/’, data_path, ‘xdeepfmresources.zip’)

    print(‘Demo with Criteo dataset’)
    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=BATCH_SIZE,
    epochs=EPOCHS,
    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)
    print(hparams)

    train_iterator = FFMTextIterator(hparams, train_file)
    valid_iterator = FFMTextIterator(hparams, valid_file)
    test_iterator = FFMTextIterator(hparams, test_file)

    model = XDeepFMModel(hparams, train_iterator, valid_iterator)
    model.load_model(output_file)

    print(“开始训练 xDeepFM 模型…”)
    model.fit(train_iterator, valid_iterator)

    print(“评估 xDeepFM 模型…”)
    res = model.run_eval(test_iterator)
    print(“测试集上的评估结果:”, res)

    model.save_model(output_file)
    print(f”模型已保存到 {output_file}”)

    # 加载保存的模型
    new_model = XDeepFMModel(hparams, train_iterator, valid_iterator)
    new_model.load_model(output_file)
    print(“模型已加载”)

    “`

    7. 结果分析

    在模型训练和评估之后,我们可以进一步分析结果。以下是一些常见的分析步骤:

    评估指标

    我们已经在测试集上计算了 AUC 和 logloss。我们可以将这些指标与基准模型进行比较,以评估 xDeepFM 的性能。

    特征重要性

    特征重要性分析有助于理解哪些特征对模型的预测最重要。xDeepFM 通过其嵌入层和 DNN 层捕捉特征交互,我们可以使用这些层的权重来推断特征重要性。

    模型改进

    可以尝试以下方法来改进模型性能:

    • 调整超参数,例如学习率、正则化参数和层大小。
    • 使用更大的训练数据集。
    • 添加新的特征或进行特征工程。

    结论

    本文档详细展示了如何使用 xDeepFM 模型进行 CTR 预测。我们介绍了从数据加载、模型训练到模型评估的完整过程,并提供了代码示例。希望这些内容对您理解和使用 xDeepFM 模型有所帮助。

    参考文献

    [1] Jianxun Lian, et al. “xDeepFM: Combining Explicit and Implicit Feature Interactions for Recommender Systems.” arXiv preprint arXiv:1803.05170 (2018).


    通过以上步骤,您应该能够成功地在 Criteo 数据集上训练和评估 xDeepFM 模型,并进一步分析和改进模型以获得更好的性能。

  • 新闻推荐的秘密武器:多视角注意力学习

    你是否曾被海量新闻淹没,难以找到感兴趣的内容?个性化新闻推荐系统应运而生,它就像一位贴心的新闻管家,根据你的喜好为你推荐最合适的新闻。然而,如何让推荐系统真正理解你的兴趣,并精准地推荐你喜欢的新闻呢?这背后隐藏着许多技术奥秘,而本文将带你揭秘其中一项关键技术:多视角注意力学习

    新闻推荐的挑战

    每天,数以万计的新闻涌现,用户不可能一一阅读。个性化新闻推荐系统肩负着帮助用户找到感兴趣的新闻,缓解信息过载的重任。然而,要实现精准的推荐,需要解决两个核心问题:

    • 如何准确地理解新闻内容? 传统的新闻推荐方法往往只关注新闻标题或内容,忽略了其他重要的信息,例如新闻类别和主题。
    • 如何准确地理解用户兴趣? 用户兴趣是复杂的,仅仅根据用户点击过的新闻无法完全刻画用户兴趣。

    多视角注意力学习:洞悉新闻与用户

    为了解决上述挑战,研究人员提出了多视角注意力学习(NAML)方法。该方法将新闻看作一个多视角的信息集合,并利用注意力机制来识别不同视角中的关键信息,从而构建更准确的新闻和用户表示。

    1. 新闻编码器:多视角融合

    NAML方法的核心是新闻编码器,它将新闻标题、内容和类别等不同信息作为不同的视角,并利用注意力机制来识别每个视角中的关键信息。

    • 标题编码器: 利用卷积神经网络(CNN)来学习标题中词语的上下文信息,并通过词级注意力机制来识别标题中最重要的词语。
    • 内容编码器: 与标题编码器类似,内容编码器也使用CNN来学习内容中的词语上下文信息,并通过词级注意力机制来识别内容中最重要的词语。
    • 类别编码器: 将新闻类别和子类别信息转化为低维向量,并利用全连接层来学习类别信息。
    • 视角级注意力机制: 不同视角的信息对新闻的理解可能具有不同的重要性。例如,对于一些标题简洁、内容丰富的新闻,内容视角可能比标题视角更重要。NAML方法利用视角级注意力机制来评估不同视角的重要性,并根据权重对不同视角的信息进行加权融合,最终得到一个综合的新闻表示。

    2. 用户编码器:个性化理解

    NAML方法还利用用户编码器来学习用户的兴趣表示。用户编码器根据用户点击过的新闻来学习用户的兴趣,并利用新闻级注意力机制来识别用户点击过的新闻中哪些新闻更能代表用户的兴趣。

    3. 点击预测:精准推荐

    NAML方法利用用户表示和新闻表示之间的内积来预测用户点击新闻的概率。为了提高预测的准确性,NAML方法还采用了负采样技术,即对于用户点击过的新闻,随机选取一些用户没有点击过的新闻作为负样本,并利用这些负样本来训练模型。

    实验验证:效果显著

    研究人员在真实世界新闻数据集上进行了实验,结果表明NAML方法显著优于其他基线方法,证明了多视角注意力学习的有效性。

    • 多视角学习的有效性: 实验结果表明,将新闻标题、内容和类别信息作为不同的视角进行融合,可以显著提升新闻推荐的效果。
    • 注意力机制的有效性: 实验结果表明,词级、新闻级和视角级注意力机制都能够有效地识别关键信息,并提升新闻推荐的效果。

    总结

    多视角注意力学习是新闻推荐领域的一项重要技术,它能够有效地利用新闻和用户的多视角信息,构建更准确的新闻和用户表示,从而实现更精准的新闻推荐。随着深度学习技术的不断发展,我们可以期待未来出现更多更强大的新闻推荐技术,为用户提供更加个性化、高效的新闻服务

    参考文献

  • 个性化新闻推荐:让新闻更懂你

    每天,我们都被海量的新闻信息包围,如何从纷繁复杂的新闻中找到自己感兴趣的内容,成为一个越来越重要的课题。个性化新闻推荐系统应运而生,它能够根据用户的兴趣和偏好,为用户推荐他们可能感兴趣的新闻,帮助用户在信息海洋中快速找到自己想要的内容,缓解信息过载带来的压力。

    然而,传统的新闻推荐系统往往存在一些局限性。例如,它们难以准确捕捉用户的个性化兴趣,无法理解不同用户对同一新闻的不同关注点,也无法有效识别新闻标题中不同词语的重要性。

    为了解决这些问题,来自清华大学、北京大学和微软亚洲研究院的研究人员提出了一种名为“个性化注意神经网络”(NPA)的新闻推荐模型。该模型的核心在于通过神经网络学习新闻和用户的表示,并利用个性化注意机制来识别不同用户对新闻的不同关注点。

    NPA:让新闻更懂你

    NPA 模型主要包含三个模块:新闻编码器、用户编码器和点击预测器。

    新闻编码器负责学习新闻的表示。它首先利用词嵌入将新闻标题中的每个词语转化为一个低维稠密向量,然后使用卷积神经网络(CNN)来提取词语之间的局部上下文信息,最后通过一个词级个性化注意网络来识别不同用户对新闻标题中不同词语的不同关注点。

    用户编码器负责学习用户的表示。它根据用户点击过的新闻来学习用户的兴趣,并利用一个新闻级个性化注意网络来识别不同用户对同一新闻的不同关注点。

    点击预测器负责预测用户点击新闻的概率。它利用用户和新闻的表示,通过内积运算和 Softmax 函数来计算用户点击新闻的概率。

    个性化注意机制:识别用户的关注点

    NPA 模型的核心是个性化注意机制,它能够根据用户的个人特征,识别用户对新闻中不同词语和不同新闻的不同关注点。

    在词级个性化注意网络中,模型首先将用户的 ID 嵌入到一个低维向量中,然后利用一个全连接层来学习用户的词语偏好查询向量。接着,模型计算每个词语与查询向量之间的相似度,并利用 Softmax 函数将相似度转化为注意权重。最后,模型根据注意权重对词语的表示进行加权求和,得到用户对新闻标题的表示。

    在新闻级个性化注意网络中,模型同样将用户的 ID 嵌入到一个低维向量中,并利用一个全连接层来学习用户的新闻偏好查询向量。接着,模型计算每个新闻的表示与查询向量之间的相似度,并利用 Softmax 函数将相似度转化为注意权重。最后,模型根据注意权重对新闻的表示进行加权求和,得到用户的表示。

    实验验证:NPA 带来显著提升

    研究人员在来自微软新闻的真实新闻推荐数据集上对 NPA 模型进行了测试,并将其与其他主流新闻推荐模型进行了比较。实验结果表明,NPA 模型在 AUC、MRR、nDCG@5 和 nDCG@10 等指标上均取得了显著的提升,证明了 NPA 模型的有效性。

    此外,研究人员还通过可视化分析,展示了 NPA 模型的个性化注意机制如何识别不同用户对新闻的不同关注点。例如,对于喜欢运动新闻的用户,模型会更多地关注新闻标题中的“NBA”、“NFL”等关键词;而对于喜欢电影新闻的用户,模型则会更多地关注新闻标题中的“电影”、“超级英雄”等关键词。

    总结:NPA 为个性化新闻推荐开辟新方向

    NPA 模型利用神经网络和个性化注意机制,有效地学习了新闻和用户的表示,并识别了不同用户对新闻的不同关注点,从而实现了更精准的个性化新闻推荐。这项研究为个性化新闻推荐领域开辟了新的方向,也为其他推荐系统提供了新的思路。

    参考文献

    [1] Wu, C., Wu, F., An, M., Huang, J., Huang, Y., & Xie, X. (2019). NPA: Neural News Recommendation with Personalized Attention. In Proceedings of the 25th ACM SIGKDD International Conference on Knowledge Discovery & Data Mining (pp. 1029-1038).

    [2] Wang, H., Zhang, F., Xie, X., & Guo, M. (2018). DKN: Deep Knowledge-Aware Network for News Recommendation. In Proceedings of the 2018 World Wide Web Conference (pp. 1835-1844).

    [3] Lian, J., Zhang, F., Xie, X., & Sun, G. (2018). Towards Better Representation Learning for Personalized News Recommendation: a Multi-Channel Deep Fusion Approach. In Proceedings of the 27th International Joint Conference on Artificial Intelligence (pp. 3805-3811).

  • LSTUR:利用长短期用户表示进行新闻推荐

    在信息爆炸的时代,个性化的新闻推荐系统变得越来越重要。LSTUR (Long- and Short-term User Representations) 是一种基于神经网络的新闻推荐方法,它能够有效地捕捉用户的长短期兴趣,从而提供更精准的推荐结果。

    LSTUR 的核心思想

    LSTUR 的核心是新闻编码器和用户编码器。新闻编码器通过学习新闻标题的表示,来理解新闻内容。用户编码器则分为两个部分:长短期用户表示。

    • 长短期用户表示:LSTUR 利用用户的 ID 来学习其长期偏好,并使用 GRU 网络来学习用户最近浏览新闻的短期兴趣。
    • 结合长短期用户表示:LSTUR 提供两种方法来结合长短期用户表示。第一种方法是使用长期用户表示来初始化 GRU 网络的隐藏状态,从而将长期偏好信息融入短期兴趣学习中。第二种方法是将长短期用户表示拼接起来,形成一个统一的用户向量。

    LSTUR 的优势

    LSTUR 具有以下优势:

    • 同时捕捉用户的长短期兴趣:LSTUR 能够同时学习用户的长期偏好和短期兴趣,从而提供更精准的推荐结果。
    • 利用用户 ID 学习长期偏好:LSTUR 利用用户的 ID 来学习其长期偏好,这是一种简单而有效的学习长期兴趣的方法。
    • 利用 GRU 网络学习短期兴趣:LSTUR 利用 GRU 网络来学习用户最近浏览新闻的短期兴趣,这是一种能够捕捉用户动态兴趣变化的有效方法。

    数据格式

    为了方便训练和评估,LSTUR 使用了 MIND 数据集。MIND 数据集分为三个版本:largesmalldemodemo 版本包含 5000 个用户,是 small 版本的子集,用于快速实验。large 版本则包含了更多用户和新闻数据,用于更全面的评估。

    MIND 数据集包含两个文件:news 文件和 behaviors 文件。

    • news 文件:包含新闻信息,例如新闻 ID、类别、子类别、新闻标题、新闻摘要、新闻链接以及新闻标题和摘要中的实体信息。

    示例:

    N46466    lifestyle   lifestyleroyals The Brands Queen Elizabeth, Prince Charles, and Prince Philip Swear By  Shop the notebooks, jackets, and more that the royals can't live without.   https://www.msn.com/en-us/lifestyle/lifestyleroyals/the-brands-queen-elizabeth,-prince-charles,-and-prince-philip-swear-by/ss-AAGH0ET?ocid=chopendata   [{\"Label\": \"Prince Philip, Duke of Edinburgh\", \"Type\": \"P\", \"WikidataId\": \"Q80976\", \"Confidence\": 1.0, \"OccurrenceOffsets\": [48], \"SurfaceForms\": [\"Prince Philip\"]}, {\"Label\": \"Charles, Prince of Wales\", \"Type\": \"P\", \"WikidataId\": \"Q43274\", \"Confidence\": 1.0, \"OccurrenceOffsets\": [28], \"SurfaceForms\": [\"Prince Charles\"]}, {\"Label\": \"Elizabeth II\", \"Type\": \"P\", \"WikidataId\": \"Q9682\", \"Confidence\": 0.97, \"OccurrenceOffsets\": [11], \"SurfaceForms\": [\"Queen Elizabeth\"]}]  []
    • behaviors 文件:包含用户行为信息,例如印象 ID、用户 ID、印象时间、用户点击历史以及印象新闻。

    示例:

    1    U82271  11/11/2019 3:28:58 PM   N3130 N11621 N12917 N4574 N12140 N9748  N13390-0 N7180-0 N20785-0 N6937-0 N15776-0 N25810-0 N20820-0 N6885-0 N27294-0 N18835-0 N16945-0 N7410-0 N23967-0 N22679-0 N20532-0 N26651-0 N22078-0 N4098-0 N16473-0 N13841-0 N15660-0 N25787-0 N2315-0 N1615-0 N9087-0 N23880-0 N3600-0 N24479-0 N22882-0 N26308-0 N13594-0 N2220-0 N28356-0 N17083-0 N21415-0 N18671-0 N9440-0 N17759-0 N10861-0 N21830-0 N8064-0 N5675-0 N15037-0 N26154-0 N15368-1 N481-0 N3256-0 N20663-0 N23940-0 N7654-0 N10729-0 N7090-0 N23596-0 N15901-0 N16348-0 N13645-0 N8124-0 N20094-0 N27774-0 N23011-0 N14832-0 N15971-0 N27729-0 N2167-0 N11186-0 N18390-0 N21328-0 N10992-0 N20122-0 N1958-0 N2004-0 N26156-0 N17632-0 N26146-0 N17322-0 N18403-0 N17397-0 N18215-0 N14475-0 N9781-0 N17958-0 N3370-0 N1127-0 N15525-0 N12657-0 N10537-0 N18224-0

    代码示例

    以下是使用 LSTUR 模型进行新闻推荐的代码示例:

    1. 导入必要的库

    import os
    import sys
    import numpy as np
    import zipfile
    from tqdm import tqdm
    from tempfile import TemporaryDirectory
    import tensorflow as tf
    tf.get_logger().setLevel('ERROR') # only show error messages
    
    from recommenders.models.deeprec.deeprec_utils import download_deeprec_resources 
    from recommenders.models.newsrec.newsrec_utils import prepare_hparams
    from recommenders.models.newsrec.models.lstur import LSTURModel
    from recommenders.models.newsrec.io.mind_iterator import MINDIterator
    from recommenders.models.newsrec.newsrec_utils import get_mind_data_set
    from recommenders.utils.notebook_utils import store_metadata
    
    print("System version: {}".format(sys.version))
    print("Tensorflow version: {}".format(tf.__version__))

    2. 设置参数

    epochs = 5
    seed = 40
    batch_size = 32
    
    # 选择数据集版本: demo, small, large
    MIND_type = "demo"

    3. 下载并加载数据

    tmpdir = TemporaryDirectory()
    data_path = tmpdir.name
    
    train_news_file = os.path.join(data_path, 'train', r'news.tsv')
    train_behaviors_file = os.path.join(data_path, 'train', r'behaviors.tsv')
    valid_news_file = os.path.join(data_path, 'valid', r'news.tsv')
    valid_behaviors_file = os.path.join(data_path, 'valid', r'behaviors.tsv')
    wordEmb_file = os.path.join(data_path, "utils", "embedding.npy")
    userDict_file = os.path.join(data_path, "utils", "uid2index.pkl")
    wordDict_file = os.path.join(data_path, "utils", "word_dict.pkl")
    yaml_file = os.path.join(data_path, "utils", r'lstur.yaml')
    
    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)
    
    if not os.path.exists(valid_news_file):
        download_deeprec_resources(mind_url, os.path.join(data_path, 'valid'), mind_dev_dataset)
    if not os.path.exists(yaml_file):
        download_deeprec_resources(r'https://recodatasets.z20.web.core.windows.net/newsrec/', os.path.join(data_path, 'utils'), mind_utils)

    4. 创建超参数

    hparams = prepare_hparams(yaml_file, 
                              wordEmb_file=wordEmb_file,
                              wordDict_file=wordDict_file, 
                              userDict_file=userDict_file,
                              batch_size=batch_size,
                              epochs=epochs)
    print(hparams)

    5. 创建迭代器

    iterator = MINDIterator

    6. 训练 LSTUR 模型

    model = LSTURModel(hparams, iterator, seed=seed)
    
    # 评估模型
    print(model.run_eval(valid_news_file, valid_behaviors_file))
    
    # 训练模型
    %%time
    model.fit(train_news_file, train_behaviors_file, valid_news_file, valid_behaviors_file)
    
    # 再次评估模型
    %%time
    res_syn = model.run_eval(valid_news_file, valid_behaviors_file)
    print(res_syn)

    7. 保存模型

    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"))

    8. 生成预测文件

    group_impr_indexes, group_labels, group_preds = model.run_fast_eval(valid_news_file, valid_behaviors_file)
    
    with open(os.path.join(data_path, 'prediction.txt'), 'w') as f:
        for impr_index, preds in tqdm(zip(group_impr_indexes, group_preds)):
            impr_index += 1
            pred_rank = (np.argsort(np.argsort(preds)[::-1]) + 1).tolist()
            pred_rank = '[' + ','.join([str(i) for i in pred_rank]) + ']'
            f.write(' '.join([str(impr_index), pred_rank])+ '\n')
    
    f = zipfile.ZipFile(os.path.join(data_path, 'prediction.zip'), 'w', zipfile.ZIP_DEFLATED)
    f.write(os.path.join(data_path, 'prediction.txt'), arcname='prediction.txt')
    f.close()

    总结

    LSTUR 是一种基于神经网络的新闻推荐方法,它能够有效地捕捉用户的长短期兴趣,从而提供更精准的推荐结果。LSTUR 的优势在于能够同时学习用户的长期偏好和短期兴趣,并利用用户 ID 和 GRU 网络来学习用户表示。实验结果表明,LSTUR 模型在新闻推荐任务中取得了较好的效果。

    参考文献

    1. An, Mingxiao, et al. “Neural News Recommendation with Long- and Short-term User Representations.” Proceedings of the 58th Annual Meeting of the Association for Computational Linguistics. 2019.
    2. Wu, Fangzhao, et al. “MIND: A Large-scale Dataset for News Recommendation.” Proceedings of the 58th Annual Meeting of the Association for Computational Linguistics. 2019.
    3. Pennington, Jeffrey, et al. “GloVe: Global Vectors for Word Representation.” Proceedings of the 2014 Conference on Empirical Methods in Natural Language Processing (EMNLP). 2014.
  • 新闻推荐的个性化:长短期用户兴趣如何影响你的阅读体验?

    你是否曾经在新闻网站上看到过你感兴趣的新闻,却发现下一条推荐的新闻与你的兴趣毫无关联?或者,你是否曾经因为一条新闻而对某个话题产生兴趣,却无法找到更多相关内容?

    这正是新闻推荐系统面临的挑战。为了更好地满足用户的个性化需求,新闻推荐系统需要了解用户的兴趣,并根据兴趣推荐相关新闻。然而,用户的兴趣并非一成不变,他们既有长期稳定的偏好,也可能因为特定事件或时间需求而产生短期兴趣。

    传统的新闻推荐方法通常只关注用户的单一兴趣,难以捕捉用户的长短期兴趣变化。 例如,一些方法通过分析用户历史浏览记录来推断用户的兴趣,但这种方法难以区分用户的长期兴趣和短期兴趣。例如,一位用户可能长期关注篮球新闻,但近期可能因为一部电影而对电影相关的新闻产生了兴趣。如果推荐系统只根据历史浏览记录进行推荐,就可能推荐与用户近期兴趣无关的篮球新闻,导致用户体验下降。

    为了解决这个问题,本文介绍了一种新的新闻推荐方法,该方法可以同时学习用户的长短期兴趣,并根据用户的综合兴趣进行推荐。

    长短期用户兴趣:捕捉新闻阅读的多样性

    我们每个人都有自己独特的新闻阅读习惯。有些人长期关注某个特定领域,例如体育、科技或财经。这种长期兴趣反映了用户的稳定偏好,例如一位篮球爱好者可能多年来一直关注NBA新闻。

    另一方面,我们的兴趣也会随着时间而变化。例如,你可能因为一部电影而对电影相关的新闻产生兴趣,或者因为某个突发事件而关注相关报道。这种短期兴趣通常由特定事件或时间需求触发,例如一位用户可能因为观看了电影《波西米亚狂想曲》而对主演拉米·马雷克的新闻产生了兴趣。

    长短期兴趣共同构成了用户的新闻阅读偏好。 为了更好地理解用户的兴趣,我们需要将长短期兴趣区分开来,并分别进行学习。

    LSTUR:长短期用户表示模型

    为了学习用户的长短期兴趣,我们提出了一个新的新闻推荐模型,称为LSTUR(Long- and Short-Term User Representations)。该模型包含两个主要部分:新闻编码器用户编码器

    新闻编码器用于学习新闻的表示,它从新闻标题和主题类别中提取信息,并使用注意力机制来选择重要的词语,从而生成更准确的新闻表示。

    用户编码器则用于学习用户的表示,它包含两个模块:长期用户表示模块(LTUR)短期用户表示模块(STUR)。LTUR通过用户的ID来学习用户的长期兴趣,而STUR则使用循环神经网络(GRU)来学习用户近期浏览新闻的短期兴趣。

    LSTUR模型的两种融合方法

    LSTUR模型提供了两种方法来融合长短期用户表示:

    1. LSTUR-ini: 使用长期用户表示来初始化STUR模型中GRU网络的隐藏状态。
    2. LSTUR-con: 将长期用户表示和短期用户表示连接起来,形成一个统一的用户向量。

    实验结果:LSTUR模型的优越性

    我们在一个真实的新闻数据集上进行了实验,结果表明LSTUR模型显著优于传统的新闻推荐方法,包括基于手工特征工程的模型和基于深度学习的模型。

    实验结果表明,LSTUR模型能够有效地捕捉用户的长短期兴趣,并根据用户的综合兴趣进行推荐。 这说明LSTUR模型能够更好地理解用户的新闻阅读偏好,从而提高新闻推荐的准确性和用户体验。

    未来展望

    LSTUR模型为新闻推荐领域提供了一个新的方向,它可以帮助我们更好地理解用户的兴趣,并提供更个性化的新闻推荐服务。未来,我们可以进一步研究以下问题:

    • 如何更有效地学习用户的长短期兴趣? 例如,我们可以利用用户在不同平台上的行为数据来更全面地了解用户的兴趣。
    • 如何将用户的兴趣与新闻内容进行更精准的匹配? 例如,我们可以利用知识图谱来构建新闻和用户的语义关系,从而进行更精准的推荐。
    • 如何提高新闻推荐系统的可解释性? 例如,我们可以通过可视化技术来展示推荐结果背后的逻辑,帮助用户更好地理解推荐系统的决策过程。

    参考文献

    • An, M., Wu, F., Wu, C., Zhang, K., Liu, Z., & Xie, X. (2019). Neural news recommendation with long- and short-term user representations. In Proceedings of the 2019 Conference of the North American Chapter of the Association for Computational Linguistics: Human Language Technologies, Volume 1 (Long Papers) (pp. 1033-1043).
    • Okura, S., Tagami, Y., Ono, S., & Tajima, A. (2017). Embedding-based news recommendation for millions of users. In Proceedings of the 23rd ACM SIGKDD International Conference on Knowledge Discovery and Data Mining (pp. 1933-1942).

    希望这篇文章能够帮助你更好地理解新闻推荐系统的工作原理,以及用户长短期兴趣对新闻推荐的影响。

  • Recommenders 库简介及使用指南

    Recommenders 是一个旨在帮助研究人员、开发者和爱好者快速构建和部署各种推荐系统的项目。该项目隶属于 Linux Foundation of AI and Data,提供了丰富的 Jupyter Notebook 示例和最佳实践,涵盖了推荐系统的五个关键任务:数据准备、模型构建、算法评估、模型选择与优化,以及模型的生产化部署。

    最新动态(2024年5月)

    我们发布了新版本 Recommenders 1.2.0。此次更新包含大量改进,如对 Python 3.8 至 3.11 的全面测试(大约 1800 个测试)、多种算法性能的提升、笔记本的审查和许多其他改进。

    项目简介

    Recommenders 项目提供了构建推荐系统的示例和最佳实践,主要通过 Jupyter Notebooks 详细展示了以下五个关键任务:

    1. 数据准备:为每个推荐算法准备和加载数据。
    2. 模型构建:使用多种经典和深度学习推荐算法构建模型,如交替最小二乘法(ALS)或极限深度因子分解机(xDeepFM)。
    3. 算法评估:使用离线指标评估算法。
    4. 模型选择与优化:调优和优化推荐模型的超参数。
    5. 模型生产化部署:在 Azure 上将模型部署到生产环境。

    此外,Recommenders 库还提供了多种实用工具,支持常见任务如加载数据集、评估模型输出和分割训练/测试数据。库中还包含了一些最先进的算法实现,供学习和在实际应用中定制。

    快速开始

    我们推荐使用 conda 进行环境管理,并使用 VS Code 进行开发。以下是在 Linux/WSL 上安装 Recommenders 包并运行示例笔记本的步骤:

    # 1. 安装 gcc(如果尚未安装)。在 Ubuntu 上,可以使用以下命令:
    # sudo apt install gcc
    
    # 2. 创建并激活新的 conda 环境
    conda create -n <environment_name> python=3.9
    conda activate <environment_name>
    
    # 3. 安装 Recommenders 核心包。它可以运行所有 CPU 笔记本。
    pip install recommenders
    
    # 4. 创建一个 Jupyter 内核
    python -m ipykernel install --user --name <environment_name> --display-name <kernel_name>
    
    # 5. 在 VSCode 中或使用命令行克隆此仓库:
    git clone https://github.com/recommenders-team/recommenders.git
    
    # 6. 在 VSCode 中:
    #   a. 打开一个笔记本,例如 examples/00_quick_start/sar_movielens.ipynb;
    #   b. 选择 Jupyter 内核 <kernel_name>;
    #   c. 运行笔记本。

    关于在其他平台(如 Windows 和 macOS)上的安装和不同配置(如 GPU、Spark 和实验特性)的更多信息,请参阅 Setup Guide

    除了核心包,Recommenders 还提供了几个额外的包,包括:

    • [gpu]:用于运行 GPU 模型。
    • [spark]:用于运行 Spark 模型。
    • [dev]:用于仓库开发。
    • [all]:包含 [gpu][spark][dev]
    • [experimental]:包含未经过充分测试和/或可能需要额外安装步骤的模型。

    支持的算法

    Recommenders 库目前支持多种推荐算法,以下是部分算法的简介及其示例:

    算法类型描述示例
    交替最小二乘法 (ALS)协同过滤针对显式或隐式反馈的大规模数据集的矩阵分解算法,适用于 PySpark 环境。快速开始 / 深入探讨
    ——-——————
    注意力异步奇异值分解 (A2SVD)协同过滤基于序列的算法,使用注意力机制捕捉用户的长短期偏好,适用于 CPU/GPU 环境。快速开始
    Cornac/Bayesian Personalized Ranking (BPR)协同过滤用于预测隐式反馈的矩阵分解算法,适用于 CPU 环境。深入探讨
    Cornac/Bilateral Variational Autoencoder (BiVAE)协同过滤用于二元数据(如用户-物品交互)的生成模型,适用于 CPU/GPU 环境。深入探讨
    卷积序列嵌入推荐 (Caser)协同过滤基于卷积的算法,旨在捕捉用户的总体偏好和序列模式,适用于 CPU/GPU 环境。快速开始
    深度知识感知网络 (DKN)内容过滤结合知识图谱和文章嵌入的深度学习算法,用于新闻或文章推荐,适用于 CPU/GPU 环境。快速开始 / 深入探讨
    极限深度因子分解机 (xDeepFM)协同过滤用于隐式和显式反馈的深度学习算法,适用于 CPU/GPU 环境。快速开始
    FastAI 嵌入点偏差 (FAST)协同过滤通用算法,使用用户和物品的嵌入和偏差,适用于 CPU/GPU 环境。快速开始
    LightFM/因子分解机协同过滤适用于隐式和显式反馈的因子分解机算法,适用于 CPU 环境。快速开始
    LightGBM/梯度提升树内容过滤适用于内容过滤问题的梯度提升树算法,具有快速训练和低内存使用的特点,适用于 CPU/GPU/PySpark 环境。CPU 快速开始 / PySpark 深入探讨
    LightGCN协同过滤简化的图卷积网络设计,用于预测隐式反馈,适用于 CPU/GPU 环境。深入探讨
    GeoIMC协同过滤利用黎曼共轭梯度优化的几何方法进行矩阵补全算法,适用于 CPU 环境。快速开始
    GRU协同过滤基于序列的算法,使用递归神经网络捕捉用户的长短期偏好,适用于 CPU/GPU 环境。快速开始
    多项式 VAE协同过滤用于预测用户/物品交互的生成模型,适用于 CPU/GPU 环境。深入探讨

    结束语

    Recommenders 库为开发推荐系统提供了丰富的资源和工具,无论是初学者还是有经验的开发者都能从中受益。通过详细的文档和多种示例,你可以快速上手并在不同的应用场景中实现推荐系统。如果你对推荐系统感兴趣,建议你深入探索 Recommenders 库中的各个示例,并根据自己的需求进行定制和扩展。

    进一步学习和支持

    文档和资源

    Recommenders 提供了详细的文档和资源,帮助你更好地理解和使用该库:

    • 官方文档:详细介绍了库的安装、使用方法和各个算法的具体实现。
    • Wiki 页面:包含项目相关的文档和演示文稿。
    • 实际应用场景:展示了推荐系统在各种实际场景中的应用实例。

    社区和支持

    Recommenders 项目由一个活跃的社区支持,你可以通过以下方式获取帮助或参与贡献:

    • 加入 Slack 社区:与其他用户和开发者交流,获取实时帮助。
    • GitHub 讨论:在项目的讨论区提出问题、分享经验或讨论改进建议。
    • 贡献代码:如果你有兴趣为项目做出贡献,可以查看贡献指南,了解如何提交代码、报告问题或改进文档。

    安装和环境配置

    为了方便开发和环境管理,Recommenders 推荐使用 conda。以下是关于环境配置的一些重要提示:

    • 核心包pip install recommenders 安装核心包,适用于大多数 CPU 环境。
    • 额外包
    • [gpu]pip install recommenders[gpu],适用于需要 GPU 支持的模型。
    • [spark]pip install recommenders[spark],适用于需要 Spark 支持的模型。
    • [dev]pip install recommenders[dev],适用于开发和测试。
    • [all]pip install recommenders[all],包含以上所有额外功能。
    • [experimental]pip install recommenders[experimental],包含实验性模型和功能。

    示例运行

    以下是一个快速示例,展示如何使用 Recommenders 运行一个 Jupyter Notebook:

    1. 安装依赖# 安装 gcc(如果尚未安装) sudo apt install gcc # 创建并激活新的 conda 环境 conda create -n recommenders_env python=3.9 conda activate recommenders_env # 安装 Recommenders 核心包 pip install recommenders # 创建 Jupyter 内核 python -m ipykernel install --user --name recommenders_env --display-name "Recommenders Env"
    2. 克隆仓库git clone https://github.com/recommenders-team/recommenders.git
    3. 运行 Jupyter Notebook
      • 打开 VS Code,加载克隆的仓库。
      • 选择一个示例笔记本,如 examples/00_quick_start/sar_movielens.ipynb
      • 选择 Jupyter 内核 “Recommenders Env”。
      • 运行笔记本,体验推荐系统的构建过程。

    通过这些步骤,你可以轻松上手 Recommenders 库,开始构建和优化自己的推荐系统。希望这篇文章能帮助你更好地理解和使用 Recommenders 库,祝你在推荐系统的探索之旅中取得成功!