Skip to content

Latest commit

 

History

1 Commit

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Intelligent Candidate Ranking — Redrob Hackathon

Hybrid AI ranking system that matches candidates to the Senior AI Engineer role at Redrob AI. Combines sentence-transformer semantic embeddings with multi-dimensional rule-based scoring and behavioral signal analysis — going far beyond keyword matching to understand who genuinely fits the role.

Team: TEAM GG | Leader: GOWTHAM MP


Quick start

pip install -r requirements.txt

# Step 1: Pre-compute semantic embeddings (runs once, ~10-15 min on CPU)
python precompute.py --candidates ./candidates.jsonl

# Step 2: Produce the ranked submission CSV (~30s on CPU)
python rank.py --candidates ./candidates.jsonl --out ./submission.csv

# Validate
python validate_submission.py submission.csv

Runtime: ~30 seconds for the ranking step (100K candidates). No GPU, no network, no API calls during ranking.


How it works

Hybrid AI Architecture

candidates.jsonl (100K profiles)
        |
        +-----------------------------------+
        |                                   |
        v                                   v
+----------------------+    +------------------------------+
| SEMANTIC SCORING     |    | RULE-BASED SCORING           |
| (35% of final)       |    | (65% of final)               |
|                      |    |                              |
| all-MiniLM-L6-v2     |    | Title Relevance     (25%)    |
| 384-dim embeddings   |    | Core Skills Match   (20%)    |
|                      |    | Career Trajectory   (20%)    |
| JD -> embedding      |    | Broad Skills        (10%)    |
| Candidate -> embed   |    | Experience Band     (10%)    |
| Cosine similarity    |    | Location + Edu + Assess (15%)|
+------+---------------+    +----------+-------------------+
       |                               |
       +-----------+-------------------+
                   |
                   v
        +---------------------+
        | HYBRID FUSION       |
        | 0.35*sem + 0.65*rule|
        +----------+----------+
                   |
                   v
        +---------------------+
        | BEHAVIORAL          |
        | MULTIPLIER          |
        | (0.3x - 1.2x)      |
        | 12 engagement       |
        | signals             |
        +----------+----------+
                   |
                   v
        +---------------------+
        | HONEYPOT FILTER     |
        | + RANK TOP 100      |
        | + GENERATE REASONING|
        +----------+----------+
                   |
                   v
            submission.csv

Why hybrid?

Approach What it catches What it misses
Pure semantic (embeddings only) Latent role similarity from free-text summaries Structured disqualifiers, exact experience bands, honeypots
Pure rule-based (features only) Explicit JD requirements, consulting penalties, date validation Nuanced descriptions that indicate fit without using exact keywords
Hybrid (ours) Both -- embeddings surface candidates whose descriptions match even if keywords don't; rules enforce hard constraints the JD explicitly states --

Semantic scoring (35%)

  • Model: all-MiniLM-L6-v2 (22M params, 384 dimensions)
  • Pre-computed offline by precompute.py -- encodes each candidate's headline, summary, career descriptions, skills, and education into a 384-dimensional vector
  • JD encoded as a dense semantic query capturing role intent
  • Cosine similarity between JD and each candidate, normalized to [0, 1]
  • Catches candidates whose career descriptions signal fit (e.g., "built a recommendation engine at scale") even if they don't list specific keywords

Rule-based scoring (65%)

Component Weight What it measures
Title relevance 25% Current + historical job titles vs AI/ML engineering roles
Core skills 20% Must-have skills (embeddings, vector DBs, Python, eval frameworks)
Career trajectory 20% Product vs consulting, production ML signals, job stability
Broad skills 10% Wider AI/ML skill coverage
Experience band 10% Proximity to 5-9 year sweet spot
Location 5% India preferred, specific cities best
Education 5% Field relevance, institution tier, degree level
Assessments 5% Platform skill assessment scores

Behavioral multiplier (0.3x - 1.2x)

12 engagement signals: last-active recency, open-to-work flag, recruiter response rate, response time, profile completeness, interview completion rate, notice period, GitHub activity, verification status, saved-by-recruiters, offer acceptance rate, work mode preference.

Honeypot detection

Catches ~42 impossible profiles:

  • Impossible tenure (claimed months >> actual date range)
  • Expert skills with 0 months of use
  • 10+ expert skills with near-zero endorsements
  • Career months wildly exceeding stated YOE

Project structure

rank.py                     Hybrid ranker (semantic + rule-based + behavioral)
precompute.py               Generates sentence-transformer embeddings
artifacts/                  Pre-computed embeddings (generated by precompute.py)
  jd_embedding.npy          JD vector (1 x 384)
  candidate_embeddings.npy  All candidates (100K x 384)
  candidate_ids.json        Ordered candidate ID list
submission.csv              Generated output (top 100 candidates)
requirements.txt            Dependencies (numpy, sentence-transformers)
submission_metadata.yaml    Hackathon metadata
TEAM_GG_Presentation.pptx   Presentation deck
TEAM_GG_Presentation.pdf    PDF version

Design decisions

Hybrid over pure-semantic or pure-rule-based. The JD explicitly warns that keyword matching is a trap -- but pure embeddings also fail because they can't enforce structured constraints (experience years, consulting-only penalty, honeypot detection). The hybrid approach lets each method cover the other's blind spots.

35/65 semantic/rule split. Rules are weighted higher because the JD is unusually specific about disqualifiers and requirements. In a more generic matching system, semantic weight would be higher.

Multiplicative behavioral scoring. A technically perfect but unresponsive candidate gets properly down-weighted (0.95 x 0.3 = 0.28). This matches the JD's explicit guidance about availability signals.

Pre-computed embeddings. Encoding 100K candidates takes ~10-15 minutes on CPU. This runs once offline. The ranking step loads the vectors and computes cosine similarity in seconds -- well within the 5-minute budget.


Reproduce

# Full pipeline (including pre-computation)
pip install -r requirements.txt
python precompute.py --candidates ./candidates.jsonl
python rank.py --candidates ./candidates.jsonl --out ./submission.csv

# Ranking step only (if artifacts/ already exists)
python rank.py --candidates ./candidates.jsonl --out ./submission.csv

About

No description, website, or topics provided.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages