Validierung – chatgpz.de – KI-Tools & Praxiswissen https://chatgpz.de Unabhängige Tests, Anleitungen und Hintergründe zu KI-Tools. Sun, 07 Jun 2026 18:34:50 +0000 de-DE hourly 1 https://wordpress.org/?v=6.4.2 234900186 Aufbau einer reflektierenden Immediate-Optimierung mit GEPA: Mehrkomponenten-Prompts, strukturiertes Suggestions und ausgehaltene Validierung https://chatgpz.de/artificial-intelligence/aufbau-einer-reflektierenden-immediate-optimierung-mit-gepa-mehrkomponenten-prompts-strukturiertes-suggestions-und-ausgehaltene-validierung/ https://chatgpz.de/artificial-intelligence/aufbau-einer-reflektierenden-immediate-optimierung-mit-gepa-mehrkomponenten-prompts-strukturiertes-suggestions-und-ausgehaltene-validierung/#respond Sun, 07 Jun 2026 18:34:50 +0000 http://chatgpz.de/artificial-intelligence/aufbau-einer-reflektierenden-prompt-optimierung-mit-gepa-mehrkomponenten-prompts-strukturiertes-feedback-und-ausgehaltene-validierung/ [ad_1]

def make_problems(n, seed=0):
   rng = random.Random(seed)
   out = ()
   for _ in vary(n):
       t = rng.selection(("low cost", "journey", "pockets", "chain"))
       if t == "low cost":
           unit  = rng.selection((40, 60, 80, 120))
           qty   = rng.selection((5, 6, 8, 10))
           disc  = rng.selection((10, 20, 25, 50))
           whole = unit * qty
           gold  = whole - whole * disc // 100
           q = (f"A store sells notebooks at {unit} rupees every. You purchase {qty} "
                f"notebooks and get a {disc}% low cost on the entire invoice. "
                f"What number of rupees do you pay in whole?")
       elif t == "journey":
           s1, h1 = rng.selection((40, 50, 60)), rng.selection((2, 3))
           s2, h2 = rng.selection((30, 45, 70)), rng.selection((1, 2, 3))
           gold = s1 * h1 + s2 * h2
           q = (f"A automotive drives at {s1} km/h for {h1} hours, then at {s2} km/h "
                f"for {h2} hours. What's the whole distance travelled, in km?")
       elif t == "pockets":
           tens   = rng.selection((3, 5, 7, 9))
           fifties= rng.selection((2, 4, 6))
           spent  = rng.selection((50, 80, 110, 150))
           gold = tens * 10 + fifties * 50 - spent
           q = (f"You might have {tens} ten-rupee notes and {fifties} fifty-rupee "
                f"notes. You spend {spent} rupees. What number of rupees are left?")
       else:
           x = rng.selection((6, 9, 12, 15)); y = rng.selection((4, 7, 10)); z = rng.selection((3, 8, 11))
           gold = x * 2 - y + z
           q = (f"Begin with the quantity {x}. Double it, then subtract {y}, "
                f"then add {z}. What quantity do you finish with?")
       out.append({"query": q, "reply": gold})
   return out
all_problems = make_problems(18, seed=42)
random.Random(1).shuffle(all_problems)
trainset = all_problems(:12)
valset   = all_problems(12:)
print(f"Dataset: {len(trainset)} prepare / {len(valset)} val problemsn")

[ad_2]

]]>
https://chatgpz.de/artificial-intelligence/aufbau-einer-reflektierenden-immediate-optimierung-mit-gepa-mehrkomponenten-prompts-strukturiertes-suggestions-und-ausgehaltene-validierung/feed/ 0 19096
Aufbau einer Agenten-KI der nächsten Technology: Ein vollständiges Framework für kognitive Blueprint-gesteuerte Laufzeitagenten mit Speichertools und Validierung https://chatgpz.de/artificial-intelligence/aufbau-einer-agenten-ki-der-naechsten-technology-ein-vollstaendiges-framework-fuer-kognitive-blueprint-gesteuerte-laufzeitagenten-mit-speichertools-und-validierung/ https://chatgpz.de/artificial-intelligence/aufbau-einer-agenten-ki-der-naechsten-technology-ein-vollstaendiges-framework-fuer-kognitive-blueprint-gesteuerte-laufzeitagenten-mit-speichertools-und-validierung/#respond Sun, 08 Mar 2026 13:14:24 +0000 https://chatgpz.de/artificial-intelligence/aufbau-einer-agenten-ki-der-naechsten-generation-ein-vollstaendiges-framework-fuer-kognitive-blueprint-gesteuerte-laufzeitagenten-mit-speichertools-und-validierung/ [ad_1]

In diesem Tutorial erstellen wir ein vollständiges Framework für kognitive Blaupausen und Laufzeitagenten. Wir definieren strukturierte Blaupausen für Identität, Ziele, Planung, Gedächtnis, Validierung und Werkzeugzugriff und verwenden sie, um Agenten zu erstellen, die nicht nur reagieren, sondern ihre Ergebnisse auch planen, ausführen, validieren und systematisch verbessern. Im Rahmen des Tutorials zeigen wir, wie dieselbe Laufzeit-Engine durch Blueprint-Portabilität mehrere Agentenpersönlichkeiten und -verhalten unterstützen kann, wodurch das Gesamtdesign modular, erweiterbar und praktisch für fortgeschrittene Agenten-KI-Experimente wird.

import json, yaml, time, math, textwrap, datetime, getpass, os
from typing import Any, Callable, Dict, Record, Elective
from dataclasses import dataclass, area
from enum import Enum


from openai import OpenAI
from pydantic import BaseModel
from wealthy.console import Console
from wealthy.panel import Panel
from wealthy.desk import Desk
from wealthy.tree import Tree


attempt:
   from google.colab import userdata
   OPENAI_API_KEY = userdata.get('OPENAI_API_KEY')
besides Exception:
   OPENAI_API_KEY = getpass.getpass("🔑 Enter your OpenAI API key: ")


os.environ("OPENAI_API_KEY") = OPENAI_API_KEY
consumer = OpenAI(api_key=OPENAI_API_KEY)
console = Console()


class PlanningStrategy(str, Enum):
   SEQUENTIAL   = "sequential"
   HIERARCHICAL = "hierarchical"
   REACTIVE     = "reactive"


class MemoryType(str, Enum):
   SHORT_TERM = "short_term"
   EPISODIC   = "episodic"
   PERSISTENT = "persistent"


class BlueprintIdentity(BaseModel):
   identify: str
   model: str = "1.0.0"
   description: str
   writer: str = "unknown"


class BlueprintMemory(BaseModel):
   sort: MemoryType = MemoryType.SHORT_TERM
   window_size: int = 10
   summarize_after: int = 20


class BlueprintPlanning(BaseModel):
   technique: PlanningStrategy = PlanningStrategy.SEQUENTIAL
   max_steps: int = 8
   max_retries: int = 2
   think_before_acting: bool = True


class BlueprintValidation(BaseModel):
   require_reasoning: bool = True
   min_response_length: int = 10
   forbidden_phrases: Record(str) = ()


class CognitiveBlueprint(BaseModel):
   identification: BlueprintIdentity
   objectives: Record(str)
   constraints: Record(str) = ()
   instruments: Record(str) = ()
   reminiscence: BlueprintMemory = BlueprintMemory()
   planning: BlueprintPlanning = BlueprintPlanning()
   validation: BlueprintValidation = BlueprintValidation()
   system_prompt_extra: str = ""


def load_blueprint_from_yaml(yaml_str: str) -> CognitiveBlueprint:
   return CognitiveBlueprint(**yaml.safe_load(yaml_str))


RESEARCH_AGENT_YAML = """
identification:
 identify: ResearchBot
 model: 1.2.0
 description: Solutions analysis questions utilizing calculation and reasoning
 writer: Auton Framework Demo
objectives:
 - Reply consumer questions precisely utilizing accessible instruments
 - Present step-by-step reasoning for all solutions
 - Cite the tactic used for every calculation
constraints:
 - By no means fabricate numbers or statistics
 - All the time validate mathematical outcomes earlier than reporting
 - Don't reply questions outdoors your software capabilities
instruments:
 - calculator
 - unit_converter
 - date_calculator
 - search_wikipedia_stub
reminiscence:
 sort: episodic
 window_size: 12
 summarize_after: 30
planning:
 technique: sequential
 max_steps: 6
 max_retries: 2
 think_before_acting: true
validation:
 require_reasoning: true
 min_response_length: 20
 forbidden_phrases:
   - "I do not know"
   - "I can not decide"
"""


DATA_ANALYST_YAML = """
identification:
 identify: DataAnalystBot
 model: 2.0.0
 description: Performs statistical evaluation and information summarization
 writer: Auton Framework Demo
objectives:
 - Compute descriptive statistics for given information
 - Determine developments and anomalies
 - Current findings clearly with numbers
constraints:
 - Solely work with numerical information
 - All the time report uncertainty when pattern measurement is small (< 5 objects)
instruments:
 - calculator
 - statistics_engine
 - list_sorter
reminiscence:
 sort: short_term
 window_size: 6
planning:
 technique: hierarchical
 max_steps: 10
 max_retries: 3
 think_before_acting: true
validation:
 require_reasoning: true
 min_response_length: 30
 forbidden_phrases: ()
"""

Wir richten die Kernumgebung ein und definieren den kognitiven Bauplan, der das Denken und Verhalten eines Agenten strukturiert. Wir erstellen stark typisierte Modelle für Identität, Speicherkonfiguration, Planungsstrategie und Validierungsregeln mithilfe von Pydantic und Enumerationen. Wir definieren außerdem zwei YAML-basierte Blaupausen, die es uns ermöglichen, verschiedene Agentenpersönlichkeiten und -funktionen zu konfigurieren, ohne das zugrunde liegende Laufzeitsystem zu ändern.

@dataclass
class ToolSpec:
   identify: str
   description: str
   parameters: Dict(str, str)
   perform: Callable
   returns: str


class ToolRegistry:
   def __init__(self):
       self._tools: Dict(str, ToolSpec) = {}


   def register(self, identify: str, description: str,
                parameters: Dict(str, str), returns: str):
       def decorator(fn: Callable) -> Callable:
           self._tools(identify) = ToolSpec(identify, description, parameters, fn, returns)
           return fn
       return decorator


   def get(self, identify: str) -> Elective(ToolSpec):
       return self._tools.get(identify)


   def name(self, identify: str, **kwargs) -> Any:
       spec = self._tools.get(identify)
       if not spec:
           increase ValueError(f"Instrument '{identify}' not present in registry")
       return spec.perform(**kwargs)


   def get_tool_descriptions(self, allowed: Record(str)) -> str:
       strains = ()
       for identify in allowed:
           spec = self._tools.get(identify)
           if spec:
               params = ", ".be a part of(f"{ok}: {v}" for ok, v in spec.parameters.objects())
               strains.append(
                   f"• {spec.identify}({params})n"
                   f"  → {spec.description}n"
                   f"  Returns: {spec.returns}"
               )
       return "n".be a part of(strains)


   def list_tools(self) -> Record(str):
       return checklist(self._tools.keys())


registry = ToolRegistry()


@registry.register(
   identify="calculator",
   description="Evaluates a secure mathematical expression",
   parameters={"expression": "A math expression string, e.g. '2 ** 10 + 5 * 3'"},
   returns="Numeric end result as float"
)
def calculator(expression: str) -> str:
   attempt:
       allowed = {ok: v for ok, v in math.__dict__.objects() if not ok.startswith("_")}
       allowed.replace({"abs": abs, "spherical": spherical, "pow": pow})
       return str(eval(expression, {"__builtins__": {}}, allowed))
   besides Exception as e:
       return f"Error: {e}"


@registry.register(
   identify="unit_converter",
   description="Converts between frequent models of measurement",
   parameters={
       "worth": "Numeric worth to transform",
       "from_unit": "Supply unit (km, miles, kg, lbs, celsius, fahrenheit, liters, gallons, meters, ft)",
       "to_unit": "Goal unit"
   },
   returns="Transformed worth as string with models"
)
def unit_converter(worth: float, from_unit: str, to_unit: str) -> str:
   conversions = {
       ("km", "miles"): lambda x: x * 0.621371,
       ("miles", "km"): lambda x: x * 1.60934,
       ("kg", "lbs"):   lambda x: x * 2.20462,
       ("lbs", "kg"):   lambda x: x / 2.20462,
       ("celsius", "fahrenheit"): lambda x: x * 9/5 + 32,
       ("fahrenheit", "celsius"): lambda x: (x - 32) * 5/9,
       ("liters", "gallons"): lambda x: x * 0.264172,
       ("gallons", "liters"): lambda x: x * 3.78541,
       ("meters", "ft"): lambda x: x * 3.28084,
       ("ft", "meters"): lambda x: x / 3.28084,
   }
   key = (from_unit.decrease(), to_unit.decrease())
   if key in conversions:
       return f"{conversions(key)(float(worth)):.4f} {to_unit}"
   return f"Conversion from {from_unit} to {to_unit} not supported"


@registry.register(
   identify="date_calculator",
   description="Calculates days between two dates, or provides/subtracts days from a date",
   parameters={
       "operation": "'days_between' or 'add_days'",
       "date1": "Date string in YYYY-MM-DD format",
       "date2": "Second date for days_between (YYYY-MM-DD), or variety of days for add_days"
   },
   returns="Outcome as string"
)
def date_calculator(operation: str, date1: str, date2: str) -> str:
   attempt:
       d1 = datetime.datetime.strptime(date1, "%Y-%m-%d")
       if operation == "days_between":
           d2 = datetime.datetime.strptime(date2, "%Y-%m-%d")
           return f"{abs((d2 - d1).days)} days between {date1} and {date2}"
       elif operation == "add_days":
           end result = d1 + datetime.timedelta(days=int(date2))
           return f"{end result.strftime('%Y-%m-%d')} (added {date2} days to {date1})"
       return f"Unknown operation: {operation}"
   besides Exception as e:
       return f"Error: {e}"


@registry.register(
   identify="search_wikipedia_stub",
   description="Returns a stub abstract for well-known subjects (demo — no dwell web)",
   parameters={"subject": "Subject to lookup"},
   returns="Brief textual content abstract"
)
def search_wikipedia_stub(subject: str) -> str:
   stubs = {
       "openai": "OpenAI is an AI analysis firm based in 2015. It created GPT-4 and the ChatGPT product.",
   }
   for key, val in stubs.objects():
       if key in subject.decrease():
           return val
   return f"No stub discovered for '{subject}'. In manufacturing, this may question Wikipedia's API."

Wir implementieren die Instrument-Registrierung, die es Agenten ermöglicht, externe Funktionen dynamisch zu erkennen und zu nutzen. Wir entwerfen ein strukturiertes System, in dem Werkzeuge mit Metadaten registriert werden, einschließlich Parametern, Beschreibungen und Rückgabewerten. Wir implementieren außerdem mehrere praktische Instruments, wie einen Taschenrechner, einen Einheitenumrechner, einen Datumsrechner und einen Wikipedia-Such-Stub, den die Agenten während der Ausführung aufrufen können.

@registry.register(
   identify="statistics_engine",
   description="Computes descriptive statistics on an inventory of numbers",
   parameters={"numbers": "Comma-separated checklist of numbers, e.g. '4,8,15,16,23,42'"},
   returns="JSON with imply, median, std_dev, min, max, rely"
)
def statistics_engine(numbers: str) -> str:
   attempt:
       nums = (float(x.strip()) for x in numbers.cut up(","))
       n = len(nums)
       imply = sum(nums) / n
       sorted_nums = sorted(nums)
       mid = n // 2
       median = sorted_nums(mid) if n % 2 else (sorted_nums(mid-1) + sorted_nums(mid)) / 2
       std_dev = math.sqrt(sum((x - imply) ** 2 for x in nums) / n)
       return json.dumps({
           "rely": n, "imply": spherical(imply, 4), "median": spherical(median, 4),
           "std_dev": spherical(std_dev, 4), "min": min(nums),
           "max": max(nums), "vary": max(nums) - min(nums)
       }, indent=2)
   besides Exception as e:
       return f"Error: {e}"


@registry.register(
   identify="list_sorter",
   description="Types a comma-separated checklist of numbers",
   parameters={"numbers": "Comma-separated numbers", "order": "'asc' or 'desc'"},
   returns="Sorted comma-separated checklist"
)
def list_sorter(numbers: str, order: str = "asc") -> str:
   nums = (float(x.strip()) for x in numbers.cut up(","))
   nums.type(reverse=(order == "desc"))
   return ", ".be a part of(str(n) for n in nums)


@dataclass
class MemoryEntry:
   function: str
   content material: str
   timestamp: float = area(default_factory=time.time)
   metadata: Dict = area(default_factory=dict)


class MemoryManager:
   def __init__(self, config: BlueprintMemory, llm_client: OpenAI):
       self.config = config
       self.consumer = llm_client
       self._history: Record(MemoryEntry) = ()
       self._summary: str = ""


   def add(self, function: str, content material: str, metadata: Dict = None):
       self._history.append(MemoryEntry(function=function, content material=content material, metadata=metadata or {}))
       if (self.config.sort == MemoryType.EPISODIC and
               len(self._history) > self.config.summarize_after):
           self._compress_memory()


   def _compress_memory(self):
       to_compress = self._history(:-self.config.window_size)
       self._history = self._history(-self.config.window_size:)
       textual content = "n".be a part of(f"{e.function}: {e.content material(:200)}" for e in to_compress)
       attempt:
           resp = self.consumer.chat.completions.create(
               mannequin="gpt-4o-mini",
               messages=({"function": "consumer", "content material":
                   f"Summarize this dialog historical past in 3 sentences:n{textual content}"}),
               max_tokens=150
           )
           self._summary += " " + resp.decisions(0).message.content material.strip()
       besides Exception:
           self._summary += f" (compressed {len(to_compress)} messages)"


   def get_messages(self, system_prompt: str) -> Record(Dict):
       messages = ({"function": "system", "content material": system_prompt})
       if self._summary:
           messages.append({"function": "system",
               "content material": f"(Reminiscence Abstract): {self._summary.strip()}"})
       for entry in self._history(-self.config.window_size:):
           messages.append({
               "function": entry.function if entry.function != "software" else "assistant",
               "content material": entry.content material
           })
       return messages


   def clear(self):
       self._history = ()
       self._summary = ""


   @property
   def message_count(self) -> int:
       return len(self._history)

Wir erweitern das Instrument-Ökosystem und führen die Speicherverwaltungsschicht ein, die den Gesprächsverlauf speichert und bei Bedarf komprimiert. Wir implementieren statistische Instruments und Sortierprogramme, die es dem Datenanalyseagenten ermöglichen, strukturierte numerische Operationen durchzuführen. Gleichzeitig entwerfen wir ein Speichersystem, das Interaktionen verfolgt, lange Historien zusammenfasst und dem Sprachmodell kontextbezogene Nachrichten liefert.

@dataclass
class PlanStep:
   step_id: int
   description: str
   software: Elective(str)
   tool_args: Dict(str, Any)
   reasoning: str


@dataclass
class Plan:
   job: str
   steps: Record(PlanStep)
   technique: PlanningStrategy


class Planner:
   def __init__(self, blueprint: CognitiveBlueprint,
                registry: ToolRegistry, llm_client: OpenAI):
       self.blueprint = blueprint
       self.registry  = registry
       self.consumer    = llm_client


   def _build_planner_prompt(self) -> str:
       bp = self.blueprint
       return textwrap.dedent(f"""
           You might be {bp.identification.identify}, model {bp.identification.model}.
           {bp.identification.description}


           ## Your Objectives:
           {chr(10).be a part of(f'  - {g}' for g in bp.objectives)}


           ## Your Constraints:
           {chr(10).be a part of(f'  - {c}' for c in bp.constraints)}


           ## Accessible Instruments:
           {self.registry.get_tool_descriptions(bp.instruments)}


           ## Planning Technique: {bp.planning.technique}
           ## Max Steps: {bp.planning.max_steps}


           Given a consumer job, produce a JSON execution plan with this precise construction:
           {{
             "steps": (
               {{
                 "step_id": 1,
                 "description": "What this step does",
                 "software": "tool_name or null if no software wanted",
                 "tool_args": {{"arg1": "value1"}},
                 "reasoning": "Why this step is required"
               }}
             )
           }}


           Guidelines:
           - Solely use instruments listed above
           - Set software to null for pure reasoning steps
           - Maintain steps <= {bp.planning.max_steps}
           - Return ONLY legitimate JSON, no markdown fences
           {bp.system_prompt_extra}
       """).strip()


   def plan(self, job: str, reminiscence: MemoryManager) -> Plan:
       system_prompt = self._build_planner_prompt()
       messages = reminiscence.get_messages(system_prompt)
       messages.append({"function": "consumer", "content material":
           f"Create a plan to finish this job: {job}"})
       resp = self.consumer.chat.completions.create(
           mannequin="gpt-4o-mini", messages=messages,
           max_tokens=1200, temperature=0.2
       )
       uncooked = resp.decisions(0).message.content material.strip()
       uncooked = uncooked.change("```json", "").change("```", "").strip()
       information = json.hundreds(uncooked)
       steps = (
           PlanStep(
               step_id=s("step_id"), description=s("description"),
               software=s.get("software"), tool_args=s.get("tool_args", {}),
               reasoning=s.get("reasoning", "")
           )
           for s in information("steps")
       )
       return Plan(job=job, steps=steps, technique=self.blueprint.planning.technique)


@dataclass
class StepResult:
   step_id: int
   success: bool
   output: str
   tool_used: Elective(str)
   error: Elective(str) = None


@dataclass
class ExecutionTrace:
   plan: Plan
   outcomes: Record(StepResult)
   final_answer: str


class Executor:
   def __init__(self, blueprint: CognitiveBlueprint,
                registry: ToolRegistry, llm_client: OpenAI):
       self.blueprint = blueprint
       self.registry  = registry
       self.consumer    = llm_client

Wir implementieren das Planungssystem, das eine Benutzeraufgabe in einen strukturierten Ausführungsplan umwandelt, der aus mehreren Schritten besteht. Wir entwerfen einen Planer, der das Sprachmodell anweist, einen JSON-Plan zu erstellen, der Begründung, Werkzeugauswahl und Argumente für jeden Schritt enthält. Diese Planungsebene ermöglicht es dem Agenten, komplexe Probleme vor der Ausführung in kleinere ausführbare Aktionen zu unterteilen.

  def execute_plan(self, plan: Plan, reminiscence: MemoryManager,
                    verbose: bool = True) -> ExecutionTrace:
       outcomes: Record(StepResult) = ()
       if verbose:
           console.print(f"n(daring yellow)⚡ Executing:(/) {plan.job}")
           console.print(f"   Technique: {plan.technique} | Steps: {len(plan.steps)}")


       for step in plan.steps:
           if verbose:
               console.print(f"n  (cyan)Step {step.step_id}:(/) {step.description}")
           attempt:
               if step.software and step.software != "null":
                   if verbose:
                       console.print(f"   🔧 Instrument: (inexperienced){step.software}(/) | Args: {step.tool_args}")
                   output = self.registry.name(step.software, **step.tool_args)
                   end result = StepResult(step.step_id, True, str(output), step.software)
                   if verbose:
                       console.print(f"   ✅ Outcome: {output}")
               else:
                   context_text = "n".be a part of(
                       f"Step {r.step_id} end result: {r.output}" for r in outcomes)
                   immediate = (
                       f"Earlier outcomes:n{context_text}nn"
                       f"Now full this step: {step.description}n"
                       f"Reasoning trace: {step.reasoning}"
                   ) if context_text else (
                       f"Full this step: {step.description}n"
                       f"Reasoning trace: {step.reasoning}"
                   )
                   sys_prompt = (
                       f"You might be {self.blueprint.identification.identify}. "
                       f"{self.blueprint.identification.description}. "
                       f"Constraints: {'; '.be a part of(self.blueprint.constraints)}"
                   )
                   resp = self.consumer.chat.completions.create(
                       mannequin="gpt-4o-mini",
                       messages=(
                           {"function": "system", "content material": sys_prompt},
                           {"function": "consumer",   "content material": immediate}
                       ),
                       max_tokens=500, temperature=0.3
                   )
                   output = resp.decisions(0).message.content material.strip()
                   end result = StepResult(step.step_id, True, output, None)
                   if verbose:
                       preview = output(:120) + "..." if len(output) > 120 else output
                       console.print(f"   🤔 Reasoning: {preview}")
           besides Exception as e:
               end result = StepResult(step.step_id, False, "", step.software, str(e))
               if verbose:
                   console.print(f"   ❌ Error: {e}")
           outcomes.append(end result)


       final_answer = self._synthesize(plan, outcomes, reminiscence)
       return ExecutionTrace(plan=plan, outcomes=outcomes, final_answer=final_answer)


   def _synthesize(self, plan: Plan, outcomes: Record(StepResult),
                   reminiscence: MemoryManager) -> str:
       steps_summary = "n".be a part of(
           f"Step {r.step_id} ({'✅' if r.success else '❌'}): {r.output(:300)}"
           for r in outcomes
       )
       synthesis_prompt = (
           f"Authentic job: {plan.job}nn"
           f"Step outcomes:n{steps_summary}nn"
           f"Present a transparent, full last reply. Combine all step outcomes."
       )
       sys_prompt = (
           f"You might be {self.blueprint.identification.identify}. "
           + ("All the time present your reasoning. " if self.blueprint.validation.require_reasoning else "")
           + f"Objectives: {'; '.be a part of(self.blueprint.objectives)}"
       )
       messages = reminiscence.get_messages(sys_prompt)
       messages.append({"function": "consumer", "content material": synthesis_prompt})
       resp = self.consumer.chat.completions.create(
           mannequin="gpt-4o-mini", messages=messages,
           max_tokens=600, temperature=0.3
       )
       return resp.decisions(0).message.content material.strip()


@dataclass
class ValidationResult:
   handed: bool
   points: Record(str)
   rating: float


class Validator:
   def __init__(self, blueprint: CognitiveBlueprint, llm_client: OpenAI):
       self.blueprint = blueprint
       self.consumer    = llm_client


   def validate(self, reply: str, job: str,
                use_llm_check: bool = False) -> ValidationResult:
       points = ()
       v = self.blueprint.validation


       if len(reply) < v.min_response_length:
           points.append(f"Response too brief: {len(reply)} chars (min: {v.min_response_length})")


       answer_lower = reply.decrease()
       for phrase in v.forbidden_phrases:
           if phrase.decrease() in answer_lower:
               points.append(f"Forbidden phrase detected: '{phrase}'")


       if v.require_reasoning:
           indicators = ("as a result of", "subsequently", "since", "step", "first",
                         "end result", "calculated", "computed", "discovered that")
           if not any(ind in answer_lower for ind in indicators):
               points.append("Response lacks seen reasoning or rationalization")


       if use_llm_check:
           points.prolong(self._llm_quality_check(reply, job))


       return ValidationResult(handed=len(points) == 0,
                               points=points,
                               rating=max(0.0, 1.0 - len(points) * 0.25))


   def _llm_quality_check(self, reply: str, job: str) -> Record(str):
       immediate = (
           f"Job: {job}nnAnswer: {reply(:500)}nn"
           f'Does this reply deal with the duty? Reply JSON: {{"on_topic": true/false, "difficulty": "..."}}'
       )
       attempt:
           resp = self.consumer.chat.completions.create(
               mannequin="gpt-4o-mini",
               messages=({"function": "consumer", "content material": immediate}),
               max_tokens=100
           )
           uncooked = resp.decisions(0).message.content material.strip().change("```json","").change("```","")
           information = json.hundreds(uncooked)
           if not information.get("on_topic", True):
               return (f"LLM high quality test: {information.get('difficulty', 'off-topic')}")
       besides Exception:
           move
       return ()

Wir erstellen den Executor und die Validierungslogik, die die vom Planer generierten Schritte tatsächlich ausführt. Wir implementieren ein System, das je nach Schrittdefinition entweder registrierte Instruments aufrufen oder Argumentationen über das Sprachmodell durchführen kann. Wir fügen außerdem einen Validator hinzu, der die endgültige Antwort anhand von Blueprint-Einschränkungen wie Mindestlänge, Begründungsanforderungen und verbotenen Phrasen prüft.

@dataclass
class AgentResponse:
   agent_name: str
   job: str
   final_answer: str
   hint: ExecutionTrace
   validation: ValidationResult
   retries: int
   total_steps: int


