LLM代理应用实战:构建Plotly数据可视化代理

news2024/9/21 14:42:07

如果你尝试过像ChatGPT这样的LLM,就会知道它们几乎可以为任何语言或包生成代码。但是仅仅依靠LLM是有局限的。对于数据可视化的问题我们需要提供一下的内容

描述数据:模型本身并不知道数据集的细节,比如列名和行细节。手动提供这些信息可能很麻烦,特别是当数据集变得更大时。如果没有这个上下文,LLM可能会产生幻觉或虚构列名,从而导致数据可视化中的错误。

样式和偏好:数据可视化是一种艺术形式,每个人都有独特的审美偏好,这些偏好因图表类型和信息而异。不断地为每个可视化提供不同的风格和偏好是很麻烦的。而配备了风格信息的代理可以简化这一过程,确保一致和个性化的视觉输出。

如果每次于LLM进行交互都附带这些内容会导致请求过于复杂,不利于用户的输入,所以这次我们构建一个数据可视化的代理,通过代理我们只需提供很少的信息就能够让LLM生成我们定制化的图表。

可视化库的选择

在构建一个数据可视化的AI代理时,选择合适的可视化工具是至关重要的。虽然存在多种工具可以用于数据可视化,但Plotly和Matplotlib是最为常用的两种。为了构建一个既功能丰富又用户友好的可视化界面,我们决定使用Plotly作为主要的可视化库。

与Matplotlib相比,Plotly提供了更加丰富的交互性功能。它支持直接在Web浏览器中的动态渲染,使得用户能够通过缩放、平移、悬停来互动式地探索数据。这种高度的交互性是Plotly的一大优势,尤其是在需要展示复杂数据集或进行深入数据分析的应用场景中。

虽然Matplotlib在科学研究和学术出版物中有广泛的应用,特别是在生成高质量的静态图像方面具有极高的灵活性和精确度,但其在交互性和Web集成方面的限制使得它在构建现代、交互式的数据可视化解决方案时可能不如Plotly那么吸引人。

所以我们选择Plotly作为构建数据可视化AI代理的工具,不仅能够满足用户对交互性的需求,还能够提供强大的数据处理能力和优秀的用户体验。这将极大地提高数据可视化的效率和效果,使得数据分析更加直观和易于理解。

下面是我使用Llama3 70B构建可视化基线。

我们执行上面的代码将得到如下的结果

要构建这个应用程序,我们需要为LLM代理配备两个工具:一个工具提供关于数据集的信息,另一个工具包含关于样式的信息。

代理提供的信息

1、DataFrame信息

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

这里我们使用layoff.fyi 的数据来进行分析。

我们这里还做了一些预处理的工作,包括将数据转换为适当的类型(例如,将数字字符串转换为整数或浮点数)并删除空值。

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

将数据集信息存储到索引中

 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)

这样第一步就完成了。

2、自定义样式信息

表样式主要包括关于如何在plot中设置不同图表样式的自然语言说明。这里需要使用自然语言描述样式,所以可能需要进行尝试,下面是我如何创建折线图和条形图的说明!

 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)

或者直接将部分样式的代码作为示例输入给模型,这样对于固定的样式是非常好的一个方式

构建AI代理

我们上面已经构建了2个索引:DataFrame信息(元数据),表格自定义样式信息

下面就可以使用lama- index从索引构建查询引擎并将其用作代理工具使用。

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

为了防止幻觉,我这里稍微调整了一下提示,这步不是必须的

这里是ReAct的默认提示

修改为:

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

可视化

现在让就可以向我们构建的代理发起请求了

 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代码进行响应(可以直接构建输出解析器或复制过去并运行)。

通过运行以代码创建的图表,将注释、标签/标题和轴格式与样式信息完全一致。因为已经有了数据信息,所以我们直接提出要求就可以,不需要输入任何的数据信息

在试一试其他的图表,生成一个柱状图

结果如下:

总结

AI代理可以自动化从多个数据源收集、清洗和整合数据的过程。这意味着可以减少手动处理错误,提高数据处理速度,让分析师有更多时间专注于解读数据而不是处理数据。使用AI代理进行数据可视化能够显著提升数据分析的深度和广度,同时提高效率和用户体验,帮助企业和组织更好地利用他们的数据资产。

