大数据职位招聘信息挖掘

唐雨馨 邬成浩 黄宇婷 徐园 李杨晓

随着互联网行业的快速发展、计算机硬件和软件能力的不断提升,大数据技术应运而生。大数据技术现已被应用到各行各业,各大互联网公司对大数据人才的需求也越来越多。如何引导相关从业人员正确的选择岗位,找到让自己满意的工作也就显得尤为重要。 本项目通过爬虫获取主流招聘网站大数据相关职位的招聘信息,对其进行数据挖掘和数据分析,探索大数据岗位的核心需求是什么,以及挖掘出不同城市、不同企业等对大数据岗位待遇的影响。旨在帮助求职者分析当前大数据行业的求职趋势。

同时,该项目还对各招聘信息的企业人才需求画像进行了建模,该模型能通过求职者的基本信息(渴望薪资、学历、工作经验等),生成可求职企业的基本画像。该功能可以帮助各招聘门户网站完善其求职搜索功能,在用户进行搜索后迅速缩小适合企业的范围,进行更加迅速有效的职位推荐。

1 数据获取

代码地址

通过爬虫爬取数据,从主流门户网站(智联招聘)上爬取大数据相关职位的招聘信息(包括职位地点、公司名称、公司性质、公司融资级别、职位空缺、薪资、福利、需求学历、需求工作经验等)。

数据来源

智联招聘上大数据相关的招聘信息。

爬虫设计

用scrapy-redis框架对智联招聘网站中的大数据相关职位进行了爬取。爬虫采用分布式双向爬取,分为master-slaver两端。master节点通过将需要爬取的url存放到redis缓存队列来调度各个slaver节点来爬取数据,slaver节点将爬取到的数据写入到数据库。爬虫架构如下图所示。


爬虫架构

最终爬取到的数据共49248行,13列。

数据说明

最终爬取到的数据共49248行,13列。

  • j_name职位名称

  • c_name公司名称

  • c_nature公司性质

  • c_scale公司规模

  • description岗位描述(岗位要求)

  • w_place工作地点

  • w_filed职位类别

  • w_experience要求的经验

  • education要求的学历

  • s_min最低工资

  • s_max最高工资

  • vacancies职位空缺

  • welfare福利

2 数据预处理

代码地址

数据预处理部分对爬虫爬到的数据进行去重,筛选,缺失值填补,概念分层,预处理后处理成合适的格式,方便进行数据挖掘。

2.1 数据去重

在数据分析过程中,原始数据常常会有一些重复的记录,因此数据去重是必不可少的一个步骤。针对数据集,自定义去重规则,删除重复行并对数据进行整合。 针对所爬取的数据集,将职位名称(j_name)和公司名称(c_name)同时相同的定义为重复数据。采用pandas提供的drop_duplicate方法对数据进行去重。

处理前数据量为49248行,13列;去重后数据量为39397行,13列。

2.2 数据去噪

实际数据是数据挖掘算法的输入,它受多个组件的影响。其中,噪声的存在是关键因素。噪声是不可避免的问题,它会影响数据挖掘应用程序中经常发生错误的数据收集和数据准备过程。噪声有两个主要来源:隐式错误由测量工具引入;以及批处理或专家在收集数据时引入的随机错误。 针对所爬取的数据集进行分析,可看出数据集中包含了许多非大数据相关职业的数据。我们采取自定义筛选规则,将不符合要求的数据筛选掉。主要对属性职位名称(j_name)和职位类别(w_field)进行筛选,筛选掉含有某些字段的数据(例如含有字段:软件测试销售运营商务等),最后进行数据整合。 使用pandas数据包中自带函数,筛选掉含有特殊字段的数据,再筛选后的数据合并起来。

去噪前数据量为39397行,13列,去噪后数据量为19872行,13列。

2.3 缺失值处理

数据值缺失是数据分析中经常遇到的问题之一,当缺失比例很小时,可直接对缺失记录进行舍弃或进行手工处理。但在实际数据中,往往缺失数据占有相当的比重。这时如果手工处理非常低效,如果舍弃缺失记录,则会丢失大量信息,使不完全观测数据与完全观测数据间产生系统差异,对这样的数据进行分析,你很可能会得出错误的结论。

针对去噪后数据集进行缺失值统计,其中没有分层的数值属性(s_min,s_max,vacancies)中出现的非数字项(如"面议""若干")视为缺失值。对于s_mins_max这两列中包含一含有中文的项,其实为带单位的数值,处理后以正常的表现形式填入。最终统计结果如下:

属性 缺失值个数
j_name 0
c_name 14
c_nature 5933
c_scale 5850
description 5796
w_place 0
w_field 2
w_experience 0
education 0
s_min 639
s_max 639
vacancies 5952
welfare 7532

