我应该使用什么算法来基于简历数据进行工作分类?


28

请注意,我正在R中做所有事情。

问题如下:

基本上,我有一份简历列表。有些候选人以前有工作经验,有些则没有。这里的目标是:基于简历的文字,我想将其分类为不同的工作领域。在候选人没有任何经验/是学生的情况下,我尤其如此,我想做出一个预测,以分类该候选人毕业后最有可能属于哪个工作领域。

问题1:我知道机器学习算法。但是,我以前从未做过NLP。我在互联网上遇到了潜在的Dirichlet分配。但是,我不确定这是否是解决我的问题的最佳方法。

我的初衷是: 使这成为有监督的学习问题。假设我们已经有大量带标签的数据,这意味着我们已经正确标记了职位列表中的求职者。我们使用ML算法(即最近的邻居...)对模型进行训练,并输入那些没有工作经验的候选人/没有学生的未标记数据,并尝试预测他们将属于哪个工作领域。

更新 问题2:通过提取简历中的所有内容并在文本文件中打印这些数据来创建文本文件,这样每个简历都与一个包含非结构化字符串的文本文件相关联,是一个好主意吗?将文本挖掘技术应用于文本文件,并使数据结构化,甚至创建文本文件中使用的术语频率矩阵?例如,文本文件可能看起来像这样:

I deployed ML algorithm in this project and... Skills: Java, Python, c++ ...

这就是我所说的“非结构化”的意思,即将所有内容折叠成一个单行字符串。

这种方法是错误的吗?如果您认为我的方法有误,请纠正我。

问题3:棘手的部分是:如何识别和提取关键字tm在R中使用包?tm 软件包基于什么算法?我应该使用NLP算法吗?如果是,我应该看什么算法?请为我指出一些很好的资源以供参考。

任何想法都很棒。

Answers:


14

查看链接。

在这里,他们将引导您加载非结构化文本以创建wordcloud。您可以调整此策略,而不是创建单词云,而可以创建所用术语的频率矩阵。想法是采用非结构化文本并以某种方式对其进行结构化。您可以通过“文档术语表”将所有内容更改为小写(或大写),删除停用词并为每个作业功能查找常用术语。您还可以选择阻止单词。如果您阻止单词,您将能够检测到同一个单词的不同形式的单词。例如,可以将“已编程”和“编程”限制为“已编程”。您可以在ML模型训练中将这些频繁项的出现添加为加权特征。

您还可以将其调整为常用短语,为每个工作功能找到2-3个单词的共同组。

例:

1)加载库并构建示例数据

library(tm)
library(SnowballC)

doc1 = "I am highly skilled in Java Programming.  I have spent 5 years developing bug-tracking systems and creating data managing system applications in C."
job1 = "Software Engineer"
doc2 = "Tested new software releases for major program enhancements.  Designed and executed test procedures and worked with relational databases.  I helped organize and lead meetings and work independently and in a group setting."
job2 = "Quality Assurance"
doc3 = "Developed large and complex web applications for client service center. Lead projects for upcoming releases and interact with consumers.  Perform database design and debugging of current releases."
job3 = "Software Engineer"
jobInfo = data.frame("text" = c(doc1,doc2,doc3),
                     "job" = c(job1,job2,job3))

2)现在我们进行一些文本结构化。我很肯定有更快或更短的方法来进行以下操作。

# Convert to lowercase
jobInfo$text = sapply(jobInfo$text,tolower)

# Remove Punctuation
jobInfo$text = sapply(jobInfo$text,function(x) gsub("[[:punct:]]"," ",x))

# Remove extra white space
jobInfo$text = sapply(jobInfo$text,function(x) gsub("[ ]+"," ",x))

# Remove stop words
jobInfo$text = sapply(jobInfo$text, function(x){
  paste(setdiff(strsplit(x," ")[[1]],stopwords()),collapse=" ")
})

