GitHub Action
Sync from GitHub
ef78361
Raw
History Blame Contribute Delete
3.74 kB
"""λΈŒλžœλ“œ 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 이유 νƒœκ·Έ 데이터가 μ—†μŠ΅λ‹ˆλ‹€")