接下来需要分别对以上属性进行缺失值处理。

  • s_mins_maxvacancies

    对于这三个属性,首先将属性转换成float类型,采用最高频率值填补缺失值。

  • c_name

    由于c_name的缺失值只有14个,在数据集中占比非常小,对于c_name属性缺失的数据行直接删除。

  • description

    对于description属性缺失的数据行采用该行j_name进行填补。

  • c_naturec_scalewelfare

    c_naturec_scalewelfare利用数据属性的相关性填补。即用拥有同一其它属性的行的这列的值填补,比如A公司的两条数据i1,i2。i1缺少福利描述,由于i2的公司和i1的公司相同,将i2的福利描述填入i1。若没有与缺失数据公司名相同的数据或者所有相同公司名的数据福利描述均为缺失,则将福利描述填入最高频率值。

2.4 可视化概览

企业性质

缺失值处理前

In [9]:
bar.render_notebook()
Out[9]:

缺失值处理后

In [18]:
bar.render_notebook()
Out[18]:

企业规模

缺失值处理前

In [21]:
bar.render_notebook()
Out[21]:

缺失值处理后

In [25]:
bar.render_notebook()
Out[25]:

学历

In [30]:
bar.render_notebook()
Out[30]:

工作经验

In [46]:
bar.render_notebook()
Out[46]:

职位需求

首先对属性岗位描述(岗位要求)(description)进行粗粒度的分词,并将分词结果保存。在此调用腾讯TexSmart HTTP API进行粗粒度分词。

对分词后的description采用wordcloud工具包进行词云生成:


职位需求词云

可以看出大数据岗位对于 分析、业务、大数据平台、团队能力、数据库操作等具有较高的需求。

公司福利

对welfare采用wordcloud工具包进行词云生成:


公司福利词云

可以看出大数据岗位均会提供 五险一金、节日福利、带薪年假、定期体检、绩效奖金等。

3 数据分析与关联挖掘

代码地址

3.1 概念分层

完整代码版报告

在此将对最低工资(s_min),最高工资(s_max),职位空缺进行概念属性分层。
对于最低工资与最高工资,我们都将其分为四层,分别为:

  • 小于等于6k
  • 大于6k,小于等于10k
  • 大于10k,小于等于16k
  • 大于16k

对于职位空缺,将其分为3层,分别为:

  • 等于1
  • 大于1,小于等于5
  • 大于5

最终分层后的分布如下图所示:

In [178]:
grid.render_notebook()
Out[178]:

我们可以从图中观察到,大多数企业对于最低薪资还是在6k-10k之间,而最高薪资在16k以上。而对于企业招聘而言,应聘者竞争压力较大,因为绝大多数企业的空缺职位都为1。

3.2 企业画像

完整代码版报告

3.2.1 企业概况 - 有大数据需求的企业都是些什么背景?

首先来了解一下,招聘大数据行业人才的企业的基本情况,了解这些有大数据需求的企业在公司性质、公司规模、地理这些维度的分布情况。

In [48]:
bar.render_notebook()
Out[48]:

对于8979家对大数据有需求的企业,上图反应了其公司性质分布,我们可以从图中观察到,在大数据相关企业中,民营企业是最多的,这符合我国国情。另外对大数据有迫切需求的分别是股份制企业、上市公司、国企、合资公司等,每种企业数量均超过了300家,另外我们还可以观察到,下至社会团体,上至国家机关,对大数据都有需求。

In [49]:
pie.render_notebook()
Out[49]:

在这8979家企业中,中型企业(100-499人)占了大多数,超过了4000家,小型企业(20-99人)和大型企业(1000-9999人)也占了不少的比重,将近达到3000家,另外可以观察到初创业(20人以下)和超大型企业(10000)也均对大数据有需求,公司数量均超过了200家。

In [52]:
m.render_notebook()
Out[52]:

上图显示了这8979家企业的地理分布,可以观察到,在北京大数据公司数量最多,超过了2000家,上海等一些发达城市(成都、重庆)及沿海城市(深圳,杭州)的大数据公司也非常密集,均超过了80多家。整体来看,大数据公司的分布有着围绕着经济中心逐渐下降,从沿海到内地逐渐下降等趋势。

3.2.2 企业与薪资 - 什么样的企业给的薪酬最高?

概况
In [59]:
c = draw_heat(gp,gp.values.max())
c.render_notebook()
Out[59]:

上图展示了不同性质和不同规模的企业,对大数据岗位给出的平均薪资(单位k/月),首先可以看见最高的竟然是一个20人以下的上市公司,这是因为20人以下的上市公司比较少,这家公司也比较特殊,并不具有非常明确的代表性,可以忽略这行数据。对于总体来看,其实可以发现不同性质对和不同规模的公司对大数据职位开出的薪资并没有相差太多,均在12k-15k左右,说明大数据需求是硬性需求,各种性质和规模的企业都不敢轻易忽视其地位。

对比不同性质的企业,港澳台公司给出的平均月薪资最高,为17k/月,其中最高的为港澳台的大型公司,给出平均月薪达到24k,最低的为社会团体,平均6k/月。