# Stem words (Also try without stemming?)
jobInfo$text = sapply(jobInfo$text, function(x)  {
  paste(setdiff(wordStem(strsplit(x," ")[[1]]),""),collapse=" ")
})

3)制作语料库和文档术语矩阵。

# Create Corpus Source
jobCorpus = Corpus(VectorSource(jobInfo$text))

# Create Document Term Matrix
jobDTM = DocumentTermMatrix(jobCorpus)

# Create Term Frequency Matrix
jobFreq = as.matrix(jobDTM)

现在我们有了频率矩阵jobFreq,它是一个(3 x)矩阵,3个条目和X个单词。

您从这里去的地方取决于您。您只能保留特定(更常见)的单词,并将它们用作模型中的特征。另一种方法是保持简单,并在每个职位描述中使用一定比例的单词,比如说“ java”在“软件工程师”中占80%,在“质量保证”中仅占50%。

现在是时候查询为什么“保证”具有1个“ r”而“出现”具有2个“ r”的原因了。


我很想看看你的榜样。
user1769197 2014年

更新了快速示例。
nfmcclure 2014年

11

只需提取关键字并在其上训练分类器即可。仅此而已。

个人简历中的大部分文字实际上与技能无关。例如考虑句子“我在Java方面经验丰富且高效”。在7个单词中,只有1个是技能名称,其余的只是噪音,会降低分类的准确性。

大多数简历并不是真正的结构化。或结构过于随意。或为部分使用不寻常的名称。或在转换为文本时不保留结构的文件格式。我有从非结构化文本中提取日期,时间,名称,地址甚至人的意图的经验,但没有技能(或大学或其他任何东西)列表,甚至没有很近。

因此,只需标记(并可能阻止)您的简历,从预定义列表中仅选择单词(您可以使用LinkedIn或类似的方法来获取此列表),创建特征向量并尝试几个分类器(例如SVM和Naive Bayes) 。

(请注意:我使用类似的方法将LinkedIn资料分为50多个类别,其准确率> 90%,所以我敢肯定,即使是幼稚的实施也能正常工作。)


假设我正在分析linkedin数据,您认为将以前的工作经验,教育建议和个人简介的技能合并到一个文本文件中并从中提取关键字对我来说是个好主意吗?
user1769197 2014年

LinkedIn现在具有人们可以自己分配的技能标签,其他用户也可以认可,因此基本上不需要手动提取关键字。但是在结构化数据较少的情况下-是的,合并所有内容然后检索关键字可能会有所帮助。但是,请记住主要规则:尝试一下。理论是好的,但是只有采用不同方法的实际实验才能揭示出最好的方法。
ffriend

@ffriend,我们如何获得该关键字列表?
NG_21 '16

1
@ffriend从以下句子中提取“ experience” =“ 5 years”,“ Language” =“ C”的最佳方法是什么。“我花了5年的时间来开发bug跟踪系统和使用C语言创建数据管理系统应用程序”。我将Rake与NLTK结合使用,它只是删除了停用词+标点符号,但是从上面的句子中我不需要诸如开发,错误跟踪,系统,创建,数据等之类的词。谢谢
Khalid Usman

3
@KhalidUsman:由于您已经使用NLTL,因此请查看命名实体识别工具,尤其是“使用正则表达式进行分类”部分。通常,您可能希望使用关键字词典(例如“ years”,“ C”等)和简单的规则集(例如“ contains'C'”或“ <number> years”)来提取命名实体不含格式的文字。
ffriend

7

这是一个棘手的问题。有很多处理方法。我想,简历可以看作是半结构化文档。有时,在文档中具有一些最小的结构是有益的。我相信,在简历中,您会看到一些表格数据。您可能希望将它们视为属性值对。例如,您将获得属性“技能集”的术语列表。