class RuntimeEngine:
   def __init__(self, blueprint: CognitiveBlueprint,
                registry: ToolRegistry, llm_client: OpenAI):
       self.blueprint = blueprint
       self.reminiscence    = MemoryManager(blueprint.reminiscence, llm_client)
       self.planner   = Planner(blueprint, registry, llm_client)
       self.executor  = Executor(blueprint, registry, llm_client)
       self.validator = Validator(blueprint, llm_client)


   def run(self, job: str, verbose: bool = True) -> AgentResponse:
       bp = self.blueprint
       if verbose:
           console.print(Panel(
               f"(daring)Agent:(/) {bp.identification.identify} v{bp.identification.model}n"
               f"(daring)Job:(/) {job}n"
               f"(daring)Technique:(/) {bp.planning.technique} | "
               f"Max Steps: {bp.planning.max_steps} | "
               f"Max Retries: {bp.planning.max_retries}",
               title="🚀 Runtime Engine Beginning", border_style="blue"
           ))


       self.reminiscence.add("consumer", job)
       retries, hint, validation = 0, None, None


       for try in vary(bp.planning.max_retries + 1):
           if try > 0 and verbose:
               console.print(f"n(yellow)⟳ Retry {try}/{bp.planning.max_retries}(/)")
               console.print(f"  Points: {', '.be a part of(validation.points)}")


           if verbose:
               console.print("n(daring magenta)📋 Part 1: Planning...(/)")
           attempt:
               plan = self.planner.plan(job, self.reminiscence)
               if verbose:
                   tree = Tree(f"(daring)Plan ({len(plan.steps)} steps)(/)")
                   for s in plan.steps:
                       icon = "🔧" if s.software else "🤔"
                       department = tree.add(f"{icon} Step {s.step_id}: {s.description}")
                       if s.software:
                           department.add(f"(inexperienced)Instrument:(/) {s.software}")
                           department.add(f"(yellow)Args:(/) {s.tool_args}")
                   console.print(tree)
           besides Exception as e:
               if verbose: console.print(f"(pink)Planning failed:(/) {e}")
               break


           if verbose:
               console.print("n(daring magenta)⚡ Part 2: Executing...(/)")
           hint = self.executor.execute_plan(plan, self.reminiscence, verbose=verbose)


           if verbose:
               console.print("n(daring magenta)✅ Part 3: Validating...(/)")
           validation = self.validator.validate(hint.final_answer, job)


           if verbose:
               standing = "(inexperienced)PASSED(/)" if validation.handed else "(pink)FAILED(/)"
               console.print(f"  Validation: {standing} | Rating: {validation.rating:.2f}")
               for difficulty in validation.points:
                   console.print(f"  ⚠  {difficulty}")


           if validation.handed:
               break


           retries += 1
           self.reminiscence.add("assistant", hint.final_answer)
           self.reminiscence.add("consumer",
               f"Your earlier reply had points: {'; '.be a part of(validation.points)}. "
               f"Please enhance."
           )


       if hint:
           self.reminiscence.add("assistant", hint.final_answer)


       if verbose:
           console.print(Panel(
               hint.final_answer if hint else "No reply generated",
               title=f"🎯 Remaining Reply — {bp.identification.identify}",
               border_style="inexperienced"
           ))


       return AgentResponse(
           agent_name=bp.identification.identify, job=job,
           final_answer=hint.final_answer if hint else "",
           hint=hint, validation=validation,
           retries=retries,
           total_steps=len(hint.outcomes) if hint else 0
       )


   def reset_memory(self):
       self.reminiscence.clear()


def build_engine(blueprint_yaml: str, registry: ToolRegistry,
                llm_client: OpenAI) -> RuntimeEngine:
   return RuntimeEngine(load_blueprint_from_yaml(blueprint_yaml), registry, llm_client)


if __name__ == "__main__":


   print("n" + "="*60)
   print("DEMO 1: ResearchBot")
   print("="*60)
   research_engine = build_engine(RESEARCH_AGENT_YAML, registry, consumer)
   research_engine.run(
       job=(
           "what number of steps of 20cm top would that be? Additionally, if I burn 0.15 "
           "energy per step, what is the complete calorie burn? Present all calculations."
       )
   )


   print("n" + "="*60)
   print("DEMO 2: DataAnalystBot")
   print("="*60)
   analyst_engine = build_engine(DATA_ANALYST_YAML, registry, consumer)
   analyst_engine.run(
       job=(
           "Analyze this dataset of month-to-month gross sales figures (in 1000's): "
           "142, 198, 173, 155, 221, 189, 203, 167, 244, 198, 212, 231. "
           "Compute key statistics, determine the very best and worst months, "
           "and calculate development from first to final month."
       )
   )


   print("n" + "="*60)
   print("PORTABILITY DEMO: Identical job → 2 totally different blueprints")
   print("="*60)
   SHARED_TASK = "Calculate 15% of two,500 and inform me the end result."


   responses = {}
   for identify, yaml_str in (
       ("ResearchBot",    RESEARCH_AGENT_YAML),
       ("DataAnalystBot", DATA_ANALYST_YAML),
   ):
       eng = build_engine(yaml_str, registry, consumer)
       responses(identify) = eng.run(SHARED_TASK, verbose=False)


   desk = Desk(title="🔄 Blueprint Portability", show_header=True, show_lines=True)
   desk.add_column("Agent",   fashion="cyan",   width=18)
   desk.add_column("Steps",   fashion="yellow", width=6)
   desk.add_column("Legitimate?",  width=7)
   desk.add_column("Rating",   width=6)
   desk.add_column("Reply Preview", width=55)


   for identify, r in responses.objects():
       desk.add_row(
           identify, str(r.total_steps),
           "✅" if r.validation.handed else "❌",
           f"{r.validation.rating:.2f}",
           r.final_answer(:140) + "..."
       )
   console.print(desk)

Wir stellen die Laufzeit-Engine zusammen, die Planung, Ausführung, Speicheraktualisierungen und Validierung zu einem vollständig autonomen Workflow orchestriert. Wir führen mehrere Demonstrationen durch, die zeigen, wie unterschiedliche Blaupausen bei Verwendung derselben Kernarchitektur unterschiedliche Verhaltensweisen hervorrufen. Abschließend veranschaulichen wir die Blueprint-Portabilität, indem wir dieselbe Aufgabe auf zwei Agenten ausführen und deren Ergebnisse vergleichen.

Zusammenfassend haben wir ein voll funktionsfähiges Laufzeitsystem im Auton-Stil erstellt, das kognitive Blaupausen, Werkzeugregister, Speicherverwaltung, Planung, Ausführung und Validierung in ein zusammenhängendes Framework integriert. Wir haben gezeigt, wie verschiedene Agenten die gleiche zugrunde liegende Architektur nutzen und sich dabei unterschiedlich verhalten können, indem wir benutzerdefinierte Blaupausen erstellt haben, was die Flexibilität und Leistungsfähigkeit des Designs hervorgehoben hat. Durch diese Implementierung haben wir nicht nur untersucht, wie moderne Laufzeitagenten funktionieren, sondern auch eine solide Grundlage geschaffen, die wir mit umfangreicheren Instruments, stärkeren Speichersystemen und fortschrittlicheren autonomen Verhaltensweisen weiter ausbauen können.


Schauen Sie sich das an Vollständige Codes hier Und Verwandtes Papier. Sie können uns auch gerne weiter folgen Twitter und vergessen Sie nicht, bei uns mitzumachen 120.000+ ML SubReddit und Abonnieren Unser E-newsletter. Warten! Bist du im Telegram? Jetzt können Sie uns auch per Telegram kontaktieren.


[ad_2]

]]>
https://chatgpz.de/artificial-intelligence/aufbau-einer-agenten-ki-der-naechsten-technology-ein-vollstaendiges-framework-fuer-kognitive-blueprint-gesteuerte-laufzeitagenten-mit-speichertools-und-validierung/feed/ 0 16894
Pydantic-Leistung: 4 Tipps zur effizienten Validierung großer Datenmengen https://chatgpz.de/machine-learning/pydantic-leistung-4-tipps-zur-effizienten-validierung-grosser-datenmengen/ https://chatgpz.de/machine-learning/pydantic-leistung-4-tipps-zur-effizienten-validierung-grosser-datenmengen/#respond Fri, 06 Feb 2026 17:53:43 +0000 https://chatgpz.de/machine-learning/pydantic-leistung-4-tipps-zur-effizienten-validierung-grosser-datenmengen/ [ad_1]

sind so einfach zu bedienen, dass man sie auch leicht falsch verwenden kann, etwa wenn man einen Hammer am Kopf hält. Das Gleiche gilt für Pydantic, eine leistungsstarke Datenvalidierungsbibliothek für Python.

In Pydantic v2 ist die Kernvalidierungs-Engine implementiert RostDamit ist es eine der schnellsten Datenvalidierungslösungen im Python-Ökosystem. Dieser Leistungsvorteil wird jedoch nur dann realisiert, wenn Sie Pydantic auf eine Weise verwenden, die diesen hochoptimierten Kern tatsächlich nutzt.

Dieser Artikel konzentriert sich auf die effiziente Nutzung von Pydantic, insbesondere bei der Validierung großer Datenmengen. Wir heben vier häufige Fallstricke hervor, die zu Leistungsunterschieden in der Größenordnung führen können, wenn sie nicht aktiviert werden.


1) Bevorzugen Annotated Einschränkungen für Feldvalidatoren

Ein Kernmerkmal von Pydantic besteht darin, dass die Datenvalidierung deklarativ in einer Modellklasse definiert wird. Wenn ein Modell instanziiert wird, analysiert und validiert Pydantic die Eingabedaten entsprechend den für diese Klasse definierten Feldtypen und Validatoren.

Der naive Ansatz: Feldvalidatoren

Wir verwenden a @field_validator um Daten zu validieren, z. B. um zu prüfen, ob eine id Spalte ist tatsächlich eine Ganzzahl oder größer als Null. Dieser Stil ist lesbar und flexibel, geht jedoch mit Leistungseinbußen einher.

class UserFieldValidators(BaseModel):
    id: int
    electronic mail: EmailStr
    tags: listing(str)

    @field_validator("id")
    def _validate_id(cls, v: int) -> int:
        if not isinstance(v, int):
            increase TypeError("id have to be an integer")
        if v < 1:
            increase ValueError("id have to be >= 1")
        return v

    @field_validator("electronic mail")
    def _validate_email(cls, v: str) -> str:
        if not isinstance(v, str):
            v = str(v)
        if not _email_re.match(v):
            increase ValueError("invalid electronic mail format")
        return v

    @field_validator("tags")
    def _validate_tags(cls, v: listing(str)) -> listing(str):
        if not isinstance(v, listing):
            increase TypeError("tags have to be an inventory")
        if not (1 <= len(v) <= 10):
            increase ValueError("tags size have to be between 1 and 10")
        for i, tag in enumerate(v):
            if not isinstance(tag, str):
                increase TypeError(f"tag({i}) have to be a string")
            if tag == "":
                increase ValueError(f"tag({i}) should not be empty")

Der Grund dafür ist, dass Feldvalidatoren in ausgeführt werden Python, nach Kerntyp-Zwang und Einschränkungsvalidierung. Dies verhindert, dass sie optimiert oder in die Kernvalidierungspipeline integriert werden.

Der optimierte Ansatz: Annotated

Wir können verwenden Annotated von Python typing Bibliothek.

class UserAnnotated(BaseModel):
    id: Annotated(int, Discipline(ge=1))
    electronic mail: Annotated(str, Discipline(sample=RE_EMAIL_PATTERN))
    tags: Annotated(listing(str), Discipline(min_length=1, max_length=10))

Diese Model ist kürzer, klarer und zeigt eine schnellere Ausführung im großen Maßstab.

Warum Annotated ist schneller

Annotated (PEP 593) ist eine Normal-Python-Funktion von typing Bibliothek. Die darin platzierten Einschränkungen Annotated werden in das interne Schema von Pydantic kompiliert und im Pydantic-Core (Rust) ausgeführt.

Dies bedeutet, dass während der Validierung keine benutzerdefinierten Python-Validierungsaufrufe erforderlich sind. Außerdem werden keine Python-Zwischenobjekte oder benutzerdefinierten Kontrollflüsse eingeführt.

Im Gegensatz dazu @field_validator Funktionen stets Wenn sie in Python ausgeführt werden, führen sie zu einem Funktionsaufruf-Overhead und häufig zu doppelten Prüfungen, die bei der Kernvalidierung hätten durchgeführt werden können.

Wichtige Nuance

Eine wichtige Nuance ist das Annotated selbst ist nicht „Rust“. Die Beschleunigung entsteht durch die Verwendung von Einschränkungen, die Pydantic-Core versteht und verwenden kann, nicht durch Annotated für sich allein existierend.

Benchmark

Der Unterschied zwischen keine Validierung Und <sturdy>Annotated</sturdy> Validierung ist in diesen Benchmarks vernachlässigbar, während Python-Validatoren einen Unterschied in der Größenordnung ausmachen können.

Validierungsleistungsdiagramm (Bild vom Autor)
                    Benchmark (time in seconds)                     
┏━━━━━━━━━━━━━━━━┳━━━━━━━━━━━┳━━━━━━━━━━┳━━━━━━━━━━━┳━━━━━━━━━━━┓
┃ Methodology         ┃     n=100 ┃     n=1k ┃     n=10k ┃     n=50k ┃
┡━━━━━━━━━━━━━━━━╇━━━━━━━━━━━╇━━━━━━━━━━╇━━━━━━━━━━━╇━━━━━━━━━━━┩
│ FieldValidators│     0.004 │    0.020 │     0.194 │     0.971 │
│ No Validation  │     0.000 │    0.001 │     0.007 │     0.032 │
│ Annotated      │     0.000 │    0.001 │     0.007 │     0.036 │
└────────────────┴───────────┴──────────┴───────────┴───────────┘

In absoluten Zahlen erreichen wir eine Validierungszeit von quick einer Sekunde auf 36 Millisekunden. Eine Leistungssteigerung um quick das 30-fache.

Urteil