In [60]:
print("开出最高薪资(150k)的企业如下:")
data[data.s_max == data.s_max.max()].c_name
开出最高薪资(150k)的企业如下:
Out[60]:
277       深圳市快乐人生人力资源有限公司 
654                    中电科
1072     北京信赢荣智企业管理咨询有限公司 
1868      浙江数秦科技有限公司北京分公司 
3239         甘肃思扬网络教育有限公司 
3354         山东纬横数据科技有限公司 
3694         海南易建科技股份有限公司 
3963         西安泽源信息科技有限公司 
4329    上海钧钰互联网金融信息服务有限公司 
4422        湖北聚一线网络开发有限公司 
4865       北京希嘉创智教育科技有限公司 
4959       武汉凯欣隆钢结构工程有限公司 
5544         河北有为文化传媒有限公司 
8490        扬州思亿欧网络科技有限公司 
8503     江苏南大电子信息技术股份有限公司 
Name: c_name, dtype: object
In [61]:
print("收入最高薪资(150k)的职业如下:")
data[data.s_max == data.s_max.max()].j_name
收入最高薪资(150k)的职业如下:
Out[61]:
277           财务大数据总监
654          首席战略官CSO
1072           技术副总经理
1868    集团副总裁/执行总裁/VP
3239     分公司总经理/区域合作方
3354        java高级工程师
3694           资深外贸业务
3963       云平台高级开发工程师
4329       理财公司(副总经理)
4422         大数据研发工程师
4865          后端开发工程师
4959          后端开发工程师
5544         科技产品城市代理
8490          博士后科研人员
8503       人工智能产品营销经理
Name: j_name, dtype: object
关联挖掘
In [65]:
from mlxtend.frequent_patterns import apriori
frequent_items = apriori(c_s, min_support=0.05, use_colnames=True, max_len=4).sort_values(by='support', ascending=False)	
frequent_items.head(10)
Out[65]:
support itemsets
11 0.676705 (民营)
0 0.563652 (100-499人)
16 0.454678 (民营, 100-499人)
8 0.357085 (a4)
7 0.293182 (a3)
23 0.284722 (a4, 民营)
15 0.255413 (a4, 100-499人)
6 0.231796 (a2)
26 0.231141 (a4, 民营, 100-499人)
22 0.181136 (a3, 民营)
In [68]:
rules = get_rules(frequent_items)
rules.head(10)
Out[68]:
antecedents consequents antecedent support consequent support support confidence lift cosine Jaccard Allconf Maxconf Kulczynski
0 (100-499人) (a4, 民营) 0.563652 0.284722 0.231141 0.410078 1.440277 0.576981 0.374480 0.410078 0.811815 0.610946
1 (a4, 民营) (100-499人) 0.284722 0.563652 0.231141 0.811815 1.440277 0.576981 0.374480 0.410078 0.811815 0.610946
2 (民营, 100-499人) (a4) 0.454678 0.357085 0.231141 0.508362 1.423643 0.573640 0.398092 0.508362 0.647299 0.577831
3 (a4) (民营, 100-499人) 0.357085 0.454678 0.231141 0.647299 1.423643 0.573640 0.398092 0.508362 0.647299 0.577831
4 (20-99人) (a2) 0.180330 0.231796 0.057609 0.319464 1.378213 0.281776 0.162500 0.248534 0.319464 0.283999
5 (a2) (20-99人) 0.231796 0.180330 0.057609 0.248534 1.378213 0.281776 0.162500 0.248534 0.319464 0.283999
6 (民营) (a4, 100-499人) 0.676705 0.255413 0.231141 0.341569 1.337317 0.555976 0.329741 0.341569 0.904968 0.623269
7 (a4, 100-499人) (民营) 0.255413 0.676705 0.231141 0.904968 1.337317 0.555976 0.329741 0.341569 0.904968 0.623269
8 (a4) (100-499人) 0.357085 0.563652 0.255413 0.715273 1.268997 0.569315 0.383893 0.453140 0.715273 0.584207
9 (100-499人) (a4) 0.563652 0.357085 0.255413 0.453140 1.268997 0.569315 0.383893 0.453140 0.715273 0.584207

导出的关联规则说明:

  • 规模为100-499人的中型民营企业一般对大数据行业岗位开出的薪资为17k左右。
  • 规模为100-499人的中型企业对大数据行业岗位开出的平均薪资为17k左右。
  • 规模为20-99人的小型企业对大数据行业岗位开出的平均薪资为7k-10k之间。

规则评价

下图给出了导出关联规则的置信度、支持度以及Lift的散点图。

In [70]:
s = draw_scatter(rules)
s.render_notebook()
Out[70]:

3.2.3 企业与职位需求量 - 什么样的企业对大数据人才的需求更高?

概况
In [75]:
vh = draw_heat(gp,2000)
vh.render_notebook()
Out[75]:

在19748条招聘信息中,由于我国民营企业占了大多数,所以自然的民营企业对大数据行业的需求是最紧缺的,一共有35180职位空缺;上市公司和股份制企业对大数据人才的需求也非常迫切,职位空缺均超过了4000人;合资企业和国企招收大数据职位空缺将近3000人。

