Update app.py
Browse files
app.py
CHANGED
|
@@ -3,7 +3,7 @@ import pandas as pd
|
|
| 3 |
from transformers import pipeline
|
| 4 |
|
| 5 |
# ------------------------------------------------
|
| 6 |
-
# Load
|
| 7 |
# ------------------------------------------------
|
| 8 |
generator = pipeline(
|
| 9 |
"text2text-generation",
|
|
@@ -11,7 +11,7 @@ generator = pipeline(
|
|
| 11 |
)
|
| 12 |
|
| 13 |
# ------------------------------------------------
|
| 14 |
-
# Generic
|
| 15 |
# ------------------------------------------------
|
| 16 |
def trend_word(diff):
|
| 17 |
return "increased" if diff > 0 else "decreased"
|
|
@@ -27,19 +27,41 @@ def magnitude_word(abs_diff):
|
|
| 27 |
def unit_word(kpi):
|
| 28 |
return "percentage points" if "%" in kpi else ""
|
| 29 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 30 |
# ------------------------------------------------
|
| 31 |
# Core logic
|
| 32 |
# ------------------------------------------------
|
| 33 |
def analyze_kpi(csv_file, top_n):
|
| 34 |
df = pd.read_csv(csv_file.name)
|
| 35 |
|
| 36 |
-
# Identify date columns
|
| 37 |
date_cols = df.columns[1:]
|
| 38 |
prev_date = date_cols[-2]
|
| 39 |
curr_date = date_cols[-1]
|
| 40 |
|
| 41 |
-
|
| 42 |
-
df["Change"] =
|
|
|
|
| 43 |
df_sorted = df.sort_values("Change", ascending=False)
|
| 44 |
top_kpis = df_sorted.head(top_n)
|
| 45 |
|
|
@@ -47,28 +69,25 @@ def analyze_kpi(csv_file, top_n):
|
|
| 47 |
# Primary KPI sentence
|
| 48 |
# -------------------------------
|
| 49 |
primary = top_kpis.iloc[0]
|
| 50 |
-
|
| 51 |
-
abs_diff = abs(diff)
|
| 52 |
|
| 53 |
primary_sentence = (
|
| 54 |
f"{primary['Kpi']} "
|
| 55 |
-
f"{trend_word(
|
| 56 |
f"{magnitude_word(abs_diff)} "
|
| 57 |
f"by {abs_diff:.2f} {unit_word(primary['Kpi'])}".strip()
|
| 58 |
)
|
| 59 |
|
| 60 |
# -------------------------------
|
| 61 |
-
# Secondary KPIs sentence
|
| 62 |
# -------------------------------
|
| 63 |
-
|
| 64 |
-
|
| 65 |
-
"suggesting overall stability across the remaining metrics."
|
| 66 |
-
)
|
| 67 |
|
| 68 |
-
#
|
| 69 |
-
model_input = primary_sentence + ". " + secondary_sentence
|
| 70 |
|
| 71 |
-
# Light
|
| 72 |
summary = generator(
|
| 73 |
model_input,
|
| 74 |
max_new_tokens=45,
|
|
@@ -78,43 +97,27 @@ def analyze_kpi(csv_file, top_n):
|
|
| 78 |
return top_kpis[["Kpi", "Change"]], summary
|
| 79 |
|
| 80 |
# ------------------------------------------------
|
| 81 |
-
# Gradio UI (
|
| 82 |
# ------------------------------------------------
|
| 83 |
with gr.Blocks(title="KPI Change Newsletter") as demo:
|
| 84 |
gr.Markdown("## 📰 KPI Change Newsletter Generator")
|
| 85 |
gr.Markdown(
|
| 86 |
-
"Upload a KPI CSV file to
|
| 87 |
-
"
|
| 88 |
-
)
|
| 89 |
-
|
| 90 |
-
csv_input = gr.File(
|
| 91 |
-
label="Upload CSV",
|
| 92 |
-
file_types=[".csv"]
|
| 93 |
)
|
| 94 |
|
| 95 |
-
|
| 96 |
-
|
| 97 |
-
maximum=5,
|
| 98 |
-
value=3,
|
| 99 |
-
step=1,
|
| 100 |
-
label="Number of KPIs to Rank"
|
| 101 |
-
)
|
| 102 |
|
| 103 |
generate_btn = gr.Button("Generate Summary")
|
| 104 |
|
| 105 |
-
table_output = gr.Dataframe(
|
| 106 |
-
|
| 107 |
-
)
|
| 108 |
-
|
| 109 |
-
summary_output = gr.Textbox(
|
| 110 |
-
label="Newsletter Summary",
|
| 111 |
-
lines=2
|
| 112 |
-
)
|
| 113 |
|
| 114 |
generate_btn.click(
|
| 115 |
-
|
| 116 |
inputs=[csv_input, top_n_input],
|
| 117 |
outputs=[table_output, summary_output]
|
| 118 |
)
|
| 119 |
|
| 120 |
-
demo.launch()
|
|
|
|
| 3 |
from transformers import pipeline
|
| 4 |
|
| 5 |
# ------------------------------------------------
|
| 6 |
+
# Load SLM (polishing only)
|
| 7 |
# ------------------------------------------------
|
| 8 |
generator = pipeline(
|
| 9 |
"text2text-generation",
|
|
|
|
| 11 |
)
|
| 12 |
|
| 13 |
# ------------------------------------------------
|
| 14 |
+
# Generic helpers (pure statistics → language)
|
| 15 |
# ------------------------------------------------
|
| 16 |
def trend_word(diff):
|
| 17 |
return "increased" if diff > 0 else "decreased"
|
|
|
|
| 27 |
def unit_word(kpi):
|
| 28 |
return "percentage points" if "%" in kpi else ""
|
| 29 |
|
| 30 |
+
def summarize_secondary(diffs):
|
| 31 |
+
avg_change = diffs.abs().mean()
|
| 32 |
+
inc_ratio = (diffs > 0).mean()
|
| 33 |
+
|
| 34 |
+
# Magnitude descriptor
|
| 35 |
+
if avg_change < 0.05:
|
| 36 |
+
magnitude = "minor variation"
|
| 37 |
+
elif avg_change < 0.2:
|
| 38 |
+
magnitude = "moderate movement"
|
| 39 |
+
else:
|
| 40 |
+
magnitude = "notable movement"
|
| 41 |
+
|
| 42 |
+
# Direction descriptor
|
| 43 |
+
if inc_ratio > 0.7:
|
| 44 |
+
direction = "mostly increased"
|
| 45 |
+
elif inc_ratio < 0.3:
|
| 46 |
+
direction = "mostly decreased"
|
| 47 |
+
else:
|
| 48 |
+
direction = "mixed movement"
|
| 49 |
+
|
| 50 |
+
return f"Remaining indicators showed {magnitude} with {direction}"
|
| 51 |
+
|
| 52 |
# ------------------------------------------------
|
| 53 |
# Core logic
|
| 54 |
# ------------------------------------------------
|
| 55 |
def analyze_kpi(csv_file, top_n):
|
| 56 |
df = pd.read_csv(csv_file.name)
|
| 57 |
|
|
|
|
| 58 |
date_cols = df.columns[1:]
|
| 59 |
prev_date = date_cols[-2]
|
| 60 |
curr_date = date_cols[-1]
|
| 61 |
|
| 62 |
+
df["Diff"] = df[curr_date] - df[prev_date]
|
| 63 |
+
df["Change"] = df["Diff"].abs()
|
| 64 |
+
|
| 65 |
df_sorted = df.sort_values("Change", ascending=False)
|
| 66 |
top_kpis = df_sorted.head(top_n)
|
| 67 |
|
|
|
|
| 69 |
# Primary KPI sentence
|
| 70 |
# -------------------------------
|
| 71 |
primary = top_kpis.iloc[0]
|
| 72 |
+
abs_diff = abs(primary["Diff"])
|
|
|
|
| 73 |
|
| 74 |
primary_sentence = (
|
| 75 |
f"{primary['Kpi']} "
|
| 76 |
+
f"{trend_word(primary['Diff'])} "
|
| 77 |
f"{magnitude_word(abs_diff)} "
|
| 78 |
f"by {abs_diff:.2f} {unit_word(primary['Kpi'])}".strip()
|
| 79 |
)
|
| 80 |
|
| 81 |
# -------------------------------
|
| 82 |
+
# Secondary KPIs sentence (DATA-DRIVEN)
|
| 83 |
# -------------------------------
|
| 84 |
+
secondary_diffs = top_kpis.iloc[1:]["Diff"]
|
| 85 |
+
secondary_sentence = summarize_secondary(secondary_diffs)
|
|
|
|
|
|
|
| 86 |
|
| 87 |
+
# Combined input
|
| 88 |
+
model_input = primary_sentence + ". " + secondary_sentence + "."
|
| 89 |
|
| 90 |
+
# Light smoothing only
|
| 91 |
summary = generator(
|
| 92 |
model_input,
|
| 93 |
max_new_tokens=45,
|
|
|
|
| 97 |
return top_kpis[["Kpi", "Change"]], summary
|
| 98 |
|
| 99 |
# ------------------------------------------------
|
| 100 |
+
# Gradio UI (HF Space)
|
| 101 |
# ------------------------------------------------
|
| 102 |
with gr.Blocks(title="KPI Change Newsletter") as demo:
|
| 103 |
gr.Markdown("## 📰 KPI Change Newsletter Generator")
|
| 104 |
gr.Markdown(
|
| 105 |
+
"Upload a KPI CSV file to rank changes and generate "
|
| 106 |
+
"a short, data-driven summary."
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 107 |
)
|
| 108 |
|
| 109 |
+
csv_input = gr.File(label="Upload CSV", file_types=[".csv"])
|
| 110 |
+
top_n_input = gr.Slider(3, 5, value=3, step=1, label="Top KPIs")
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 111 |
|
| 112 |
generate_btn = gr.Button("Generate Summary")
|
| 113 |
|
| 114 |
+
table_output = gr.Dataframe(label="Top KPI Changes")
|
| 115 |
+
summary_output = gr.Textbox(label="Newsletter Summary", lines=2)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 116 |
|
| 117 |
generate_btn.click(
|
| 118 |
+
analyze_kpi,
|
| 119 |
inputs=[csv_input, top_n_input],
|
| 120 |
outputs=[table_output, summary_output]
|
| 121 |
)
|
| 122 |
|
| 123 |
+
demo.launch()
|