File size: 3,139 Bytes
ef78361
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
"""ν”Όλ“œλ°± 톡계 μ„Ήμ…˜.

μ‚¬μš©μž 검증 ν˜„ν™© (Human-in-the-Loop).
"""
import pandas as pd
import streamlit as st

from core.utils import get_feedback_reason_label, get_feedback_type_emoji


def render_feedback_stats(feedback_stats: dict):
    """ν”Όλ“œλ°± 톡계 μ„Ήμ…˜ λ Œλ”λ§."""
    if not feedback_stats or feedback_stats.get("total_feedback", 0) == 0:
        return

    with st.expander("πŸ“ **ν”Όλ“œλ°± 뢄석** - μ‚¬μš©μž 검증 ν˜„ν™©", expanded=False):
        fb_total = feedback_stats.get("total_feedback", 0)
        fb_correct = feedback_stats.get("correct_count", 0)
        fb_wrong = feedback_stats.get("wrong_count", 0)
        fb_ambiguous = feedback_stats.get("ambiguous_count", 0)
        accuracy = feedback_stats.get("accuracy_rate", 0)

        fb_col1, fb_col2, fb_col3, fb_col4, fb_col5 = st.columns(5)

        with fb_col1:
            st.metric(label="총 ν”Όλ“œλ°±", value=f"{fb_total}건", help="μ‚¬μš©μžκ°€ μ œμΆœν•œ 총 ν”Όλ“œλ°± 수")
        with fb_col2:
            st.metric(
                label="πŸ‘ μ •ν™•", value=f"{fb_correct}건",
                delta=f"{fb_correct/fb_total*100:.0f}%" if fb_total > 0 else None,
                delta_color="normal", help="μ •ν™•ν•˜λ‹€κ³  ν‰κ°€λœ 뢄석 수",
            )
        with fb_col3:
            st.metric(
                label="πŸ‘Ž 였λ₯˜", value=f"{fb_wrong}건",
                delta=f"{fb_wrong/fb_total*100:.0f}%" if fb_total > 0 else None,
                delta_color="inverse", help="ν‹€λ Έλ‹€κ³  ν‰κ°€λœ 뢄석 수",
            )
        with fb_col4:
            st.metric(label="πŸ€” μ• λ§€", value=f"{fb_ambiguous}건", help="νŒλ‹¨ν•˜κΈ° μ–΄λ €μš΄ 경우")
        with fb_col5:
            st.metric(label="정확도", value=f"{accuracy:.1f}%", help="correct / (correct + wrong) x 100")

        wrong_reasons = feedback_stats.get("wrong_reasons", {})
        if wrong_reasons:
            st.markdown("##### 였λ₯˜ 원인 뢄포")
            reason_df = pd.DataFrame([
                {"원인": get_feedback_reason_label(k), "건수": v}
                for k, v in wrong_reasons.items()
            ]).sort_values("건수", ascending=False)
            st.dataframe(reason_df, use_container_width=True, hide_index=True)

        recent_feedback = feedback_stats.get("recent_feedback", [])
        if recent_feedback:
            st.markdown("##### 졜근 ν”Όλ“œλ°± (10건)")
            recent_df = pd.DataFrame([
                {
                    "Answer ID": fb.get("answer_id"),
                    "μœ ν˜•": get_feedback_type_emoji(fb.get("feedback_type", "")),
                    "원인": get_feedback_reason_label(fb.get("wrong_reason")) if fb.get("wrong_reason") else "-",
                    "μ½”λ©˜νŠΈ": fb.get("comment", "-")[:50] + "..." if fb.get("comment") and len(fb.get("comment", "")) > 50 else fb.get("comment", "-"),
                    "μ‹œκ°„": fb.get("created_at", "")[:16].replace("T", " ") if fb.get("created_at") else "-",
                }
                for fb in recent_feedback
            ])
            st.dataframe(recent_df, use_container_width=True, hide_index=True)