Algoritmo de Compatibilidad
El Finder utiliza el Algoritmo de Credito Parcial para calcular que tan compatible es un candidato con una vacante. Este documento explica en detalle como funciona el calculo.
Concepto general
El algoritmo evalua cada habilidad de la vacante contra las habilidades del candidato y produce:
- Match por habilidad: Porcentaje de cumplimiento de cada skill
- Match de requeridas: Promedio ponderado de skills obligatorias
- Bonus de preferidas: Puntos extra por skills deseables
- Match general: Combinacion final que determina el ranking
Formula basica
Match por habilidad individual
Formula:
matchPercent = min(100, (userScore / minimumScore) * 100)
Ejemplos:
| Minimo | Score | Calculo | Resultado |
|---|---|---|---|
| 7 | 8 | (8/7) x 100 = 114% | 100% (cap) |
| 7 | 7 | (7/7) x 100 | 100% |
| 7 | 5 | (5/7) x 100 | 71% |
| 7 | 0 | (0/7) x 100 | 0% |
Nota: El maximo es 100%, no se dan puntos extra por exceder el minimo.
Determinacion de "cumple"
Formula:
met = (userScore >= minimumScore)
| Minimo | Score | ¿Cumple? |
|---|---|---|
| 7 | 8 | Si |
| 7 | 7 | Si |
| 7 | 5 | No (parcial) |
| 7 | 0 | No (faltante) |
Match de habilidades requeridas
Formula ponderada
requiredMatch = Sum(matchPercent x weight) / Sum(weight)
Ejemplo:
| Skill | Peso | Match% | Ponderado |
|---|---|---|---|
| JavaScript | 2 | 100% | 200 |
| React | 2 | 100% | 200 |
| CSS | 1 | 80% | 80 |
| Node.js | 1 | 100% | 100 |
Calculo:
requiredMatch = (200 + 200 + 80 + 100) / (2 + 2 + 1 + 1)
= 580 / 6
= 96.7%
Bonus de habilidades preferidas
Formula
Por cada habilidad preferida cumplida:
bonus = 10% x weight (sumado al match general)
Ejemplo:
| Skill Preferida | Peso | ¿Cumple? | Bonus |
|---|---|---|---|
| TypeScript | 1 | Si | +10% |
| GraphQL | 1 | No | +0% |
| Docker | 1 | Si | +10% |
Calculo:
preferredBonus = 10% + 0% + 10% = 20%
Match general (overallMatch)
Formula completa
overallMatch = (requiredMatch x 0.9) + (preferredBonus x 0.1)
Nota: Las preferidas contribuyen un maximo de ~20% al score total.
Ejemplo completo
Vacante: Desarrollador Frontend
Candidato: Juan Perez
Habilidades requeridas:
| Skill | Peso | Min | Score | Match% | Cumple |
|---|---|---|---|---|---|
| JavaScript | 2 | 7 | 8 | 100% | Si |
| React | 2 | 6 | 7 | 100% | Si |
| CSS | 1 | 5 | 4 | 80% | No |
| HTML | 1 | 5 | 6 | 100% | Si |
Habilidades preferidas:
| Skill | Peso | Min | Score | Cumple | Bonus |
|---|---|---|---|---|---|
| TypeScript | 1 | 5 | 6 | Si | +10% |
| Testing | 1 | 4 | 0 | No | 0% |
Calculo:
-
Match requeridas:
- = (100x2 + 100x2 + 80x1 + 100x1) / (2+2+1+1)
- = (200 + 200 + 80 + 100) / 6
- = 580 / 6
- = 96.7%
-
Bonus preferidas:
- = 10% (TypeScript cumple)
-
Match general:
- = (96.7% x 0.9) + (10% x 0.1)
- = 87% + 1%
- = 88%
-
¿Cumple requisitos?
- = 3 de 4 requeridas cumplidas = NO
Indicadores del resultado
Estructura MatchResult
interface MatchResult {
overallMatch: number; // 0-100, el % final
meetsRequirements: boolean; // true si TODAS requeridas OK
requiredMatch: number; // % de requeridas
preferredBonus: number; // % de bonus
breakdown: SkillMatch[]; // detalle por skill
}
Estructura SkillMatch
interface SkillMatch {
skillId: number;
skillName: string;
required: boolean; // requerida o preferida
minimumScore: number; // nivel minimo
userScore: number; // nivel del candidato
weight: number; // ponderacion
met: boolean; // cumple el minimo?
matchPercent: number; // % de match (0-100)
}
Casos especiales
Sin habilidades evaluadas
Si el candidato no tiene ninguna habilidad evaluada:
overallMatch = 0%meetsRequirements = false- Todos los skills aparecen como "Faltante"
Vacante sin habilidades
Si la vacante no tiene requisitos definidos:
overallMatch = 100%(todos los candidatos "cumplen")- No hay breakdown util
Solo preferidas
Si la vacante solo tiene habilidades preferidas (sin requeridas):
requiredMatch = 100%meetsRequirements = true- El ranking se define solo por el bonus
Peso cero
Si una habilidad tiene peso 0:
- No contribuye al calculo
- Aparece en el breakdown pero no afecta el score
Ordenamiento de candidatos
Los candidatos se ordenan por:
- Primario:
overallMatchdescendente - Secundario: Nombre alfabetico
Ejemplo de ranking:
| Pos | Candidato | Match | Cumple Req |
|---|---|---|---|
| #1 | Juan | 95% | Si |
| #2 | Maria | 88% | Si |
| #3 | Pedro | 88% | No |
| #4 | Ana | 72% | No |
Nota: Aunque Maria y Pedro tienen el mismo %, Maria tiene prioridad alfabetica.
Pesos y su impacto
Que son los pesos
Cada habilidad puede tener un peso (weight) de 1, 2, 3, etc. que representa su importancia relativa.
Ejemplo de impacto
Escenario: Dos skills con minimo 7
| Configuracion | JavaScript (w=2) | CSS (w=1) | Match |
|---|---|---|---|
| Ambas OK (8,8) | 100% x 2 = 200 | 100% x 1 = 100 | 300/3 = 100% |
| Solo JS OK (8,5) | 100% x 2 = 200 | 71% x 1 = 71 | 271/3 = 90% |
| Solo CSS OK (5,8) | 71% x 2 = 142 | 100% x 1 = 100 | 242/3 = 81% |
Conclusion: Fallar en JavaScript (peso 2) impacta mas que fallar en CSS (peso 1).
Recomendaciones de pesos
| Peso | Uso recomendado |
|---|---|
| 1 | Habilidad estandar |
| 2 | Habilidad muy importante |
| 3 | Habilidad critica/core |
Credito parcial explicado
Por que "credito parcial"
A diferencia de un sistema binario (cumple/no cumple), este algoritmo da credito proporcional:
Sistema binario:
- Requiere: 7, Tiene: 6 - 0% de credito
Credito parcial:
- Requiere: 7, Tiene: 6 - 86% de credito
Esto permite:
- Diferenciar entre "casi cumple" y "muy lejos"
- Rankear candidatos con diferentes grados de fit
- Identificar brechas especificas
Visualizacion
Minimo requerido: 7
| Candidato | Nivel | Match |
|---|---|---|
| A | 8 | 100% (cap) |
| B | 7 | 100% |
| C | 5 | 71% |
| D | 3 | 43% |
| E | 0 | 0% |
Optimizacion de busquedas
Para el reclutador
- Define minimos realistas: Si pides 10/10, pocos candidatos calificaran
- Usa pesos estrategicamente: Skills core con peso mayor
- Balance requeridas/preferidas: No todo debe ser obligatorio
Para mejores matches
- Evalua habilidades consistentemente: Misma escala para todos
- Cubre todas las skills de tus vacantes: Si no evaluas, score = 0
- Actualiza evaluaciones: Skills pueden mejorar con el tiempo
Limitaciones del algoritmo
No considera
- Experiencia: Solo niveles de skill, no anos
- Educacion: Titulos no afectan el score
- Soft skills subjetivas: Solo las evaluadas numericamente
- Contexto: Un 7 en "JavaScript React" vs "JavaScript vanilla"
Posibles mejoras futuras
- Factor de experiencia
- Boost por certificaciones
- Decaimiento temporal de evaluaciones
- Skills relacionados (transferibles)
Codigo de referencia
El algoritmo esta implementado en:
backend/src/services/SkillMatchingService.ts
Metodos principales:
calculateMatch(): Match individualcalculateMatchFromSkills(): Logica corefindMatchingCandidates(): Busqueda por vacantefindMatchingPositions(): Busqueda por candidato
Proximos pasos
- Habilidades en el Matching - Configurar requisitos
- Buscador de Candidatos - Aplicar el algoritmo
- Buscador de Vacantes - Busqueda inversa