def build_top_factors(features, anomaly_score, final_score): factors=[] if features.get("close_approach_proxy",0)>0.5: factors.append("small orbital separation proxy") if features.get("same_shell",0)>=1: factors.append("same orbital shell") if features.get("graph_local_density",0)>0.2: factors.append("dense interaction neighborhood") if features.get("recurrence_count",0)>=3: factors.append("repeated appearance across scoring windows") if features.get("trend_delta_score",0)>0.1: factors.append("risk trend increasing over time") if anomaly_score>0.6: factors.append("unusual conjunction pattern") if final_score>0.9: factors.append("high blended system score") return factors[:5] or ["general risk elevation from orbital similarity"] def analyst_summary(features, top_factors, final_score): text="This pair is prioritized because "+", ".join(top_factors[:3])+"." if top_factors else "This pair is prioritized because multiple similarity signals are elevated." if features.get("recurrence_count",0)>=3: text+=" The pair has appeared repeatedly in recent scoring windows." if features.get("graph_local_density",0)>0.2: text+=" The surrounding interaction neighborhood is congested." if final_score>0.9: text+=" This pair should be reviewed first." return text def structured_explanation(features, top_factors, final_score, action): return {"why_risky":top_factors[:3],"what_changed":"Risk increased recently." if features.get("trend_delta_score",0)>0.1 else "No major recent change detected.","context":"Pair sits in a dense local interaction neighborhood." if features.get("graph_local_density",0)>0.2 else "Pair context is not highly congested.","recommended_action":action,"final_score":final_score} def recommended_action(label): return {"critical":"immediate analyst review","high":"prioritize analyst review","medium":"monitor and rescore on next cycle"}.get(label,"low priority monitoring")