AI-agenten voor het verwerken van tijdreeksen en grote dataframes
Vanaf nul bouwen met alleen Python en Ollama (geen GPU, geen API-sleutel)
een introductie
Agenten zijn AI-systemen die werken met grote taalmodellen (LLM's) en die kunnen redeneren over hun doelen en actie kunnen ondernemen om dat einddoel te bereiken. Het is niet alleen ontworpen om te reageren op vragen, maar ook om een reeks bewerkingen te organiseren, waaronder het verwerken van gegevens (zoals dataframes en tijdreeksen). Dankzij deze mogelijkheid kunnen veel praktische toepassingen de toegang tot gegevensanalyse democratiseren, met onder meer geautomatiseerde rapportages, codevrije query's en ondersteuning voor het opschonen en verwerken van gegevens.

Agenten kunnen op twee manieren met dataframes communiceren:
- door natuurlijke taal – Het grote taalmodel (LLM) leest de tabel als een tekstreeks en probeert deze te begrijpen op basis van zijn kennisbank.
- door Code maken en uitvoeren – De agent activeert hulpmiddelen om de dataset als object te verwerken.
Door de kracht van natuurlijke taalverwerking (NLP) te combineren met de precisie van code-uitvoering, zorgen AI-agenten ervoor dat een breder scala aan gebruikers met complexe datasets kan werken en waardevolle inzichten kan verkrijgen.
In deze tutorial laat ik je zien hoe je Verwerking van dataframes en tijdreeksen met behulp van AI-agenten. Ik zal wat nuttige Python-code leveren die eenvoudig kan worden toegepast op andere, vergelijkbare situaties (gewoon kopiëren, plakken en uitvoeren). Ik zal elke regel code toelichten met opmerkingen, zodat u dit voorbeeld kunt reproduceren (de link naar de volledige code vindt u aan het einde van het artikel).
voorbereiding
Laten we beginnen met voorbereiden Ollama (pip install ollama==0.4.7), een bibliotheek waarmee gebruikers grote open-source taalmodellen lokaal kunnen uitvoeren, zonder dat ze daarvoor cloudservices nodig hebben. Zo krijgen ze meer controle over de privacy en prestaties van hun gegevens. Omdat het lokaal wordt uitgevoerd, verlaten geen chatgegevens uw apparaat.
Eerst moet je downloaden Ollama Vanaf de website.
Gebruik vervolgens bij de opdrachtprompt de opdracht om het grote taalmodel (LLM) van uw keuze te downloaden. Ik zal gebruiken Qwen Die van Alibaba, omdat hij zowel slim als licht is.
Zodra het downloaden voltooid is, kunt u overschakelen naar Python en beginnen met het schrijven van code.
import ollama
llm = "qwen2.5"
Laten we het grote taalmodel eens proberen:
stream = ollama.generate(model=llm, prompt='''what time is it?''', stream=True)
for chunk in stream:
print(chunk['response'], end='', flush=True)
Tijdreeks
Een tijdreeks is een reeks datapunten die over een bepaalde periode worden gemeten. Deze reeks wordt vaak gebruikt voor analyses en prognoses. Hiermee kunnen we zien hoe variabelen in de loop van de tijd veranderen en kunnen we trends en seizoenspatronen identificeren. Het wordt beschouwd Tijdreeks Een krachtig hulpmiddel voor statistische analyses en prognoses.
Ik ga een dataset maken. tijdreeks Nep om als voorbeeld te gebruiken.
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
## create data
np.random.seed(1) #<--for reproducibility
length = 30
ts = pd.DataFrame(data=np.random.randint(low=0, high=15, size=length),
columns=['y'],
index=pd.date_range(start='2023-01-01', freq='MS', periods=length).strftime('%Y-%m'))
## plot
ts.plot(kind="bar", figsize=(10,3), legend=False, color="black").grid(axis='y')
Meestal bevatten datasets Tijdreeks Op een heel eenvoudige structuur met de hoofdvariabele als kolom en tijd als index.
Voordat ik het naar een string converteer, wil ik ervoor zorgen dat alles onder een kolom staat, zodat er geen informatie verloren gaat.
dtf = ts.reset_index().rename(columns={"index":"date"})
dtf.head()
Vervolgens moet u het gegevenstype wijzigen. Van DataFrame naar Woordenboek.
data = dtf.to_dict(orient='records')
data[0:5]
Tenslotte, Van woordenboek naar tekststring.
str_data = "\n".join([str(row) for row in data])
str_data
Nu we een string hebben, kunnen we Voeg het toe in een prompt Elk taalmodel kan het verwerken. Wanneer u een dataset in een prompt plakt, ziet de tekst er als volgt uit: Groot Taalmodel (LLM) De gegevens bestaan uit platte tekst, maar kunnen toch structuur en betekenis bevatten op basis van patronen die tijdens de training zijn waargenomen.
prompt = f'''
Analyze this dataset, it contains monthly sales data of an online retail product:
{str_data}
'''
We kunnen gemakkelijk een gesprek beginnen met Groot Taalmodel (LLM). Houd er rekening mee dat dit op dit moment geen agent is. Er zijn geen hulpmiddelen beschikbaar, maar we gebruiken alleen het taalmodel. Hoewel het geen getallen verwerkt zoals een computer, doet het dat wel. Groot Taalmodel (LLM) Het kan kolomnamen, tijdgebonden patronen, trends en uitschieters herkennen, vooral bij kleinere datasets. Het kan de analyse simuleren en de resultaten verklaren, maar het kan niet zelfstandig nauwkeurige berekeningen uitvoeren, omdat het geen code uitvoert zoals een agent.
messages = [{"role":"system", "content":prompt}]
while True:
## User
q = input('
>')
if q == "quit":
break
messages.append( {"role":"user", "content":q} )
## Model
agent_res = ollama.chat(model=llm, messages=messages, tools=[])
res = agent_res["message"]["content"]
## Response
print("
>", f"\x1b[1;30m{res}\x1b[0m")
messages.append( {"role":"assistant", "content":res} )
herken Groot Taalmodel (LLM) kan goed overweg met getallen en begrijpt de algehele context, net zoals hij een recept of een regel code begrijpt.
Zoals u kunt zien, wordt er gebruik gemaakt van Grote taalmodellen (LLM's) Om te analyseren Tijdreeks Ideaal voor snelle inzichten en gesprekken.
Tussenpersoon
Grote taalmodellen (LLM's) zijn uitermate geschikt voor het genereren van ideeën en het verkennen van initiële concepten, terwijl een agent code kan uitvoeren. Daarom kan het complexere taken aan, zoals grafieken maken, prognoses maken en anomaliedetectie. Laten we dus de tools creëren.
Soms is het omgaan met “‘Definitief antwoord’ als hulpmiddel Effectiever. Als een agent bijvoorbeeld meerdere acties uitvoert om tussenresultaten te creëren, kun je het uiteindelijke antwoord zien als het hulpmiddel dat al deze informatie samenvoegt tot een samenhangend antwoord. Als u het op deze manier ontwerpt, kunt u de resultaten beter aanpassen en controleren.
def final_answer(text:str) -> str:
return text
tool_final_answer = {'type':'function', 'function':{
'name': 'final_answer',
'description': 'Returns a natural language response to the user',
'parameters': {'type': 'object',
'required': ['text'],
'properties': {'text': {'type':'str', 'description':'natural language response'}}
}}}
final_answer(text="hi")
dan, Coderingstool.
import io
import contextlib
def code_exec(code:str) -> str:
output = io.StringIO()
with contextlib.redirect_stdout(output):
try:
exec(code)
except Exception as e:
print(f"Error: {e}")
return output.getvalue()
tool_code_exec = {'type':'function', 'function':{
'name': 'code_exec',
'description': 'Execute python code. Use always the function print() to get the output.',
'parameters': {'type': 'object',
'required': ['code'],
'properties': {
'code': {'type':'str', 'description':'code to execute'},
}}}}
code_exec("from datetime import datetime; print(datetime.now().strftime('%H:%M'))")
Verder zal ik nog wat toevoegen utils-functies Om het gereedschap te gebruiken en de agent uit te voeren.
dic_tools = {"final_answer":final_answer, "code_exec":code_exec}
# Utils
def use_tool(agent_res:dict, dic_tools:dict) -> dict:
## use tool
if "tool_calls" in agent_res["message"].keys():
for tool in agent_res["message"]["tool_calls"]:
t_name, t_inputs = tool["function"]["name"], tool["function"]["arguments"]
if f := dic_tools.get(t_name):
### calling tool
print('
>', f"\x1b[1;31m{t_name} -> Inputs: {t_inputs}\x1b[0m")
### tool output
t_output = f(**tool["function"]["arguments"])
print(t_output)
### final res
res = t_output
else:
print('
>', f"\x1b[1;31m{t_name} -> NotFound\x1b[0m")
## don't use tool
if agent_res['message']['content'] != '':
res = agent_res["message"]["content"]
t_name, t_inputs = '', ''
return {'res':res, 'tool_used':t_name, 'inputs_used':t_inputs}
Wanneer een agent een taak probeert op te lossen, wil ik dat er wordt bijgehouden welke hulpmiddelen zijn gebruikt, welke invoer is geprobeerd en welke resultaten zijn behaald. Het proces mag pas stoppen als het model klaar is om het definitieve antwoord te geven.
Wat betreft de coderingstool, merkte ik dat de agents de neiging hebben om het dataframe bij elke stap opnieuw te creëren. Dus ik zal gebruiken geheugenversterking Om het model eraan te herinneren dat de dataset al bestaat. Het is een veelgebruikte truc om het gewenste gedrag te bewerkstelligen. Uiteindelijk zorgen geheugenversterkingen ervoor dat interacties betekenisvoller en effectiever zijn.
# Start a chat
messages = [{"role":"system", "content":prompt}]
memory = '''
The dataset already exists and it's called 'dtf', don't create a new one.
'''
while True:
## User
q = input('
>')
if q == "quit":
break
messages.append( {"role":"user", "content":q} )
## Memory
messages.append( {"role":"user", "content":memory} )
## Model
available_tools = {"final_answer":tool_final_answer, "code_exec":tool_code_exec}
res = run_agent(llm, messages, available_tools)
## Response
print("
>", f"\x1b[1;30m{res}\x1b[0m")
messages.append( {"role":"assistant", "content":res} )
Een plot creëren is iets wat een groot taalmodel (LLM) alleen niet kan. Houd er echter rekening mee dat agenten weliswaar afbeeldingen kunnen genereren, maar deze niet kunnen zien. De engine is uiteindelijk nog steeds een taalmodel. Daarom is de gebruiker de enige die het verhaal visualiseert.
De agent maakt gebruik van een bibliotheek statistiekenmodellen Om een model te trainen en tijdreeksen te voorspellen.
Omgaan met grote dataframes
Grote taalmodellen (LLM's) hebben een beperkt geheugen, waardoor de hoeveelheid informatie die ze tegelijkertijd kunnen verwerken, beperkt is. Zelfs de meest geavanceerde modellen hebben tokenlimieten (een paar honderd pagina's tekst). Bovendien bewaren grote taalmodellen (LLM's) het geheugen niet tussen sessies, tenzij er een ophaalsysteem in is opgenomen. Om in de praktijk effectief met grote dataframes te kunnen werken, maken ontwikkelaars vaak gebruik van strategieën als chunking, retrieval augmented generation (RAG), vectordatabases en het samenvatten van inhoud voordat deze in het model wordt ingevoerd.
Laten we een grote dataset maken om mee te spelen.
import random
import string
length = 1000
dtf = pd.DataFrame(data={
'Id': [''.join(random.choices(string.ascii_letters, k=5)) for _ in range(length)],
'Age': np.random.randint(low=18, high=80, size=length),
'Score': np.random.uniform(low=50, high=100, size=length).round(1),
'Status': np.random.choice(['Active','Inactive','Pending'], size=length)
})
dtf.tail()
Ik zal toevoegen Webzoektoolzodat algemene AI, met de mogelijkheid om Python-code uit te voeren en op internet te zoeken, toegang krijgt tot alle beschikbare kennis en datagestuurde beslissingen kan nemen.
De makkelijkste manier om in Python een webzoekmachine te maken, is door gebruik te maken van de populaire privébrowser. DuckDuckGo (pip install duckduckgo-search==6.3.5). U kunt de originele bibliotheek direct gebruiken of een shell importeren. LangChain (pip install langchain-community==0.3.17).
from langchain_community.tools import DuckDuckGoSearchResults
def search_web(query:str) -> str:
return DuckDuckGoSearchResults(backend="news").run(query)
tool_search_web = {'type':'function', 'function':{
'name': 'search_web',
'description': 'Search the web',
'parameters': {'type': 'object',
'required': ['query'],
'properties': {
'query': {'type':'str', 'description':'the topic or subject to search on the web'},
}}}}
search_web(query="nvidia")
In totaal heeft de agent nu 3 tools.
dic_tools = {'final_answer':final_answer,
'search_web':search_web,
'code_exec':code_exec}
Omdat ik niet de volledige dataframe in de prompt kan toevoegen, vul ik alleen de eerste 10 rijen in, zodat de LLM de algehele context van de dataset kan begrijpen. Bovendien zal ik aangeven waar de volledige dataset te vinden is.
str_data = "\n".join([str(row) for row in dtf.head(10).to_dict(orient='records')])
prompt = f'''
You are a Data Analyst, you will be given a task to solve as best you can.
You have access to the following tools:
- tool 'final_answer' to return a text response.
- tool 'code_exec' to execute Python code.
- tool 'search_web' to search for information on the internet.
If you use the 'code_exec' tool, remember to always use the function print() to get the output.
The dataset already exists and it's called 'dtf', don't create a new one.
This dataset contains credit score for each customer of the bank. Here's the first rows:
{str_data}
'''
Ten slotte kunnen we de agent uitvoeren.
messages = [{"role":"system", "content":prompt}]
memory = '''
The dataset already exists and it's called 'dtf', don't create a new one.
'''
while True:
## User
q = input('
>')
if q == "quit":
break
messages.append( {"role":"user", "content":q} )
## Memory
messages.append( {"role":"user", "content":memory} )
## Model
available_tools = {"final_answer":tool_final_answer, "code_exec":tool_code_exec, "search_web":tool_search_web}
res = run_agent(llm, messages, available_tools)
## Response
print("
>", f"\x1b[1;30m{res}\x1b[0m")
messages.append( {"role":"assistant", "content":res} )
Bij deze interactie gebruikte de agent de coderingstool correct. Nu wil ik hem ook het andere gereedschap laten gebruiken.
Tot slot moet de agent alle informatie die hij tot nu toe tijdens het chatgesprek heeft verkregen, samenvoegen.
Conclusie
Dit artikel was bedoeld als een handleiding om te illustreren Hoe je agents vanaf nul bouwt om tijdreeksen en grote dataframes te verwerken. We hebben de twee manieren besproken waarop modellen met gegevens kunnen communiceren: via natuurlijke taal, waarbij een groot taalmodel (LLM) een tabel interpreteert als een tekenreeks met behulp van zijn kennisbank, en door code te genereren en uit te voeren, met behulp van hulpmiddelen om de dataset als een object te manipuleren.
Volledige code voor dit artikel: GitHub
Ik hoop dat je het leuk vond! Neem gerust contact met mij op als u vragen en opmerkingen heeft of uw interessante projecten wilt delen.
Reacties zijn gesloten.