对于不同规模的企业,职位空缺并不是完全集中在超大型公司(10000人以上),而是更多的分布在中大型企业(100-9999人)中。

关联挖掘
In [76]:
frequent_items = apriori(c_v, min_support=0.05, use_colnames=True, max_len=4).sort_values(by='support', ascending=False)	
rules = get_rules(frequent_items)
rules.head(10)
Out[76]:
antecedents consequents antecedent support consequent support support confidence lift cosine Jaccard Allconf Maxconf Kulczynski
0 (20-99人) (v2, 民营) 0.180330 0.151878 0.059724 0.331192 2.180643 0.360883 0.219183 0.331192 0.393236 0.362214
1 (v2, 民营) (20-99人) 0.151878 0.180330 0.059724 0.393236 2.180643 0.360883 0.219183 0.331192 0.393236 0.362214
2 (v2) (20-99人, 民营) 0.272837 0.132037 0.059724 0.218900 1.657862 0.314665 0.173038 0.218900 0.452326 0.335613
3 (20-99人, 民营) (v2) 0.132037 0.272837 0.059724 0.452326 1.657862 0.314665 0.173038 0.218900 0.452326 0.335613
4 (20-99人) (v2) 0.180330 0.272837 0.080421 0.445965 1.634546 0.362563 0.215752 0.294758 0.445965 0.370362
5 (v2) (20-99人) 0.272837 0.180330 0.080421 0.294758 1.634546 0.362563 0.215752 0.294758 0.445965 0.370362
6 (100-499人) (民营, v1) 0.563652 0.467268 0.363884 0.645582 1.381611 0.709046 0.545523 0.645582 0.778748 0.712165
7 (民营, v1) (100-499人) 0.467268 0.563652 0.363884 0.778748 1.381611 0.709046 0.545523 0.645582 0.778748 0.712165
8 (v1, 100-499人) (民营) 0.416558 0.676705 0.363884 0.873549 1.290887 0.685370 0.498895 0.537729 0.873549 0.705639
9 (民营) (v1, 100-499人) 0.676705 0.416558 0.363884 0.537729 1.290887 0.685370 0.498895 0.537729 0.873549 0.705639

导出的关联规则说明:

  • 规模为20-99人的小型民营企业每个职位平均空缺为2-5人。
  • 规模为100-499人的中型民营企业每个职位平均空缺为1人。
  • 规模为20-99人的小型企业每个职位平均空缺为2-5人。

规则评价

下图给出了导出关联规则的置信度、支持度以及Lift的散点图。

In [77]:
sv = draw_scatter(rules)
sv.render_notebook()
Out[77]:

3.3 大数据行业个人画像

完整代码地址

3.3.1 个人能力概况 - 企业对人才的要求是怎样的?

首先从工作经验和教育背景两方面了解大数据行业所需要的个人能力基本情况。

In [80]:
bar.render_notebook()
Out[80]:

对于8979家对大数据有需求的企业,上图反应了这些公司对人才工作经验方面的要求,可以发现多数公司要求有1-5年的工作经验,占到了公司总数的一半,也有大约20%的公司对工作经验没有限制,比较灵活,这可能包含校招或转岗的部分。

In [82]:
pie.render_notebook()
Out[82]:

从图中我们看到,一半以上的大数据企业要求应聘者至少有本科学历,大约20%的企业要求至少大专学历,这表明企业对学历的要求是比较宽松的,推测是由于大数据行业比较注重实践能力,大多数对高学历没有硬性要求。

3.3.2 个人能力与薪资 - 什么样的人才薪酬最高?

概况
In [84]:
c = draw_heat(gp,gp.values.max())
c.render_notebook()
Out[84]:

上图展示了不同工作经验及学历所对应的平均薪资(k/月),很明显,博士工作经验3-5年的薪资水平最高,硕士工作十年以上的薪资紧随其后,这表明虽然大多数公司对硕士、博士学历没有硬性要求,但是在同等工作经验条件下,拥有更高学历的人才所获得薪资也会更高。同时在工作经验方面,我们也能看到,工作十年以上的人才对应的平均薪资最高,其次是5-10年,3-5年,推测在大数据方向工作时间越久,专业技术能力越强,累积的经验越多,对于新任务也更容易上手,所以公司为这类人才提供更高的薪资。

