Sobes.tech
Назад к вопросам
Middle — Senior
13

Какие особенности ранжирования вакансий и резюме?

Компании, где спрашивали
ЦифровыеПривычки
СБЕРСБЕР
Теле2Теле2

Ответ от нейросети

sobes.tech AI

Что хотят услышать интервьюеры:

Ранжирование вакансий и резюме обычно решает не задачу точного предсказания, а задачу сортировки по полезности для пользователя. Важно учитывать двустороннюю релевантность: вакансия должна подходить кандидату, а кандидат — вакансии, с учетом ограничений по локации, зарплате, навыкам и уровню. Также критичны качество фичей, борьба с bias и корректная офлайн/онлайн оценка.

Определение:

Ранжирование вакансий и резюме — это построение порядка элементов в выдаче так, чтобы сверху оказывались наиболее подходящие пары «кандидат–вакансия» или наиболее релевантные вакансии для конкретного резюме. Обычно это задача Learning to Rank, где модель учится предсказывать не просто класс, а относительную полезность объекта в контексте запроса, профиля пользователя и бизнес-ограничений.

Особенность домена в том, что релевантность не симметрична и зависит от стороны поиска: одна и та же вакансия может быть отличной для одного кандидата и плохой для другого. Поэтому в ранжировании часто используют смешение контентных, поведенческих и бизнес-фичей, а также этапы фильтрации, бустинга и персонализации.

Пример использования:

Например, кандидат открыл ленту вакансий. Система сначала отфильтровывает нерелевантные вакансии по локации, уровню и обязательным требованиям, затем ранжирует оставшиеся по вероятности отклика, вероятности отклика с позитивным исходом и ожидаемой ценности для бизнеса.

candidates = [
    {"job_id": 1, "skill_match": 0.9, "location_match": 1, "salary_match": 0.8, "apply_prob": 0.3},
    {"job_id": 2, "skill_match": 0.7, "location_match": 1, "salary_match": 0.9, "apply_prob": 0.4},
    {"job_id": 3, "skill_match": 0.95, "location_match": 0, "salary_match": 0.7, "apply_prob": 0.5},
]

def score(x):
    if x["location_match"] == 0:
        return -1  # жесткий фильтр
    return 0.5 * x["skill_match"] + 0.3 * x["salary_match"] + 0.2 * x["apply_prob"]

ranked = sorted(candidates, key=score, reverse=True)
print([x["job_id"] for x in ranked])

В этом примере вакансия №3 отсекается на первом этапе, потому что не совпадает локация. Оставшиеся вакансии сортируются по суммарному скору, где сильнее всего влияет соответствие навыков.

Пояснение кода:

Код показывает типичный двухэтапный подход. Сначала применяется жесткое правило-фильтр, которое исключает заведомо неподходящие вакансии, потому что такие ограничения часто важнее любых ML-оценок. Затем считается итоговый скор как взвешенная сумма признаков, и список сортируется по нему.

На практике вместо ручной формулы используют модель ранжирования, которая сама учится подбирать веса и нелинейные зависимости. Но логика остается той же: сначала убрать невозможные варианты, потом упорядочить релевантные.

Ключевые моменты:

  • Ранжирование в HR-search почти всегда контекстное: оценка зависит от пары «кандидат–вакансия», а не только от одного объекта.
  • Часто нужен двухэтапный пайплайн: фильтрация hard constraints, затем ML/LTR-ранжирование.
  • Важны как точность матчинга по навыкам, так и бизнес-ограничения: локация, зарплата, формат работы, уровень.
  • Поведенческие метрики могут быть смещены позицией в выдаче, поэтому нужна борьба с position bias и корректная разметка.
  • Оценивать систему лучше не одной метрикой, а набором: offline ranking metrics, CTR/response rate, качество найма, удовлетворенность пользователя.
  • Для резюме и вакансий полезны как текстовые эмбеддинги, так и структурные признаки, потому что одного текста обычно недостаточно.