Skip to content

Latest commit

 

History

History
458 lines (355 loc) · 15.3 KB

File metadata and controls

458 lines (355 loc) · 15.3 KB

Temporal Graph Analysis: Revolutionary Customer Journey Analytics

Table of Contents

  1. What is the Temporal Graph?
  2. Episode Grouping Logic
  3. Why Temporal Graphs Are Revolutionary
  4. Comparison with Traditional Approaches
  5. Hybrid Architecture: Temporal + Regular Graphs
  6. Real-World Applications
  7. Technical Implementation

What is the Temporal Graph?

The Temporal Graph is a sophisticated bi-temporal knowledge graph that revolutionizes how we understand customer journeys by tracking both:

Bi-Temporal Data Model

  • Valid Time: When a fact was actually true in the real world
  • Transaction Time: When the fact was recorded in your database

Example:

  • Alice's address changed on Jan 1st (valid time)
  • But you recorded this change on Jan 5th (transaction time)

Core Components

TemporalNodes (Entities)

  • Customers, products, orders, addresses, etc.
  • Each has valid_from and valid_to timestamps
  • Properties stored as JSONB for flexibility
  • Vector embeddings for semantic search

TemporalEdges (Relationships)

  • "customer PURCHASED product"
  • "customer LIVES_AT address"
  • Also have valid_from and valid_to timestamps

Events

  • Raw customer actions (purchase, support request, etc.)
  • Trigger the creation/updating of nodes and edges

Episode Grouping Logic

What Makes Multiple Events Group Into An Episode?

Primary Rule: Time-based grouping within 1 hour

  • Events are grouped into episodes if they occur within 1 hour of each other
  • The threshold is defined as episode_threshold = timedelta(hours=1)

How the Grouping Works

  1. Sorting: All events are first sorted by their timestamp in chronological order

  2. Sequential Grouping: The algorithm processes events one by one:

    • The first event starts a new episode
    • Each subsequent event is compared to the last event in the current episode
    • If the time difference is ≤ 1 hour, the event is added to the current episode
    • If the time difference is > 1 hour, the current episode is finalized and a new episode starts
  3. Episode Creation: When an episode is finalized, it includes:

    • All events within the time window
    • Start time: timestamp of the first event
    • End time: timestamp of the last event
    • Summary: description of event types (e.g., "Episode with 3 events: purchase, support_request")

Example Scenario

Alice Johnson has these events:

10:00 AM - purchase (laptop)
10:15 AM - support_request (setup help)
10:30 AM - purchase (accessories)
2:00 PM - support_request (warranty question)
2:15 PM - purchase (extended warranty)

This creates 2 episodes:

  • Episode 1 (10:00-10:30 AM): purchase → support_request → purchase
  • Episode 2 (2:00-2:15 PM): support_request → purchase

The gap between 10:30 AM and 2:00 PM (3.5 hours) exceeds the 1-hour threshold, so they become separate episodes.


Why Temporal Graphs Are Revolutionary

1. Time Travel Analytics 🕰️

  • See exactly what your system "knew" at any point in time
  • Track how customer relationships evolved
  • Understand causality: "Did the price change cause the purchase spike?"

2. Historical Accuracy 📊

  • No data loss - every change is preserved
  • Audit trail for compliance
  • Can "replay" business decisions with historical context

3. Relationship Evolution 🔗

  • Track when relationships started/ended
  • "Alice was a VIP customer from Jan-Mar, then churned"
  • Understand patterns: "Support requests often precede cancellations"

4. Complex Queries 🔍

  • "Find customers who were active 6 months ago but are quiet now"
  • "What products were trending during the holiday season?"
  • "Which support issues led to customer churn?"

5. Memory-Like Intelligence 🧠

  • Your system "remembers" context across time
  • Can answer questions like: "Why did Alice's behavior change?"
  • Builds a rich, evolving understanding of each customer

6. Search Across Time 🔎

  • Semantic search with temporal filters
  • "Find customers similar to Alice's profile from last year"
  • Hybrid search combining meaning, keywords, and time

Comparison with Traditional Approaches

Traditional Database Problems

Static Snapshots 📸

-- Traditional approach
UPDATE customers SET status='VIP', tier='Gold' WHERE id='alice';
-- ❌ LOST FOREVER: When did Alice become VIP? What was her previous tier?

No Historical Context 🚫

-- Traditional approach
SELECT * FROM customers WHERE status='VIP';
-- ❌ CAN'T ANSWER: "Who were VIPs 6 months ago but churned since?"
-- ❌ CAN'T ANSWER: "What caused Alice to become VIP?"

Traditional Graph (Neo4j, etc.) Problems

Static Relationships 🔗

// Traditional graph
CREATE (alice:Customer)-[:PURCHASED]->(laptop:Product)
// ❌ MISSING: When? For how long was this relationship valid?
// ❌ MISSING: What was Alice's state BEFORE this purchase?

GraphRAG Problems