Verwenden Annotated wann immer möglich. Du bekommst bessere Leistung Und klarere Modelle. Benutzerdefinierte Validatoren sind leistungsstark, aber Sie zahlen für diese Flexibilität in den Laufzeitkosten, additionally reservieren Sie @field_validator für Logik, die nicht als Einschränkungen ausgedrückt werden kann.


2). Validieren Sie JSON mit model_validate_json()

Wir haben Daten in Type eines JSON-Strings. Was ist der effizienteste Weg, diese Daten zu validieren?

Der naive Ansatz

Analysieren Sie einfach den JSON und validieren Sie das Wörterbuch:

py_dict = json.hundreds(j)
UserAnnotated.model_validate(py_dict)

Der optimierte Ansatz

Verwenden Sie eine Pydantic-Funktion:

UserAnnotated.model_validate_json(j)

Warum das schneller ist

  • model_validate_json() analysiert JSON und validiert es in einer Pipeline
  • Es verwendet Pydantic intern und einen schnelleren JSON-Parser
  • Es vermeidet den Aufbau großer Python-Zwischenwörterbücher und das zweite Durchlaufen dieser Wörterbücher während der Validierung

Mit json.hundreds() Sie zahlen doppelt: zuerst für das Parsen von JSON in Python-Objekte, dann für die Validierung und Erzwingung dieser Objekte.

model_validate_json() Reduziert Speicherzuweisungen und redundantes Durchlaufen.

Benchmarked

Die Pydantic-Model ist quick doppelt so schnell.

Leistungsdiagramm (Bild vom Autor)
                  Benchmark (time in seconds)                   
┏━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━┳━━━━━━━┳━━━━━━━┳━━━━━━━┳━━━━━━━━┓
┃ Methodology              ┃ n=100 ┃  n=1K ┃ n=10K ┃ n=50K ┃ n=250K ┃
┡━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━╇━━━━━━━╇━━━━━━━╇━━━━━━━╇━━━━━━━━┩
│ Load json           │ 0.000 │ 0.002 │ 0.016 │ 0.074 │  0.368 │
│ mannequin validate json │ 0.001 │ 0.001 │ 0.009 │ 0.042 │  0.209 │
└─────────────────────┴───────┴───────┴───────┴───────┴────────┘

In absoluten Zahlen sparen wir durch die Änderung 0,1 Sekunden bei der Validierung einer Viertelmillion Objekte.

Urteil

Wenn Ihre Eingabe JSON ist, überlassen Sie Pydantic die Analyse und Validierung in einem Schritt. Aus Leistungsgründen ist die Verwendung nicht unbedingt erforderlich model_validate_json() aber tun Sie dies trotzdem, um die Erstellung von Python-Zwischenobjekten zu vermeiden und Ihren Code zu komprimieren.


3) Verwendung TypeAdapter zur Massenvalidierung

Wir haben ein Consumer Modell und jetzt wollen wir a validieren listing von ConsumerS.

Der naive Ansatz

Wir können die Liste durchlaufen und jeden Eintrag validieren oder ein Wrapper-Modell erstellen. Annehmen batch ist ein listing(dict):

# 1. Per-item validation
fashions = (Consumer.model_validate(merchandise) for merchandise in batch)

# 2. Wrapper mannequin


# 2.1 Outline a wrapper mannequin:
class UserList(BaseModel):
  customers: listing(Consumer)


# 2.2 Validate with the wrapper mannequin
fashions = UserList.model_validate({"customers": batch}).customers

Optimierter Ansatz

Typadapter sind für die Validierung von Objektlisten schneller.

ta_annotated = TypeAdapter(listing(UserAnnotated))
fashions = ta_annotated.validate_python(batch)

Warum das schneller ist

Überlassen Sie die schwere Arbeit Rust. Für die Verwendung eines TypeAdapter ist die Erstellung eines zusätzlichen Wrappers nicht erforderlich, und die Validierung wird mit einem ausgeführt einzelnes kompiliertes Schema. Es gibt weniger Grenzübergänge von Python nach Rust und zurück und es entsteht ein geringerer Aufwand für die Objektzuweisung.

Wrapper-Modelle sind langsamer, weil sie mehr als nur die Liste validieren:

  • Konstruiert eine zusätzliche Modellinstanz
  • Verfolgt Feldsätze und internen Standing
  • Behandelt Konfiguration, Standardeinstellungen und Extras

Diese zusätzliche Ebene ist professional Aufruf klein, wird aber im Maßstab messbar.

Benchmarked

Bei der Verwendung großer Units stellen wir fest, dass der Typ-Adapter deutlich schneller ist, insbesondere im Vergleich zum Wrapper-Modell.

Leistungsdiagramm (Bild vom Autor)
                   Benchmark (time in seconds)                    
┏━━━━━━━━━━━━━━┳━━━━━━━┳━━━━━━━┳━━━━━━━┳━━━━━━━┳━━━━━━━━┳━━━━━━━━┓
┃ Methodology       ┃ n=100 ┃  n=1K ┃ n=10K ┃ n=50K ┃ n=100K ┃ n=250K ┃
┡━━━━━━━━━━━━━━╇━━━━━━━╇━━━━━━━╇━━━━━━━╇━━━━━━━╇━━━━━━━━╇━━━━━━━━┩
│ Per-item     │ 0.000 │ 0.001 │ 0.021 │ 0.091 │  0.236 │  0.502 │
│ Wrapper mannequin│ 0.000 │ 0.001 │ 0.008 │ 0.108 │  0.208 │  0.602 │
│ TypeAdapter  │ 0.000 │ 0.001 │ 0.021 │ 0.083 │  0.152 │  0.381 │
└──────────────┴───────┴───────┴───────┴───────┴────────┴────────┘

In absoluten Zahlen sparen wir durch die Beschleunigung jedoch etwa 120 bis 220 Millisekunden bei 250.000 Objekten.

Urteil

Wenn Sie nur einen Typ validieren und kein Domänenobjekt definieren möchten, TypeAdapter ist die schnellste und sauberste Choice. Obwohl dies aus Gründen der Zeitersparnis nicht unbedingt erforderlich ist, überspringt es unnötige Modellinstanziierungen und vermeidet Python-seitige Validierungsschleifen, wodurch Ihr Code sauberer und besser lesbar wird.


4) Vermeiden from_attributes es sei denn, Sie brauchen es

Mit from_attributes Sie konfigurieren Ihre Modellklasse. Wenn Sie es einstellen True Sie weisen Pydantic an, Werte aus Objektattributen statt aus Wörterbuchschlüsseln zu lesen. Dies ist wichtig, wenn Ihre Eingabe etwas anderes als ein Wörterbuch ist, wie etwa eine SQLAlchemy ORM-Instanz, eine Datenklasse oder ein beliebiges einfaches Python-Objekt mit Attributen.

Standardmäßig from_attributes Ist False. Manchmal setzen Entwickler dieses Attribut auf True Um das Modell flexibel zu halten:

class Product(BaseModel):
    id: int
    identify: str

    model_config = ConfigDict(from_attributes=True)

Wenn Sie jedoch nur Wörterbücher an Ihr Modell übergeben, sollten Sie dies am besten vermeiden from_attributes weil es erfordert, dass Python viel mehr Arbeit leistet. Der resultierende Overhead bietet keinen Vorteil, wenn sich die Eingabe bereits in der einfachen Zuordnung befindet.

Warum from_attributes=True ist langsamer

Diese Methode verwendet getattr() anstelle der Wörterbuchsuche, die langsamer ist. Außerdem kann es Funktionen für das Objekt auslösen, von dem wir lesen, wie Deskriptoren, Eigenschaften oder ORM-Lazy-Loading.

Benchmark

Mit zunehmender Batch-Größe wird die Verwendung von Attributen immer teurer.

Leistungsdiagramm (Bild vom Autor)
                       Benchmark (time in seconds)                        
┏━━━━━━━━━━━━━━┳━━━━━━━┳━━━━━━━┳━━━━━━━┳━━━━━━━┳━━━━━━━━┳━━━━━━━━┓
┃ Methodology       ┃ n=100 ┃  n=1K ┃ n=10K ┃ n=50K ┃ n=100K ┃ n=250K ┃
┡━━━━━━━━━━━━━━╇━━━━━━━╇━━━━━━━╇━━━━━━━╇━━━━━━━╇━━━━━━━━╇━━━━━━━━┩
│ with attribs │ 0.000 │ 0.001 │ 0.011 │ 0.110 │  0.243 │  0.593 │
│ no attribs   │ 0.000 │ 0.001 │ 0.012 │ 0.103 │  0.196 │  0.459 │
└──────────────┴───────┴───────┴───────┴───────┴────────┴────────┘

In absoluten Zahlen werden bei der Validierung von 250.000 Objekten etwas weniger als 0,1 Sekunden eingespart.

Urteil

Nur verwenden from_attributes wenn Ihre Eingabe ist kein Diktat. Es dient zur Unterstützung attributbasierter Objekte (ORMs, Datenklassen, Domänenobjekte). In diesen Fällen kann es schneller sein, als das Objekt zunächst in ein Diktat zu übertragen und es dann zu validieren. Bei einfachen Zuordnungen erhöht sich der Overhead ohne Nutzen.


Abschluss

Der Sinn dieser Optimierungen besteht nicht darin, um ihrer selbst willen ein paar Millisekunden einzusparen. In absoluten Zahlen ist selbst ein Unterschied von 100 ms selten der Flaschenhals in einem realen System.

Der wahre Wert liegt darin, klareren Code zu schreiben und Ihre Instruments richtig zu verwenden.

Die Verwendung der in diesem Artikel angegebenen Tipps führt zu klarere Modellemehr explizite Absichtund a bessere Ausrichtung mit der Funktionsweise von Pydantic. Diese Muster verschieben die Validierungslogik aus Advert-hoc-Python-Code in deklarative Schemata einfacher zu lesen, zu begründen und zu warten.

Die Leistungsverbesserungen sind ein Nebeneffekt des Handelns der richtige Weg. Wenn Validierungsregeln deklarativ ausgedrückt werden, kann Pydantic sie konsistent anwenden, intern optimieren und auf natürliche Weise skalieren, wenn Ihre Daten wachsen.

Zusamenfassend:

Übernehmen Sie diese Muster nicht, nur weil sie schneller sind. Übernehmen Sie sie, weil sie Ihren Code einfacher, expliziter und besser für die von Ihnen verwendeten Instruments geeignet machen.

Die Beschleunigung ist einfach ein netter Bonus.


Ich hoffe, dieser Artikel conflict so klar, wie ich es beabsichtigt hatte. Sollte dies jedoch nicht der Fall sein, teilen Sie mir bitte mit, was ich zur weiteren Klärung tun kann. Schauen Sie sich in der Zwischenzeit meine an andere Artikel zu allen möglichen Programmierthemen.

Viel Spaß beim Codieren!

– Mike

Ps: Gefällt mir, was ich mache? Folgen Sie mir!

[ad_2]

]]>
https://chatgpz.de/machine-learning/pydantic-leistung-4-tipps-zur-effizienten-validierung-grosser-datenmengen/feed/ 0 16114
So führen Sie eine umfassende LLM -Validierung in großem Maßstab durch https://chatgpz.de/artificial-intelligence/so-fuehren-sie-eine-umfassende-llm-validierung-in-grossem-massstab-durch/ https://chatgpz.de/artificial-intelligence/so-fuehren-sie-eine-umfassende-llm-validierung-in-grossem-massstab-durch/#respond Fri, 22 Aug 2025 07:32:56 +0000 http://chatgpz.de/artificial-intelligence/so-fuehren-sie-eine-umfassende-llm-validierung-in-grossem-massstab-durch/ [ad_1]

und Bewertungen sind entscheidend, um robuste, leistungsstarke LLM-Anwendungen sicherzustellen. Solche Themen werden jedoch im größeren Schema von LLMs oft übersehen.

Stellen Sie sich dieses Szenario vor: Sie haben eine LLM -Abfrage, die 999/1000 Mal korrekt antwortet, wenn sie aufgefordert werden. Sie müssen jedoch 1,5 Millionen Elemente ausführen, um die Datenbank zu füllen. In diesem (sehr realistischen) Szenario werden Sie erleben 1500 Fehler für diese LLM -Eingabeaufforderung allein. Skalieren Sie nun diese bis zu 10 Sekunden, wenn nicht 100er von verschiedenen Eingabeaufforderungen, und Sie haben ein echtes Skalierbarkeitsproblem zur Hand.

Die Lösung soll Ihre LLM -Ausgabe validieren und eine hohe Leistung unter Verwendung von Bewertungen sicherstellen.

Diese Infografik unterstreicht den Hauptinhalt dieses Artikels. Ich werde über die Validierung und Bewertung von LLM-Outputs, qualitativen und quantitativen Bewertungen und dem Umgang mit großflächigen LLM-Anwendungen diskutieren.
Diese Infografik unterstreicht den Hauptinhalt dieses Artikels. Ich werde über die Validierung und Bewertung von LLM-Outputs, qualitativen und quantitativen Bewertungen und dem Umgang mit großflächigen LLM-Anwendungen diskutieren. Bild von Chatgpt.

Inhaltsverzeichnis

Was ist LLM -Validierung und -bewertung?

Ich denke, es ist wichtig, zunächst zu definieren, was LLM -Validierung und -bewertung sind und warum sie für Ihre Anwendung wichtig sind.

Bei der LLM -Validierung geht es darum, die Qualität Ihrer Ausgaben zu validieren. Ein häufiges Beispiel dafür ist, dass ein Stück Code ausgeführt wird, das überprüft, ob die LLM -Antwort die Frage des Benutzers beantwortet. Die Validierung ist wichtig, da Sie sicherstellen, dass Sie hochwertige Antworten liefern und Ihr LLM wie erwartet funktioniert. Die Validierung kann als etwas angesehen werden, das Sie in Echtzeit auf individuelle Antworten tun. Bevor Sie die Antwort an den Benutzer zurückgeben, überprüfen Sie beispielsweise, dass die Antwort tatsächlich von hoher Qualität ist.

Die LLM -Bewertung ist ähnlich; Es tritt jedoch normalerweise nicht in Echtzeit auf. Die Bewertung Ihrer LLM -Ausgabe kann beispielsweise alle Benutzerabfragen aus den letzten 30 Tagen betrachten und quantitativ bewerten, wie intestine Ihre LLM ausgeführt wurde.

