Agents d'IA pour le traitement des séries chronologiques et des big data
Construisez à partir de zéro en utilisant uniquement Python et Ollama (pas de GPU, pas de clé API)
une introduction
Les agents sont des systèmes d’IA alimentés par de grands modèles de langage (LLM), capables de raisonner sur leurs objectifs et de prendre des mesures pour atteindre un objectif final. Il est conçu non seulement pour répondre aux requêtes, mais également pour organiser une série d'opérations, notamment le traitement de données (telles que les trames de données et les séries chronologiques). Cette capacité permet à de nombreuses applications du monde réel de démocratiser l’accès à l’analyse des données, comme l’automatisation des rapports, les requêtes sans code et la prise en charge du nettoyage et du traitement des données.

Les agents peuvent interagir avec les dataframes de deux manières différentes :
- عن طريق langage naturel – Le grand modèle de langage (LLM) lit le tableau comme une chaîne de texte et essaie de le comprendre en fonction de sa base de connaissances.
- عن طريق Créer et exécuter du code – L’agent active des outils pour traiter l’ensemble de données comme un objet.
En combinant la puissance du traitement du langage naturel (NLP) avec la précision de l’exécution du code, les agents d’IA permettent à un plus large éventail d’utilisateurs d’interagir avec des ensembles de données complexes et d’extraire des informations précieuses.
Dans ce tutoriel, je vais vous montrer comment Traitement de trames de données et de séries chronologiques à l'aide d'agents IA. Je fournirai du code Python utile qui peut être facilement appliqué dans d'autres situations similaires (il suffit de copier, coller et exécuter), et j'expliquerai chaque ligne de code avec des commentaires afin que vous puissiez reproduire cet exemple (lien vers le code complet à la fin de l'article).
Configuration
Commençons à nous préparer Ollama (pip install ollama==0.4.7), une bibliothèque qui permet aux utilisateurs d'exécuter de grands modèles de langage open source localement, sans avoir besoin de services cloud, offrant ainsi plus de contrôle sur la confidentialité des données et les performances. Parce qu'il s'exécute localement, aucune donnée de discussion ne quitte votre appareil.
Tout d'abord, vous devez télécharger Ollama Depuis le site Web.
Ensuite, à votre invite de commande, utilisez la commande pour télécharger le modèle de langage large (LLM) que vous avez choisi. J'utiliserai Qwen C'est le propre d'Alibaba, car il est à la fois intelligent et léger.
Une fois le téléchargement terminé, vous pouvez passer à Python et commencer à écrire du code.
import ollama
llm = "qwen2.5"
Essayons le grand modèle de langage :
stream = ollama.generate(model=llm, prompt='''what time is it?''', stream=True)
for chunk in stream:
print(chunk['response'], end='', flush=True)
Séries chronologiques
Une série chronologique est une séquence de points de données mesurés sur une période donnée, souvent utilisée à des fins d'analyse et de prévision. Il nous permet de voir comment les variables évoluent au fil du temps et est utilisé pour identifier les tendances et les modèles saisonniers. Il est considéré Séries chronologiques Un outil puissant d’analyse statistique et de prévision.
Je vais créer un ensemble de données. séries chronologiques Faux à utiliser comme exemple.
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')
En règle générale, les ensembles de données contiennent Séries chronologiques Sur une structure vraiment simple avec la variable principale comme colonne et le temps comme index.
Avant de le convertir en chaîne, je veux m'assurer que tout est placé sous une colonne, afin de ne perdre aucune information.
dtf = ts.reset_index().rename(columns={"index":"date"})
dtf.head()
Ensuite, vous devez changer le type de données. Du DataFrame au dictionnaire.
data = dtf.to_dict(orient='records')
data[0:5]
finalement, Du dictionnaire à la chaîne de texte.
str_data = "\n".join([str(row) for row in data])
str_data
Maintenant que nous avons une chaîne, nous pouvons Incluez-le dans une invite N’importe quel modèle de langage peut le traiter. Lorsque vous collez un ensemble de données dans une invite, il indique : Grand modèle de langage (LLM) Les données sont du texte brut, mais elles peuvent néanmoins comprendre la structure et le sens en fonction des modèles observés pendant la formation.
prompt = f'''
Analyze this dataset, it contains monthly sales data of an online retail product:
{str_data}
'''
Nous pouvons facilement démarrer une conversation avec Grand modèle de langage (LLM). Veuillez noter que pour le moment, ce n'est pas un agent car il ne dispose d'aucun outil, nous utilisons uniquement le modèle de langage. Bien qu'il ne traite pas les nombres comme un ordinateur, il le fait. Grand modèle de langage (LLM) Il peut reconnaître les noms de colonnes, les modèles temporels, les tendances et les valeurs aberrantes, en particulier avec des ensembles de données plus petits. Il peut simuler l'analyse et expliquer les résultats, mais il n'effectuera pas de calculs précis de manière indépendante, car il n'exécute pas de code comme un 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} )
Apprenez à connaître Grand modèle de langage (LLM) sur les chiffres et comprend le contexte global, de la même manière qu'il pourrait comprendre une recette ou une ligne de code.
Comme vous pouvez le voir, l’utilisation de Grands modèles de langage (LLM) لتحليل Séries chronologiques Idéal pour des aperçus et des conversations rapides.
Agent
Les grands modèles de langage (LLM) excellent dans la génération d'idées et l'exploration de concepts initiaux, tandis qu'un agent peut exécuter du code. Il peut donc gérer des tâches plus complexes telles que la création de graphiques, la prévision et la détection d'anomalies. Alors, créons les outils.
Parfois, traiter avec «« Réponse finale » comme outil Plus efficace. Par exemple, si un agent effectue plusieurs actions pour créer des résultats intermédiaires, la réponse finale peut être considérée comme l’outil qui intègre toutes ces informations dans une réponse cohérente. En le concevant de cette manière, vous pouvez avoir plus de personnalisation et de contrôle sur les résultats.
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")
Puis, Outil d'encodage.
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'))")
De plus, j'ajouterai quelques fonctions utils Pour utiliser l'outil et exécuter l'agent.
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}
Lorsqu'un agent tente de résoudre une tâche, je souhaite qu'il suive les outils utilisés, les entrées qu'il a essayées et les résultats qu'il a obtenus. Le processus ne doit s’arrêter que lorsque le modèle est prêt à fournir la réponse finale.
Concernant l'outil de codage, j'ai remarqué que les agents ont tendance à recréer le dataframe à chaque étape. Je vais donc utiliser renforcement de la mémoire Pour rappeler au modèle que l'ensemble de données existe déjà. C'est une astuce courante utilisée pour obtenir le comportement souhaité. En fin de compte, les renforcements de mémoire vous aident à avoir des interactions plus significatives et plus efficaces.
# 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} )
Créer une intrigue est quelque chose qu'un grand modèle de langage (LLM) seul ne peut pas faire. Mais gardez à l’esprit que même si les agents peuvent générer des images, ils ne peuvent pas les voir, car le moteur reste en fin de compte un modèle de langage. L’utilisateur est donc le seul à visualiser l’intrigue.
L'agent utilise une bibliothèque statistiquesmodèles Pour former un modèle et prévoir des séries chronologiques.
Gestion de grandes trames de données
Les grands modèles de langage (LLM) ont une mémoire limitée, ce qui restreint la quantité d'informations qu'ils peuvent traiter à la fois. Même les modèles les plus sophistiqués ont des limites symboliques (quelques centaines de pages de texte). De plus, les grands modèles de langage (LLM) ne conservent pas la mémoire entre les sessions, à moins qu'un système de récupération ne soit intégré. En pratique, pour travailler efficacement avec de grandes trames de données, les développeurs utilisent souvent des stratégies telles que le découpage en blocs, la génération augmentée de récupération (RAG), les bases de données vectorielles et la synthèse du contenu avant de l'introduire dans le modèle.
Créons un grand ensemble de données avec lequel jouer.
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()
J'ajouterai Outil de recherche Web, afin que l'IA à usage général, avec la capacité d'exécuter du code Python et de rechercher sur Internet, ait accès à toutes les connaissances disponibles et puisse prendre des décisions basées sur les données.
En Python, le moyen le plus simple de créer un outil de recherche Web consiste à utiliser le navigateur privé populaire. DuckDuckGo (pip install duckduckgo-search==6.3.5). Vous pouvez utiliser directement la bibliothèque d'origine ou importer un shell. LangChaîne (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")
Au total, l'agent dispose désormais de 3 outils.
dic_tools = {'final_answer':final_answer,
'search_web':search_web,
'code_exec':code_exec}
Comme je ne peux pas ajouter le dataframe complet dans l'invite, je n'alimenterai que les 10 premières lignes afin que le LLM puisse comprendre le contexte global de l'ensemble de données. De plus, je préciserai où trouver l'ensemble de données complet.
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}
'''
Enfin, nous pouvons exécuter l'agent.
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} )
Dans cette interaction, l’agent a utilisé correctement l’outil de codage. Maintenant, je veux lui faire utiliser l’autre outil également.
Enfin, j'ai besoin que l'agent rassemble toutes les informations obtenues jusqu'à présent à partir de cette discussion.
CONCLUSION
Cet article a été conçu comme un tutoriel pour illustrer Comment créer des agents à partir de zéro pour traiter des séries chronologiques et des cadres de données volumineux. Nous avons abordé les deux manières dont les modèles peuvent interagir avec les données : via le langage naturel, où un grand modèle de langage (LLM) interprète une table comme une chaîne en utilisant sa base de connaissances, et en générant et en exécutant du code, en exploitant des outils pour manipuler l'ensemble de données comme un objet.
Code complet pour cet article : GitHub
J'espère que vous avez apprécié ! N'hésitez pas à me contacter pour des questions et des commentaires, ou pour partager vos projets intéressants.
Les commentaires sont fermés.