前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
社区首页 >专栏 >构建数据可视化代理(Plotly)

构建数据可视化代理(Plotly)

作者头像
云云众生s
发布于 2024-05-30 05:07:07
发布于 2024-05-30 05:07:07
19100
代码可运行
举报
文章被收录于专栏:云云众生s云云众生s
运行总次数:0
代码可运行

Plotly 是我最喜欢的数据可视化库。在广泛撰写有关使用 Plotly 创建高级可视化的文章后,我产生了好奇:我能否通过仅提供 dataframe 和自然语言指令来教语言模型构建我喜欢的可视化?本项目就是尝试此想法的成果,我很高兴与你分享结果。

译自 Building an Agent for Data Visualization (Plotly),作者 Arslan Shahid。

为什么构建代理?

如果你曾尝试过 ChatGPTLLM,你就会知道它们可以为几乎任何语言或包生成代码。但是,仅依赖 LLM 存在局限性。以下是通过构建代理我旨在解决的一些关键问题:

  1. 描述你的数据:LLM 本质上不知道你的数据集的具体信息,例如列名称和行详细信息。手动提供此信息可能很麻烦,尤其是在数据集变大时。如果没有此上下文,LLM 可能会产生幻觉或发明列名称,从而导致数据可视化中的错误。
  2. 样式和偏好:数据可视化是一种艺术形式,每个人都有独特的审美偏好,这些偏好因图表类型和信息而异。为每个可视化持续向 LLM 提供详细说明很乏味。配备了样式信息的代理可以简化此过程,确保一致且个性化的视觉输出。
  3. 代理推理:ReAct 代理具有“推理”和执行任务的能力,从而产生更准确的响应和更少的幻觉。这种高级提示工程技术已被证明可以产生更强大、更可靠的结果。你可以在此 论文 中阅读有关 ReAct 代理的更多信息。

构建代理可以缓解这些问题,为数据可视化和其他任务提供更高效、更定制的方法。

下面你可以看到当我告诉 Llama3:70B(我为最终代理使用的 LLM)构建可视化时的基线。

作者图片——用70B 模型询问 Groq,它为数据创建的假名,下面可以看到可视化

作者图片 — 当我修复Llama3制作的一些错误时,可视化看起来是这样。不是一个好的输出

设计

要构建此应用程序,我们需要为 LLM 代理配备两个工具,以便帮助它生成更好的数据可视化。一个工具提供有关数据集的信息,另一个工具包含有关样式的信息。

Llama-index 允许将任何查询引擎用作代理工具。由于这两个工具都涉及信息检索,因此查询引擎工具适合我们的需求。

dataframe 索引

此工具的目的是分析 dataframe 并将其内容信息存储到索引中。要编制索引的数据包括列名称、数据类型以及值的最小、最大和平均范围。这有助于代理了解他们正在处理的变量类型。

在此示例中,使用了 layoff.fyi 中的数据。但是,该工具可以与任何 dataframe 一起使用。

预处理

预处理至关重要,并且因数据集而异。建议将数据转换为适当的类型(例如,将数字字符串转换为整数或浮点数)并删除空值。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
#Optional pre-processing
import pandas as pd
import numpy as np


df = pd.read_csv('WARN Notices California_Omer Arain - Sheet1.csv')

#Changes date like column into datetime 
df['Received Date'] = [pd.to_datetime(x) for x in df['Received Date']]
df['Effective Date'] = [pd.to_datetime(x) for x in df['Effective Date']]
#Converts numbers stored as strings into ints
df['Number of Workers'] = [int(str(x).replace(',','')) if str(x)!='nan' else np.nan for x in df['Number of Workers']]
# Replacing NULL values
df = df.replace(np.nan,0)

将数据集信息存储到索引

以下是如何实现 DataFrame 索引

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
from llama_index.core.readers.json import JSONReader
from llama_index.core import VectorStoreIndex
import json

# Function that stores the max,min & mean for numerical values
def return_vals(df,c):
    if isinstance(df[c].iloc[0], (int, float, complex)):
        return [max(df[c]), min(df[c]), np.mean(df[c])]
# For datetime we need to store that information as string
    elif(isinstance(df[c].iloc[0],datetime.datetime)):
        return [str(max(df[c])), str(min(df[c])), str(np.mean(df[c]))]
    else:
# For categorical variables you can store the top 10 most frequent items and their frequency
        return list(df[c].value_counts()[:10])

# declare a dictionary 
dict_ = {}
for c in df.columns:
# storing the column name, data type and content
  dict_[c] = {'column_name':c,'type':str(type(df[c].iloc[0])), 'variable_information':return_vals(df,c)}