Die Validierung und Bewertung der Leistung Ihres LLM ist wichtig, da Sie Probleme mit der LLM -Ausgabe haben. Es könnte zum Beispiel sein

  • Probleme mit Eingabedaten (fehlende Daten)
  • Eine Kantenhülle, die Ihre Eingabeaufforderung nicht für die Handlung ausgerüstet ist
  • Daten sind nicht verteilt
  • Usw.

Daher benötigen Sie eine robuste Lösung für die Behandlung von LLM -Ausgangsproblemen. Sie müssen sicherstellen, dass Sie sie so oft wie möglich vermeiden und in den verbleibenden Fällen umgehen.

Murphys Gesetz wurde an dieses Szenario angepasst:

In großem Maßstab wird alles, was schief gehen kann, schief gehen

Qualitative vs. quantitative Bewertungen

Bevor ich zu den einzelnen Abschnitten zur Durchführung von Validierungen und Bewertungen übergeht, möchte ich auch qualitative und quantitative Bewertungen von LLMs kommentieren. Bei der Arbeit mit LLMs ist es oft verlockend, die Leistung des LLM für verschiedene Eingabeaufforderungen manuell zu bewerten. Solche manuellen (qualitativen) Bewertungen unterliegen jedoch stark voreingenommenen Vorurteilen. Zum Beispiel könnten Sie sich den größten Teil Ihrer Aufmerksamkeit auf die Fälle konzentrieren, in denen die LLM erfolgreich battle, und somit die Leistung Ihres LLM überschätzen. Die potenziellen Verzerrungen bei der Arbeit mit LLMs sind wichtig, um das Risiko von Verzerrungen zu mildern, die Ihre Fähigkeit zur Verbesserung des Modells beeinflussen.

Große LLM-Ausgangsvalidierung

Nachdem ich Millionen von LLM-Anrufen ausgeführt hatte, habe ich viele verschiedene Ausgänge gesehen, wie z.

Diese Fehler sind mit manueller Inspektion unglaublich schwer zu erkennen, da sie normalerweise in weniger als 1 von 1000 API -Aufrufen des LLM auftreten. Sie benötigen jedoch einen Mechanismus, um diese Probleme zu fangen, wenn sie in Echtzeit in großem Maßstab auftreten. Daher werde ich einige Ansätze zum Umgang mit diesen Themen diskutieren.

Einfache IF-ELSE-Anweisung

Die einfachste Lösung für die Validierung besteht darin, einen Code zu haben, der eine einfache If -Anweisung verwendet, die die LLM -Ausgabe überprüft. Wenn Sie beispielsweise Zusammenfassungen für Dokumente generieren möchten, möchten Sie möglicherweise sicherstellen, dass die LLM -Ausgabe mindestens über eine minimale Länge liegt

# LLM summay validation

# first generate abstract by means of an LLM consumer akin to OpenAI, Anthropic, Mistral, and so forth. 
abstract = llm_client.chat(f"Make a abstract of this doc {doc}")

# validate the abstract
def validate_summary(abstract: str) -> bool:
    if len(abstract) < 20:
        return False
    return True

Dann können Sie die Validierung ausführen.

  • Wenn die Validierung vergeht, können Sie wie gewohnt fortfahren
  • Wenn es fehlschlägt, können Sie wählen Ignorieren Sie die Anfrage oder benutzen a Mechanismus wiederholen

Sie können die validate_summary -Funktion natürlich aufwändiger machen, zum Beispiel:

  • Verwendung von Regex für komplexe String -Matching
  • Mit a Bibliothek wie Tiktoken Um die Anzahl der Token in der Anfrage zu zählen
  • Stellen Sie sicher, dass bestimmte Wörter in der Antwort vorhanden sind/nicht vorhanden sind
  • usw.

LLM als Validator

Dieses Diagramm zeigt den Fluss einer LLM -Anwendung unter Verwendung eines LLM als Validator. Sie geben zunächst die Eingabeaufforderung ein, die hier eine Zusammenfassung eines Dokuments erstellen soll. Das LLM erstellt eine Zusammenfassung eines Dokuments und sendet es an einen LLM -Validator. Wenn die Zusammenfassung gültig ist, geben wir die Anfrage zurück. Wenn die Zusammenfassung jedoch ungültig ist, können wir die Anfrage entweder ignorieren oder erneut versuchen. Bild des Autors.

Ein fortschrittlicherer und kostspieligerer Validator verwendet ein LLM. In diesen Fällen verwenden Sie eine andere LLM, um zu bewerten, ob die Ausgabe gültig ist. Dies funktioniert, da die Validierung der Korrektheit normalerweise eine einfachere Aufgabe ist als eine korrekte Antwort zu generieren. Die Verwendung eines LLM -Validators ist im Wesentlichen Mit LLM als Richter habe ich hier einen weiteren Thema in Richtung Knowledge Science geschrieben.

Ich verwende oft kleinere LLMs, um diese Validierungsaufgabe auszuführen, da sie schnellere Reaktionszeiten haben, weniger kosten und trotzdem intestine funktionieren, da die Validierungsaufgabe einfacher ist als eine korrekte Antwort zu generieren. Zum Beispiel, wenn ich benutze GPT-4.1 Um eine Zusammenfassung zu erzeugen, würde ich GPT-4.1-Mini oder GPT-4.1-Nano in Betracht ziehen, um die Gültigkeit der generierten Zusammenfassung zu bewerten.

Wenn die Validierung erfolgreich ist, setzen Sie Ihren Anwendungsfluss fort, und wenn sie fehlschlägt, können Sie die Anfrage ignorieren oder sie erneut versuchen.

Bei der Validierung der Zusammenfassung würde ich die validierende LLM auffordern, nach Zusammenfassungen zu suchen, die:

  • Sind zu kurz
  • Halten Sie sich nicht an das erwartete Antwortformat (z. B. Markdown)
  • Und andere Regeln, die Sie möglicherweise für die generierten Zusammenfassungen haben

Quantitative LLM -Bewertungen

Es ist auch sehr wichtig, großflächige Bewertungen von LLM-Ausgängen durchzuführen. Ich empfehle entweder kontinuierlich oder in regelmäßigen Abständen. Quantitative LLM -Bewertungen sind auch in Kombination mit qualitativen Bewertungen von Datenproben effektiver. Nehmen wir beispielsweise an, dass die Bewertungsmetriken hervorheben, dass Ihre generierten Zusammenfassungen länger sind als das, was Benutzer bevorzugen. In diesem Fall sollten Sie die generierten Zusammenfassungen und die Dokumente, auf denen sie basieren, manuell untersuchen. Dies hilft Ihnen, das zugrunde liegende Drawback zu verstehen, was das Lösen des Issues erneut erleichtert.

LLM als Richter

Wie bei der Validierung können Sie LLM als Richter zur Bewertung verwenden. Der Unterschied besteht darin, dass die Validierung LLM als Richter für binäre Vorhersagen verwendet (entweder ist die Ausgabe gültig oder nicht gültig), die Bewertung verwendet sie für detailliertere Rückmeldungen. Sie können beispielsweise Suggestions vom LLM-Richter über die Qualität einer Zusammenfassung von 1 bis 10 erhalten, wodurch die Unterscheidung mittlerer Qualität (ca. 4-6) von hochwertiger Summarie (7+) einfacher wird.

Auch hier müssen Sie Kosten berücksichtigen, wenn Sie LLM als Richter verwenden. Obwohl Sie möglicherweise kleinere Modelle verwenden, verdoppeln Sie im Wesentlichen die Anzahl der LLM -Anrufe, wenn Sie LLM als Richter verwenden. Sie können daher die folgenden Änderungen berücksichtigen, um Kosten zu sparen:

  • Abtastdatenpunkte, sodass Sie LLM nur als Richter auf einer Teilmenge von Datenpunkten ausführen
  • Gruppieren Sie mehrere Datenpunkte in einem LLM als Richteraufforderung, um Eingabe- und Ausgabe -Token zu speichern

Ich empfehle, den LLM -Richter die Beurteilungskriterien zu beschreiben. Zum Beispiel sollten Sie angeben, was eine Punktzahl von 1, eine Punktzahl von 5 und eine Punktzahl von 10 ausmacht. Wenn Sie Beispiele verwenden Mein Artikel über die Verwendung von LLM als Richter. Ich denke oft darüber nach, wie hilfreich Beispiele für mich sind, wenn jemand ein Thema erklärt, und Sie können sich daher vorstellen, wie hilfreich es für ein LLM ist.

Benutzerfeedback

Benutzer -Suggestions ist eine großartige Möglichkeit, quantitative Metriken für die Ausgaben Ihres LLM zu erhalten. Benutzer-Suggestions kann beispielsweise eine Schaltfläche Daumen nach oben oder Daumen nach unten sein, die besagt, ob die generierte Zusammenfassung zufriedenstellend ist. Wenn Sie ein solches Suggestions von Hunderten oder Tausenden von Benutzern kombinieren, haben Sie einen zuverlässigen Suggestions -Mechanismus, den Sie verwenden können, um die Leistung Ihres LLM -Zusammenfassungsgenerators erheblich zu verbessern!

Diese Benutzer können Ihre Kunden sein. Sie sollten es ihnen einfach erleichtern, Suggestions bereitzustellen und sie zu ermutigen, so viel Suggestions wie möglich zu geben. Diese Benutzer können jedoch im Wesentlichen jeder sein, der Ihre Anwendung nicht täglich nutzt oder entwickelt. Es ist wichtig, sich daran zu erinnern, dass ein solches Suggestions unglaublich wertvoll ist, um die Leistung Ihres LLM zu verbessern, und es kostet Sie (als Entwickler der Anwendung), jederzeit, um dieses Suggestions zu sammeln.

Abschluss

In diesem Artikel habe ich besprochen, wie Sie in Ihrer LLM-Anwendung eine groß angelegte Validierung und Bewertung durchführen können. Dies ist unglaublich wichtig, um sicherzustellen, dass Ihre Anwendung wie erwartet ausgeführt wird, und Ihre Anwendung basierend auf dem Benutzer -Suggestions zu verbessern. Ich empfehle, solche Validierungs- und Bewertungsströme so bald wie möglich in Ihre Anwendung einzubeziehen, da die Wichtigkeit der von Natur aus unvorhersehbaren LLMs zuverlässig einen Wert in Ihrer Anwendung bieten kann.

Sie können meine Artikel auch lesen Wie man LLMs mit ARC AGI 3 bewertet Und So extrahieren Sie mühelos Quittungsinformationen mit OCR und GPT-4O Mini

👉 Finden Sie mich in Socials:

🧑‍💻 Sich in Verbindung setzen

🔗 LinkedIn

🐦 X / Twitter

✍ Medium

[ad_2]

]]>
https://chatgpz.de/artificial-intelligence/so-fuehren-sie-eine-umfassende-llm-validierung-in-grossem-massstab-durch/feed/ 0 11789
MarshMallow: Die süßeste Python-Bibliothek zur Datenserialisierung und -validierung https://chatgpz.de/data-science/marshmallow-die-suesseste-python-bibliothek-zur-datenserialisierung-und-validierung/ https://chatgpz.de/data-science/marshmallow-die-suesseste-python-bibliothek-zur-datenserialisierung-und-validierung/#respond Tue, 30 Jul 2024 23:32:54 +0000 http://chatgpz.de/data-science/marshmallow-die-suesseste-python-bibliothek-zur-datenserialisierung-und-validierung/ [ad_1]

MarshMallow: Die süßeste Python-Bibliothek zur Datenserialisierung und -validierungMarshMallow: Die süßeste Python-Bibliothek zur Datenserialisierung und -validierung
Bild vom Autor | Leonardo AI & Canva

Datenserialisierung ist ein grundlegendes Programmierkonzept mit großem Nutzen in alltäglichen Programmen. Es bezieht sich auf die Konvertierung komplexer Datenobjekte in ein Zwischenformat, das gespeichert und problemlos wieder in seine ursprüngliche Type zurückkonvertiert werden kann. Die gängigen Python-Bibliotheken zur Datenserialisierung wie JSON und Pickle sind jedoch in ihrer Funktionalität sehr eingeschränkt. Bei strukturierten Programmen und objektorientierter Programmierung benötigen wir stärkere Unterstützung für den Umgang mit Datenklassen.

Marshmallow ist eine der bekanntesten Datenverarbeitungsbibliotheken, die von Python-Entwicklern häufig zur Entwicklung robuster Softwareanwendungen verwendet wird. Es unterstützt die Datenserialisierung und bietet eine starke abstrakte Lösung für die Datenvalidierung in einem objektorientierten Paradigma.

In diesem Artikel verwenden wir ein laufendes Beispiel, das unten aufgeführt ist, um zu verstehen, wie Marshmallow in bestehenden Projekten verwendet wird. Der Code zeigt drei Klassen, die ein einfaches E-Commerce-Modell darstellen: Product, BuyerUnd Order. Jede Klasse definiert ihre Parameter minimal. Wir werden sehen, wie man eine Instanz eines Objekts speichert und ihre Korrektheit sicherstellt, wenn wir versuchen, es in unserem Code erneut zu laden.

from typing import Listing

class Product:
    def __init__(self, _id: int, identify: str, worth: float):
    	self._id = _id
    	self.identify = identify
    	self.worth = worth

class Buyer:
    def __init__(self, _id: int, identify: str):
    	self._id = _id
    	self.identify = identify

class Order:
    def __init__(self, _id: int, buyer: Buyer, merchandise: Listing(Product)):
    	self._id = _id
    	self.buyer = buyer
    	self.merchandise = merchandise

Erste Schritte mit Marshmallow

Set up

Marshmallow ist als Python-Bibliothek bei PyPI verfügbar und kann einfach mit pip installiert werden. Um die Marshmallow-Abhängigkeit zu installieren oder zu aktualisieren, führen Sie den folgenden Befehl aus:

pip set up -U marshmallow

Dadurch wird die aktuelle stabile Model von Marshmallow in der aktiven Umgebung installiert. Wenn Sie die Entwicklungsversion der Bibliothek mit allen neuesten Funktionen wünschen, können Sie diese mit dem folgenden Befehl installieren:

pip set up -U git+https://github.com/marshmallow-code/marshmallow.git@dev

Erstellen von Schemas

Beginnen wir mit der Erweiterung des Product Klasse. Wir müssen eine neue Klasse erstellen, die ein Schema darstellt, eine Instanz der Product Klasse folgen muss. Stellen Sie sich ein Schema wie eine Blaupause vor, die die Variablen in der Product Klasse und der Datentyp, zu dem sie gehören.

