SHELLAPANDIANGANHUNGING commited on
Commit
684baf4
·
verified ·
1 Parent(s): 966a0c5

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +87 -87
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
- 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,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-Positive Only)"
1589
  "<span style='font-size:0.75em; font-weight:400; color:#003DA5;'>"
1590
  " &nbsp;&nbsp;(* 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
- 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()
 
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
  " &nbsp;&nbsp;(* 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()