KI-Agenten zur Verarbeitung von Zeitreihen und großen Datenmengen

Von Grund auf neu erstellen, nur mit Python und Ollama (keine GPU, kein API-Schlüssel)

eine Einleitung

Agenten sind KI-Systeme, die auf großen Sprachmodellen (LLMs) basieren und in der Lage sind, über ihre Ziele nachzudenken und Maßnahmen zu ergreifen, um ein Endziel zu erreichen. Es ist nicht nur darauf ausgelegt, auf Abfragen zu antworten, sondern auch eine Reihe von Vorgängen zu organisieren, einschließlich der Verarbeitung von Daten (wie Datenrahmen und Zeitreihen). Diese Funktion ermöglicht vielen realen Anwendungen einen demokratisierten Zugriff auf die Datenanalyse, beispielsweise durch Berichtsautomatisierung, codefreie Abfragen und Unterstützung bei der Datenbereinigung und -verarbeitung.

Agenten können auf zwei verschiedene Arten mit Datenrahmen interagieren:

  • durch natürliche Sprache – Das große Sprachmodell (LLM) liest die Tabelle als Textzeichenfolge und versucht, sie basierend auf seiner Wissensbasis zu verstehen.
  • durch Erstellen und Ausführen von Code – Der Agent aktiviert Tools, um den Datensatz als Objekt zu verarbeiten.

Durch die Kombination der Leistungsfähigkeit der natürlichen Sprachverarbeitung (NLP) mit der Präzision der Codeausführung ermöglichen KI-Agenten einem größeren Benutzerkreis die Interaktion mit komplexen Datensätzen und die Gewinnung wertvoller Erkenntnisse.

In diesem Tutorial zeige ich Ihnen, wie Sie Verarbeitung von Datenrahmen und Zeitreihen mithilfe von KI-Agenten. Ich stelle nützlichen Python-Code bereit, der problemlos auf andere ähnliche Situationen angewendet werden kann (einfach kopieren, einfügen und ausführen), und ich erkläre jede Codezeile mit Kommentaren, damit Sie dieses Beispiel replizieren können (Link zum vollständigen Code am Ende des Artikels).

 

Vorbereitung

Beginnen wir mit den Vorbereitungen Ollama (pip install ollama==0.4.7), eine Bibliothek, die es Benutzern ermöglicht, große Open-Source-Sprachmodelle lokal auszuführen, ohne dass Cloud-Dienste erforderlich sind, und so mehr Kontrolle über Datenschutz und Leistung bietet. Da es lokal ausgeführt wird, verlassen keine Chatdaten Ihr Gerät.

Zuerst müssen Sie herunterladen Ollama Von der Website.

Verwenden Sie als Nächstes in Ihrer Eingabeaufforderung den Befehl, um das große Sprachmodell (LLM) Ihrer Wahl herunterzuladen. Ich werde verwenden Qwen Alibabas eigenes, weil es sowohl intelligent als auch leichtgewichtig ist.

Nachdem der Download abgeschlossen ist, können Sie zu Python wechseln und mit dem Schreiben von Code beginnen.

import ollama
llm = "qwen2.5"

Versuchen wir es mit dem großen Sprachmodell:

stream = ollama.generate(model=llm, prompt='''what time is it?''', stream=True)
for chunk in stream:
    print(chunk['response'], end='', flush=True)

Zeitreihen

Eine Zeitreihe ist eine Abfolge von Datenpunkten, die über einen bestimmten Zeitraum gemessen werden und häufig für Analysen und Prognosen verwendet werden. Es ermöglicht uns zu sehen, wie sich Variablen im Laufe der Zeit verändern und wird verwendet, um Trends und saisonale Muster zu erkennen. Es wird berücksichtigt Zeitreihen Ein leistungsstarkes Tool für statistische Analysen und Prognosen.

Ich werde einen Datensatz erstellen. Zeitreihen Fälschung zur Verwendung als Beispiel.

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

