v1.0.1
Core Conceptsv1.0.1

Behavioral States

Defining and configuring discrete behavioral states in BehaviorSim.

A State in BehaviorSim represents a discrete behavioral status of an agent.

The State Class

The behaviorsim.State dataclass requires a unique name and accepts an optional human-readable description:

states.py
from behaviorsim import State

active_state = State(
    name="ActiveSession",
    description="Agent is actively performing transactions"
)
idle_state = State(
    name="Idle",
    description="Agent is passive or awaiting notification"
)

State Lifecycle & Absorbing States

States can be transient or absorbing:

  • Transient States: States where outgoing transition probabilities sum to 1 across other states.
  • Absorbing States: States such as Discharged or Churned where transition to self equals 1.0. Once reached, the agent remains in this state for remaining steps.

Example: Custom States

custom_states.py
import numpy as np
from behaviorsim import State, Profile, Simulator, FeatureDistribution

states = [
    State("Exploring", description="Browsing product catalog"),
    State("Comparing", description="Evaluating alternatives"),
    State("Purchased", description="Completed checkout"),
    State("Exited", description="Session concluded")
]

# Define transition matrix between the 4 states
trans_matrix = np.array([
    [0.4, 0.4, 0.1, 0.1],  # Exploring
    [0.2, 0.5, 0.2, 0.1],  # Comparing
    [0.0, 0.0, 0.0, 1.0],  # Purchased -> Exited
    [0.0, 0.0, 0.0, 1.0],  # Exited absorbing
])

# Define profile with state emissions and transition matrix
profile = Profile(
    name="shopper",
    transition_matrix=trans_matrix,
    state_emissions={
        "Exploring": {"duration_sec": FeatureDistribution("exponential", {"scale": 15.0})},
        "Comparing": {"duration_sec": FeatureDistribution("normal", {"loc": 35.0, "scale": 10.0})},
        "Purchased": {"duration_sec": FeatureDistribution("uniform", {"low": 4.0, "high": 6.0})},
        "Exited": {"duration_sec": FeatureDistribution("uniform", {"low": 0.0, "high": 1.0})},
    }
)

# Initialize simulator and generate 20 interactions
sim = Simulator(states=states, profile=profile)
df = sim.generate(num_interactions=20, seed=42)
print(df[["interaction_id", "state", "duration_sec"]].head())