fix(growth): rank the rate board by a smoothed score
Show the real percentage on the card, but sort with delta / (baseline + prior) so a small baseline cannot dominate. Same-day publishes stay off the rate board.
This commit is contained in:
1 parent
0f2ac612f5
commit
39a6537f67
14 files changed
+158
-16
No files matched your search
@@ -20,6 +20,7 @@ from ..analytics import (
|
||||
METRICS,
|
||||
MIN_VIEW_FOR_GROWTH_RATE,
|
||||
compute_growth,
|
||||
smoothed_growth_rate,
|
||||
content_hours,
|
||||
eb_rate,
|
||||
effective_shrink_minutes,
|
||||
@@ -437,6 +438,8 @@ class DashboardQueries:
|
||||
growth = compute_growth(current, 0, 0, allow_zero_gap=True)
|
||||
payload = growth.as_dict()
|
||||
payload["baseline"] = "zero"
|
||||
# previous=0 时 rate = view/1,会按原始播放碾压真日环比。
|
||||
payload["rate"] = None
|
||||
return payload
|
||||
try:
|
||||
open_at = snapshot.get("open_captured_at")
|
||||
@@ -1031,9 +1034,13 @@ class DashboardQueries:
|
||||
if sort == "growth_rate":
|
||||
items = [
|
||||
item for item in items
|
||||
if (item["metrics"] or {}).get("view", 0) >= MIN_VIEW_FOR_GROWTH_RATE
|
||||
if item.get("growth", {}).get("baseline") != "zero"
|
||||
and item.get("growth", {}).get("rate") is not None
|
||||
and (item["metrics"] or {}).get("view", 0) >= MIN_VIEW_FOR_GROWTH_RATE
|
||||
]
|
||||
|
||||
rate_prior = max(0, int(analytics.growth_rate_prior))
|
||||
|
||||
def sort_key(item: Mapping[str, Any]):
|
||||
if sort == "added":
|
||||
return (int(item["first_seen"]), int(item["pubdate"]))
|
||||
@@ -1050,9 +1057,18 @@ class DashboardQueries:
|
||||
)
|
||||
value = item.get(field)
|
||||
return value if value is not None else float("-inf")
|
||||
if sort in {"growth", "growth_rate"}:
|
||||
field = "delta" if sort == "growth" else "rate"
|
||||
value = item.get("growth", {}).get(field)
|
||||
if sort == "growth":
|
||||
value = item.get("growth", {}).get("delta")
|
||||
return value if value is not None else float("-inf")
|
||||
if sort == "growth_rate":
|
||||
growth = item.get("growth") or {}
|
||||
delta = growth.get("delta")
|
||||
current = (item.get("metrics") or {}).get("view")
|
||||
if delta is None or current is None:
|
||||
return float("-inf")
|
||||
value = smoothed_growth_rate(
|
||||
delta, int(current) - int(delta), rate_prior,
|
||||
)
|
||||
return value if value is not None else float("-inf")
|
||||
value = (item["metrics"] or {}).get(sort)
|
||||
return value if value is not None else -1
|
||||
@@ -1069,7 +1085,12 @@ class DashboardQueries:
|
||||
reason = None
|
||||
if sort in {"growth", "growth_rate"} and not growth_available:
|
||||
available = False
|
||||
if growth_days == 1:
|
||||
if growth_days == 1 and sort == "growth_rate":
|
||||
reason = (
|
||||
"近 1 日增速需要前一日快照,或更早发布的新入库当天至少两次成功采样;"
|
||||
"当日发布不计入增速"
|
||||
)
|
||||
elif growth_days == 1:
|
||||
reason = (
|
||||
"近 1 日增长需要前一日快照;当日发布有一次成功采样即可;"
|
||||
"更早发布的新入库需要当天至少两次成功采样"
|
||||
@@ -1108,6 +1129,7 @@ class DashboardQueries:
|
||||
"available": available,
|
||||
"reason": reason,
|
||||
"duration_filter": duration_filter,
|
||||
"growth_rate_prior": rate_prior if sort == "growth_rate" else None,
|
||||
}
|
||||
return self.db.read(run)
|
||||
|
||||
@@ -1754,6 +1776,7 @@ class DashboardQueries:
|
||||
"video_shrink_minutes": cfg.analytics.video_shrink_minutes,
|
||||
"shrink_minutes": cfg.analytics.shrink_minutes,
|
||||
"home_growth_days": cfg.analytics.home_growth_days,
|
||||
"growth_rate_prior": cfg.analytics.growth_rate_prior,
|
||||
},
|
||||
"heat_weights": {
|
||||
metric: float(value)
|
||||
|
||||
Reference in new issue
Block a user