def score_lead(features: dict) -> float:
# Heurísticos manuales sin calibración
score = 0.0
if features['plan_elegido'] == 'PRO':
score += 0.4
elif features['plan_elegido'] == 'BASIC':
score += 0.2
score += features['numero_clientes'] * 0.003
score += 0.1 if features['tiene_app_movil'] else 0
score += features['dias_trial'] * 0.01
return min(score, 1.0)
import numpy as np
# Pesos optimizados (iters 1-17)
WEIGHTS = {
'plan': {'PRO': 0.60, 'BASIC': 0.25, 'FREE': 0.05},
'fuente': {'referido': 0.35, 'organico': 0.20, 'pago': 0.10},
}
def _heuristic_a(f) -> float:
nc = min(f['numero_clientes'] / 100, 1.0)
plan = WEIGHTS['plan'].get(f['plan_elegido'], 0)
interaction = 0.18 if (plan > 0.5 and nc > 0.5) else 0
return plan + nc * 0.3 + interaction
def _heuristic_b(f) -> float:
trial = 0.20 if f['dias_trial'] > 7 else (0 if f['dias_trial'] == 0 else 0.08)
fuente = WEIGHTS['fuente'].get(f['fuente'], 0)
return trial + fuente
def _heuristic_c(f) -> float:
p = f['precio_dispuesto']
q75 = 149.0 # cuartil 75 del dataset
return 0.25 if p >= q75 else p / (q75 * 4)
def score_lead(features: dict) -> float:
votes = np.array([_heuristic_a(features),
_heuristic_b(features),
_heuristic_c(features)])
weights = np.array([0.50, 0.30, 0.20])
return float(min(np.dot(votes, weights), 1.0))