In [85]:
print("最高薪资(150k)对应的工作经验及学历如下:")
data[data.s_max == data.s_max.max()][['w_experience','education']]
最高薪资(150k)对应的工作经验及学历如下:
Out[85]:
w_experience education
277 不限 不限
654 10年以上 硕士
1072 5-10年 硕士
1868 10年以上 硕士
3239 不限 不限
3354 3-5年 本科
3694 不限 本科
3963 不限 不限
4329 5-10年 大专
4422 不限 大专
4865 5-10年 本科
4959 5-10年 本科
5544 3-5年 大专
8490 不限 博士
8503 不限 不限
关联挖掘
In [88]:
frequent_items = apriori(c_s, min_support=0.05, use_colnames=True, max_len=4).sort_values(by='support', ascending=False)	
frequent_items.head(10)
Out[88]:
support itemsets
11 0.622570 (本科)
8 0.357085 (a4)
7 0.293182 (a3)
30 0.279736 (a4, 本科)
9 0.266895 (不限)
6 0.231796 (a2)
10 0.210444 (大专)
3 0.208178 (3-5年)
29 0.203495 (a3, 本科)
2 0.158123 (1-3年)
In [89]:
rules = get_rules(frequent_items)
rules.head(10)
Out[89]:
antecedents consequents antecedent support consequent support support confidence lift cosine Jaccard Allconf Maxconf Kulczynski
0 ( 3-5年) (a4, 本科) 0.142411 0.279736 0.097089 0.681754 2.437132 0.486436 0.298683 0.347075 0.681754 0.514414
1 (a4, 本科) ( 3-5年) 0.279736 0.142411 0.097089 0.347075 2.437132 0.486436 0.298683 0.347075 0.681754 0.514414
2 (本科, 3-5年) (a4) 0.122872 0.357085 0.097089 0.790164 2.212816 0.463509 0.253584 0.271894 0.790164 0.531029
3 (a4) (本科, 3-5年) 0.357085 0.122872 0.097089 0.271894 2.212816 0.463509 0.253584 0.271894 0.790164 0.531029
4 (a1) (不限) 0.117937 0.266895 0.069443 0.588813 2.206160 0.391411 0.220182 0.260189 0.588813 0.424501
5 (不限) (a1) 0.266895 0.117937 0.069443 0.260189 2.206160 0.391411 0.220182 0.260189 0.588813 0.424501
6 (a4) ( 3-5年) 0.357085 0.142411 0.110585 0.309688 2.174608 0.490387 0.284345 0.309688 0.776521 0.543104
7 ( 3-5年) (a4) 0.142411 0.357085 0.110585 0.776521 2.174608 0.490387 0.284345 0.309688 0.776521 0.543104
8 (大专) (a1) 0.210444 0.117937 0.053077 0.252213 2.138537 0.336908 0.192793 0.252213 0.450043 0.351128
9 (a1) (大专) 0.117937 0.210444 0.053077 0.450043 2.138537 0.336908 0.192793 0.252213 0.450043 0.351128

导出的关联规则说明:

  • 本科学历有3-5年工作经验的人才平均薪资为17k左右。
  • 不限学历及工作经验的岗位提供平均薪资为6k左右
  • 要求大专学历的岗位平均薪资为6k左右

规则评价

下图给出了导出关联规则的置信度、支持度以及Lift的散点图。

In [90]:
s = draw_scatter(rules)
s.render_notebook()
Out[90]:

3.4 地域对薪资的影响

完整代码版报告

3.4.1 地域信息概览

在3.2节中,我们已经看到了这些大数据企业的地理分布,呈现出围绕着经济中心逐渐下降,从沿海到内地逐渐下降等趋势。

从大数据岗位的招聘信息数量上来看,这些企业遍布全国208座城市,且不同城市对大数据人才的需求程度差异悬殊,需求量较大的城市能达到几千则招聘信息,如北京高达4797;而也有许多需求量小的城市,可能在数据集中只出现过1则。

In [91]:
print("大数据岗位招聘信息量Top30:")
data['w_place'].value_counts().head(30)
大数据岗位招聘信息量Top30:
Out[91]:
北京     4785
深圳     2010
杭州     1452
上海     1184
广州     1029
成都      974
南京      702
武汉      691
郑州      531
西安      499
济南      390
合肥      359
长沙      350
苏州      303
重庆      302
福州      288
厦门      274
青岛      255
贵阳      250
沈阳      231
天津      193
哈尔滨     189
石家庄     174
长春      164
大连      157
太原      129
无锡      111
南昌      105
昆明      105
佛山       79
Name: w_place, dtype: int64

对比大数据岗位招聘信息发布量的前30座城市,再次印证了刚才的观点,即各城市间对大数据人才的需求程度差异非常大。北京遥遥领先,深圳紧随其后,其次是杭州、上海、广州,均在1000以上。其他二十几座城市的大数据人才招聘信息数分布在100-1000之间。

In [94]:
pie.render_notebook()
Out[94]:

再来看一下各城市的大数据企业分布。从占比上来看,拥有大数据企业数量前十的城市,皆是一线城市和新一线城市,这也正照应了上述大数据岗位招聘信息数排名情况:大数据企业越多,对大数据人才的需求越大。

其中,北京的大数据企业最多,达到2000家,其次是深圳、杭州、广州。这是符合事实的,随着大数据国家战略的加速落地,大数据体量呈现爆发式增长,这些一线城市、新一线城市在大数据行业的发展上处于领先态势,急需招揽大量的大数据人才。正如我们所知道的,许多知名大数据企业正是坐落在上述城市。