No Temporal Retrieval 🔍

# GraphRAG approach
vector_search("customers similar to Alice")
# ❌ MISSING: "Customers similar to Alice's profile from LAST YEAR"
# ❌ MISSING: "How Alice's behavior CHANGED over time"

Our Temporal Graph Advantages

1. Time Travel Queries ⏰

# Your system CAN do this:
graph.query_at_time("customer", datetime(2024, 12, 1))
# Returns: "Alice was 'Standard' tier, had 2 support tickets, $500 lifetime value"

graph.query_at_time("customer", datetime(2025, 6, 1))  
# Returns: "Alice is 'VIP' tier, 0 open tickets, $5000 lifetime value"

# INSIGHT: Alice's transformation from Standard→VIP over 6 months!

2. Causality Analysis 🔄

# Your system tracks the SEQUENCE:
# Dec 15: Alice purchases laptop ($1200)
# Dec 16: Support request (setup help) 
# Dec 17: Support resolved positively
# Dec 18: Alice leaves 5-star review
# Dec 20: Alice's tier upgraded to VIP
# Dec 25: Alice purchases accessories ($800)

# INSIGHT: Great support experience → VIP upgrade → higher purchases

3. Relationship Evolution 📈

# Traditional: "Alice bought products X, Y, Z"
# Your system: 
# "Alice's relationship with ProductX: 
#  - Purchased (Dec 2024)
#  - Had issues (Dec 2024-Jan 2025) 
#  - Resolved satisfaction (Jan 2025)
#  - Became advocate/reviewer (Feb 2025)"

4. Predictive Temporal Patterns 🔮

# Your system can identify:
# "Customers who have 2+ support tickets within 30 days 
#  have 60% churn probability in the following 90 days"

# "VIP customers who go 45+ days without purchases
#  typically downgrade within 2 months"

Concrete Business Value Examples

Traditional Approach:

❌ "Alice is a VIP customer with $5000 lifetime value"

Your Temporal Graph:

✅ "Alice started as Standard tier (Dec 2024), had initial product issues requiring 2 support contacts, but after positive resolution became highly engaged, upgraded to VIP (Jan 2025), and now has $5000 LTV with 95% satisfaction trend. Prediction: Likely to remain VIP for 12+ months based on similar temporal patterns."

Real Scenarios Your System Solves

1. Churn Prevention 🚨

# Find customers following Alice's early pattern (pre-VIP)
similar_journeys = graph.find_similar_temporal_patterns(
    customer_id="alice", 
    time_period="first_60_days"
)
# Proactively help customers showing early Alice-like issues

2. Personalized Marketing 🎯

# "What was Alice interested in 3 months ago vs now?"
interests_then = graph.query_at_time("interests", 3.months.ago)
interests_now = graph.query_at_time("interests", now)
# Send contextual offers based on interest evolution

3. Product Development 🛠️

# "What product issues emerge 30-60 days after purchase?"
post_purchase_issues = graph.query_temporal_patterns(
    event_sequence=["purchase", "support_request"],
    time_gap=(30, 60, "days")
)

Why GraphRAG Can't Do This

GraphRAG is great for semantic retrieval but lacks:

  • Temporal reasoning: "How did this relationship change over time?"
  • Causality tracking: "What sequence of events led to this outcome?"
  • Historical context: "What was true 6 months ago vs now?"
  • Predictive patterns: "Based on temporal patterns, what happens next?"

Hybrid Architecture: Temporal + Regular Graphs

Dual Storage System - Best of Both Worlds! 🚀

Your system uses BOTH temporal and regular graph storage in a smart hybrid approach:

Primary: Temporal Graph Storage

-- Your main temporal storage tables:
temporal_graph.nodes     -- TemporalNodes (customers, products, etc.)
temporal_graph.edges     -- TemporalEdges (relationships with time)
temporal_graph.events    -- Raw events (purchases, support requests, etc.)

Secondary: Apache AGE (Regular Graph)

-- Apache AGE tables (regular graph database):
temporal_graph._ag_label_vertex  -- Regular graph vertices
temporal_graph._ag_label_edge    -- Regular graph edges

Data Flow Architecture

Raw Event → Temporal Processing → Dual Storage
    ↓              ↓                    ↓
Customer       Extract           Store in both:
Action         Entities &        • temporal_graph.* 
               Relationships     • _ag_label_*

When Each Is Used

Temporal Graph Queries:

# Time-based questions
graph.query_at_time("customer", last_month)
graph.get_entity_history("alice_johnson") 
graph.query_in_time_range("purchases", holiday_season)

Regular Graph Queries:

-- Traditional graph questions
-- "Find all customers who bought products similar to what Alice bought"
-- "What's the shortest path from Alice to Product X?"
-- "Which customers are most central in the network?"

Why This Hybrid Approach Is Superior 🎖️

1. Performance Optimization

  • Temporal queries → Use temporal tables (optimized for time ranges)
  • Graph algorithms → Use AGE (optimized for traversals)

