JD简历语义匹配
创建于:2024年11月18日
使用 O1 Preview 回答 Chat01
创建于:2024年11月18日
使用 O1 Preview 回答 Chat01
nlp 语义匹配,实现 岗位 jd 和简历内容匹配
要实现岗位 JD(职位描述)与简历内容的语义匹配,可以利用自然语言处理(NLP)技术,从而评估求职者的简历与特定岗位的契合度。以下是一个可能的实现步骤:
pythonfrom sentence_transformers import SentenceTransformer, util # 加载预训练模型 model = SentenceTransformer('paraphrase-MiniLM-L6-v2') # 示例JD和简历 job_description = "我们正在寻找一位精通Python和数据分析的工程师。" resume = "拥有丰富的Python编程经验,擅长数据分析和机器学习。" # 转换为向量 jd_embedding = model.encode(job_description, convert_to_tensor=True) resume_embedding = model.encode(resume, convert_to_tensor=True) # 计算相似度 cosine_scores = util.pytorch_cos_sim(jd_embedding, resume_embedding) print(f"匹配度:{cosine_scores.item() * 100:.2f}%")
通过以上步骤,您可以构建一个基本的JD与简历匹配系统。当然,实际应用中可能需要考虑更多的细节和优化,如处理多语言、应对大规模数据等。
按照你给出的流程,帮我实现整个代码
好的,按照之前的流程,我将帮助您实现一个完整的岗位JD与简历内容的语义匹配代码。我们将使用Python和相关的NLP库,如jieba
、sentence-transformers
等。以下是详细的实现步骤:
首先,确保您的环境中安装了以下库:
bashpip install jieba pip install sentence-transformers
如果您需要处理大型数据集,建议安装GPU版本的torch
:
bashpip install torch torchvision torchaudio --index-url https://download.pytorch.org/whl/cu117
pythonimport jieba import jieba.analyse import re from sentence_transformers import SentenceTransformer, util
pythondef clean_text(text): # 去除HTML标签 text = re.sub(r'<[^>]+>', '', text) # 去除标点符号和特殊字符 text = re.sub(r'[^\w\s]', '', text) # 去除数字 text = re.sub(r'\d+', '', text) # 去除多余的空格 text = text.strip() return text
pythondef tokenize(text): # 分词 words = jieba.lcut(text) # 加载中文停用词表 stopwords = set() with open('stopwords.txt', 'r', encoding='utf-8') as f: for line in f: stopwords.add(line.strip()) # 去停用词 words = [word for word in words if word not in stopwords] return words
注意:请确保在当前目录下有一个名为stopwords.txt
的中文停用词表。您可以从这里下载。
pythonmodel = SentenceTransformer('shibing624/text2vec-base-chinese')
说明:text2vec-base-chinese
是一个适用于中文的预训练Sentence-BERT模型。
pythondef get_sentence_embedding(text): # 清洗文本 clean = clean_text(text) # 分词并重新组合为字符串(可选) tokens = tokenize(clean) processed_text = ' '.join(tokens) # 获取文本向量 embedding = model.encode(processed_text, convert_to_tensor=True) return embedding
pythondef calculate_similarity(embedding1, embedding2): # 计算余弦相似度 cosine_scores = util.cos_sim(embedding1, embedding2) return cosine_scores.item()
pythonjob_description = """ 我们公司正在招聘一名数据分析师,需要熟练掌握Python和SQL,具备机器学习和统计学背景。有大数据处理经验者优先。 """ resume = """ 拥有三年数据分析经验,精通Python编程,熟悉SQL数据库。曾参与机器学习项目,有处理大规模数据的经验。 """
pythonif __name__ == '__main__': # 获取向量表示 jd_embedding = get_sentence_embedding(job_description) resume_embedding = get_sentence_embedding(resume) # 计算相似度 similarity_score = calculate_similarity(jd_embedding, resume_embedding) print(f"匹配度:{similarity_score * 100:.2f}%")
假设运行上述代码,可能会得到如下输出:
匹配度:85.67%
这表示简历与JD的匹配度为85.67%。
为了方便,以下是上述所有代码的整合:
pythonimport jieba import jieba.analyse import re from sentence_transformers import SentenceTransformer, util def clean_text(text): text = re.sub(r'<[^>]+>', '', text) text = re.sub(r'[^\w\s]', '', text) text = re.sub(r'\d+', '', text) text = text.strip() return text def tokenize(text): words = jieba.lcut(text) stopwords = set() with open('stopwords.txt', 'r', encoding='utf-8') as f: for line in f: stopwords.add(line.strip()) words = [word for word in words if word not in stopwords] return words model = SentenceTransformer('shibing624/text2vec-base-chinese') def get_sentence_embedding(text): clean = clean_text(text) tokens = tokenize(clean) processed_text = ' '.join(tokens) embedding = model.encode(processed_text, convert_to_tensor=True) return embedding def calculate_similarity(embedding1, embedding2): cosine_scores = util.cos_sim(embedding1, embedding2) return cosine_scores.item() if __name__ == '__main__': job_description = """ 我们公司正在招聘一名数据分析师,需要熟练掌握Python和SQL,具备机器学习和统计学背景。有大数据处理经验者优先。 """ resume = """ 拥有三年数据分析经验,精通Python编程,熟悉SQL数据库。曾参与机器学习项目,有处理大规模数据的经验。 """ jd_embedding = get_sentence_embedding(job_description) resume_embedding = get_sentence_embedding(resume) similarity_score = calculate_similarity(jd_embedding, resume_embedding) print(f"匹配度:{similarity_score * 100:.2f}%")
stopwords.txt
文件。SentenceTransformer
会自动下载预训练模型,可能需要一些时间。job_description
和resume
的内容。希望以上代码能够帮助您实现JD与简历的语义匹配。如有疑问,欢迎提问。
实现完善优雅,可以直接使用的代码
好的,我将为您提供一个完善、优雅、可直接使用的Python代码,实现岗位JD与简历内容的语义匹配。这个代码将包括:
<a name="环境准备"></a>
确保您的Python版本为3.6或更高。安装必要的库:
bashpip install jieba pip install sentence-transformers pip install torch
注意:sentence-transformers
依赖于torch
,建议根据您的硬件环境安装对应版本的torch
(CPU或GPU)。
<a name="代码结构"></a>
我们将创建一个ResumeMatcher
类,包含以下方法:
__init__
:初始化,加载模型和停用词表。clean_text
:文本清洗。tokenize
:分词和去停用词。get_embedding
:获取文本向量表示。calculate_similarity
:计算相似度。match
:对外接口,输入JD和简历,输出匹配度。<a name="主要功能实现"></a>
pythonclass ResumeMatcher: def __init__(self, model_name='shibing624/text2vec-base-chinese', stopwords_path=None): import jieba from sentence_transformers import SentenceTransformer self.jieba = jieba self.model = SentenceTransformer(model_name) self.stopwords = set() if stopwords_path: self.load_stopwords(stopwords_path)
pythondef load_stopwords(self, filepath): try: with open(filepath, 'r', encoding='utf-8') as f: for line in f: self.stopwords.add(line.strip()) except Exception as e: print(f"加载停用词表失败:{e}")
pythondef clean_text(self, text): import re text = re.sub(r'<[^>]+>', '', text) # 去除HTML标签 text = re.sub(r'[^\w\s]', '', text) # 去除标点符号和特殊字符 text = re.sub(r'\d+', '', text) # 去除数字 text = text.strip() return text
pythondef tokenize(self, text): words = self.jieba.lcut(text) if self.stopwords: words = [word for word in words if word not in self.stopwords] return words
pythondef get_embedding(self, text): clean = self.clean_text(text) tokens = self.tokenize(clean) processed_text = ' '.join(tokens) embedding = self.model.encode(processed_text, convert_to_tensor=True) return embedding
pythondef calculate_similarity(self, embedding1, embedding2): from sentence_transformers.util import cos_sim cosine_scores = cos_sim(embedding1, embedding2) return float(cosine_scores)
pythondef match(self, jd_text, resume_text): try: jd_embedding = self.get_embedding(jd_text) resume_embedding = self.get_embedding(resume_text) similarity = self.calculate_similarity(jd_embedding, resume_embedding) return similarity except Exception as e: print(f"匹配过程中出现错误:{e}") return None
<a name="使用示例"></a>
pythonif __name__ == '__main__': # 初始化匹配器,指定停用词表路径 matcher = ResumeMatcher(stopwords_path='stopwords.txt') # 示例JD和简历 job_description = """ 我们公司正在招聘一名数据分析师,需要熟练掌握Python和SQL,具备机器学习和统计学背景。有大数据处理经验者优先。 """ resume = """ 拥有三年数据分析经验,精通Python编程,熟悉SQL数据库。曾参与机器学习项目,有处理大规模数据的经验。 """ # 计算匹配度 similarity_score = matcher.match(job_description, resume) if similarity_score is not None: print(f"匹配度:{similarity_score * 100:.2f}%") else: print("无法计算匹配度。")
输出示例:
匹配度:85.67%
<a name="完整代码"></a>
pythonimport re import jieba from sentence_transformers import SentenceTransformer from sentence_transformers.util import cos_sim class ResumeMatcher: def __init__(self, model_name='shibing624/text2vec-base-chinese', stopwords_path=None): """ 初始化匹配器,加载模型和停用词表。 :param model_name: SentenceTransformer预训练模型名称 :param stopwords_path: 停用词表文件路径 """ self.model = SentenceTransformer(model_name) self.stopwords = set() if stopwords_path: self.load_stopwords(stopwords_path) def load_stopwords(self, filepath): """ 加载停用词表。 :param filepath: 停用词表文件路径 """ try: with open(filepath, 'r', encoding='utf-8') as f: for line in f: self.stopwords.add(line.strip()) except Exception as e: print(f"加载停用词表失败:{e}") def clean_text(self, text): """ 清洗文本。 :param text: 原始文本 :return: 清洗后的文本 """ text = re.sub(r'<[^>]+>', '', text) # 去除HTML标签 text = re.sub(r'[^\w\s]', '', text) # 去除标点符号和特殊字符 text = re.sub(r'\d+', '', text) # 去除数字 text = text.strip() return text def tokenize(self, text): """ 分词并去停用词。 :param text: 文本字符串 :return: 分词后的词列表 """ words = jieba.lcut(text) if self.stopwords: words = [word for word in words if word not in self.stopwords] return words def get_embedding(self, text): """ 获取文本的向量表示。 :param text: 文本字符串 :return: 向量表示 """ clean = self.clean_text(text) tokens = self.tokenize(clean) processed_text = ' '.join(tokens) embedding = self.model.encode(processed_text, convert_to_tensor=True) return embedding def calculate_similarity(self, embedding1, embedding2): """ 计算两个向量的余弦相似度。 :param embedding1: 向量1 :param embedding2: 向量2 :return: 相似度得分 """ cosine_scores = cos_sim(embedding1, embedding2) return float(cosine_scores) def match(self, jd_text, resume_text): """ 计算JD和简历的匹配度。 :param jd_text: 职位描述文本 :param resume_text: 简历文本 :return: 匹配度得分 """ try: jd_embedding = self.get_embedding(jd_text) resume_embedding = self.get_embedding(resume_text) similarity = self.calculate_similarity(jd_embedding, resume_embedding) return similarity except Exception as e: print(f"匹配过程中出现错误:{e}") return None if __name__ == '__main__': # 初始化匹配器,指定停用词表路径 matcher = ResumeMatcher(stopwords_path='stopwords.txt') # 示例JD和简历 job_description = """ 我们公司正在招聘一名数据分析师,需要熟练掌握Python和SQL,具备机器学习和统计学背景。有大数据处理经验者优先。 """ resume = """ 拥有三年数据分析经验,精通Python编程,熟悉SQL数据库。曾参与机器学习项目,有处理大规模数据的经验。 """ # 计算匹配度 similarity_score = matcher.match(job_description, resume) if similarity_score is not None: print(f"匹配度:{similarity_score * 100:.2f}%") else: print("无法计算匹配度。")
<a name="注意事项"></a>
stopwords.txt
停用词表文件存在。您可以从这里下载常用的中文停用词表。SentenceTransformer
会自动下载预训练模型,可能需要一些时间和网络流量。ResumeMatcher
时,传入自定义的模型名称和停用词表路径。<a name="参考资料"></a>
总结:通过以上代码,您可以直接实现岗位JD与简历内容的语义匹配。代码采用模块化设计,方便扩展和维护。如需处理批量数据,您可以在此基础上进行修改,或将match
方法改为支持批量输入。
如果您有任何疑问或需要进一步的帮助,请随时提问。