File size: 5,271 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
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
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
"""Dashboard metrics and KPI components."""

import streamlit as st


def render_kpi_row(
    total_nudge: int,
    high_count: int,
    medium_count: int,
    risk_score: float,
    citation_total: int,
) -> None:
    """Render key metrics row with 5 KPIs.

    Args:
        total_nudge: Total negative mentions
        high_count: HIGH tier count
        medium_count: MEDIUM tier count
        risk_score: Calculated risk score
        citation_total: Total citation sources
    """
    kpi1, kpi2, kpi3, kpi4, kpi5 = st.columns(5)

    with kpi1:
        st.metric(
            label="총 λΆ€μ • μ–ΈκΈ‰",
            value=f"{total_nudge}건",
            help="AIκ°€ μžμ‚¬ λΈŒλžœλ“œλ₯Ό λΆ€μ •μ μœΌλ‘œ μ–ΈκΈ‰ν•œ λ‹΅λ³€ 수",
        )

    with kpi2:
        st.metric(
            label="πŸ”΄ HIGH (μ¦‰μ‹œ λŒ€μ‘)",
            value=f"{high_count}건",
            help="β‰₯85% 확신도 - μ¦‰μ‹œ λŒ€μ‘ ꢌμž₯",
        )

    with kpi3:
        st.metric(
            label="🟑 MEDIUM (κ²€ν† )",
            value=f"{medium_count}건",
            help="70-85% 확신도 - κ²€ν†  ν•„μš”",
        )

    with kpi4:
        st.metric(
            label="리슀크 점수",
            value=f"{risk_score:.1f}",
            help="HIGH=100%, MEDIUM=50%, LOW=20% 가쀑 평균",
        )

    with kpi5:
        st.metric(
            label="총 인용 μ†ŒμŠ€",
            value=f"{citation_total}개",
            help="AI λ‹΅λ³€μ—μ„œ 인용된 총 μ†ŒμŠ€ 수",
        )


def render_verification_stats(
    total_verified: int,
    false_positives_count: int,
    true_negatives_count: int,
) -> None:
    """Render LLM verification statistics row.

    Args:
        total_verified: Total verified items
        false_positives_count: False positive count
        true_negatives_count: True negative count
    """
    stat_col1, stat_col2, stat_col3, stat_col4 = st.columns(4)

    with stat_col1:
        st.metric("검증 μ™„λ£Œ", f"{total_verified}건")

    with stat_col2:
        fp_rate = (false_positives_count / total_verified * 100) if total_verified > 0 else 0
        st.metric("μ˜€νƒ (False Positive)", f"{false_positives_count}건", f"{fp_rate:.1f}%")

    with stat_col3:
        tn_rate = (true_negatives_count / total_verified * 100) if total_verified > 0 else 0
        st.metric("μ§„μŒμ„± (True Negative)", f"{true_negatives_count}건", f"{tn_rate:.1f}%")

    with stat_col4:
        if total_verified > 0:
            st.metric("μ˜€νƒλ₯ ", f"{fp_rate:.1f}%", delta=None)
        else:
            st.metric("μ˜€νƒλ₯ ", "N/A")


def render_polarity_stats(
    positive_count: int,
    neutral_count: int,
    negative_count: int,
) -> None:
    """Render polarity distribution statistics.

    Args:
        positive_count: Positive sentiment count
        neutral_count: Neutral sentiment count
        negative_count: Negative sentiment count
    """
    total_answers = positive_count + neutral_count + negative_count

    pol_col1, pol_col2, pol_col3, pol_col4 = st.columns(4)

    with pol_col1:
        st.metric("전체 뢄석", f"{total_answers:,}건")

    with pol_col2:
        pos_rate = (positive_count / total_answers * 100) if total_answers > 0 else 0
        st.metric("😊 긍정", f"{positive_count:,}건", f"{pos_rate:.1f}%")

    with pol_col3:
        neu_rate = (neutral_count / total_answers * 100) if total_answers > 0 else 0
        st.metric("😐 쀑립", f"{neutral_count:,}건", f"{neu_rate:.1f}%")

    with pol_col4:
        neg_rate = (negative_count / total_answers * 100) if total_answers > 0 else 0
        st.metric("😞 λΆ€μ •", f"{negative_count:,}건", f"{neg_rate:.1f}%")


def render_feedback_stats(feedback_stats: dict) -> None:
    """Render feedback statistics row.

    Args:
        feedback_stats: Dict with feedback counts and accuracy
    """
    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="μ •ν™• / (μ •ν™• + 였λ₯˜) λΉ„μœ¨",
        )