# After looping storing the information as a json dump that can be loaded 
# into a llama-index Document

# Writing the information into dataframe.json 

with open("dataframe.json", "w") as fp:
    json.dump(dict_ ,fp) 


reader = JSONReader()
# Load data from JSON file
documents = reader.load_data(input_file='dataframe.json')

# Creating an Index
dataframe_index =  VectorStoreIndex.from_documents(documents)

样式索引

样式工具作为文档存储,其中包含有关如何使用 plotly 样式不同图表自然语言说明。我鼓励你尝试给出的不同说明。以下是有关如何构建折线图和条形图的说明!

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
from llama_index.core import Document
from llama_index.core import VectorStoreIndex

styling_instructions =[Document(text="""
  Dont ignore any of these instructions.
        For a line chart always use plotly_white template, reduce x axes & y axes line to 0.2 & x & y grid width to 1. 
        Always give a title and make bold using html tag axis label and try to use multiple colors if more than one line
        Annotate the min and max of the line
        Display numbers in thousand(K) or Million(M) if larger than 1000/100000 
        Show percentages in 2 decimal points with '%' sign
        """
        )
        , Document(text="""
        Dont ignore any of these instructions.
        For a bar chart always use plotly_white template, reduce x axes & y axes line to 0.2 & x & y grid width to 1. 
        Always give a title and make bold using html tag axis label and try to use multiple colors if more than one line
        Always display numbers in thousand(K) or Million(M) if larger than 1000/100000. Add annotations x values
        Annotate the values on the y variable
        If variable is a percentage show in 2 decimal points with '%' sign.
        """)


       # You should fill in instructions for other charts and play around with these instructions
       , Document(text=
          """ General chart instructions
        Do not ignore any of these instructions
         always use plotly_white template, reduce x & y axes line to 0.2 & x & y grid width to 1. 
        Always give a title and make bold using html tag axis label 
        Always display numbers in thousand(K) or Million(M) if larger than 1000/100000. Add annotations x values
        If variable is a percentage show in 2 decimal points with '%'""")
         ]
# Creating an Index
style_index =  VectorStoreIndex.from_documents(styling_instructions)

构建代理

创建的索引需要基于代理作为工具。Llama-Index 具有可从索引构建查询引擎并将其用作工具的功能。

图片作者 — 解释 Agent 的工作原理

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
#All imports for this section
from llama_index.core.agent import ReActAgent
from llama_index.core.tools import QueryEngineTool
from llama_index.core.tools import  ToolMetadata
from llama_index.llms.groq import Groq


# Build query engines over your indexes
# It makes sense to only retrieve one document per query 
# However, you may play around with this if you need multiple charts
# Or have two or more dataframes with similar column names
dataframe_engine = dataframe_index.as_query_engine(similarity_top_k=1)
styling_engine = style_index.as_query_engine(similarity_top_k=1)

# Builds the tools
query_engine_tools = [
    QueryEngineTool(
        query_engine=dataframe_engine,
# Provides the description which helps the agent decide which tool to use 
        metadata=ToolMetadata(
            name="dataframe_index",
            description="Provides information about the data in the data frame. Only use column names in this tool",
        ),
\
    ),
    QueryEngineTool(
# Play around with the description to see if it leads to better results
        query_engine=styling_engine,
        metadata=ToolMetadata(
            name="Styling",
            description="Provides instructions on how to style your Plotly plots"
            "Use a detailed plain text question as input to the tool.",
        ),
    ),
]

# I used open-source models via Groq but you can use OpenAI/Google/Mistral models as well
llm = Groq(model="llama3-70b-8192", api_key="<your_api_key>")

# initialize ReAct agent
agent = ReActAgent.from_tools(query_engine_tools, llm=llm, verbose=True)

调整 Agent 提示

Llama-Index 和其他编排包具有默认提示,这些提示可能不适用于你的特定用例。在反复试验时我发现,稍微调整提示有助于防止出现幻觉。

作者图片——这是 ReAct Agent 的默认提示语

图片来自作者——调整提示,以黄色突出显示所做的更改

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
from llama_index.core import PromptTemplate

