Skip to main content

Job Description Skill Classifier [JobSelect CLI & JobAnalyze Model] (Multi-Label)

Python PyTorch scikit-learn NumPy Pandas Website Hugging Face PyPI LinkedIn PyPI Downloads

An open source Job Description Analyzer that can be accessed through API and MCP servers, get your free API keys at https://jobselect.vercel.app

JobSelect Labs, an AI open source venture by Akshay Babu (Founder and CEO)

JobSelect CLI :

JobSelect CLI

Installation:

It uses:

  • TF-IDF features over the combined text (job description + role + type)
  • A PyTorch feed-forward neural network trained as a multi-label classifier
  • Per-skill thresholding for evaluation and top-k ranked probabilities for inference

What it does

  1. Data preparation (model/prep/data_prep.py)

    • Reads cleaned job description data.
    • Normalizes/repairs common skill typos (e.g., tesnorflow/pytorchtensorflow/pytorch).
    • Builds a multi-hot target vector of skills.
    • Fits a TF-IDF vectorizer (with n-grams) and splits into train/test.
    • Saves:
      • model/prep/prepared_data.npz (TF-IDF arrays + labels + indexes)
      • model/prep/vectorizer.pkl (fitted TF-IDF vectorizer)
      • model/prep/label_vocab.json (skill label vocabulary)
  2. Model training (model/model.py)

    • Loads prepared TF-IDF arrays.
    • Defines a simple MLP:
      • Linear → ReLU → Dropout → Linear (one logit per skill)
    • Trains with BCEWithLogitsLoss (multi-label setting).
    • Saves:
      • model_out/skill_classifier.pt (model weights)
      • model_out/training_history.json (train/test loss curves)
  3. Evaluation (model/eval.py)

    • Loads the trained model.
    • Applies a fixed sigmoid + threshold (0.3) to obtain binary skill predictions.
    • Reports:
      • Per-skill precision/recall/F1
      • Micro-F1 and Macro-F1
    • Compares against a simple baseline (frequency-driven / always-predict-most-frequent labels).
  4. Prediction / Inference (model/pred.py)

    • Loads the TF-IDF vectorizer and trained model.
    • Creates TF-IDF features for the input text.
    • Outputs the top-k skills by probability.

Use cases

  • Resume/job-post matching (first-pass filtering of relevant skills)
  • Job taxonomy building (discover recurring skills from postings)
  • Recruiting analytics (aggregate predicted skill demand by seniority/role/type)
  • Prototyping multi-label NLP classifiers (TF-IDF + MLP baseline)

Project structure

