proofrank / src /score.py
Sarthak080907's picture
Deploy ProofRank sandbox with production-parity ranker
c643b04
Raw
History Blame Contribute Delete
4.08 kB
from __future__ import annotations
from datetime import datetime, timezone
def _float(row: dict, key: str, default: float = 0.0) -> float:
try:
return float(row.get(key, default) or default)
except (TypeError, ValueError):
return default
def composite_score(row: dict, spec: dict) -> float:
weights = spec.get("scoring_weights") or {}
score = (
weights.get("retrieval_rrf", 0.14) * _float(row, "retrieval_rrf")
+ weights.get("career_evidence", 0.38) * _float(row, "career_evidence")
+ weights.get("title_tier", 0.13) * _float(row, "title_tier_score")
+ weights.get("yoe_location_fit", 0.09) * _float(row, "yoe_location_fit")
+ weights.get("skill_trust", 0.07) * _float(row, "skill_trust")
+ weights.get("assessment_score", 0.05) * _float(row, "assessment_score")
+ weights.get("product_company", 0.04) * _float(row, "product_company_score")
+ weights.get("education_score", 0.04) * _float(row, "education_score")
+ weights.get("company_scale_score", 0.03) * _float(row, "company_scale_score")
+ weights.get("work_mode_fit", 0.02) * _float(row, "work_mode_fit")
+ weights.get("platform_activity_score", 0.02) * _float(row, "platform_activity_score")
- weights.get("anti_pattern_penalty", 0.12) * _float(row, "anti_pattern_penalty")
+ _float(row, "rank_time_bonus")
)
return max(0.0, min(1.0, score))
def _recency_multiplier(last_active: str | None) -> float:
if not last_active:
return 0.78
try:
dt = datetime.fromisoformat(str(last_active).replace("Z", "+00:00"))
if dt.tzinfo is None:
dt = dt.replace(tzinfo=timezone.utc)
days = (datetime.now(timezone.utc) - dt).days
except (TypeError, ValueError):
return 0.82
if days <= 30:
return 1.00
if days <= 90:
return 0.93
if days <= 180:
return 0.84
if days <= 365:
return 0.76
return 0.68
def behavioral_multiplier(row: dict) -> float:
mult = _recency_multiplier(row.get("last_active_date"))
response = _float(row, "recruiter_response_rate")
if response >= 0.60:
mult *= 1.06
elif response < 0.10:
mult *= 0.76
elif response < 0.25:
mult *= 0.90
avg_hours = _float(row, "avg_response_time_hours", 48)
if avg_hours and avg_hours <= 12:
mult *= 1.02
elif avg_hours > 96:
mult *= 0.95
notice = int(_float(row, "notice_period_days", 90))
if notice <= 30:
mult *= 1.05
elif notice > 90:
mult *= 0.90
if row.get("open_to_work_flag"):
mult *= 1.04
if row.get("willing_to_relocate"):
mult *= 1.02
completeness = _float(row, "profile_completeness_score")
if completeness >= 80:
mult *= 1.02
elif completeness < 40:
mult *= 0.95
if _float(row, "github_activity_score", -1) >= 50:
mult *= 1.02
if _float(row, "saved_by_recruiters_30d") >= 3:
mult *= 1.03
if _float(row, "interview_completion_rate") >= 0.85:
mult *= 1.02
if 0 <= _float(row, "offer_acceptance_rate", -1) < 0.25:
mult *= 0.96
if _float(row, "verified_trust") >= 0.66:
mult *= 1.01
if _float(row, "work_mode_fit") >= 0.90:
mult *= 1.02
if _float(row, "platform_activity_score") >= 0.50:
mult *= 1.02
return max(0.70, min(1.15, mult))
def final_score(row: dict, spec: dict) -> float:
base = composite_score(row, spec)
return base * behavioral_multiplier(row)
def monotonic_submission_scores(raw_scores: list[float]) -> list[float]:
if not raw_scores:
return []
hi, lo = max(raw_scores), min(raw_scores)
if hi == lo:
return [round(max(0.01, 0.99 - i * 0.001), 4) for i in range(len(raw_scores))]
scaled = [0.20 + 0.79 * (s - lo) / (hi - lo) for s in raw_scores]
out = [min(0.99, scaled[0])]
for score in scaled[1:]:
out.append(min(out[-1] - 0.0001, score))
return [round(max(0.01, s), 4) for s in out]