我们这里只是做了第一步,如果要制作一套代理工具还需要很多步骤,比如可视化代码的自动执行,优化提示和处理常见故障等等,如果你对这方面感兴趣,可以留言,如果人多的话我们会在后续的文章中一一介绍。

https://avoid.overfit.cn/post/b7250a6a029d46adb2c5948eb71b5d28

作者:Arslan Shahid

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1925577.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

javascipt学习笔记一

JavaScript基础day1 一、编程语言 1.编程 编程&#xff1a;就是让计算机为解决某个问题而使用某种编程设计语言编写程序代码&#xff0c;最终得到结果的过程 计算机程序&#xff1a; 就是计算机所执行的一系列的指令集合。 2.计算机语言 计算机语言指的是用于人与计算机之间通…

Manim的代码练习02:在manim中Dot ,Arrow和NumberPlane对象的使用

Dot&#xff1a;指代点对象或者表示点的符号。Arrow&#xff1a;指代箭头对象&#xff0c;包括直线上的箭头或者向量箭头等。NumberPlane&#xff1a;指代数轴平面对象&#xff0c;在Manim中用来创建包含坐标轴的数学坐标系平面。Text&#xff1a;指代文本对象&#xff0c;用来…

国产数据库VastBase与C/C++程序适配

背景 2022年底的项目&#xff0c;记录一下。 某项目后台使用C程序开发&#xff0c;使用的是OCI连接Oracle数据库。现需要做去O国产化适配改造。 本文聊聊C/C应用程序如何使用VastBase替换Oracle。 编译适配 开发包获取 从VastBase官方或接口人处获取OCI开发包&#xff0c;包含…

品牌产业出海指南如何搭建国际化架构的跨境电商平台?

在“品牌&产业出海指南 – 成功搭建跨境电商平台”系列中&#xff0c;我们将从电商分销系统、跨境平台商城/多商户商城系统和国际化架构三个方面对帮助您梳理不同平台模式的优缺点、应用场景、开发重点和运营建议。 在“品牌&产业出海指南 – 成功搭建跨境电商平台”系…

verITAS:大规模验证图像转换

1. 引言 斯坦福大学Trisha Datta、Binyi Chen 和 Dan Boneh 2024年论文《VerITAS: Verifying Image Transformations at Scale》&#xff0c;开源代码实现见&#xff1a; https://github.com/zk-VerITAS/VerITAS&#xff08;RustPython&#xff09; 依赖https://github.com/a…

Java的高级特性

类的继承 继承是从已有的类中派生出新的类&#xff0c;新的类能拥有已有类的属性和行为&#xff0c;并且可以拓展新的属性和行为 public class 子类 extends 父类{子类类体 } 优点 代码的复用 提高编码效率 易于维护 使类与类产生关联&#xff0c;是多态的前提 缺点 类缺乏独…

纯vue+js实现数字0到增加到指定数字动画效果功能

关于数字增加动画效果网上基本上都是借助第三方插件实现的,就会导致有的项目安装插件总会出问题,所有最好使用原生vue+js实现,比较稳妥 纯vue+js实现数字0到增加到指定数字动画效果功能 vue+js 实现数字增加动画功能 效果图 其中,关于数字变化的间隔时间,延时效果都可…

Linux环境下激活使用Navicat

Linux环境下激活使用Navicat 解压navicat15-premium-linux.zip文件&#xff0c;存放目录自行定义&#xff0c;此处我解压到/home/admin/Downloads&#xff0c;下载地址&#xff1a;https://www.123pan.com/s/hyS7Vv-zJCR.html # 在桌面创建临时目录 mkdir ~/Desktop/navicat…

Flutter和React Native(RN)的比较

Flutter和React Native&#xff08;RN&#xff09;都是用于构建跨平台移动应用程序的流行框架。两者都具有各自的优势和劣势&#xff0c;选择哪个框架取决于您的具体需求和项目。北京木奇移动技术有限公司&#xff0c;专业的软件外包开发公司&#xff0c;欢迎交流合作。 以下是…

算法学习笔记(8.5)-零钱兑换问题二

目录 Question&#xff1a; 动态规划思路&#xff1a; 代码实现&#xff1a; 空间优化代码 Question&#xff1a; 给定n种硬币&#xff0c;第i种硬币的面值为coins[i-1],目标金额为amt&#xff0c;每种硬币可以重复选取&#xff0c;问凑出目标金额的硬币组合数量。 动态规划思路…