.
├─ data/
│  ├─ raw/
│  │  ├─ Job_descriptions.csv                 # Original v1 raw dataset
│  │  └─ Job_descriptions_v2.csv              # v2 raw dataset (expanded/updated)
│  ├─ sample_data/
│  │  ├─ v1/
│  │  │  ├─ cli.txt                           # Example JD for CLI testing (v1)
│  │  │  ├─ eval.txt                          # Example JD for evaluation testing (v1)
│  │  │  └─ test.txt                          # Example JD, Role and Type for testing (v1)
│  │  └─ v2/
│  │     ├─ cli.txt                           # Example JD for CLI testing (v2)
│  │     ├─ eval.txt                          # Example JD for evaluation testing (v2)
│  │     └─ test.txt                          # Example JD, Role and Type for testing (v2)
│  └─ clean/
│     ├─ v1/
│     │  ├─ cleaned_job_descriptions.csv      # Cleaned master CSV (v1)
│     │  ├─ cleaned_job_descriptions_internships.csv
│     │  ├─ cleaned_job_descriptions_junior.csv
│     │  └─ cleaned_job_descriptions_senior.csv
│     └─ v2/
│        ├─ cleaned_job_descriptions_v2.csv   # Cleaned master CSV (v2)
│        ├─ cleaned_job_descriptions_internships_v2.csv
│        ├─ cleaned_job_descriptions_junior_v2.csv
│        └─ cleaned_job_descriptions_senior_v2.csv
│
├─ model/
│  ├─ __init__.py
│  ├─ model.py                                # PyTorch multi-label classifier training
│  ├─ eval.py                                 # Thresholded evaluation + F1 metrics + baseline comparison
│  ├─ pred.py                                 # Predict top-k skills for new text
│  ├─ MODEL.md                                # Model architecture & performance documentation
│  └─ prep/
│     ├─ __init__.py
│     ├─ data_prep.py                         # TF-IDF + multi-hot label creation + train/test split
│     ├─ sym_map.py                           # Synonym/phrase normalization map used during prep
│     ├─ test.py                              # Test utilities for data preparation
│     ├─ v1/
│     │  ├─ vectorizer.pkl                    # v1 TF-IDF vectorizer (generated by data_prep)
│     │  ├─ prepared_data.npz                 # v1 TF-IDF arrays + labels + indexes
│     │  └─ label_vocab.json                  # v1 skill label vocabulary
│     └─ v2/
│        ├─ vectorizer_v2.pkl                 # v2 TF-IDF vectorizer (generated by data_prep)
│        ├─ prepared_data_v2.npz              # v2 TF-IDF arrays + labels + indexes
│        └─ label_vocab_v2.json               # v2 skill label vocabulary
│
├─ model_out/
│  ├─ v1/
│  │  ├─ skill_classifier.pt                  # v1 trained model weights (generated by model.py)
│  │  └─ training_history.json                # v1 training loss history (generated by model.py)
│  └─ v2/
│     ├─ skill_classifier_v2.pt               # v2 trained model weights (generated by model.py)
│     └─ training_history_v2.json             # v2 training loss history (generated by model.py)
│
├─ api/
│  ├─ __init__.py
│  ├─ .dockerignore
│  ├─ Dockerfile                              # Dockerfile for API deployment
│  ├─ JobAnalyze_API.py                       # FastAPI service + Pydantic validation + API-key verification
│  ├─ supabase_client.py                      # Optional API key persistence (Supabase)
│  └─ JobAnalyze/
│     ├─ __init__.py
│     ├─ v1/
│     │  ├─ __init__.py
│     │  └─ pred_v1.py                        # v1 prediction wrapper (imports model.pred)
│     └─ v2/
│        ├─ __init__.py
│        └─ pred_v2.py                        # v2 prediction wrapper (imports model.pred)
│
├─ cli/
│  ├─ api_val.py                              # API key prompt / mode selection for CLI
│  ├─ jobselect.py                            # Rich terminal CLI (prompts + prints top skills)
│  ├─ main_screen.py                          # CLI main screen / splash UI
│  ├─ model_select.py                         # Inference routing: API-first, LOCAL fallback
│  └─ utils.py                                # Shared CLI utility functions
│
├─ backups/
│  ├─ __init__.py
│  ├─ backup.py                               # Data backup routines
│  ├─ sync.py                                 # Sync utilities
│  └─ data/                                   # Backup data storage
│
├─ frontend/
│  └─ repo/
│     ├─ favicon.png                          # JobSelect favicon
│     ├─ favicon.b64.txt                      # Base64-encoded favicon
│     ├─ title_page_jobselect.png             # CLI title page screenshot
│     └─ mode_selection_jobselect.png         # Mode selection screen
│
├─ notebooks/
│  ├─ 01_EDA.ipynb                            # Exploratory Data Analysis
│  └─ 02_Data_Engineering.ipynb               # Data engineering / cleaning notes
│
├─ test/
│  └─ test_model.py                           # Pytest checks expected artifacts exist in model_out/ and model/prep/
│
├─ .dockerignore
├─ .gitignore
├─ Dockerfile                                 # Root Dockerfile (if applicable)
├─ LICENSE
├─ pipeline.py                                # Executes notebooks + training/eval steps in order
├─ pyproject.toml                             # Installs as a cli tool (jobselect)
├─ pytest.ini                                 # Pytest configuration
├─ requirements.txt
└─ README.md

Requirements

See requirements.txt for the exact dependencies.


Getting started

1) Clone and Install dependencies

git clone https://github.com/Ak47xdd/Job-Description-Analysis.git
pip install -r requirements.txt

2) Run data preparation (optional)

This builds the TF-IDF features and label vocabulary from the cleaned CSV.

python model/prep/data_prep.py

Expected outputs:

  • model/prep/prepared_data.npz
  • model/prep/vectorizer.pkl
  • model/prep/label_vocab.json

3) Train the model (optional)

python model/model.py

Expected outputs:

  • model_out/skill_classifier.pt
  • model_out/training_history.json

4) Evaluate performance (optional)

python model/eval.py

Outputs include:

  • Per-skill metrics (precision/recall/F1)
  • Micro-F1 and Macro-F1
  • Baseline comparison

5) Predict skills for a new job description

Option A: Python function (LOCAL model) — advanced / offline use only

You can still run predictions locally if you have the prepared artifacts (model/prep/vectorizer.pkl and model_out/skill_classifier.pt). Local inference is useful for offline experimentation or development, but for most users we recommend using the hosted API (see Option C).

from api.pred import JobAnalyze_6k

data/sample_data/test.txt contains an example job description inside. Use:

JobAnalyze_6k(job_desc, role="AI Engineer", job_type="Junior", top_k=50)

Option B: Use the interactive CLI (API-first)

The CLI (cli/jobselect.py) is API-first. Provide a valid API key to run the CLI against the hosted service so you always get the up-to-date model and label set. If no API key is provided the CLI can fall back to local inference, but this is not recommended for general usage.

python -m cli.jobselect

# or after install
pip install jobselect
jobselect

The CLI:

  • prompts for Job Description, Role, and Type
  • validates them via the API schema when running in API mode
  • prints the top skills ranked by probability as returned by the hosted API

Option C: Get predictions through the hosted API (recommended)

The API is hosted and recommended for production and general use — it provides the latest model, label vocabulary, and automatic updates.

To call the hosted API, send a POST request to the hosted endpoint (replace <HOSTED_API_URL> with the actual API base URL) with the header JOBSELECT_KEY set to your API key, and a JSON body containing Job_Desc, Role, and Type.

