DEV Community

Meet Kelwa
Meet Kelwa

Posted on

CareerPilot AI:AI Resume Analyzer

In the modern job market, hiring managers and talent acquisition teams face an overwhelming influx of job applications. For a single opening, hundreds of resumes are submitted, each with unique formatting, fonts, layouts, and styles. Manually reading through each file is a huge bottleneck that costs teams countless hours.

To solve this, I built the AI Resume Analyzerβ€”a lightweight, cloud-native application that leverages Natural Language Processing (NLP) and Machine Learning (ML) to automatically parse PDF resumes, categorize candidates into primary professional domains (e.g., DevOps, Frontend, Data Science), analyze their skills, and suggest missing competencies to fill the gap.

In this blog, I will walk you through the architecture, the machine learning pipeline, NLP extraction, and how I deployed it for free on the cloud.

πŸš€ Key Project Features
Instant PDF Extraction: Extracts and cleans raw text from unstructured PDF formats in under 300ms.
AI-Driven Domain Classification: Classifies resumes into matching job roles (like Data Science or Design) with confidence percentages using an ML model.
Contact Details Miner: Extracts phone numbers and email addresses automatically using regular expressions.
NLP Entity & Skill Extraction: Uses spaCy's POS tagger and custom regex boundaries to identify technical skills.
Career Gap Recommendations: Compares the candidate's skills against core domain standards to suggest missing technologies they should learn.
πŸ› οΈ The Architecture & Data Flow
The app is built as a REST API using FastAPI with a responsive front-end UI. The overall flow is as follows:

[Resume PDF Upload]
↓
[PyPDF2 Text Extraction & Cleaning]
↓
[spaCy Named Entity Recognition (NER)] β†’ Extracts Names, Companies & Locations
↓
[Word-Boundary Skills Extraction] β†’ Identifies 30+ Tech Skills
↓
[TF-IDF Vectorization] β†’ Converts cleaned text to numerical weights
↓
[Random Forest Classification] β†’ Predicts Primary Job Category (e.g., Backend Engineering)
↓
[Skill Gap Analysis & Career Mapping] β†’ Compares extracted skills with target profile
↓
[Interactive HTML Dashboard] β†’ Displays Profile, Confidence, Contacts, & Recommended Skills
🧠 The Machine Learning Core
To categorize resumes, we implemented a supervised machine learning pipeline composed of TF-IDF Vectorization and a Random Forest Classifier in Python.

  1. Vectorization (TF-IDF)
    Machines cannot read plain English paragraphs. We use TfidfVectorizer (Term Frequency-Inverse Document Frequency) from Scikit-Learn to convert clean text into a matrix of token counts. TF-IDF automatically down-weights common words (like experience, projects, or work) and awards higher statistical weights to highly discriminative technical words (like TensorFlow, Kubernetes, Figma, or React).

  2. Classification (Random Forest)
    We utilize a RandomForestClassifier (an ensemble of decision trees) to predict the candidate's career category. Random Forest is ideal for text classification because it generalizes exceptionally well on dense matrices, averages out variance, and prevents overfitting on smaller training datasets.

Here is the Python implementation used for the training stage (train.py):

python

import os
import joblib
import pandas as pd
from sklearn.feature_extraction.text import TfidfVectorizer
from sklearn.ensemble import RandomForestClassifier
from sklearn.model_selection import train_test_split

1. Load Data

We generated specialized training text profiles for backend, frontend, data science, devops, and design.

df = load_training_data()

2. Extract TF-IDF Features

vectorizer = TfidfVectorizer(stop_words='english', max_features=5000)
X_vectorized = vectorizer.fit_transform(df['text'])
y = df['category']

3. Split & Train

X_train, X_test, y_train, y_test = train_test_split(X_vectorized, y, test_size=0.2, random_state=42)
model = RandomForestClassifier(n_estimators=100, random_state=42)
model.fit(X_train, y_train)

4. Save Models for API Inference

os.makedirs("models", exist_ok=True)
joblib.dump(model, "models/model.pkl")
joblib.dump(vectorizer, "models/vectorizer.pkl")
πŸ” NLP Parsing: Entity & Skill Extraction
While the ML model determines the high-level category, an NLP parsing engine extracts details from the text block.

We used spaCy (en_core_web_sm) to analyze the grammatical structure of the sentences and retrieve named entities.

Named Entity Recognition (NER): spaCy automatically identifies organizations (ORG), person names (PERSON), and geopolitical entities (GPE).
Regular Expressions: We use strict regex patterns to extract emails and phone numbers.
Skill Extraction: Using clean text boundaries (\b), a list of core technical skills is compared with the document text to compile verified skills.
Here is a snippet of our parser (resume_parser.py):

python

import re
import spacy
nlp = spacy.load("en_core_web_sm")
def extract_entities(text):
doc = nlp(text)
entities = {}

# Extract Names, Companies, and Locations
allowed_labels = ['ORG', 'PERSON', 'GPE']
for ent in doc.ents:
    if ent.label_ in allowed_labels:
        clean_text = re.sub(r'\s+', ' ', ent.text).strip()
        if 2 < len(clean_text) < 30:
            if ent.label_ not in entities:
                entities[ent.label_] = []
            entities[ent.label_].append(clean_text)

# Add Technical Skills via boundary matches
entities['Skills'] = extract_skills(text)
return entities
Enter fullscreen mode Exit fullscreen mode

⚑ Interactive Frontend & FastAPI Server
We integrated this pipeline into a FastAPI web server (app.py). When a user uploads a PDF, the file is temporarily loaded, parsed, and run through the loaded ML vectorizer.

The API returns a JSON response containing the category, confidence percentage, parsed entities, contact details, and a list of recommended job titles.

To make the application user-friendly, the server exposes a beautiful responsive HTML front-end styled with a sleek dark mode, glowing accents, and micro-animations. The interface gives candidates a visual report card of their skills, showing a direct comparison between what was found and what they should learn to land a job in their domain.

☁️ Deployment Strategy
We hosted the application on Render.com.

Originally, we set up a Docker configuration. However, cloud-hosted Free Tiers are restricted to 512MB RAM. Heavy libraries like Scikit-Learn, Pandas, and spaCy require significant memory during the Docker image building phase, causing the build to crash.

To solve this, we updated our configuration (render.yaml) to run in a Native Python Environment instead of Docker:

yaml

services:

  • type: web name: ai-resume-analyzer-api env: python buildCommand: "pip install -r requirements.txt && python -m spacy download en_core_web_sm && python train.py" startCommand: "uvicorn app:app --host 0.0.0.0 --port $PORT" plan: free By switching to native Python, Render installs packages using pre-built wheels, reducing memory overhead, and allowing our application to deploy successfully!

πŸ“Š Project Metrics
Average Inference Latency: <300 milliseconds
Model Accuracy: ~95% classification accuracy on test resumes
Deployment Cost: $0 (Utilizing Render free web service plan)
πŸ”— Live Links & Code
Live Web Application: https://careerpilot-ai-s8xe.onrender.com
GitHub Repository: https://github.com/meetkelwa2005-bot/CareerPilot-AI.git

Top comments (0)