关键思想是手动配置关键短语的列表,例如“技能”,“教育”,“出版物”等。下一步是通过以某种方式利用结构来提取与这些关键短语有关的术语(例如(例如表格)或通过利用这些关键短语周围的术语接近性(例如,单词“ Java”与术语“技能”非常接近的事实)可能表明该人是Java熟练者。

提取这些信息后,下一步可能是为每个关键短语建立一个特征向量。然后,您可以将文档表示为具有不同字段的矢量(每个关键字一个)。例如,考虑以下以两个领域表示的两个简历,即项目教育

Doc1:{项目:(java,3)(c,4)},{教育程度:(计算机,2),(物理学,1)}

Doc2:{项目:(java,3)(python,2)},{教育程度:(数学,3),(计算机,2)}

在上面的示例中,我显示了带有频率的术语。当然,在提取术语时,您需要阻止和删除停用词。从示例中可以明显看出,简历是Doc1的人比D2的人在C方面更熟练。在实现方面,在Lucene中将文档表示为字段矢量非常容易。

现在,下一步是在给定工作说明的情况下检索简历的排名列表。实际上,如果您也将查询(作业规范)表示为字段向量,那将是相当简单的。您只需要使用Lucene从索引的简历集中检索候选人(简历)的排名列表。


算法方面:您会推荐什么?
user1769197 2014年

您的意思是给定查询工作向量时用于计算最相似的简历向量的算法?您可以使用任何标准算法,例如BM25或语言模型...
Debasis 2014年

我从未听说过这些算法。这些是NLP算法还是ML算法?
user1769197 2014年

这些是标准的检索模型...检索模型定义了如何计算文档(在您的情况下为简历)和查询(在您的情况下为工作)之间的相似度。
Debasis 2014年

我对信息检索一无所知,您是否认为像集群/最近邻居之类的机器学习算法也适用于我?
user1769197 2014年

7

我在一个在线工作网站上工作,我们建立解决方案以根据简历推荐工作。我们采用的方法是一个人的职务(如果是学生和知名人士,则为所需的职务),以及我们从其简历中提取的技能及其位置(对大多数人而言非常重要),然后根据该职务找到与之匹配的人。

在文档分类方面,我将采用类似的方法。我建议为每个简历计算一个tf idf矩阵作为标准的单词模型模型,仅提取该人的职位和技能(您将需要定义要查找的技能列表),并将其输入到ML中算法。我建议您尝试使用knn和SVM,后者支持高维文本数据。线性SVM的性能往往优于非线性(例如,使用RBf内核)。如果您能够输出合理的结果,那么我将使用自然语言解析器\块处理程序以及一些与regex匹配的自定义构建短语来提取特征。


当您拥有3个或更多类时,您仍在使用SVM吗?您想使用自然语言解析器提取哪些功能?出于什么目的 ?
user1769197 2014年

您可以使用一个vs其余策略训练n个类的n个svm。SciKitLearn具有自动执行此操作的代码。从技术上讲,您需要n-1个分类器,但是我发现拥有n个分类器效果更好。
西蒙(Simon)

@Simon您可以编写此推荐系统的完整步骤吗?我在ML方面经验很少(实施MS论文),但是在IR领域却是全新的。现在,我正在此系统上工作,并编写了以下步骤。1.使用NLTK提取关键字,2.计算关键字和短语的得分,3.词干,4.分类(最具挑战性的任务),以及5.频率矩阵,tf-idf或BM25算法。我是否采用正确的实施方式?谢谢
Khalid Usman

@KhalidUsman我无法确切告诉您它是如何工作的,这可能会给我带来麻烦。最简单的解决方案是将数据放入Solr或Elastic Search中并使用其MLT推荐程序实现。一种更复杂的方法是提取关键字和短语,通过LSA推送文档,并对所得向量进行k-nn运算。然后,您可能希望使用其他信号,例如“协同过滤”和整体流行度。
西蒙(Simon)

@Simon,感谢您的指导。我正在应用第二种方法,我已经使用RAKE + NLTK提取了关键字/关键词,之后我打算应用tf-idf或BM25。我对吗?您能否详细说明一下KNN的方式,我的意思是如何在关键字上应用knn,我是否应该将关键字作为功能?感谢
Khalid Usman
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.