Spaces:
Sleeping
Sleeping
| """λΈλλ x ν€μλ κ΅μ°¨ λΆμ + LLM μ΄μ νκ·Έ.""" | |
| import html | |
| import pandas as pd | |
| import plotly.graph_objects as go | |
| import streamlit as st | |
| from core.api_client import ChainShiftClient | |
| def render_brand_keyword_cross(data: dict, competitor: bool = False): | |
| """λΈλλ x ν€μλ κ΅μ°¨ λΆμ + LLM μ΄μ νκ·Έ.""" | |
| brand_label = "κ²½μμ¬" if competitor else "μμ¬" | |
| st.markdown(f"**{brand_label} λΈλλ x ν€μλ κ΅μ°¨ λΆμ**") | |
| st.caption(f"ν€μλλ³λ‘ {brand_label} λΈλλκ° μ΄λ€ λ§₯λ½μμ μΈκΈλλμ§ λΆμν©λλ€") | |
| try: | |
| client = ChainShiftClient(api_key=data.get("api_key"), access_token=data.get("access_token")) | |
| response = client.get_keyword_brand_analysis(data["campaign_id"], competitor=competitor) | |
| resp_data = response.get("data", {}) | |
| items = resp_data.get("items", []) | |
| except Exception as e: | |
| st.error(f"λΈλλxν€μλ λΆμ λ‘λ μ€ν¨: {e}") | |
| return | |
| if not items: | |
| st.info("λΈλλxν€μλ κ΅μ°¨ λ°μ΄ν°κ° μμ΅λλ€") | |
| return | |
| # Cross table | |
| rows = [] | |
| for item in items: | |
| keyword = item.get("keyword", "") | |
| brand = item.get("brand", "") | |
| total = item.get("total", 0) | |
| sent = item.get("sentiment", {}) | |
| pos = sent.get("positive", 0) | |
| neu = sent.get("neutral", 0) | |
| neg = sent.get("negative", 0) | |
| reason_tags = item.get("reason_tags", []) | |
| top_tags = ", ".join(rt.get("tag", "") for rt in reason_tags[:3]) | |
| rows.append({ | |
| "ν€μλ": keyword, | |
| "λΈλλ": brand, | |
| "μ΄ κ±΄μ": total, | |
| "κΈμ ": pos, | |
| "μ€λ¦½": neu, | |
| "λΆμ ": neg, | |
| "μ£Όμ μ΄μ νκ·Έ": top_tags, | |
| }) | |
| if rows: | |
| df = pd.DataFrame(rows).sort_values("λΆμ ", ascending=False) | |
| st.dataframe(df, use_container_width=True, hide_index=True) | |
| # LLM Reason Tag Analysis | |
| st.markdown("---") | |
| st.markdown("**π·οΈ LLM μ΄μ νκ·Έ λΆμ**") | |
| st.caption("LLMμ΄ μλ μμ±ν μ΄μ νκ·Έ λΉλ") | |
| # Aggregate all reason tags | |
| tag_counts: dict[str, int] = {} | |
| tag_examples: dict[str, str] = {} | |
| for item in items: | |
| for rt in item.get("reason_tags", []): | |
| tag = rt.get("tag", "") | |
| count = rt.get("count", 0) | |
| if tag: | |
| tag_counts[tag] = tag_counts.get(tag, 0) + count | |
| if tag not in tag_examples and rt.get("example_sentence"): | |
| tag_examples[tag] = rt["example_sentence"] | |
| if tag_counts: | |
| # Bar chart for top tags | |
| sorted_tags = sorted(tag_counts.items(), key=lambda x: -x[1])[:15] | |
| tag_names = [t[0] for t in sorted_tags] | |
| tag_vals = [t[1] for t in sorted_tags] | |
| fig = go.Figure(go.Bar( | |
| x=tag_vals, | |
| y=tag_names, | |
| orientation="h", | |
| marker_color="#059669", | |
| )) | |
| fig.update_layout( | |
| height=max(250, len(sorted_tags) * 30), | |
| margin=dict(l=20, r=20, t=10, b=10), | |
| yaxis=dict(autorange="reversed"), | |
| ) | |
| st.plotly_chart(fig, use_container_width=True, config={"displayModeBar": False}) | |
| # Tag detail table | |
| tag_rows = [] | |
| for tag, count in sorted_tags: | |
| example = tag_examples.get(tag, "") | |
| tag_rows.append({ | |
| "νκ·Έ": tag, | |
| "λΉλ": count, | |
| "μμ λ¬Έμ₯": example[:100] if example else "", | |
| }) | |
| st.dataframe(pd.DataFrame(tag_rows), use_container_width=True, hide_index=True) | |
| else: | |
| st.info("LLM μ΄μ νκ·Έ λ°μ΄ν°κ° μμ΅λλ€") | |