Base URL : https://job-description-analysis.onrender.com

JOBSELECT_KEY : Vist the website (jobselect.vercel.app)

Example (curl):

curl -X POST "https://<HOSTED_API_URL>/predict" \
  -H "Content-Type: application/json" \
  -H "JobAnalyze_6k_Key: YOUR_API_KEY_HERE" \
  -d '{"Job_Desc":"Senior ML engineer with 3+ years experience...","Role":"AI Engineer","Type":"Senior"}'

The response will include ranked skills and probabilities (top-k). Contact the repository maintainer or your account admin to obtain an API key and the exact hosted API base URL.


Option D: Run the FastAPI service locally (optional)

If you prefer to host your own instance of the API, you can run the FastAPI server in api/JobAnalyze_API.py. Local hosting is useful for private deployments or testing with custom models.

Run the service and send requests with the same header and JSON body as described in Option C (JobAnalyze_6k_Key, Job_Desc, Role, Type).


How predictions work

  • Text is concatenated as: "{job_desc} {role} {job_type}"
  • TF-IDF transforms text into a fixed-size vector
  • The network outputs one logit per skill
  • Sigmoid converts logits → probabilities
  • Skills are ranked by probability and the top-k are returned

Important implementation notes

  • Multi-label learning: Each skill is treated independently (binary relevance via sigmoid + BCEWithLogitsLoss).
  • Evaluation threshold: model/eval.py uses a fixed threshold of 0.3. For production use, you may want per-label thresholds tuned on a validation set.
  • Dataset size: The included notebooks and evaluation code suggest the dataset may be small; results can be limited by label frequency and data coverage.

New features / capabilities

  • Rich terminal CLI (cli/jobselect.py) using rich + pyfiglet for interactive top-skill display.
  • API validation + schema enforcement
    • Input validation via Pydantic model constraints in api/JobAnalyze_API.py.
    • API key auth via header + secure verification, with optional Supabase-backed storage in api/supabase_client.py.
    • CLI mode auto-detection (cli/api_val.py + cli/model_select.py): uses API when a key is available, otherwise falls back to local inference.
  • Synonym/phrase normalization hook (model/prep/sym_map.py) applied during data preparation.
  • Pipeline runner (pipeline.py) to execute notebooks and training steps in sequence.

Customization ideas

  • Improve text cleaning and skill normalization in data_prep.py
  • Tune TF-IDF parameters (max_features, ngram_range, min_df)
  • Replace the simple MLP with a stronger baseline (e.g., logistic regression on TF-IDF)
  • Calibrate thresholds per label using validation data
  • Add a CLI or web service endpoint for prediction


Author

Developed with ❤️ by Akshay Babu

LinkedIn GitHub

For questions, feedback, or collaboration opportunities, feel free to reach out!


References / Inspiration

This repository follows a common pattern for multi-label NLP baselines: TF-IDF features + a simple neural network + sigmoid-based multi-label outputs.

Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

jobselect-0.12.6.tar.gz (206.9 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

jobselect-0.12.6-py3-none-any.whl (209.9 kB view details)

Uploaded Python 3

File details

Details for the file jobselect-0.12.6.tar.gz.

File metadata

  • Download URL: jobselect-0.12.6.tar.gz
  • Upload date:
  • Size: 206.9 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.14.0

File hashes

Hashes for jobselect-0.12.6.tar.gz
Algorithm Hash digest
SHA256 cea4f36f7bb99d282d85b6a4b89e21b8c593053754188cd0fa8e8aa0826269fa
MD5 1e232b5b949c33fb973206e9c052669b
BLAKE2b-256 372c129d28e73b322f8238612f5e940322069a3bf31b6b03c0c97f9c23bbe51c

See more details on using hashes here.

File details

Details for the file jobselect-0.12.6-py3-none-any.whl.

File metadata

  • Download URL: jobselect-0.12.6-py3-none-any.whl
  • Upload date:
  • Size: 209.9 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.14.0

File hashes

Hashes for jobselect-0.12.6-py3-none-any.whl
Algorithm Hash digest
SHA256 19dcb8b4205b8071db50cac069097c2319c54e6869bdaff4ae5d832516264610
MD5 d99ff734eb7052e39337d26a26ee623c
BLAKE2b-256 33b6f111bb2c04ec4abf3531609e2dd0313d6258838c9a0539d49bdd775d5f08

See more details on using hashes here.

Release history Release notifications | RSS feed

0.12.7

2 files

This release

0.12.6 This release

2 files

0.12.5

2 files

0.12.4

2 files

0.12.3

2 files

0.12.2

2 files

0.12.1

2 files

0.12.0

2 files

0.11.6

2 files

0.11.5

2 files

0.11.4

2 files

0.11.3

2 files

0.11.2

2 files

0.11.1

2 files

0.10.9

2 files

0.10.8

2 files

0.10.7

2 files

0.10.5

2 files

0.10.4

2 files

0.10.3

2 files

0.10.2

2 files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page