In [100]:
m.render_notebook()
Out[100]:

从地理分布上来看,各城市对于大数据岗位开出的平均薪资,与各城市大数据企业的地理分布趋势相似。沿海地区城市的薪资相对更高,内陆地区相对较低。

In [102]:
bar.render_notebook()
Out[102]:

柱状图反映了各省的平均薪资排名。

  • 北京、上海的大数据招聘岗位给出的平均薪资最高,为21k左右。

  • 东北三省的平均薪资为7-8k,在各省份中处于较低水平。

  • 从沿海省份到内陆,薪资水平逐渐降低,并呈现阶梯状分布。

In [104]:
c = draw_heat(gp,gp.values.max())
c.render_notebook()
Out[104]:

上图所示为各省份不同性质的大数据企业,对大数据岗位给出的平均薪资(单位k/月)。从图中可以看出:

  • 1.对于一些大数据发展较成熟的省份,如北京、上海、广东等,能够对大数据岗位开出的薪资明显较高,平均在22k,且基本覆盖各种性质的企业。

  • 2.像江浙、福建、山东等沿海省份,依托沿海的优势,虽然薪资水平略低于一线城市,10-17k之间都有分布,但在各种企业间也基本都有所涉及。

  • 3.广东、福建的港澳台公司贡献了当地较高的大数据岗位薪资,达到18k-20k,这说明当地与港澳台合作的大数据企业发展迅速,且对大数据人才的需求急切。

  • 4.内陆省份一般都会有大数据发展突出的某种类型的企业,例如河南省的外商独资、甘肃省与陕西省的代表处、新疆维吾尔自治区的上市公司、西藏自治区的国企等,能够开出18k左右,甚至高达30k的月薪,可以说是当地大数据企业中的“领头羊”。

3.4.2 关联挖掘

In [106]:
frequent_items = apriori(c_s, min_support=0.05, use_colnames=True, max_len=4).sort_values(by='support', ascending=False)	
frequent_items.head(10)
Out[106]:
support itemsets
10 0.676705 (民营)
3 0.357085 (a4)
2 0.293182 (a3)
18 0.284722 (a4, 民营)
6 0.241565 (北京)
1 0.231796 (a2)
21 0.184711 (民营, 北京)
16 0.181136 (a3, 民营)
17 0.160892 (a4, 北京)
14 0.144425 (民营, a2)
In [107]:
rules = get_rules(frequent_items)
rules
Out[107]:
antecedents consequents antecedent support consequent support support confidence lift cosine Jaccard Allconf Maxconf Kulczynski
0 (a4) (民营, 北京) 0.357085 0.184711 0.132692 0.371598 2.011775 0.516669 0.324348 0.371598 0.718375 0.544986
1 (民营, 北京) (a4) 0.184711 0.357085 0.132692 0.718375 2.011775 0.516669 0.324348 0.371598 0.718375 0.544986
2 (a4, 民营) (北京) 0.284722 0.241565 0.132692 0.466042 1.929259 0.505962 0.337129 0.466042 0.549302 0.507672
3 (北京) (a4, 民营) 0.241565 0.284722 0.132692 0.549302 1.929259 0.505962 0.337129 0.466042 0.549302 0.507672
4 (北京) (a4) 0.241565 0.357085 0.160892 0.666041 1.865216 0.547813 0.367537 0.450571 0.666041 0.558306
5 (a4) (北京) 0.357085 0.241565 0.160892 0.450571 1.865216 0.547813 0.367537 0.450571 0.666041 0.558306
6 (a4) (深圳) 0.357085 0.101521 0.051063 0.142998 1.408560 0.268188 0.125293 0.142998 0.502976 0.322987
7 (深圳) (a4) 0.101521 0.357085 0.051063 0.502976 1.408560 0.268188 0.125293 0.142998 0.502976 0.322987
8 (民营) (上海) 0.676705 0.059674 0.055695 0.082304 1.379233 0.277159 0.081823 0.082304 0.933333 0.507819
9 (上海) (民营) 0.059674 0.676705 0.055695 0.933333 1.379233 0.277159 0.081823 0.082304 0.933333 0.507819
10 (民营) (a4, 北京) 0.676705 0.160892 0.132692 0.196086 1.218739 0.402141 0.188241 0.196086 0.824726 0.510406
11 (a4, 北京) (民营) 0.160892 0.676705 0.132692 0.824726 1.218739 0.402141 0.188241 0.196086 0.824726 0.510406
12 (民营) (a4) 0.676705 0.357085 0.284722 0.420747 1.178282 0.579208 0.380101 0.420747 0.797349 0.609048
13 (a4) (民营) 0.357085 0.676705 0.284722 0.797349 1.178282 0.579208 0.380101 0.420747 0.797349 0.609048
14 (北京) (民营) 0.241565 0.676705 0.184711 0.764645 1.129953 0.456854 0.251802 0.272957 0.764645 0.518801
15 (民营) (北京) 0.676705 0.241565 0.184711 0.272957 1.129953 0.456854 0.251802 0.272957 0.764645 0.518801
16 (民营) (深圳) 0.676705 0.101521 0.074731 0.110433 1.087788 0.285116 0.106228 0.110433 0.736111 0.423272
17 (深圳) (民营) 0.101521 0.676705 0.074731 0.736111 1.087788 0.285116 0.106228 0.110433 0.736111 0.423272
18 (民营) (杭州) 0.676705 0.073270 0.050861 0.075160 1.025792 0.228414 0.072751 0.075160 0.694158 0.384659
19 (杭州) (民营) 0.073270 0.676705 0.050861 0.694158 1.025792 0.228414 0.072751 0.075160 0.694158 0.384659
20 (民营) (a2) 0.676705 0.231796 0.144425 0.213425 0.920744 0.364663 0.189020 0.213425 0.623072 0.418248
21 (a2) (民营) 0.231796 0.676705 0.144425 0.623072 0.920744 0.364663 0.189020 0.213425 0.623072 0.418248
22 (民营) (a3) 0.676705 0.293182 0.181136 0.267674 0.912996 0.406665 0.229649 0.267674 0.617829 0.442751
23 (a3) (民营) 0.293182 0.676705 0.181136 0.617829 0.912996 0.406665 0.229649 0.267674 0.617829 0.442751
24 (民营) (a1) 0.676705 0.117937 0.066422 0.098154 0.832260 0.235117 0.091211 0.098154 0.563194 0.330674
25 (a1) (民营) 0.117937 0.676705 0.066422 0.563194 0.832260 0.235117 0.091211 0.098154 0.563194 0.330674