Lassen Sie uns den folgenden Basiscode aufschlüsseln und verstehen:

from marshmallow import Schema, fields

class ProductSchema(Schema):
    _id = fields.Int(required=True)
    identify = fields.Str(required=True)
    worth = fields.Float(required=True)

Wir erstellen eine neue Klasse, die erbt von der Schema Klasse in Marshmallow. Dann deklarieren wir die gleichen Variablennamen wie unsere Product Klasse und definieren Sie ihre Feldtypen. Die Klasse „Felder“ in Marshmallow unterstützt verschiedene Datentypen. Hier verwenden wir die primitiven Typen Int, String und Float.

Serialisierung

Nachdem wir nun ein Schema für unser Objekt definiert haben, können wir nun eine Python-Klasseninstanz zur Serialisierung in eine JSON-Zeichenfolge oder ein Python-Wörterbuch konvertieren. Hier ist die grundlegende Implementierung:

product = Product(_id=4, identify="Take a look at Product", worth=10.6)
schema = ProductSchema()
    
# For Python Dictionary object
end result = schema.dump(product)

# kind(dict) -> {'_id': 4, 'identify': 'Take a look at Product', 'worth': 10.6}

# For JSON-serializable string
end result = schema.dumps(product)

# kind(str) -> {"_id": 4, "identify": "Take a look at Product", "worth": 10.6}

Wir erschaffen ein Objekt unserer ProductSchemadas ein Produktobjekt in ein serialisierbares Format wie JSON oder ein Wörterbuch konvertiert.

Beachten Sie den Unterschied zwischen dump Und dumps Funktionsergebnisse. Eines gibt ein Python-Wörterbuchobjekt zurück, das mit Pickle gespeichert werden kann, und das andere gibt ein Zeichenfolgenobjekt zurück, das dem JSON-Format folgt.

Deserialisierung

Um den Serialisierungsprozess umzukehren, verwenden wir die Deserialisierung. Ein Objekt wird gespeichert, damit es später geladen und abgerufen werden kann, und Marshmallow hilft dabei.

Ein Python-Wörterbuch kann mit der Ladefunktion validiert werden, die die Variablen und ihre zugehörigen Datentypen überprüft. Die folgende Funktion zeigt, wie es funktioniert:

product_data = {
    "_id": 4,
    "identify": "Take a look at Product",
    "worth": 50.4,
}
end result = schema.load(product_data)
print(end result)  	

# kind(dict) -> {'_id': 4, 'identify': 'Take a look at Product', 'worth': 50.4}

faulty_data = {
    "_id": 5,
    "identify": "Take a look at Product",
    "worth": "ABCD" # Flawed enter datatype
}
end result = schema.load(faulty_data) 

# Raises validation error

Das Schema überprüft, ob das Wörterbuch die richtigen Parameter und Datentypen enthält. Wenn die Überprüfung fehlschlägt, wird ein ValidationError ist angehoben, so ist es wichtig, die load perform in einem Attempt-Besides-Block. Wenn es erfolgreich ist, ist das Ergebnisobjekt immer noch ein Wörterbuch, wenn das ursprüngliche Argument auch ein Wörterbuch ist. Nicht so hilfreich, oder? Was wir im Allgemeinen wollen, ist, das Wörterbuch zu validieren und es wieder in das ursprüngliche Objekt zu konvertieren, aus dem es serialisiert wurde.

Um dies zu erreichen, verwenden wir die post_load Dekorateur bereitgestellt von Marshmallow:

from marshmallow import Schema, fields, post_load

class ProductSchema(Schema):
    _id = fields.Int(required=True)
    identify = fields.Str(required=True)
    worth = fields.Float(required=True)

@post_load
def create_product(self, knowledge, **kwargs):
    return Product(**knowledge)

Wir erstellen eine Funktion in der Schemaklasse mit dem post_load Dekorator. Diese Funktion nimmt das validierte Wörterbuch und konvertiert es zurück in ein Produktobjekt. Einschließlich **kwargs ist wichtig, da Marshmallow zusätzliche notwendige Argumente über den Dekorator übergeben kann.

Diese Änderung der Ladefunktion stellt sicher, dass das Python-Wörterbuch nach der Validierung an den post_load Funktion, die eine Product Objekt aus dem Wörterbuch. Dadurch ist es möglich, ein Objekt mit Marshmallow zu deserialisieren.

Validierung

Oft benötigen wir zusätzliche Validierungen, die speziell auf unseren Anwendungsfall zugeschnitten sind. Obwohl die Datentypvalidierung wichtig ist, deckt sie nicht alle Validierungen ab, die wir möglicherweise benötigen. Selbst in diesem einfachen Beispiel ist eine zusätzliche Validierung für unseren Product Objekt. Wir müssen sicherstellen, dass der Preis nicht unter 0 liegt. Wir können auch weitere Regeln definieren, beispielsweise sicherstellen, dass unser Produktname zwischen 3 und 128 Zeichen lang ist. Diese Regeln helfen sicherzustellen, dass unsere Codebasis einem definierten Datenbankschema entspricht.

Sehen wir uns nun an, wie wir diese Validierung mit Marshmallow implementieren können:

from marshmallow import Schema, fields, validates, ValidationError, post_load

class ProductSchema(Schema):
    _id = fields.Int(required=True)
    identify = fields.Str(required=True)
    worth = fields.Float(required=True)

@post_load
def create_product(self, knowledge, **kwargs):
    return Product(**knowledge)


@validates('worth')
def validate_price(self, worth):
    if worth <= 0:
        elevate ValidationError('Value should be larger than zero.')

@validates('identify')
def validate_name(self, worth):
    if len(worth) < 3 or len(worth) > 128:
        elevate ValidationError('Identify of Product should be between 3 and 128 letters.')

Wir modifizieren die ProductSchema Klasse, um zwei neue Funktionen hinzuzufügen. Eine validiert den Preisparameter und die andere validiert den Namensparameter. Wir verwenden den Validates-Funktionsdekorator und kommentieren den Namen der Variable, die die Funktion validieren soll. Die Implementierung dieser Funktionen ist unkompliziert: Wenn der Wert falsch ist, lösen wir eine ValidationError.

Verschachtelte Schemas

Nun mit den grundlegenden Product Klassenvalidierung: Wir haben alle grundlegenden Funktionen der Marshmallow-Bibliothek abgedeckt. Lassen Sie uns nun die Komplexität erhöhen und sehen, wie die anderen beiden Klassen validiert werden.

Der Buyer Klasse ist ziemlich unkompliziert, da sie die grundlegenden Attribute und primitiven Datentypen enthält.

class CustomerSchema(Schema):
    _id = fields.Int(required=True)
    identify = fields.Int(required=True)

Die Definition des Schemas für die Order Klasse zwingt uns, ein neues und erforderliches Konzept von verschachtelten Schemas zu lernen. Eine Bestellung wird einem bestimmten Kunden zugeordnet und der Kunde kann eine beliebige Anzahl von Produkten bestellen. Dies wird in der Klassendefinition definiert, und wenn wir die Order Schema müssen wir auch validieren die Product Und Buyer an ihn übergebene Objekte.

Anstatt alles neu zu definieren im OrderSchemavermeiden wir Wiederholungen und verwenden verschachtelte Schemata. Das Bestellschema ist wie folgt definiert:

class OrderSchema(Schema):
    _id = fields.Int(require=True)
    buyer = fields.Nested(CustomerSchema, required=True)
    merchandise = fields.Listing(fields.Nested(ProductSchema), required=True)

Innerhalb der Order Schema, wir schließen die ProductSchema Und CustomerSchema Definitionen. Dadurch wird sichergestellt, dass die definierten Validierungen für diese Schemata automatisch angewendet werden, gemäß den DRY (Wiederholen Sie sich nicht) Prinzip in der Programmierung, welches die Wiederverwendung von bestehendem Code ermöglicht.

Einpacken

In diesem Artikel haben wir den Schnellstart und den Anwendungsfall der Marshmallow-Bibliothek behandelt, einer der beliebtesten Serialisierungs- und Datenvalidierungsbibliotheken in Python. Obwohl sie Pydantic ähnelt, bevorzugen viele Entwickler Marshmallow aufgrund ihrer Schemadefinitionsmethode, die Validierungsbibliotheken in anderen Sprachen wie JavaScript ähnelt.

Marshmallow lässt sich problemlos in Python-Backend-Frameworks wie FastAPI und Flask integrieren und ist daher eine beliebte Wahl für Internet-Frameworks und Datenvalidierungsaufgaben sowie für ORMs wie SQLAlchemy.

Kanwal Mehreen Kanwal ist Ingenieurin für maschinelles Lernen und technische Autorin mit einer tiefen Leidenschaft für Datenwissenschaft und die Schnittstelle zwischen KI und Medizin. Sie ist Mitautorin des E-Books „Maximizing Productiveness with ChatGPT“. Als Google Era Scholar 2022 für APAC setzt sie sich für Vielfalt und akademische Exzellenz ein. Sie ist außerdem als Teradata Range in Tech Scholar, Mitacs Globalink Analysis Scholar und Harvard WeCode Scholar anerkannt. Kanwal ist eine leidenschaftliche Verfechterin des Wandels und hat FEMCodes gegründet, um Frauen in MINT-Fächern zu stärken.

[ad_2]

]]>
https://chatgpz.de/data-science/marshmallow-die-suesseste-python-bibliothek-zur-datenserialisierung-und-validierung/feed/ 0 2752
Was ist klinische Validierung? Ihr Leitfaden zu Greatest Practices und Prozessen https://chatgpz.de/artificial-intelligence/was-ist-klinische-validierung-ihr-leitfaden-zu-greatest-practices-und-prozessen/ https://chatgpz.de/artificial-intelligence/was-ist-klinische-validierung-ihr-leitfaden-zu-greatest-practices-und-prozessen/#respond Sun, 07 Jul 2024 14:53:22 +0000 http://chatgpz.de/artificial-intelligence/was-ist-klinische-validierung-ihr-leitfaden-zu-best-practices-und-prozessen/ [ad_1]

Stellen Sie sich ein Szenario vor, in dem ein neues Diagnosetool entwickelt wird. Ärzte sind von seinem Potenzial begeistert. Doch bevor sie es in die Routineversorgung integrieren, müssen sie seine Zuverlässigkeit und Genauigkeit sicherstellen. Hier wird die klinische Validierung von entscheidender Bedeutung. Diese Vorgehensweise schützt vor Fehlern und Inkonsistenzen in der Patientenversorgung.

Die klinische Validierung überprüft, ob jeder medizinische Anspruch und jede Diagnose mit dem tatsächlichen Zustand des Patienten übereinstimmt. Dabei geht es nicht nur darum, Kästchen anzukreuzen, sondern darum, die Requirements medizinischer Genauigkeit und Patientensicherheit einzuhalten.

Was ist klinische Validierung?

Die klinische Validierung ist ein wesentlicher Prozess in Gesundheitspflege das die Genauigkeit von Krankenakten gewährleistet. Dabei wird überprüft und bestätigt, dass die in den Krankenakten dokumentierten Diagnosen und Verfahren durch klinische Nachweise gestützt werden. Dieser Prozess ist für die Wahrung der Integrität von Patientendaten von entscheidender Bedeutung.

Der Prozess der klinischen Validierung

Die klinische Validierung beginnt mit einer gründlichen Untersuchung der Krankenakte eines Patienten. Medizinisches Fachpersonal prüft die dokumentierten Informationen genau. Anschließend vergleichen sie diese mit klinischen Indikatoren und Angaben aus der Patientengeschichte.

Sie überprüfen, ob die Diagnosen und Verfahren klinisch fundiert sind. Neben der Gegenprüfung von Daten wird diese Validierung anhand etablierter medizinischer Requirements und Praktiken bewertet.

Bedeutung der klinischen Validierung

Die klinische Validierung spielt eine wesentliche Rolle bei der Einhaltung von Gesundheitsvorschriften und der Qualitätssicherung. Sie stellt sicher, dass Krankenakten den klinischen Zustand des Patienten genau widerspiegeln, was zur Einhaltung gesetzlicher Requirements und zur Bereitstellung einer qualitativ hochwertigen Versorgung erforderlich ist.

Eine genaue Dokumentation durch klinische Validierung hilft Gesundheitsorganisationen, die Einhaltung von Gesetzen und Vorschriften sicherzustellen und so rechtliche und finanzielle Strafen zu vermeiden. Darüber hinaus hat die klinische Validierung erhebliche Auswirkungen auf die Erstattung und Prüfung von Gesundheitsleistungen. Erstattungen durch Versicherungsanbieter, einschließlich Medicare und Medicaid, hängen in hohem Maße von einer genauen und vollständigen medizinischen Dokumentation ab.

Bedeutung der klinischen ValidierungBedeutung der klinischen ValidierungDurch die klinische Validierung wird sichergestellt, dass die erfassten Diagnosen und Verfahren gerechtfertigt sind und durch klinische Nachweise gestützt werden. Sie verhindert eine Über- oder Unterdeckung, die zu einer Über- oder Unterzahlung führen kann.

Im Rahmen von Audits dient die klinische Validierung als vorbeugende Maßnahme. Sie reduziert das Risiko von Auditfehlern, indem sie sicherstellt, dass alle Angaben und Unterlagen korrekt und konform sind. Dieser strenge Validierungsprozess hilft Gesundheitseinrichtungen, kostspielige Strafen zu vermeiden und ihren Ruf zu wahren.

Der klinische Validierungsprozess

Der klinische Validierungsprozess ist ein systematischer Ansatz im Gesundheitswesen, um die Genauigkeit und Rechtmäßigkeit von Krankenakten sicherzustellen. Dieser Prozess umfasst mehrere wichtige Schritte:

