Files

64 lines
2.4 KiB
Python
Raw Permalink Normal View History

"""
core/confidence_scorer.py
Calculates signal freshness, staleness decay, and multi-platform confidence.
Enforces zero-imputation rules across timestamps and verification confidence.
"""
from datetime import datetime, timezone
from typing import Optional
import numpy as np
import pandas as pd
class FreshnessConfidenceScorer:
"""
Evaluates signal age and applies confidence penalties for stale data.
Decays confidence by 10% if signal exceeds 14 days old.
"""
@staticmethod
def calculate_signal_age_days(collected_at: Optional[str]) -> Optional[float]:
"""Calculates difference in days between current UTC timestamp and collection date."""
if not collected_at or pd.isna(collected_at) or str(collected_at).strip().lower() in ("nan", "none", ""):
return None
try:
# Parse ISO or standard timestamp format
dt = pd.to_datetime(collected_at, utc=True)
now = datetime.now(timezone.utc)
delta = now - dt.to_pydatetime()
return round(max(0.0, delta.total_seconds() / 86400.0), 2)
except Exception:
return None
@classmethod
def apply_staleness_decay(
cls,
base_confidence: float,
signal_age_days: Optional[float]
) -> float:
"""Decays confidence by 10% if age > 14 days; missing age leaves confidence unadjusted."""
if signal_age_days is None or pd.isna(signal_age_days):
return base_confidence
if signal_age_days > 14.0:
return round(max(0.0, base_confidence * 0.90), 2)
return round(base_confidence, 2)
@classmethod
def enrich_cohort_freshness(cls, df: pd.DataFrame) -> pd.DataFrame:
"""Adds signal_age_days and updates confidence scores for cohort records."""
out = df.copy()
if "collected_at" in out.columns:
out["signal_age_days"] = out["collected_at"].apply(cls.calculate_signal_age_days)
else:
out["signal_age_days"] = np.nan
# Decay instagram_confidence_score where applicable
if "instagram_confidence_score" in out.columns:
out["instagram_confidence_score"] = out.apply(
lambda row: cls.apply_staleness_decay(
row.get("instagram_confidence_score", 0.0),
row.get("signal_age_days")
),
axis=1
)
return out