new_prompt_txt= """You are designed to help with building data visualizations in Plotly. You may do all sorts of analyses and actions using Python

## Tools

You have access to a wide variety of tools. You are responsible for using the tools in any sequence you deem appropriate to complete the task at hand.
This may require breaking the task into subtasks and using different tools to complete each subtask.

You have access to the following tools, use these tools to find information about the data and styling:
{tool_desc}


## Output Format

Please answer in the same language as the question and use the following format:

\`\`\`
Thought: The current language of the user is: (user's language). I need to use a tool to help me answer the question.
Action: tool name (one of {tool_names}) if using a tool.
Action Input: the input to the tool, in a JSON format representing the kwargs (e.g. {{"input": "hello world", "num_beams": 5}})
\`\`\`

Please ALWAYS start with a Thought.

Please use a valid JSON format for the Action Input. Do NOT do this {{'input': 'hello world', 'num_beams': 5}}.

If this format is used, the user will respond in the following format:

\`\`\`
Observation: tool response
\`\`\`

You should keep repeating the above format till you have enough information to answer the question without using any more tools. At that point, you MUST respond in the one of the following two formats:

\`\`\`
Thought: I can answer without using any more tools. I'll use the user's language to answer
Answer: [your answer here (In the same language as the user's question)]
\`\`\`

\`\`\`
Thought: I cannot answer the question with the provided tools.
Answer: [your answer here (In the same language as the user's question)]
\`\`\`

## Current Conversation

Below is the current conversation consisting of interleaving human and assistant messages."""

# Adding the prompt text into PromptTemplate object
new_prompt = PromptTemplate(new_prompt_txt)

# Updating the prompt
agent.update_prompts({'agent_worker:system_prompt':new_prompt})

可视化

现在进入有趣的部分,在第一部分中,我展示了 Llama 3 如何响应我构建可视化的请求。现在让我们向代理提出类似的请求。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
response = agent.chat("Give Plotly code for a line chart for Number of Workers get information from the dataframe about the correct column names and make sure to style the plot properly and also give a title")

作者图片 — 你可以了解代理如何分解请求,并在最后用 Python 代码做出响应(你可以直接生成输出解析器,或复制并运行)

作者图片 — 通过运行以下代码创建的图表,注释、标签/标题、轴格式完全按照样式化信息进行。并且不会构成数据,因为它已经包含了关于 dataframe 的信息。

不断围绕样式指令和代理提示进行调整可以产生更好的回复。该项目还有很长的路要走!然而,它可以帮助你节省时间并提供更好的可视化代码。

后续步骤

该项目的下一阶段涉及优化提示和处理常见的故障用例。最终目标是制作一套代理工具,可以帮助我(作为数据科学家)在工作时节省时间。如果您喜欢这个概念,请在 Medium 上关注我。

感谢您的阅读!

相关文章:

  1. LangChain:2023 年最流行的 Web 框架,这要归功于 AI
  2. 低代码生成式AI:让AI更容易的新解决方案
  3. 人工智能代理需要Code Interpreter的4个原因
  4. LLM 如何转变企业应用
  5. 当云遇见智能:推理AI即服务