Typischerweise enthalten Datensätze Zeitreihen Auf einer wirklich einfachen Struktur mit der Hauptvariablen als Spalte und der Zeit als Index.

Bevor ich es in eine Zeichenfolge konvertiere, möchte ich sicherstellen, dass alles in einer Spalte platziert ist, damit keine Informationen verloren gehen.

dtf = ts.reset_index().rename(columns={"index":"date"})
dtf.head()

Anschließend müssen Sie den Datentyp ändern. Vom DataFrame zum Dictionary.

data = dtf.to_dict(orient='records')
data[0:5]

endlich, Vom Wörterbuch zur Textzeichenfolge.

str_data = "\n".join([str(row) for row in data])
str_data

Da wir nun eine Zeichenfolge haben, können wir Fügen Sie es in eine Eingabeaufforderung ein Jedes Sprachmodell kann es verarbeiten. Wenn Sie einen Datensatz in eine Eingabeaufforderung einfügen, lautet dieser: Großes Sprachmodell (LLM) Bei den Daten handelt es sich um reinen Text, aber die Struktur und Bedeutung der Daten kann dennoch anhand der während des Trainings erkannten Muster verstanden werden.

prompt = f'''
Analyze this dataset, it contains monthly sales data of an online retail product:
{str_data}
'''

Wir können ganz einfach ein Gespräch beginnen mit Großes Sprachmodell (LLM). Bitte beachten Sie, dass dies derzeit kein Agent ist, da er über keine Tools verfügt. Wir verwenden lediglich das Sprachmodell. Obwohl es Zahlen nicht wie ein Computer verarbeitet, tut es das. Großes Sprachmodell (LLM) Es kann Spaltennamen, zeitbasierte Muster, Trends und Ausreißer erkennen, insbesondere bei kleineren Datensätzen. Es kann die Analyse simulieren und die Ergebnisse erklären, führt jedoch keine genauen Berechnungen selbstständig durch, da es keinen Code wie ein Agent ausführt.

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

erkenne Großes Sprachmodell (LLM) Er versteht Zahlen und den Gesamtzusammenhang, so wie er vielleicht ein Rezept oder eine Codezeile versteht.

Wie Sie sehen, ist die Verwendung von Große Sprachmodelle (LLMs) Analysieren Zeitreihen Ideal für schnelle Einblicke und Gespräche.

Agent

Große Sprachmodelle (LLMs) eignen sich hervorragend zum Generieren von Ideen und Erkunden anfänglicher Konzepte, während ein Agent Code ausführen kann. Daher kann es komplexere Aufgaben wie die Erstellung grafischer Darstellungen, Prognosen und Anomalieerkennung bewältigen. Lassen Sie uns also die Tools erstellen.

Manchmal ist der Umgang mit „„Endgültige Antwort“ als Werkzeug Effektiver. Wenn ein Agent beispielsweise mehrere Aktionen ausführt, um Zwischenergebnisse zu erzielen, kann die endgültige Antwort als das Tool betrachtet werden, das alle diese Informationen in eine zusammenhängende Antwort integriert. Durch diese Gestaltung haben Sie mehr Möglichkeiten zur individuellen Anpassung und Kontrolle über die Ergebnisse.

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

Dann, Kodierungstool.

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

Darüber hinaus werde ich einige hinzufügen Utils-Funktionen So verwenden Sie das Tool und führen den Agenten aus.

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}

Wenn ein Agent versucht, eine Aufgabe zu lösen, möchte ich, dass er nachverfolgt, welche Tools verwendet wurden, welche Eingaben er ausprobiert hat und welche Ergebnisse er erzielt hat. Der Prozess sollte erst beendet werden, wenn das Modell bereit ist, die endgültige Antwort zu liefern.