导出的关联规则说明:

  • 1.北京的民营企业通常对大数据行业岗位开出平均17k左右的薪资;

  • 2.北京和深圳的大数据企业对招聘岗位一般能够给出17k左右的薪资;

  • 3.在大数据人才需求量较大、大数据企业聚集的这几座城市中,即北京、深圳、上海、杭州,民营企业都占了较大比例,所开出的薪资范围广泛,从6k、7-10k、11-16k、17k都有涉及,可见民营企业在当地的大数据行业群体内占据了非常重要的位置;

规则评价

下图给出了导出关联规则的置信度、支持度以及Lift的散点图。

In [108]:
s = draw_scatter(rules)
s.render_notebook()
Out[108]:

4 模型建立

4.1 概述

对各招聘信息的企业人才需求画像进行了建模,该模型能通过求职者的基本信息(渴望最低工资、最高工资、学历、工作经验、工作地点),生成可求职企业的基本画像(公司性质与公司规模)。该功能可以帮助各招聘门户网站完善其求职搜索功能,在用户进行搜索后迅速缩小适合企业的范围,进行更加迅速有效的职位推荐。
该问题的本质是多标签分类问题。Multi-Label Machine Learning(MLL算法)是指预测模型中存在多个y值,具体分为两类不同情况:

  • 多个预测y值
  • 在分类模型中,一个样例可能存在多个不固定的类别

在本项目中,通过输入用户信息,预测公司的两个标签,为公司性质公司规模

根据多标签问题的复杂性,可以将问题分为两大类:

  • 待预测值之间存在相互的依赖关系
  • 待预测值之间不存在依赖关系

多标签问题的学习策略主要有三种,分别是一阶策略,二阶策略和高阶策略。

  1. 一阶策略不考虑标签相关性,效率高;
  2. 二阶策略考虑两个标签之间的相关性;
  3. 高阶策略考虑多个标签之间的相关性,性能好。

目前有很多关于多标签的学习算法,依据解决问题的角度,这些算法可以分为两大类:一是问题转换策略,二是算法适应性策略
问题转换策略是转化问题数据,使之使用现有算法,是一种将多标签的分类问题转换成为单标签模型构造的问题,然后将模型合并的一种方式。可分为:

  • Binary Relevance(二元关联):标签之间无关联
  • Classifier Chains(分类器链):标签之间有依赖关系
  • Calibrated Label Ranking(LP法):两两标签之间有关系

算法适应性策略是指针对某一特定的算法进行扩展,从而能够处理多标记数据,改进算法,适用数据。主要有:

  • Multi Label-KNN

4.2 问题转换策略

4.2.1 Binary Relevance (二元关联)

Binary Relevance的核心思想是将多标签分类问题进行分解,将其转换为q个二元分类问题,其中每个二元分类器对应一个待预测的标签。
由于没有考虑标签之间的相关性,是一阶策略
优点:

  • 估计单标签分类器;
  • 可以推广到超出标签组合的范围;
  • 实现方式简单,容易理解;
  • 当y值之间不存在相关的依赖关系的时候,模型的效果不错

缺点:

  • 标签数目很多的时候不适合;
  • 忽略标签之间的相关性;
  • 如果y直接存在相互的依赖关系,那么最终构建的模型的泛化能力比较弱;
  • 需要构建q个二分类器,q为待预测的y值数量,当q比较大的时候,需要构建的模型会比较多