2. Query Flexibility

  • "When did this happen?" → Temporal graph
  • "Who is connected to whom?" → Regular graph
  • "How did relationships evolve?" → Temporal graph
  • "Find the shortest path" → Regular graph

3. Best Tool for Each Job

  • Time-series analysis → Temporal storage excels
  • Network analysis → Traditional graph excels
  • Combined insights → Use both together!

Real Example: Complex Query Using BOTH Systems

# Complex query using BOTH systems:

# 1. Temporal: Find Alice's VIP upgrade time
vip_date = temporal_graph.query("SELECT valid_from FROM nodes 
                                WHERE type='customer' AND properties->>'tier'='VIP'")

# 2. Regular Graph: Find customers with similar network position to Alice
similar_customers = age_graph.query("MATCH (a:Customer)-[:SIMILAR_TO]-(c:Customer) 
                                    WHERE a.name = 'Alice' RETURN c")

# 3. Temporal: Check when those customers became VIP
for customer in similar_customers:
    vip_timeline = temporal_graph.get_entity_history(customer.id)
    # Compare Alice's timeline vs others

Real-World Applications

Customer Journey Analytics

  • Episode Analysis: Group related customer actions within time windows
  • Behavioral Patterns: Identify sequences that lead to conversions or churn
  • Temporal Segmentation: Group customers by journey patterns, not just demographics

Predictive Intelligence

  • Churn Prediction: Identify patterns that historically led to customer loss
  • Upsell Opportunities: Find temporal patterns that indicate readiness for upgrades
  • Support Optimization: Predict which issues will escalate based on historical sequences

Business Intelligence

  • Causality Analysis: Understand what events actually drive business outcomes
  • Trend Analysis: See how customer behavior evolves over time
  • Performance Attribution: Track how changes in process/product affect customer journeys

Technical Implementation

Core Models

TemporalNode

class TemporalNode(Base):
    __tablename__ = "nodes"
    
    id = Column(PG_UUID(as_uuid=True), primary_key=True)
    type = Column(String(50), nullable=False)
    properties = Column(JSONB)
    valid_from = Column(DateTime(timezone=True), nullable=False)
    valid_to = Column(DateTime(timezone=True))
    recorded_at = Column(DateTime(timezone=True))
    embedding = Column(Vector(1536))  # For semantic search

TemporalEdge

class TemporalEdge(Base):
    __tablename__ = "edges"
    
    id = Column(PG_UUID(as_uuid=True), primary_key=True)
    source_node_id = Column(PG_UUID(as_uuid=True), ForeignKey('nodes.id'))
    target_node_id = Column(PG_UUID(as_uuid=True), ForeignKey('nodes.id'))
    relationship_type = Column(String(50), nullable=False)
    properties = Column(JSONB)
    valid_from = Column(DateTime(timezone=True), nullable=False)
    valid_to = Column(DateTime(timezone=True))
    recorded_at = Column(DateTime(timezone=True))

Event

class Event(Base):
    __tablename__ = "events"
    
    id = Column(PG_UUID(as_uuid=True), primary_key=True)
    event_type = Column(String(50), nullable=False)
    event_data = Column(JSONB, nullable=False)
    timestamp = Column(DateTime(timezone=True), nullable=False)
    processed = Column(Boolean, default=False)
    created_at = Column(DateTime(timezone=True))

Key Operations

Time Travel Queries

def query_at_time(self, query: str, timestamp: datetime) -> List[TemporalNode]:
    """Query graph state at specific time."""
    nodes = session.query(TemporalNode).filter(
        and_(
            TemporalNode.type == query,
            TemporalNode.valid_from <= timestamp,
            or_(
                TemporalNode.valid_to.is_(None),
                TemporalNode.valid_to > timestamp
            )
        )
    ).all()
    return nodes

Entity History

def get_entity_history(self, entity_id: str) -> List[Tuple[TemporalNode, TimeRange]]:
    """Get complete history of entity changes."""
    nodes = session.query(TemporalNode).filter(
        TemporalNode.properties['identifier'].astext == entity_id
    ).order_by(TemporalNode.valid_from).all()
    
    history = []
    for node in nodes:
        time_range = TimeRange(node.valid_from, node.valid_to)
        history.append((node, time_range))
    
    return history

Conclusion

The temporal graph system represents a paradigm shift from static data storage to dynamic, time-aware intelligence. By preserving the full history of customer interactions and relationships, it enables:

  1. Deep Understanding: See not just what happened, but when, why, and what came next
  2. Predictive Power: Use historical patterns to predict future behavior
  3. Contextual Intelligence: Understand the full story behind each customer journey
  4. Business Impact: Make data-driven decisions based on temporal causality, not just correlations

This system transforms customer analytics from simple reporting to temporal intelligence - understanding customers as they evolve through time, not just as static profiles. 🚀


Generated on June 19, 2025 - Graphiti Temporal Graph Analysis