Spaces:
Runtime error
Runtime error
File size: 3,901 Bytes
b8b3ced | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 | import spacy
from rapidfuzz import process
from nltk import ngrams
from nltk.tokenize import word_tokenize
from huggingface_hub import snapshot_download
class SkillListMatcher:
"""
Provides methods to extract and match skills from text.
"""
def __init__(self, spacy_model= "en_core_web_sm"):
"""
Initializes the matcher and loads the spaCy model.
:param spacy_model: Name of the spaCy model to load.
"""
if not spacy.util.is_package(spacy_model):
spacy.cli.download(spacy_model)
self.nlp = spacy.load(spacy_model)
def __lemmatization(self, skills):
"""
Lemmatizes a list of skills.
:param skills: List of skill strings.
:return: List of lemmatized skills.
"""
new_skills = []
for i in range(len(skills)):
skill = skills[i]
doc = self.nlp(skill)
tokens = [token.lemma_ for token in doc]
new_skills.append(" ".join(tokens).lower().strip())
return new_skills
def extract(self, text, skills, threshold=95):
"""
Extracts relevant skills from the given text.
:param text: The input text.
:param skills: List of reference skill strings.
:param threshold: Threshold for matching skills.
:return: List of matched skills found in the text.
"""
text = text.lower()
tokens = word_tokenize(text)
candidates = set()
for n in range(1, 5):
for gram in ngrams(tokens, n):
phrase = ' '.join(gram)
candidates.add(phrase)
new_skills = self.__lemmatization(skills)
found_skills = set()
for phrase in candidates:
match, score, _ = process.extractOne(phrase, new_skills)
if score >= threshold:
found_skills.add(match)
return list(found_skills)
def match(self, main_skills, extract_skills):
"""
Matches extracted skills with main skills.
:param main_skills: List of target skill strings.
:param extract_skills: List of extracted skill strings.
:return: Tuple of match ratio and formatted match string.
"""
main_skills = self.__lemmatization(main_skills)
extract_skills = self.__lemmatization(extract_skills)
count = 0
for skill in extract_skills:
if skill in main_skills:
count += 1
return count / len(main_skills), f"{count}/{len(main_skills)}"
class SkillDynamicMatcher:
"""
Extracts and matches skills using a trained spaCy NER model.
"""
def __init__(self, model_path="amjad-awad/skill-extractor"):
"""
Initializes the NER model from the specified path.
:param model_path: Path to the trained NER model.
"""
model_path = snapshot_download(model_path, repo_type="model")
self.ner_model = spacy.load(model_path)
def extract(self, text):
"""
Extracts skill entities from the input text.
:param text: The input text.
:return: List of extracted skill entities.
"""
skills = []
doc = self.ner_model(text)
for ent in doc.ents:
if "SKILLS" in ent.label_:
skills.append(ent.text.lower())
return list(set(skills))
def match(self, main_skills, extract_skills):
"""
Matches extracted skills with main skills.
:param main_skills: List of target skill strings.
:param extract_skills: List of extracted skill strings.
:return: Tuple of match ratio and formatted match string.
"""
count = 0
for skill in extract_skills:
if skill in main_skills:
count += 1
return count / len(main_skills), f"{count}/{len(main_skills)}" |