Der klinische ValidierungsprozessDer klinische Validierungsprozess

  • Überprüfung der Krankenakten: Die Krankengeschichte des Patienten wird von medizinischem Fachpersonal gründlich überprüft.
  • Vergleich mit klinischen Indikatoren: Sie vergleichen die dokumentierten Diagnosen und Verfahren mit klinischen Indikatoren und medizinischen Benchmarks.
  • Beweisprüfung: Der Prozess umfasst die Überprüfung, ob jede dokumentierte Diagnose und jedes dokumentierte Verfahren durch klinische Beweise gestützt wird.
  • Angleichung an medizinische Requirements: Die Diagnosen und Verfahren werden überprüft, um sicherzustellen, dass sie den anerkannten medizinischen Requirements und Praktiken entsprechen.
  • Zusammenarbeit zwischen Fachleuten: In diesem Prozess arbeiten Spezialisten für die Integrität klinischer Dokumentationen, Kodierungsexperten und Gesundheitsdienstleister zusammen.
  • Kontinuierliche Überwachung und Aktualisierung: Der Prozess umfasst die laufende Überwachung und Aktualisierung von Aufzeichnungen, um Genauigkeit und Konformität sicherzustellen.

Diese Schritte stellen sicher, dass die Krankenakten den klinischen Zustand des Patienten genau wiedergeben. Dies ist von entscheidender Bedeutung für eine qualitativ hochwertige Patientenversorgung, die Einhaltung von Gesundheitsvorschriften und angemessene Erstattungspraktiken.

Herausforderungen bei der klinischen Validierung

Die klinische Validierung ist im Gesundheitswesen von wesentlicher Bedeutung und bringt mehrere Herausforderungen mit sich, die ihre Wirksamkeit beeinträchtigen können:

  • Komplexität medizinischer Daten: Das Entschlüsseln komplexer medizinischer Daten und deren Abgleich mit klinischen Beweisen kann eine Herausforderung sein.
  • Variabilität klinischer Requirements: Unterschiede in klinischen Requirements und Praktiken können zu Inkonsistenzen bei der Validierung führen.
  • Unzureichende Ausbildung: Dem medizinischen Fachpersonal fehlt möglicherweise eine ausreichende Ausbildung in den neuesten klinischen Validierungstechniken.
  • Zeitbeschränkungen: Zeitdruck in einem geschäftigen Gesundheitswesen kann eine gründliche klinische Validierung verhindern.
  • Datenschutzbedenken: Die Gewährleistung des Datenschutzes der Patienten während der Validierung ist eine ständige Herausforderung.
  • Widerstand zur Aenderung: Es kann sein, dass das medizinische Private Widerstand gegen die Einführung neuer Validierungsprozesse oder -technologien leistet.

Wenn keine ordnungsgemäße klinische Validierung durchgeführt wird, kann dies zu Fehldiagnosen, falschen Behandlungen und Problemen mit der Einhaltung von Gesundheitsvorschriften führen. Dies kann zu einer Verschlechterung der Patientenversorgungsqualität, möglichen rechtlichen Konsequenzen und finanziellen Einbußen für Gesundheitsorganisationen führen.

Daher ist die Bewältigung dieser Herausforderungen von entscheidender Bedeutung für die Genauigkeit und Zuverlässigkeit von Krankenakten und die allgemeine Wirksamkeit der Gesundheitsversorgung.

Greatest Practices in der klinischen Validierung

Eine effektive klinische Validierung ist der Schlüssel zur Aufrechterhaltung hoher Requirements in der Gesundheitsdokumentation. Die Implementierung bewährter Verfahren gewährleistet Genauigkeit und Konformität in Krankenakten.

  • Entwickeln und implementieren Sie klare Richtlinien für klinische Validierungsprozesse.
  • Bieten Sie fortlaufende Schulungen für medizinisches Fachpersonal zu den neuesten Validierungstechniken und -standards an.
  • Nutzen Sie die Technologie zur Unterstützung des Validierungsprozesses, um Effizienz und Genauigkeit sicherzustellen.
  • Wenden Sie klinische Requirements bei allen Validierungen einheitlich an.
  • Erstellen und durchsetzen Sie interne Kriterien und Richtlinien für die klinische Validierung, um Einheitlichkeit zu gewährleisten.
  • Beziehen Sie ein multidisziplinäres Staff ein. Es muss Kliniker und Kodierungsexperten in den Validierungsprozess einbeziehen.
  • Führen Sie regelmäßige Audits der klinischen Garantien durch und geben Sie Suggestions zur kontinuierlichen Verbesserung.
  • Bleiben Sie über Änderungen der Gesundheitsvorschriften und -standards auf dem Laufenden, die sich auf die klinische Validierung auswirken.

Die Einhaltung dieser Greatest Practices kann die Wirksamkeit der klinischen Validierung erheblich steigern.

Die Zukunft der klinischen Validierung

Die Zukunft der klinischen ValidierungDie Zukunft der klinischen ValidierungDie Zukunft der klinischen Validierung im Gesundheitswesen entwickelt sich in Richtung einer stärkeren Integration fortschrittlicher Technologien und Datenanalyse. Diese Entwicklung zielt darauf ab, die Genauigkeit und Effizienz des Validierungsprozesses zu verbessern.

Da das Gesundheitswesen die digitale Transformation vorantreibt, wird die klinische Validierung zunehmend auf ausgefeilte Algorithmen und KI angewiesen sein, um komplexe Daten zu verarbeiten. Diese Fortschritte versprechen eine Rationalisierung des Prozesses. Sie machen ihn anpassungsfähiger an die dynamische Natur des Gesundheitswesens und halten gleichzeitig strenge Requirements hinsichtlich Genauigkeit und Konformität aufrecht.

Abschluss

Die klinische Validierung ist ein entscheidender Bestandteil der Gesundheitsfürsorge. Sie stellt die Genauigkeit und Integrität von Krankenakten sicher. Dabei handelt es sich um einen sorgfältigen Prozess zur Überprüfung von Diagnosen und Verfahren anhand klinischer Beweise.

Da sich der medizinische Bereich ständig weiterentwickelt, passt sich auch die klinische Validierung an. Sie integriert Technologien zur Verbesserung von Effizienz und Genauigkeit. Diese Praxis sichert Gesundheitsstandards und trägt wesentlich zur allgemeinen Qualität und Sicherheit der Patientenversorgung bei.

[ad_2]

]]>
https://chatgpz.de/artificial-intelligence/was-ist-klinische-validierung-ihr-leitfaden-zu-greatest-practices-und-prozessen/feed/ 0 2072
Validierung der kausalen Auswirkungen der synthetischen Kontrollmethode | von Ryan O’Sullivan | Juni 2024 https://chatgpz.de/machine-learning/validierung-der-kausalen-auswirkungen-der-synthetischen-kontrollmethode-von-ryan-osullivan-juni-2024/ https://chatgpz.de/machine-learning/validierung-der-kausalen-auswirkungen-der-synthetischen-kontrollmethode-von-ryan-osullivan-juni-2024/#respond Sun, 09 Jun 2024 04:26:01 +0000 http://chatgpz.de/machine-learning/validierung-der-kausalen-auswirkungen-der-synthetischen-kontrollmethode-von-ryan-osullivan-juni-2024/ [ad_1]

Kausale KI: Erforschung der Integration kausalen Denkens in maschinelles Lernen

Foto von Irina Inga An Unsplash

Willkommen zu meiner Serie über kausale KI, in der wir die Integration kausalen Denkens in Modelle des maschinellen Lernens untersuchen. Freuen Sie sich auf eine Reihe praktischer Anwendungen in unterschiedlichen Geschäftskontexten.

Im letzten Artikel behandelten wir Messung des intrinsischen kausalen Einflusses Ihrer Marketingkampagnen. In diesem Artikel werden wir uns mit Validierung der kausalen Wirkung der synthetischen Kontrollen.

Wenn Sie den letzten Artikel zum Thema intrinsischer kausaler Einfluss verpasst haben, können Sie ihn hier nachlesen:

In diesem Artikel konzentrieren wir uns auf das Verständnis der synthetischen Kontrollmethode und untersuchen, wie wir die geschätzten kausalen Auswirkungen validieren können.

Folgende Aspekte werden behandelt:

  • Was ist die synthetische Kontrollmethode?
  • Welche Herausforderung versucht es zu bewältigen?
  • Wie können wir die geschätzten kausalen Auswirkungen validieren?
  • Eine Python-Fallstudie mit realistischen Google-Trenddaten, die zeigt, wie wir die geschätzte kausale Auswirkung der synthetischen Kontrollen validieren können.

Das vollständige Notizbuch finden Sie hier:

Was ist es?

Die synthetische Kontrollmethode ist eine kausale Technik, die verwendet werden kann, um die kausale Wirkung einer Intervention oder Behandlung zu beurteilen, wenn eine randomisierte kontrollierte Studie (RCT) oder ein A/B-Check nicht möglich struggle. Sie wurde ursprünglich 2003 von Abadie und Gardezabal vorgeschlagen. Das folgende Dokument enthält eine großartige Fallstudie, die Ihnen dabei hilft, die vorgeschlagene Methode zu verstehen:

https://net.stanford.edu/~jhain/Paper/JASA2010.pdf

Vom Benutzer erstelltes Bild

Lassen Sie uns einige der Grundlagen selbst durchgehen … Die synthetische Kontrollmethode erstellt eine kontrafaktische Model der Behandlungseinheit, indem sie eine gewichtete Kombination von Kontrolleinheiten erstellt, die weder die Intervention noch die Behandlung erhalten haben.

  • Behandelte Einheit: Die Einheit, die die Intervention erhält.
  • Steuergeräte: Eine Reihe ähnlicher Einheiten, bei denen die Intervention nicht durchgeführt wurde.
  • Kontrafaktisch: Erstellt als gewichtete Kombination der Kontrolleinheiten. Ziel ist es, für jede Kontrolleinheit Gewichte zu finden, die zu einem kontrafaktischen Ergebnis führen, das der behandelten Einheit in der Zeit vor der Intervention möglichst nahe kommt.
  • Kausale Auswirkungen: Der Unterschied zwischen der Behandlungseinheit nach der Intervention und der kontrafaktischen Scenario.

Wenn wir die Dinge wirklich vereinfachen wollten, könnten wir es als lineare Regression betrachten, bei der jede Kontrolleinheit ein Merkmal und die Behandlungseinheit das Ziel ist. Der Zeitraum vor der Intervention ist unser Trainingssatz und wir verwenden das Modell, um unseren Zeitraum nach der Intervention zu bewerten. Der Unterschied zwischen dem tatsächlichen und dem vorhergesagten Wert ist die kausale Auswirkung.

Nachfolgend finden Sie einige Beispiele, die verdeutlichen, wann wir einen Einsatz in Betracht ziehen könnten:

  • Bei einer TV-Marketingkampagne können wir das Publikum nicht nach dem Zufallsprinzip in diejenigen einteilen, die die Kampagne sehen können und diejenigen, die sie nicht sehen können. Wir könnten jedoch sorgfältig eine Area auswählen, um die Kampagne zu testen, und die übrigen Regionen als Kontrolleinheiten verwenden. Sobald wir die Wirkung gemessen haben, könnte die Kampagne in anderen Regionen eingeführt werden. Dies wird oft als Geo-Carry-Check bezeichnet.
  • Politische Veränderungen, die in einigen Regionen eingeführt werden, in anderen jedoch nicht – Beispielsweise kann ein Gemeinderat eine politische Veränderung in Kraft setzen, um die Arbeitslosigkeit zu senken. Andere Regionen, in denen die Politik nicht umgesetzt wurde, könnten als Kontrolleinheiten dienen.

Welche Herausforderung versucht es zu bewältigen?

Wenn wir eine hohe Dimensionalität (viele Merkmale) mit begrenzten Beobachtungen kombinieren, kann ein überangepasstes Modell entstehen.

Nehmen wir zur Veranschaulichung das Beispiel des Geo-Lifts. Wenn wir wöchentliche Daten aus dem letzten Jahr als Zeitraum vor der Intervention verwenden, erhalten wir 52 Beobachtungen. Wenn wir uns dann entscheiden, unsere Intervention in mehreren Ländern Europas zu testen, erhalten wir ein Verhältnis von Beobachtung zu Merkmal von 1:1!

Wir haben bereits darüber gesprochen, wie die synthetische Kontrollmethode mithilfe einer linearen Regression implementiert werden könnte. Das Verhältnis von Beobachtung zu Merkmal bedeutet jedoch, dass es sehr wahrscheinlich ist, dass die lineare Regression überanpasst, was zu einer schlechten Schätzung der kausalen Auswirkungen in der Zeit nach der Intervention führt.

Bei der linearen Regression können die Gewichte (Koeffizienten) für jedes Merkmal (Kontrolleinheit) negativ oder positiv sein und ihre Summe kann eine Zahl größer als 1 ergeben. Die synthetische Kontrollmethode lernt die Gewichte jedoch unter Anwendung der folgenden Einschränkungen:

  • Beschränkung der Gewichte auf die Summe von 1
  • Gewichte müssen ≥ 0 sein
Vom Benutzer generiertes Bild

Diese Einschränkungen helfen bei der Regularisierung und vermeiden eine Extrapolation über den Bereich der beobachteten Daten hinaus.

Es ist erwähnenswert, dass Ridge- und Lasso-Regression dies in Bezug auf die Regularisierung erreichen können und in einigen Fällen sinnvolle Alternativen sind. Aber wir werden dies in der Fallstudie testen!

Wie können wir die geschätzten kausalen Auswirkungen validieren?

Eine wohl noch größere Herausforderung besteht in der Tatsache, dass wir die geschätzten kausalen Auswirkungen in der Zeit nach der Intervention nicht validieren können.

Wie lang sollte meine Vorinterventionsphase sein? Sind wir sicher, dass wir unsere Vorinterventionsphase nicht überangepasst haben? Wie können wir wissen, ob unser Modell in der Nachinterventionsphase intestine verallgemeinert werden kann? Was ist, wenn ich verschiedene Implementierungen der synthetischen Kontrollmethode ausprobieren möchte?

Wir könnten nach dem Zufallsprinzip einige Beobachtungen aus der Zeit vor der Intervention auswählen und sie zur Validierung zurückhalten. Doch wir haben bereits die Herausforderungen hervorgehoben, die sich aus der begrenzten Anzahl an Beobachtungen ergeben, sodass wir die Dinge möglicherweise sogar noch schlimmer machen!

Was wäre, wenn wir vor der Intervention eine Artwork Simulation durchführen könnten? Könnte uns das helfen, einige der oben hervorgehobenen Fragen zu beantworten und Vertrauen in die von unseren Modellen geschätzten kausalen Auswirkungen zu gewinnen? Alles wird in der Fallstudie erklärt!