构造二分类器的方法使用one-vs-rest的方式。可以直接使用如下接口实现,其中的基分类器可以使用任意sklearn中的预设分类器。 使用scikit-multilearn工具包进行策略及模型的构建与训练。例如:

In [ ]:
# Decision Tree
classifier = BinaryRelevance(DecisionTreeClassifier())
classifier.fit(X_train, y_train)
y_pred = classifier.predict(X_test)

precision_score(y_test, y_pred, average='micro')

4.2.2 Classifier Chains (分类器链)

Classifier Chains的核心思想是将多标签分类问题进行分解,将其转换成为一个二元分类器链的形式,其中链后的二元分类器的构建式在前面分类器预测结果的基础上的。在模型构建的时候,首先将标签顺序进行shuffle打乱排序操作,然后按照从头到尾分别构建每个标签对应的模型。
虽然还是作为二分类问题解决的,但以链式的方式随机考虑了多个标签的相关性,这是高阶策略
优点:

  • 实现方式相对比较简单,容易理解;
  • 考虑标签之间的依赖关系,最终模型的泛化能力相对于Binary Relevance方式构建的模型效果要好。

缺点:

  • 很难找到一个比较适合的标签依赖关系。
In [ ]:
# Naive Bayes
classifier = ClassifierChain(GaussianNB())
classifier.fit(X_train, y_train)
y_pred = classifier.predict(X_test)

precision_score(y_test, y_pred, average='micro')

4.2.3 Label Powerset (LP法)

Label Powerset的核心思想是将多标签学习转化为一个多类分类问题,每个不同的标签组合认为是一个不同的类。
考虑了多个标签之间的相关性,是高阶策略

优点:

  • 利用一个分类器考虑了多标签的相关性;
  • 在训练数据包括全部标签组合时通常是最优解。

缺点

  • 要求训练数据包括所有的标签组合;
  • 当标签空间大时,很容易过拟合。
In [ ]:
# SVM
classifier = LabelPowerset(SVC())
classifier.fit(X_train, y_train)
y_pred = classifier.predict(X_test)

precision_score(y_test, y_pred, average='micro')

4.3 算法适应性策略

4.3.1 Multi-Label KNN

MLKNN的核心思想是对于每一个实例而言,先获取距离它最近的K个实例,然后使用这些实例的标签集合,通过最大后验概率(MAP)来判断这个实例的预测标签集合的值。

In [ ]:
# MLKNN
classifier = MLkNN(k=10)
classifier.fit(X_train, y_train)
y_pred = classifier.predict(X_test)

precision_score(y_test, y_pred, average='micro')

4.3.2 Neural Network

由于传统的基于统计的方法最终准确率结果不佳,我们采用MLP神经网络模型进行训练和预测。

In [ ]:
# create simple mlp
model = Sequential()
model.add(Dense(128, activation='relu'))
model.add(Dense(64, activation='relu'))
model.add(Dense(class_no, activation='sigmoid'))
model.compile(loss='binary_crossentropy', optimizer='adagrad', metrics=['accuracy'])
# train
model.fit(X_train, y_train, epochs=10, verbose=2, validation_data=(X_test,y_test))
# evaluation
y_pred = model.predict(X_test)
model.evaluate(X_test, y_test)

4.4 结果与分析

为了获得统计上可信的结果,我们将实验重复20次并报告平均结果。

模型 准确率
Binary Relevance
DT 0.731
NB 0.296
SVM 0.810
RFC 0.737
Classifier Chains
DT 0.593
NB 0.458
SVM 0.602
RFC 0.607
Label Powerset
DT 0.612
NB 0.358
SVM 0.628
RFC 0.610
Algorithm Adaptation
MLKNN 0.752
Neural Network
MLP 0.931

由以上结果,经过我们的分析,对比三种转换策略,Label Powerset与Classifier Chains的整体效果均不如Binary Relevance,原因可能是因为在当前应用场景下,对于y值即“公司性质”与“公司规模”,两者并不存在明显的依赖关系。
对比二元关联转换策略中的4种模型,即决策树、朴素贝叶斯、SVM、随机森林分类器的效果,首先由于朴素贝叶斯模型给定输出类别的情况下,假设属性之间相互独立,这个假设在实际应用中往往是不成立的,在属性个数比较多或者属性之间相关性较大时,分类效果不好,所以无论何种转换策略,使用朴素贝叶斯模型分类的结果都不理想。 对于DT与RFC而言,由于我们的特征相对较少,所以随机森林相比决策树的提升效果并不明显。而SVM在这四种统计模型中则达到了最高的准确率,同样其运算时间也是最长的。
而对于算法适应性策略,MLKNN在我们的应用场景下,准确率也相对较高。
而模型结果最好的则是神经网络模型,我们仅采用了MLP效果就已经达到了0.931,对比其他模型得到了最优的效果。