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 |
-
#
|
| 1488 |
-
|
| 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)
|
|
|
|
| 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)
|