Files
hiffi-artist-intelligence/core/health_detector.py
T

87 lines
3.3 KiB
Python
Raw Normal View History

"""
core/health_detector.py
Identifies inactive, legacy, zombie, and hyper-viral channels
based on engagement-to-audience ratios and upload cadence.
"""
from typing import Dict, Any
import numpy as np
import pandas as pd
class ChannelHealthDetector:
"""
Evaluates channel vitality by examining daily velocity against subscriber scale.
"""
def __init__(self, zombie_sub_threshold: int = 25000, zombie_velocity_cutoff: float = 100.0):
self.zombie_sub_threshold = zombie_sub_threshold
self.zombie_velocity_cutoff = zombie_velocity_cutoff
def classify_channel(self, row: pd.Series) -> Dict[str, Any]:
subs = row.get("subscriber_count")
daily_vel = row.get("daily_view_velocity")
status_flag = row.get("status_flag", "")
# Handle unresolvable or missing data
if pd.isna(subs) or status_flag == "FAILED_LOOKUP":
return {
"health_status": "UNRESOLVED",
"is_zombie": False,
"health_notes": "Channel could not be resolved via YouTube API."
}
subs = float(subs)
daily_vel = float(daily_vel) if pd.notna(daily_vel) else 0.0
engagement_ratio = daily_vel / max(subs, 1000.0)
# 1. Zombie Channel: Large subscriber base with dead viewership
if subs >= self.zombie_sub_threshold and daily_vel < self.zombie_velocity_cutoff:
return {
"health_status": "ZOMBIE_CHANNEL",
"is_zombie": True,
"health_notes": f"High subscriber base ({int(subs):,}) with negligible viewership ({daily_vel:.1f} views/day)."
}
# 2. Dormant Catalog: No recent uploads and negligible velocity
if status_flag == "INACTIVE_OR_DORMANT" or daily_vel == 0.0:
return {
"health_status": "DORMANT_CATALOG",
"is_zombie": subs >= 10000,
"health_notes": "Zero recent uploads and stalled catalog velocity."
}
# 3. Viral Surge: Recent views exceed subscriber base
if engagement_ratio >= 1.0:
return {
"health_status": "VIRAL_SURGE",
"is_zombie": False,
"health_notes": "Audience reach is exploding beyond existing subscriber base."
}
# 4. Catalog Evergreen: Big catalog keeping views high despite no new release
if status_flag == "CATALOG_ACTIVE_NO_RECENT_UPLOAD":
return {
"health_status": "CATALOG_EVERGREEN",
"is_zombie": False,
"health_notes": "Strong passive catalog views despite release pause."
}
# 5. Healthy Active Channel
return {
"health_status": "ACTIVE_HEALTHY",
"is_zombie": False,
"health_notes": "Consistent release schedule and steady audience engagement."
}
def evaluate_dataframe(self, df: pd.DataFrame) -> pd.DataFrame:
"""Applies health classification across all artist records."""
out = df.copy()
health_results = out.apply(self.classify_channel, axis=1)
out["health_status"] = [r["health_status"] for r in health_results]
out["is_zombie"] = [r["is_zombie"] for r in health_results]
out["health_notes"] = [r["health_notes"] for r in health_results]
return out