Spaces:
Sleeping
Sleeping
Update app.py
Browse files
app.py
CHANGED
|
@@ -1484,62 +1484,62 @@ def predict_creators(df):
|
|
| 1484 |
# ✅ Ambil 10 creator dengan slope paling negatif (paling turun)
|
| 1485 |
return df_res.sort_values('Trend Slope', ascending=True).head(10) if not df_res.empty else df_res
|
| 1486 |
|
| 1487 |
-
# ——————— 3. Issues: ONLY Coverage=100% & Trend Slope > 0 → Avg/Month ———————
|
| 1488 |
-
def predict_issues(df):
|
| 1489 |
-
|
| 1490 |
-
|
| 1491 |
|
| 1492 |
-
|
| 1493 |
-
|
| 1494 |
|
| 1495 |
-
|
| 1496 |
-
|
| 1497 |
-
|
| 1498 |
-
|
| 1499 |
|
| 1500 |
-
|
| 1501 |
-
|
| 1502 |
-
|
| 1503 |
-
|
| 1504 |
-
|
| 1505 |
-
|
| 1506 |
-
|
| 1507 |
-
|
| 1508 |
-
|
| 1509 |
-
|
| 1510 |
-
|
| 1511 |
|
| 1512 |
-
|
| 1513 |
-
|
| 1514 |
-
|
| 1515 |
-
|
| 1516 |
-
|
| 1517 |
-
|
| 1518 |
|
| 1519 |
-
|
| 1520 |
-
|
| 1521 |
-
|
| 1522 |
-
|
| 1523 |
-
|
| 1524 |
-
|
| 1525 |
-
|
| 1526 |
|
| 1527 |
-
|
| 1528 |
|
| 1529 |
-
|
| 1530 |
-
|
| 1531 |
-
|
| 1532 |
-
|
| 1533 |
-
|
| 1534 |
-
|
| 1535 |
|
| 1536 |
-
|
| 1537 |
-
|
| 1538 |
-
|
| 1539 |
-
|
| 1540 |
-
|
| 1541 |
|
| 1542 |
-
|
| 1543 |
|
| 1544 |
# ——————— RUN ———————
|
| 1545 |
df_creator = predict_creators(df_filtered)
|
|
@@ -1585,7 +1585,7 @@ st.markdown("</div>", unsafe_allow_html=True)
|
|
| 1585 |
st.markdown("<div class='predictive-panel'>", unsafe_allow_html=True)
|
| 1586 |
st.markdown(
|
| 1587 |
"<div class='predictive-header'>"
|
| 1588 |
-
"3. Which Issue Categories Are Likely to Appear in the Next 3 Months (Non
|
| 1589 |
"<span style='font-size:0.75em; font-weight:400; color:#003DA5;'>"
|
| 1590 |
" (* Categorization uses NLP — Natural Language Processing from random text)"
|
| 1591 |
"</span>"
|
|
@@ -1593,45 +1593,45 @@ st.markdown(
|
|
| 1593 |
unsafe_allow_html=True
|
| 1594 |
)
|
| 1595 |
|
| 1596 |
-
if not df_issue.empty:
|
| 1597 |
-
|
| 1598 |
-
|
| 1599 |
-
|
| 1600 |
-
|
| 1601 |
-
|
| 1602 |
-
|
| 1603 |
-
|
| 1604 |
-
|
| 1605 |
-
|
| 1606 |
-
|
| 1607 |
-
# st.markdown(
|
| 1608 |
-
# "<div class='predictive-note'>"
|
| 1609 |
-
# "<strong>Filtered:</strong> Reported every month (100% coverage) with increasing trend. "
|
| 1610 |
-
# "<strong>Avg/Month</strong> = total ÷ months. "
|
| 1611 |
-
# "<span class='trend-rising'>High-Risk Rising</span> = slope > 0.2."
|
| 1612 |
-
# "</div>",
|
| 1613 |
-
# unsafe_allow_html=True
|
| 1614 |
-
# )
|
| 1615 |
-
|
| 1616 |
-
# else:
|
| 1617 |
-
# st.markdown(
|
| 1618 |
-
# "<div class='predictive-table-wrapper'>"
|
| 1619 |
-
# "<p style='text-align:center; color:#c62828; padding:24px; font-weight:500;'>"
|
| 1620 |
-
# "⚠️ No rising categories with 100% monthly coverage."
|
| 1621 |
-
# "</p>"
|
| 1622 |
-
# "<p style='text-align:center; color:#666; font-size:0.9em;'>"
|
| 1623 |
-
# "Consider relaxing coverage filter if data is sparse."
|
| 1624 |
-
# "</p></div>",
|
| 1625 |
-
# unsafe_allow_html=True
|
| 1626 |
-
# )
|
| 1627 |
-
|
| 1628 |
-
st.markdown("</div>", unsafe_allow_html=True)
|
| 1629 |
-
|
| 1630 |
-
|
| 1631 |
-
# =================== WHITEBOARD STYLE CHART FOR PANEL 3 ===================
|
| 1632 |
-
st.markdown("<h4 style='text-align: center; color: #2c3e50;'>Whiteboard Insight: Trend vs Frequency</h4>", unsafe_allow_html=True)
|
| 1633 |
-
|
| 1634 |
-
# Buat chart scatter dengan gaya whiteboard
|
| 1635 |
if not df_issue.empty:
|
| 1636 |
# Ambil data untuk scatter
|
| 1637 |
df_plot = df_issue.copy()
|
|
|
|
| 1484 |
# ✅ Ambil 10 creator dengan slope paling negatif (paling turun)
|
| 1485 |
return df_res.sort_values('Trend Slope', ascending=True).head(10) if not df_res.empty else df_res
|
| 1486 |
|
| 1487 |
+
# # ——————— 3. Issues: ONLY Coverage=100% & Trend Slope > 0 → Avg/Month ———————
|
| 1488 |
+
# def predict_issues(df):
|
| 1489 |
+
# if 'kategori' not in df.columns or df.empty:
|
| 1490 |
+
# return pd.DataFrame()
|
| 1491 |
|
| 1492 |
+
# # 🔥 Filter: Hanya yang bukan 'Positive'
|
| 1493 |
+
# df = df[df['kategori'] != 'Positive'].copy() # ✅ Filter non-Positive
|
| 1494 |
|
| 1495 |
+
# start_month = df['created_at'].min().to_period('M')
|
| 1496 |
+
# end_month = df['created_at'].max().to_period('M')
|
| 1497 |
+
# all_months = pd.period_range(start=start_month, end=end_month, freq='M')
|
| 1498 |
+
# n_months = len(all_months)
|
| 1499 |
|
| 1500 |
+
# results = []
|
| 1501 |
+
# for cat, group in df.groupby('kategori'):
|
| 1502 |
+
# ts_data = (
|
| 1503 |
+
# group.groupby(group['created_at'].dt.to_period('M'))
|
| 1504 |
+
# .size()
|
| 1505 |
+
# .reindex(all_months, fill_value=0)
|
| 1506 |
+
# )
|
| 1507 |
+
# total_reports = ts_data.sum()
|
| 1508 |
+
# avg_per_month = total_reports / n_months if n_months > 0 else 0
|
| 1509 |
+
# active_months = (ts_data > 0).sum()
|
| 1510 |
+
# coverage = active_months / n_months if n_months > 0 else 0
|
| 1511 |
|
| 1512 |
+
# slope = 0.0
|
| 1513 |
+
# if len(ts_data) >= 2:
|
| 1514 |
+
# try:
|
| 1515 |
+
# slope = np.polyfit(np.arange(len(ts_data)), ts_data.values, 1)[0]
|
| 1516 |
+
# except:
|
| 1517 |
+
# pass
|
| 1518 |
|
| 1519 |
+
# results.append({
|
| 1520 |
+
# 'Category': cat,
|
| 1521 |
+
# 'Avg/Month': round(avg_per_month, 2),
|
| 1522 |
+
# 'Coverage (%)': round(coverage * 100, 1),
|
| 1523 |
+
# 'Trend Slope': round(slope, 3),
|
| 1524 |
+
# 'Trend': ascii_sparkline_pln(ts_data.values.tolist())
|
| 1525 |
+
# })
|
| 1526 |
|
| 1527 |
+
# df_res = pd.DataFrame(results)
|
| 1528 |
|
| 1529 |
+
# # ✅ FILTER: Coverage = 100% AND Trend Slope > 0
|
| 1530 |
+
# if not df_res.empty:
|
| 1531 |
+
# df_res = df_res[
|
| 1532 |
+
# (df_res['Coverage (%)'] == 100.0) &
|
| 1533 |
+
# (df_res['Trend Slope'] > 0)
|
| 1534 |
+
# ].copy()
|
| 1535 |
|
| 1536 |
+
# df_res['Status'] = df_res['Trend Slope'].apply(
|
| 1537 |
+
# lambda s: "<span class='trend-rising'>High-Risk Rising</span>" if s > 0.2 else
|
| 1538 |
+
# "<span class='trend-stable'>Emerging Rising</span>"
|
| 1539 |
+
# )
|
| 1540 |
+
# df_res = df_res.sort_values('Trend Slope', ascending=False)
|
| 1541 |
|
| 1542 |
+
# return df_res.reset_index(drop=True)
|
| 1543 |
|
| 1544 |
# ——————— RUN ———————
|
| 1545 |
df_creator = predict_creators(df_filtered)
|
|
|
|
| 1585 |
st.markdown("<div class='predictive-panel'>", unsafe_allow_html=True)
|
| 1586 |
st.markdown(
|
| 1587 |
"<div class='predictive-header'>"
|
| 1588 |
+
"3. Which Issue Categories Are Likely to Appear in the Next 3 Months (Non Positive Only)"
|
| 1589 |
"<span style='font-size:0.75em; font-weight:400; color:#003DA5;'>"
|
| 1590 |
" (* Categorization uses NLP — Natural Language Processing from random text)"
|
| 1591 |
"</span>"
|
|
|
|
| 1593 |
unsafe_allow_html=True
|
| 1594 |
)
|
| 1595 |
|
| 1596 |
+
# if not df_issue.empty:
|
| 1597 |
+
# cols = ['Category', 'Avg/Month', 'Coverage (%)', 'Trend Slope', 'Status', 'Trend']
|
| 1598 |
+
|
| 1599 |
+
# # 🔵 Rename ONLY for display
|
| 1600 |
+
# df_display = df_issue[cols].rename(columns={
|
| 1601 |
+
# "Status": "Status Issue for Next Month"
|
| 1602 |
+
# })
|
| 1603 |
+
|
| 1604 |
+
# html = df_display.to_html(escape=False, index=False, table_id="tbl-issues")
|
| 1605 |
+
# st.markdown(f"<div class='predictive-table-wrapper'>{html}</div>", unsafe_allow_html=True)
|
| 1606 |
+
|
| 1607 |
+
# # st.markdown(
|
| 1608 |
+
# # "<div class='predictive-note'>"
|
| 1609 |
+
# # "<strong>Filtered:</strong> Reported every month (100% coverage) with increasing trend. "
|
| 1610 |
+
# # "<strong>Avg/Month</strong> = total ÷ months. "
|
| 1611 |
+
# # "<span class='trend-rising'>High-Risk Rising</span> = slope > 0.2."
|
| 1612 |
+
# # "</div>",
|
| 1613 |
+
# # unsafe_allow_html=True
|
| 1614 |
+
# # )
|
| 1615 |
+
|
| 1616 |
+
# # else:
|
| 1617 |
+
# # st.markdown(
|
| 1618 |
+
# # "<div class='predictive-table-wrapper'>"
|
| 1619 |
+
# # "<p style='text-align:center; color:#c62828; padding:24px; font-weight:500;'>"
|
| 1620 |
+
# # "⚠️ No rising categories with 100% monthly coverage."
|
| 1621 |
+
# # "</p>"
|
| 1622 |
+
# # "<p style='text-align:center; color:#666; font-size:0.9em;'>"
|
| 1623 |
+
# # "Consider relaxing coverage filter if data is sparse."
|
| 1624 |
+
# # "</p></div>",
|
| 1625 |
+
# # unsafe_allow_html=True
|
| 1626 |
+
# # )
|
| 1627 |
+
|
| 1628 |
+
# st.markdown("</div>", unsafe_allow_html=True)
|
| 1629 |
+
|
| 1630 |
+
|
| 1631 |
+
# # =================== WHITEBOARD STYLE CHART FOR PANEL 3 ===================
|
| 1632 |
+
# st.markdown("<h4 style='text-align: center; color: #2c3e50;'>Whiteboard Insight: Trend vs Frequency</h4>", unsafe_allow_html=True)
|
| 1633 |
+
|
| 1634 |
+
# # Buat chart scatter dengan gaya whiteboard
|
| 1635 |
if not df_issue.empty:
|
| 1636 |
# Ambil data untuk scatter
|
| 1637 |
df_plot = df_issue.copy()
|