Files
hiffi-artist-intelligence/scripts/verify_publication_gates.py
T
2026-10-26 12:39:08 +05:30

65 lines
2.8 KiB
Python

"""
scripts/verify_publication_gates.py
Verifies raw score immutability, evidence gates (Top 10/Top 50),
consecutive published ranks, and missing data retention.
"""
import sys
from pathlib import Path
# Add project root to sys.path so 'core' and other local packages resolve
PROJECT_ROOT = Path(__file__).resolve().parent.parent
if str(PROJECT_ROOT) not in sys.path:
sys.path.insert(0, str(PROJECT_ROOT))
import pandas as pd
from core.ranking_engine import HIFFIRankingEngine
DATASET_PATH = PROJECT_ROOT / "data" / "hiffi_multiplatform_500.csv"
# 1. Load dataset & apply publication eligibility gates
df = pd.read_csv(DATASET_PATH)
orig_scores = df["hiffi_xp_score"].copy()
orig_ranks = df["hiffi_xp_rank"].copy()
engine = HIFFIRankingEngine()
gated_df = engine.apply_publication_eligibility_gates(df)
# Check 1: Raw scores & raw ranks unchanged
score_match = (gated_df["hiffi_xp_score"].fillna(-999) == orig_scores.fillna(-999)).all()
rank_match = (gated_df["hiffi_xp_rank"].fillna(-999) == orig_ranks.fillna(-999)).all()
print("=== 1. RAW SCORE & RANK IMMUTABILITY ===")
print(f"Raw hiffi_xp_score Unaltered: {score_match}")
print(f"Original hiffi_xp_rank Unaltered: {rank_match}")
# Check 2: Published rank bounds, uniqueness, and completeness
pub_ranks = gated_df["hiffi_xp_published_rank"].sort_values().tolist()
is_consecutive_500 = pub_ranks == list(range(1, 501))
print("\n=== 2. PUBLISHED RANK STRUCTURE ===")
print(f"Unique, consecutive 1 to 500: {is_consecutive_500}")
print(f"Total cohort count: {len(gated_df)}")
# Check 3: Evidence Gates
top_10 = gated_df[gated_df["hiffi_xp_published_rank"] <= 10]
top_50 = gated_df[gated_df["hiffi_xp_published_rank"] <= 50]
t10_all_tier3 = (top_10["platform_evidence_tier"] == 3).all()
t50_all_tier2plus = (top_50["platform_evidence_tier"] >= 2).all()
t10_tiers = top_10["platform_evidence_tier"].unique().tolist()
t50_tiers = top_50["platform_evidence_tier"].unique().tolist()
print("\n=== 3. EVIDENCE GATES VALIDATION ===")
print(f"Top 10 strictly Tier 3 (3 platforms): {t10_all_tier3} (Tiers present: {t10_tiers})")
print(f"Top 50 strictly Tier >= 2: {t50_all_tier2plus} (Tiers present: {t50_tiers})")
# Check 4: Missing data preservation
missing_sp = gated_df["spotify_monthly_listeners"].isna().sum()
missing_ig = gated_df["instagram_followers"].isna().sum()
zero_sp = (gated_df["spotify_monthly_listeners"] == 0).sum()
zero_ig = (gated_df["instagram_followers"] == 0).sum()
print("\n=== 4. DATA INTEGRITY & ZERO-IMPUTATION ===")
print(f"Spotify Missing (NaN): {missing_sp} | Literal Zeroes: {zero_sp}")
print(f"Instagram Missing (NaN): {missing_ig} | Literal Zeroes: {zero_ig}")
# Persist gated dataset with publication rank column
gated_df.to_csv(DATASET_PATH, index=False)
print("\nSaved updated cohort with hiffi_xp_published_rank to data/hiffi_multiplatform_500.csv.")