教你如何白嫖ioDraw

ioDraw推出了这个活动&#xff0c;大家看看~ 领取页面 邀请奖励 您和好友都将获得7天的会员权益 邀请攻略 活动介绍 1. 每成功邀请一个新用户&#xff0c;邀请者与被邀请者均可获得7天会员 2. 每年最高可得350天 3. 新用户是指首次登录ioDraw的用户 获取邀请链接步骤 1. 浏…

VS2019配置OpenGL的库

OpenGL环境的配置&#xff08;GLUT安装教程&#xff09;_opengl官网-CSDN博客 我是根据这篇来配置的&#xff0c;然后&#xff1a; 引用的头文件不是<OpenGL/glut.h>而是<GL/glut.h>&#xff0c;然后就可以运行了。

CCSI: 数据无关类别增量学习的持续类特定印象| 文献速递-基于深度学习的多模态数据分析与生存分析

Title 题目 CCSI: Continual Class-Specific Impression for data-free class incremental learning CCSI: 数据无关类别增量学习的持续类特定印象 01 文献速递介绍 当前用于医学影像分类任务的深度学习模型表现出令人鼓舞的性能。这些模型大多数需要在训练之前收集所有的…

【tomcat】Tomcat如何扩展Java线程池原理

池化技术 在后端中&#xff0c;对于经常使用池化就是来提升系统性能&#xff0c;比如数据库连接池、线程池连接池等&#xff0c;本质都是利用空间换时间的来提升性能&#xff0c;用来避免资源的频繁创建和销毁&#xff0c;以此提高资源的复用率&#xff0c;所以合理设置系统所…

springboot个人健康信息管理小程序-计算机毕业设计源码

摘要 在当今这个数字化、信息化的时代&#xff0c;个人健康管理已成为人们生活中不可或缺的一部分。随着生活节奏的加快&#xff0c;越来越多的人开始关注自己的身体状况&#xff0c;希望能够及时了解并调整自己的生活习惯&#xff0c;以达到最佳的健康状态。为此&#xff0c;我…

Codeforces Round 957 (Div. 3) D,F

D. Test of Love 很容易想到dp&#xff0c;对于dp的转移方程也比较好写&#xff0c;当前点只能从当前点前面m个点转移过来&#xff0c;那么思考转移的条件&#xff0c;对于前面的点 j j j &#xff0c;如果 j j j 是水并且 i i i 和 j j j 不相邻&#xff0c;那么不能进行转…

初始化列表和explicit关键字和static成员

初始化列表 1.初始化和赋值的概念&#xff1a; 首先我们先来了解一下成员变量初始化和赋值的概念&#xff0c;初始化是是对成员变量进行一次赋值&#xff0c;注意是只能一次赋值&#xff0c;而赋值是可以多次进行赋值的。 2.初始化列表的引出&#xff1a; 我们知道了初始化…

ftp pool 功能分析及 golang 实现

本文探究一种轻量级的 pool 实现 ftp 连接。 一、背景 简要介绍&#xff1a;业务中一般使用较多的是各种开源组件&#xff0c;设计有点重&#xff0c;因此本文探究一种轻量级的 pool 池的思想实现。 期望&#xff1a;设置连接池最大连接数为 N 时&#xff0c;批量执行 M 个 F…

Transformer模型:Decoder的self-attention mask实现

前言 这是对Transformer模型Word Embedding、Postion Embedding、Encoder self-attention mask、intra-attention mask内容的续篇。 视频链接&#xff1a;20、Transformer模型Decoder原理精讲及其PyTorch逐行实现_哔哩哔哩_bilibili 文章链接&#xff1a;Transformer模型&…

【JVM实战篇】内存调优:内存泄露危害+内存监控工具介绍+内存泄露原因介绍

文章目录 内存调优内存溢出和内存泄漏内存泄露带来什么问题内存泄露案例演示内存泄漏的常见场景场景一场景二 解决内存溢出的方法常用内存监控工具Top命令优缺点 VisualVM软件、插件优缺点监控本地Java进程监控服务器的Java进程&#xff08;生产环境不推荐使用&#xff09; Art…