Beim Codierungstool ist mir aufgefallen, dass die Agenten dazu neigen, den Datenrahmen bei jedem Schritt neu zu erstellen. Also werde ich verwenden Gedächtnisverstärkung Um das Modell daran zu erinnern, dass der Datensatz bereits vorhanden ist. Dies ist ein gängiger Trick, um das gewünschte Verhalten zu erzielen. Letztendlich verhelfen Ihnen Gedächtnisverstärkungen zu aussagekräftigeren und effektiveren Interaktionen.

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

Das Erstellen einer Handlung ist mit einem großen Sprachmodell (LLM) allein nicht möglich. Bedenken Sie jedoch, dass Agenten zwar Bilder generieren können, diese jedoch nicht sehen können, da die Engine letztendlich immer noch ein Sprachmodell ist. Der Benutzer ist somit der einzige, der die Handlung visualisiert.

Der Agent verwendet eine Bibliothek Statistikmodelle Um ein Modell zu trainieren und Zeitreihen vorherzusagen.

Umgang mit großen Dataframes

Große Sprachmodelle (LLMs) verfügen über einen begrenzten Speicher, wodurch die Menge an Informationen, die sie gleichzeitig verarbeiten können, begrenzt ist. Selbst die ausgefeiltesten Modelle haben Token-Grenzen (einige hundert Seiten Text). Darüber hinaus behalten große Sprachmodelle (LLMs) den Speicher nicht über Sitzungen hinweg, sofern kein Abrufsystem integriert ist. Um in der Praxis effektiv mit großen Datenrahmen arbeiten zu können, verwenden Entwickler häufig Strategien wie Chunking, Retrieval Augmented Generation (RAG), Vektordatenbanken und das Zusammenfassen von Inhalten, bevor sie diese in das Modell einspeisen.

Lassen Sie uns einen großen Datensatz zum Spielen erstellen.

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

Ich werde hinzufügen Web-Suchtool, sodass eine universelle KI mit der Fähigkeit, Python-Code auszuführen und das Internet zu durchsuchen, Zugriff auf das gesamte verfügbare Wissen erhält und datenbasierte Entscheidungen treffen kann.

In Python lässt sich ein Websuchtool am einfachsten mithilfe des beliebten privaten Browsers erstellen. DuckDuckGo (pip install duckduckgo-search==6.3.5). Sie können die Originalbibliothek direkt verwenden oder eine Shell importieren. 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")

Insgesamt stehen dem Agenten nun 3 Werkzeuge zur Verfügung.

dic_tools = {'final_answer':final_answer,
             'search_web':search_web,
             'code_exec':code_exec}

Da ich in der Eingabeaufforderung nicht den vollständigen Datenrahmen hinzufügen kann, gebe ich nur die ersten 10 Zeilen ein, damit das LLM den Gesamtkontext des Datensatzes verstehen kann. Darüber hinaus werde ich angeben, wo der vollständige Datensatz zu finden ist.

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

Schließlich können wir den Agenten ausführen.

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

Bei dieser Interaktion hat der Agent das Codiertool korrekt verwendet. Jetzt möchte ich ihn dazu bringen, auch das andere Werkzeug zu verwenden.

Abschließend muss der Agent alle bisher aus diesem Chat erhaltenen Informationen zusammentragen.

 

Fazit

Dieser Artikel war als Tutorial zur Veranschaulichung gedacht So erstellen Sie Agenten von Grund auf, um Zeitreihen und große Datenrahmen zu verarbeiten. Wir haben die beiden Möglichkeiten behandelt, wie Modelle mit Daten interagieren können: durch natürliche Sprache, wobei ein großes Sprachmodell (LLM) eine Tabelle unter Verwendung seiner Wissensbasis als Zeichenfolge interpretiert, und durch das Generieren und Ausführen von Code unter Nutzung von Tools zum Bearbeiten des Datensatzes als Objekt.

Vollständiger Code für diesen Artikel: GitHub

Ich hoffe, es hat Ihnen gefallen! Kontaktieren Sie mich gerne bei Fragen und Anmerkungen oder teilen Sie mir Ihre interessanten Projekte mit.

 

Kommentarfunktion ist geschlossen.