File size: 3,290 Bytes
b0efede
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
import argparse
import os
import sys
from datetime import datetime, date
from pathlib import Path

import django


ROOT_DIR = Path(__file__).resolve().parents[2]
BACKEND_DIR = ROOT_DIR / "backend"

HUE_PORTAL_DIR = BACKEND_DIR / "hue_portal"

for path in (HUE_PORTAL_DIR, BACKEND_DIR, ROOT_DIR):
    if str(path) not in sys.path:
        sys.path.insert(0, str(path))

os.environ.setdefault("DJANGO_SETTINGS_MODULE", "hue_portal.hue_portal.settings")
django.setup()

from django.db.models import Avg, Count, Q
from hue_portal.core.models import AuditLog, MLMetrics


def parse_args():
    parser = argparse.ArgumentParser(description="Tổng hợp metrics ML hàng ngày")
    parser.add_argument("--date", help="Ngày cần tổng hợp (YYYY-MM-DD), mặc định hôm nay")
    return parser.parse_args()


def target_date(arg: str) -> date:
    if not arg:
        return date.today()
    return datetime.strptime(arg, "%Y-%m-%d").date()


def compute_metrics(day: date) -> dict:
    logs = AuditLog.objects.filter(created_at__date=day)
    total = logs.count()
    if total == 0:
        return {
            "date": day.isoformat(),
            "total_requests": 0,
            "intent_accuracy": None,
            "average_latency_ms": None,
            "error_rate": None,
            "intent_breakdown": {},
        }

    latency_avg = logs.exclude(latency_ms__isnull=True).aggregate(avg=Avg("latency_ms"))["avg"]
    errors = logs.filter(status__gte=400).count()
    intents_with_conf = logs.filter(~Q(intent=""), status__lt=400)
    intent_accuracy = None
    if intents_with_conf.exists():
        confident = intents_with_conf.filter(Q(confidence__gte=0.6) | Q(confidence__isnull=True)).count()
        intent_accuracy = confident / intents_with_conf.count()

    breakdown = (
        logs.exclude(intent="")
        .values("intent")
        .annotate(count=Count("id"))
        .order_by("intent")
    )
    breakdown_dict = {row["intent"]: row["count"] for row in breakdown}

    return {
        "date": day.isoformat(),
        "total_requests": total,
        "intent_accuracy": intent_accuracy,
        "average_latency_ms": latency_avg,
        "error_rate": errors / total,
        "intent_breakdown": breakdown_dict,
    }


def save_metrics(day: date, metrics: dict) -> MLMetrics:
    obj, _ = MLMetrics.objects.update_or_create(
        date=day,
        defaults={
            "total_requests": metrics["total_requests"],
            "intent_accuracy": metrics["intent_accuracy"],
            "average_latency_ms": metrics["average_latency_ms"],
            "error_rate": metrics["error_rate"],
            "intent_breakdown": metrics["intent_breakdown"],
        },
    )
    return obj


def main():
    args = parse_args()
    day = target_date(args.date)
    metrics = compute_metrics(day)
    save_metrics(day, metrics)

    print("=== ML Metrics ===")
    print(f"Ngày: {metrics['date']}")
    print(f"Tổng request: {metrics['total_requests']}")
    print(f"Độ chính xác (ước tính): {metrics['intent_accuracy']}")
    print(f"Latency trung bình (ms): {metrics['average_latency_ms']}")
    print(f"Tỉ lệ lỗi: {metrics['error_rate']}")
    print(f"Phân bổ intent: {metrics['intent_breakdown']}")


if __name__ == "__main__":
    main()