本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2024-05-29,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
Unity动画☀️8. 添加角色控制器、Curves、添加滑动
添加角色控制器Character Controller后,人物不会因动画问题而导致Y轴变化,人物会始终位于水平地面上
星河造梦坊官方
2024/08/14
1280
Unity动画☀️8. 添加角色控制器、Curves、添加滑动
Unity动画☀️9. 木头自转、扛起木头、OnTriggerEnter
1️⃣ 导入木头Log,找回丢失的贴图,通过Perfab的Model—Scale Factor调节导入比例—0.3
星河造梦坊官方
2024/08/14
1260
Unity动画☀️9. 木头自转、扛起木头、OnTriggerEnter
Unity动画☀️11. IK动画—手与木头的匹配
MatchTarget实现从一段时间区域内,一个点到另一个点匹配的过程;IK动画用于直接将手或脚与某点的匹配
星河造梦坊官方
2024/08/14
2230
Unity动画☀️11. IK动画—手与木头的匹配
Unity动画☀️7. 通过MatchTarget匹配跳墙动画、Vector3、获取动画层GetCurrentAnimatorStateInfo(a).IsName(b)
b、Animator.GetCurrentAnimatorStateInfo(a).IsName("b")
星河造梦坊官方
2024/08/14
1210
Unity动画☀️7. 通过MatchTarget匹配跳墙动画、Vector3、获取动画层GetCurrentAnimatorStateInfo(a).IsName(b)
【Unity3D】鼠标射线点击,UI出现在鼠标点击的位置
创建一条射线Ray需要指明射线的起点(origin)和射线的方向(direction)。这两个参数也是Ray的成员变量。注意,射线的方向在设置时如果未单位化,Unity 3D会自动进行单位归一化处理。射线Ray的构造函数为 :
恬静的小魔龙
2020/03/10
5.3K0
Unity 基础 - 射线
Unity 中虚拟射线能够检测所碰撞到物体,使用 Physics 类的 Raycast 方法实现色心啊碰撞检测功能。
hrscy
2018/08/30
1.2K0
控制人物移动篇
版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
bering
2019/12/03
1.2K0
unity3d:动画animator,AvatarMask,边走边攻击,单独设置run动画速度
分为3layer,run-idel层(layer0),攻击时上半身层(layer1),原地攻击层(layer2),其中layer1,layer2里面完全复制的动画状态机
立羽
2023/08/24
3560
unity3d:动画animator,AvatarMask,边走边攻击,单独设置run动画速度
Unity-BattleStar丨8. 物理引擎Rigidbody组件、Collider组件、Raycast
游戏中物理引擎用于模拟真实世界物理环境效果,要实现游戏对象的物理行为,Rigidbody(刚体)组件是必不可少的,当挂载该组件之后,物体立刻受到重力等物理效果影响。如果对象身上还挂载着Collider(碰撞)组件,那么该对象还受到碰撞物理效果影响,例如游戏中的被车撞飞
星河造梦坊官方
2024/08/14
2150
Unity-BattleStar丨8. 物理引擎Rigidbody组件、Collider组件、Raycast
unity中射线碰撞检测总结
版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
bering
2019/12/03
2.1K0
Unity基础(14)-事件系统
1.Awake:用于在游戏开始之前初始化变量或游戏状态。在脚本整个生命周期内它仅被调用一次.Awake在所有对象被初始化之后调用,所以你可以安全的与其他对象对话或用诸如GameObject.FindWithTag()这样的函数搜索它们。每个游戏物体上的Awake以随机的顺序被调用。因此,你应该用Awake来设置脚本间的引用,并用Start来传递信息Awake总是在Start之前被调用。它不能用来执行协同程序。
孙寅
2020/06/02
1.7K0
Unity动画☀️3. Blend Tree下角色左右转向 &amp; Computer Positions
1️⃣ a、将Blend Tree的Blend Type设置为2D Freeform Directional,下方的两个参数代表:我们将通过控制这两个参数,来控制角色两个方向的运动
星河造梦坊官方
2024/08/14
1550
Unity动画☀️3. Blend Tree下角色左右转向 &amp; Computer Positions
Unity动画☀️一、通过 StringToHash ,控制Animator
并对他身上的Animator进行配置,方便我们使用代码,控制Animator,从而控制这个人物做出各种动作。
星河造梦坊官方
2024/08/14
2800
Unity动画☀️一、通过 StringToHash ,控制Animator
Unity-BattleStar丨11. 且听风吟:音乐与音效
Assets新建Resources文件夹,将音乐放入其中,代码使用Resources.Load方法,动态更换Audio Clip
星河造梦坊官方
2024/08/14
1080
Unity-BattleStar丨11. 且听风吟:音乐与音效
官方案例--Survival Shoot(一)
导入Survival Shooter.unitypackage,里面有个完整了,新版本导入的时候,需要简单的修改一下代码;
酱紫安
2021/11/30
4750
官方案例--Survival Shoot(一)
Unity Rigidbody实现爬坡功能
实现人物爬坡功能前,通过获取用户Horizontal和Vertical轴输入形成了一个移动方向Move Direction,该方向平行于地面,驱动Rigidbody沿该方向移动,代码如下:
CoderZ
2022/12/26
1.1K0
Unity Rigidbody实现爬坡功能
Unity3D+VR的实现
1、创建VRCamera: 使用Dive插件,从DiveUnityDemo提取摄像机和有关的脚本并export出来。
py3study
2020/01/14
6390
Unity动画☀️2.角色左右转向、Blend Tree混合树、批量注释
因为这三个动画对旋转、Y轴无影响,只对Z方向有影响,所以在Blend Tree的Blend Type选择1D。
星河造梦坊官方
2024/08/14
5760
Unity动画☀️2.角色左右转向、Blend Tree混合树、批量注释
Unity LineRenderer 射线检测 激光攻击
在进行激光攻击的脚本编写前,我们先进行一定程度的想象,思考激光和普通的远程攻击有哪些不太一样的地方。
汐夜koshio
2020/03/19
2.1K1
Unity基础(22)-Navigation导航系统
同时设置为不阻碍行走-Walkable ,即可以在障碍物上行走。
孙寅
2020/06/02
1.3K0
Unity基础(22)-Navigation导航系统
推荐阅读
相关推荐
Unity动画☀️8. 添加角色控制器、Curves、添加滑动
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档