Hintergrund

Nachdem Sie die Finanzabteilung davon überzeugt haben, dass Markenmarketing einen echten Mehrwert schafft, kommt das Marketingteam auf Sie zu und fragt Sie nach Geo-Carry-Exams. Jemand von Fb hat ihnen gesagt, dass das der nächste große Development ist (obwohl es dieselbe Particular person struggle, die ihnen gesagt hat, dass Prophet ein gutes Prognosemodell ist) und sie möchten wissen, ob sie es zur Messung ihrer neuen, bevorstehenden TV-Kampagne verwenden können.

Sie sind ein wenig besorgt, da das Marketinganalyseteam bei Ihrem letzten Geo-Carry-Check der Meinung struggle, es wäre eine gute Idee, mit dem verwendeten Vorinterventionszeitraum herumzuexperimentieren, bis ein schöner, großer kausaler Einfluss festgestellt würde.

Dieses Mal schlagen Sie vor, eine „Vorinterventionssimulation“ durchzuführen und anschließend vor Beginn des Exams den Vorinterventionszeitraum zu vereinbaren.

Sehen wir uns additionally an, wie eine „Simulation vor einer Intervention“ aussieht!

Erstellen der Daten

Um dies so realistisch wie möglich zu gestalten, habe ich einige Google-Trenddaten für die Mehrheit der europäischen Länder extrahiert. Der Suchbegriff ist nicht related. Tun Sie einfach so, als wäre es der Umsatz Ihres Unternehmens (und Sie sind in ganz Europa tätig).

Wenn Sie jedoch wissen möchten, wie ich an die Google-Trenddaten gekommen bin, sehen Sie sich mein Notizbuch an:

Unten sehen wir den Datenrahmen. Wir haben Verkäufe der letzten 3 Jahre in 50 europäischen Ländern. Das Marketingteam plant, seine TV-Kampagne in Großbritannien durchzuführen.

Vom Benutzer erstelltes Bild

Jetzt kommt der clevere Teil. Wir werden eine Intervention in den letzten 7 Wochen der Zeitreihe simulieren.

np.random.seed(1234)

# Create intervention flag
masks = (df('date') >= "2024-04-14") & (df('date') <= "2024-06-02")
df('intervention') = masks.astype(int)

row_count = len(df)

# Create intervention uplift
df('uplift_perc') = np.random.uniform(0.10, 0.20, measurement=row_count)
df('uplift_abs') = spherical(df('uplift_perc') * df('GB'))
df('y') = df('GB')
df.loc(df('intervention') == 1, 'y') = df('GB') + df('uplift_abs')

Lassen Sie uns nun die tatsächlichen und kontrafaktischen Verkäufe in ganz GB darstellen, um unsere Ergebnisse in die Praxis umzusetzen:

def synth_plot(df, counterfactual):

plt.determine(figsize=(14, 8))
sns.set_style("white")

# Create plot
sns.lineplot(information=df, x='date', y='y', label='Precise', shade='b', linewidth=2.5)
sns.lineplot(information=df, x='date', y=counterfactual, label='Counterfactual', shade='r', linestyle='--', linewidth=2.5)
plt.title('Artificial Management Technique: Precise vs. Counterfactual', fontsize=24)
plt.xlabel('Date', fontsize=20)
plt.ylabel('Metric Worth', fontsize=20)
plt.legend(fontsize=16)
plt.gca().xaxis.set_major_formatter(plt.matplotlib.dates.DateFormatter('%Y-%m-%d'))
plt.xticks(rotation=90)
plt.grid(True, linestyle='--', alpha=0.5)

# Excessive the intervention level
intervention_date = '2024-04-07'
plt.axvline(pd.to_datetime(intervention_date), shade='ok', linestyle='--', linewidth=1)
plt.textual content(pd.to_datetime(intervention_date), plt.ylim()(1)*0.95, 'Intervention', shade='ok', fontsize=18, ha='proper')

plt.tight_layout()
plt.present()

synth_plot(df, 'GB')
Vom Benutzer erstelltes Bild

Nachdem wir nun eine Intervention simuliert haben, können wir untersuchen, wie intestine die synthetische Kontrollmethode funktioniert.

Vorverarbeitung

Alle europäischen Länder außer GB werden als Kontrolleinheiten (Merkmale) festgelegt. Die Behandlungseinheit (Ziel) ist der Umsatz in GB mit der angewandten Intervention.

# Delete the unique goal column so we do not use it as a function by chance
del df('GB')

# set function & targets
X = df.columns(1:50)
y = 'y'

Regression

Unten habe ich eine Funktion eingerichtet, die wir mit verschiedenen Vorinterventionszeiträumen und verschiedenen Regressionsmodellen (z. B. Ridge, Lasso) wiederverwenden können:

def train_reg(df, start_index, reg_class):

df_temp = df.iloc(start_index:).copy().reset_index()

X_pre = df_temp(df_temp('intervention') == 0)(X)
y_pre = df_temp(df_temp('intervention') == 0)(y)

X_train, X_test, y_train, y_test = train_test_split(X_pre, y_pre, test_size=0.10, random_state=42)

mannequin = reg_class
mannequin.match(X_train, y_train)

yhat_train = mannequin.predict(X_train)
yhat_test = mannequin.predict(X_test)

mse_train = mean_squared_error(y_train, yhat_train)
mse_test = mean_squared_error(y_test, yhat_test)
print(f"Imply Squared Error practice: {spherical(mse_train, 2)}")
print(f"Imply Squared Error check: {spherical(mse_test, 2)}")

r2_train = r2_score(y_train, yhat_train)
r2_test = r2_score(y_test, yhat_test)
print(f"R2 practice: {spherical(r2_train, 2)}")
print(f"R2 check: {spherical(r2_test, 2)}")

df_temp('pred') = mannequin.predict(df_temp.loc(:, X))
df_temp('delta') = df_temp('y') - df_temp('pred')

pred_lift = df_temp(df_temp('intervention') == 1)('delta').sum()
actual_lift = df_temp(df_temp('intervention') == 1)('uplift_abs').sum()
abs_error_perc = abs(pred_lift - actual_lift) / actual_lift
print(f"Predicted carry: {spherical(pred_lift, 2)}")
print(f"Precise carry: {spherical(actual_lift, 2)}")
print(f"Absolute error share: {spherical(abs_error_perc, 2)}")

return df_temp, abs_error_perc

Zu Beginn halten wir es einfach und verwenden eine lineare Regression, um die kausalen Auswirkungen anhand einer kurzen Vorinterventionsphase abzuschätzen:

df_lin_reg_100, pred_lift_lin_reg_100 = train_reg(df, 100, LinearRegression())
Vom Benutzer erstelltes Bild

Betrachtet man die Ergebnisse, schneidet die lineare Regression nicht besonders intestine ab. Aber das ist angesichts des Verhältnisses von Beobachtung zu Merkmal nicht überraschend.

synth_plot(df_lin_reg_100, 'pred')
Vom Benutzer erstelltes Bild

Synthetische Kontrollmethode

Lassen Sie uns direkt loslegen und sehen, wie es im Vergleich zur synthetischen Kontrollmethode abschneidet. Unten habe ich eine ähnliche Funktion wie zuvor eingerichtet, aber die synthetische Kontrollmethode mithilfe von sciPy angewendet:

def synthetic_control(weights, control_units, treated_unit):

artificial = np.dot(control_units.values, weights)

return np.sqrt(np.sum((treated_unit - artificial)**2))

def train_synth(df, start_index):

df_temp = df.iloc(start_index:).copy().reset_index()

X_pre = df_temp(df_temp('intervention') == 0)(X)
y_pre = df_temp(df_temp('intervention') == 0)(y)

X_train, X_test, y_train, y_test = train_test_split(X_pre, y_pre, test_size=0.10, random_state=42)

initial_weights = np.ones(len(X)) / len(X)

constraints = ({'kind': 'eq', 'enjoyable': lambda w: np.sum(w) - 1})

bounds = ((0, 1) for _ in vary(len(X)))

consequence = decrease(synthetic_control,
initial_weights,
args=(X_train, y_train),
technique='SLSQP',
bounds=bounds,
constraints=constraints,
choices={'disp': False, 'maxiter': 1000, 'ftol': 1e-9},
)

optimal_weights = consequence.x

yhat_train = np.dot(X_train.values, optimal_weights)
yhat_test = np.dot(X_test.values, optimal_weights)

mse_train = mean_squared_error(y_train, yhat_train)
mse_test = mean_squared_error(y_test, yhat_test)
print(f"Imply Squared Error practice: {spherical(mse_train, 2)}")
print(f"Imply Squared Error check: {spherical(mse_test, 2)}")

r2_train = r2_score(y_train, yhat_train)
r2_test = r2_score(y_test, yhat_test)
print(f"R2 practice: {spherical(r2_train, 2)}")
print(f"R2 check: {spherical(r2_test, 2)}")

df_temp('pred') = np.dot(df_temp.loc(:, X).values, optimal_weights)
df_temp('delta') = df_temp('y') - df_temp('pred')

pred_lift = df_temp(df_temp('intervention') == 1)('delta').sum()
actual_lift = df_temp(df_temp('intervention') == 1)('uplift_abs').sum()
abs_error_perc = abs(pred_lift - actual_lift) / actual_lift
print(f"Predicted carry: {spherical(pred_lift, 2)}")
print(f"Precise carry: {spherical(actual_lift, 2)}")
print(f"Absolute error share: {spherical(abs_error_perc, 2)}")

return df_temp, abs_error_perc

Ich lasse den Zeitraum vor der Intervention unverändert, um einen fairen Vergleich mit der linearen Regression zu ermöglichen:

df_synth_100, pred_lift_synth_100 = train_synth(df, 100)
Vom Benutzer erstelltes Bild

Wow! Ich gebe zu, dass ich mit einer so deutlichen Verbesserung nicht gerechnet habe!

synth_plot(df_synth_100, 'pred')
Vom Benutzer erstelltes Bild

Vergleich der Ergebnisse

Lassen Sie uns noch nicht zu weit ausholen. Im Folgenden führen wir noch ein paar Experimente durch, in denen wir Modelltypen und Zeiträume vor der Intervention untersuchen:

# run regression experiments
df_lin_reg_00, pred_lift_lin_reg_00 = train_reg(df, 0, LinearRegression())
df_lin_reg_100, pred_lift_lin_reg_100 = train_reg(df, 100, LinearRegression())
df_ridge_00, pred_lift_ridge_00 = train_reg(df, 0, RidgeCV())
df_ridge_100, pred_lift_ridge_100 = train_reg(df, 100, RidgeCV())
df_lasso_00, pred_lift_lasso_00 = train_reg(df, 0, LassoCV())
df_lasso_100, pred_lift_lasso_100 = train_reg(df, 100, LassoCV())

# run artificial management experiments
df_synth_00, pred_lift_synth_00 = train_synth(df, 0)
df_synth_100, pred_lift_synth_100 = train_synth(df, 100)

experiment_data = {
"Technique": ("Linear", "Linear", "Ridge", "Ridge", "Lasso", "Lasso", "Artificial Management", "Artificial Management"),
"Information Measurement": ("Massive", "Small", "Massive", "Small", "Massive", "Small", "Massive", "Small"),
"Worth": (pred_lift_lin_reg_00, pred_lift_lin_reg_100, pred_lift_ridge_00, pred_lift_ridge_100,pred_lift_lasso_00, pred_lift_lasso_100, pred_lift_synth_00, pred_lift_synth_100)
}

df_experiments = pd.DataFrame(experiment_data)

Wir verwenden den folgenden Code, um die Ergebnisse zu visualisieren:

# Set the model
sns.set_style="whitegrid"

# Create the bar plot
plt.determine(figsize=(10, 6))
bar_plot = sns.barplot(x="Technique", y="Worth", hue="Information Measurement", information=df_experiments, palette="muted")

# Add labels and title
plt.xlabel("Technique")
plt.ylabel("Absolute error share")
plt.title("Artificial Controls - Comparability of Strategies Throughout Totally different Information Sizes")
plt.legend(title="Information Measurement")

# Present the plot
plt.present()

Vom Benutzer erstelltes Bild

Die Ergebnisse für den kleinen Datensatz sind wirklich interessant! Wie erwartet hat die Regularisierung geholfen, die Schätzungen der kausalen Auswirkungen zu verbessern. Die synthetische Kontrolle ging dann noch einen Schritt weiter!

Die Ergebnisse des großen Datensatzes legen nahe, dass längere Zeiträume vor der Intervention nicht immer besser sind.

Ich möchte Ihnen jedoch zeigen, wie wertvoll die Durchführung einer Simulation vor der Intervention ist. Es gibt so viele Möglichkeiten, die Sie mit Ihrem eigenen Datensatz erkunden könnten!

Heute haben wir uns mit der synthetischen Kontrollmethode beschäftigt und wie Sie die kausalen Auswirkungen validieren können. Ich möchte Ihnen noch ein paar abschließende Gedanken mit auf den Weg geben:

  • Aufgrund ihrer Einfachheit ist die synthetische Steuerungsmethode eine der am häufigsten eingesetzten Techniken aus dem Werkzeugkasten der kausalen KI.
  • Leider wird dieser Wert auch am häufigsten missbraucht. Lassen Sie uns das R CausalImpact-Paket ausführen und den Zeitraum vor der Intervention ändern, bis wir eine Steigerung sehen, die uns gefällt. 😭
  • Aus diesem Grund empfehle ich dringend, vor der Intervention Simulationen durchzuführen, um das Testdesign im Voraus zu vereinbaren.
  • Die synthetische Kontrollmethode ist ein intensiv erforschter Bereich. Es lohnt sich, die vorgeschlagenen Anpassungen Augmented SC, Strong SC und Penalized SC zu prüfen.

Alberto Abadie, Alexis Diamond und Jens Hainmueller (2010) Synthetische Kontrollmethoden für vergleichende Fallstudien: Schätzung der Auswirkungen des kalifornischen Tabakkontrollprogramms, Journal of the American Statistical Affiliation, 105:490, 493–505, DOI: 10.1198/jasa.2009.ap08746

[ad_2]

]]>
https://chatgpz.de/machine-learning/validierung-der-kausalen-auswirkungen-der-synthetischen-kontrollmethode-von-ryan-osullivan-juni-2024/feed/ 0 1273