File size: 2,291 Bytes
fcf8749
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
"""
DriverEffortModel database model.
Stores per-driver XGBoost models for personalized effort prediction.
"""

import uuid
from datetime import datetime
from typing import Optional

from sqlalchemy import Boolean, Float, Integer, DateTime, ForeignKey, LargeBinary, JSON
from sqlalchemy.orm import Mapped, mapped_column

from app.database import Base, GUID


class DriverEffortModel(Base):
    """
    DriverEffortModel stores serialized XGBoost models per driver.
    Each driver gets their own personalized effort prediction model.
    """
    __tablename__ = "driver_effort_models"

    driver_id: Mapped[uuid.UUID] = mapped_column(
        GUID(),
        ForeignKey("drivers.id", ondelete="CASCADE"),
        primary_key=True,
    )
    
    model_version: Mapped[int] = mapped_column(
        Integer,
        default=1,
        nullable=False,
    )
    
    # Serialized XGBoost model (pickle format)
    model_pickle: Mapped[Optional[bytes]] = mapped_column(
        LargeBinary,
        nullable=True,
    )
    
    # Training metadata
    training_samples: Mapped[int] = mapped_column(
        Integer,
        default=0,
    )
    feature_names: Mapped[Optional[dict]] = mapped_column(
        JSON,
        nullable=True,
    )
    
    # Performance tracking
    mse_history: Mapped[Optional[dict]] = mapped_column(
        JSON,
        nullable=True,
        default=list,
    )  # List of last 10 MSE values
    current_mse: Mapped[Optional[float]] = mapped_column(
        Float,
        nullable=True,
    )
    r2_score: Mapped[Optional[float]] = mapped_column(
        Float,
        nullable=True,
    )
    
    # Model state
    active: Mapped[bool] = mapped_column(
        Boolean,
        default=True,
        index=True,
    )
    
    last_trained_at: Mapped[Optional[datetime]] = mapped_column(
        DateTime,
        nullable=True,
    )
    created_at: Mapped[datetime] = mapped_column(
        DateTime,
        default=datetime.utcnow,
        nullable=False,
    )
    updated_at: Mapped[datetime] = mapped_column(
        DateTime,
        default=datetime.utcnow,
        onupdate=datetime.utcnow,
        nullable=False,
    )

    def __repr__(self) -> str:
        return f"<DriverEffortModel(driver_id={self.driver_id}, v{self.model_version})>"