Resume-parser-app / parser /ner_extractor.py
alihaider1001
Updated resume parser with enhanced skill extraction and job matcher
1f5134c
Raw
History Blame Contribute Delete
2.86 kB
import spacy
import re
from difflib import get_close_matches
# Safe model load
try:
nlp = spacy.load("en_core_web_sm")
except:
from spacy.cli import download
download("en_core_web_sm")
nlp = spacy.load("en_core_web_sm")
# Common skills list (used for fuzzy matching)
common_skills = [
"python", "sql", "java", "c++", "machine learning", "deep learning", "nlp", "tensorflow",
"keras", "pandas", "numpy", "matplotlib", "power bi", "excel", "html", "css", "django", "flask",
"scikit-learn", "seaborn", "fastapi", "pytorch"
]
edu_keywords = ["bachelor", "bs", "msc", "ms", "phd", "b.sc", "b.s.", "university", "institute", "college"]
def extract_skills(text):
doc = nlp(text)
# Extract noun phrases
noun_phrases = set(chunk.text.lower().strip() for chunk in doc.noun_chunks)
# Add common skills if fuzzy matched
matched_common = set()
words = set(text.lower().split())
for skill in common_skills:
if get_close_matches(skill.lower(), words, n=1, cutoff=0.85):
matched_common.add(skill.lower())
# Combine and clean
all_skills = noun_phrases.union(matched_common)
filtered = [s for s in all_skills if 2 <= len(s.split()) <= 5 and not s.startswith(("i ", "my ", "our "))]
return list(set(filtered))
def extract_entities(text):
doc = nlp(text)
entities = {
"Name": None,
"Email": None,
"Phone": None,
"Skills": [],
"Education": [],
"Experience": [],
"Certifications": [],
"Projects": []
}
# βœ… Extract Name
for ent in doc.ents:
if ent.label_ == "PERSON":
entities["Name"] = ent.text
break
# βœ… Extract Email & Phone
entities["Email"] = next(iter(re.findall(r"[a-zA-Z0-9_.+-]+@[a-zA-Z0-9-]+\.[a-zA-Z0-9-.]+", text)), None)
entities["Phone"] = next(iter(re.findall(r"\+?\d[\d\s\-]{8,15}", text)), None)
# βœ… Extract Skills
entities["Skills"] = extract_skills(text)
# βœ… Section-based parsing
current_section = None
lines = text.split("\n")
for line in lines:
clean_line = line.strip()
if not clean_line:
continue
line_lower = clean_line.lower()
if "experience" in line_lower:
current_section = "Experience"
elif "project" in line_lower:
current_section = "Projects"
elif "certification" in line_lower:
current_section = "Certifications"
elif any(kw in line_lower for kw in edu_keywords):
entities["Education"].append(clean_line)
elif current_section:
entities[current_section].append(clean_line)
# βœ… Deduplicate list entries
for key in entities:
if isinstance(entities[key], list):
entities[key] = list(set(entities[key]))
return entities