能力管理:过滤与推荐引擎的实践。

引言
本GraphGist模拟了一个内部职位推荐引擎,换句话说,一个能力管理系统。当一个组织需要快速在其现有员工中找到合适的人来完成一项任务或填补突然空缺的职位时,可以实施这个系统。这项任务可能很棘手,找到最适合该职位的员工可能会很困难,特别是对于大型组织[1]。为了克服这些问题,组织会寻求以下策略:
-
寻找“理想员工”的任务分配给一个人。然而,空缺职位可能涉及某些技术技能,而这个人无法单独评估。此外,无论谁进行选拔,都不可能认识所有人,因此他或她的选择很可能存在偏见,因为一个人无法快速地探索整个员工网络。
-
为了克服偏见,由一组人负责选择。然而,谁来选择这些选拔者?他们如何进行?他们的决策过程可能(过于)缓慢,并且在协商结束时必须提供一种方法来处理不同人之间不一致的判断。
如果组织保持有关其人员的活动、角色和绩效的最新记录,这些问题可能会得到克服。然而,仅仅在一个存储库中记录是不够的:信息必须像往常一样经过组织并易于访问,才能有意义。
本GraphGist演示了将上述存储库存储在Neo4j图数据库中,并使用Cypher语言进行查询是多么有用和简单。此外,还特别努力建议如何定制这个原型。整个讨论表明,使用图数据库解决此问题在灵活性方面进行了优化,因此不同的组织可以在相同的基本查询结构基础上进行构建,通过移除某些组件和改进其他组件来适应其需求。
讨论结构总结如下目录。
目录
-
初始数据模型 首先,介绍了一个数据模型,该模型考虑了“内部职位推荐”问题的主要特点。
-
热身:过滤 接下来,将在Cypher中对现有记录进行基本过滤。
-
候选人排名:“社交”方法 这是另一部分的开始,其中介绍了正式工具(类似于协同推荐引擎)。在两个小节中,通过代数过程的要素,展示了对协同结果的改进。该过程目前在一些制造企业中用于内部能力管理,其一些关键特性以Cypher查询的形式报告。
-
超越职位推荐:能力管理工具 本节概述了在前面章节中用于内部职位推荐的同一模型,如何也可用于人力资源管理。用例将是如何更好地识别某项活动的专家、需要培训的员工,或缺乏足够资源执行某项活动的团队。
初始数据模型
本GraphGist示例是基于某些特定功能构建的,使其能够重现和改进大型组织现有能力管理工具的功能[2]。然而,保留了一些通用功能和模式,使得该示例也可用于表示在线通用推荐系统。在此模型中,该原型具有足够的灵活性,可以集成组织内部存储库的信息以及从在线社交网络收集的外部信息。

请参阅Alistair Jones的箭头工具。
从关注图1中每个Employee
的单一“自我中心网络”[3]开始,这个网络可视化展示了几个有趣的数据关系。与公司内部数据相关,请注意:
-
WORKS_AS
,指向Employee
当前的Role
。此关系具有两个属性:duration
(Employee
在该角色中花费的年数)和location
(员工的工作地点)。第一个属性可用于推断员工在某个领域获得的专业水平,而第二个属性可用于了解是否应调动资源以在新Role
中工作。Role
节点本身链接到一组Activity
节点,代表组织内部的某个职位。 -
WORKED_AS
与前一个关系高度等同,唯一的区别在于它还说明了Employee
之前的角色[4]。 -
CAN_PERFORM
是关于Employee
能力的一个近似二元陈述:如果员工已经成功执行过某项活动,则链接属性为bin_threshold=1;如果假定Employee
能够执行该活动但从未尝试过,则在图中设置为bin_threshold=-1;最后,如果已知Employee
无法执行相关活动,则属性bin_threshold=0。 -
IN_TEAM
表示员工是否是或曾经是某个团队的一部分,其中员工参与的当前状态嵌入在链接属性current
中(如果员工不再是团队的活跃成员,则该属性为0)。
员工的个人信息可以来自专业社交网络中的Employee
个人资料、组织内部画像活动的数据,或者整合这两种数据源。
-
HAS_DEGREE
突出显示员工的Degree
(其特征包括颁发机构、学习科目/领域以及最终成绩)。这种连接对于知识型员工或新人来说尤其重要。 -
HAS_SKILL
表示Employee
具有特定技能。现在,对该技能的掌握程度并未嵌入到链接中(这可能暗示对该技能的自我评估),而是可以从其他同事的认可中得出。 -
ENDORSES
代表员工为同事评分的可能性。这些分数(1<级别<4)不是通用的——它们指向特定的Personal Skill
,因为一位同事可能自信评估某个特定技能,但无法评估另一个。

上图展示了组织图中的活动和角色网络。每个Role
节点都具有以下几个属性:
-
dept
指示该角色所属的部门 -
hierarchy
是员工和经理角色的基本区分——需要时,可以分配更复杂的结构 -
open_status
是一个二元值,标记为:“1”表示职位空缺,“0”表示已填充)。
Activity
节点被赋予一个complexity
(复杂度)(值为1<`complexity`<5),这是一个衡量某项Activity
难易程度的指标,它同时考虑了所需的技术专业知识以及与同事、顾问、客户等进行社交互动的程度。
Role
节点可以通过RELATED_ACTIVITY
链接与一个或多个Activity
节点相连。此连接通过属性 level_weight(也在离散量表 1→4 中)得到丰富,表示该Role
需要对相应的RELATED_ACTIVITY
有一定程度的掌握,以便员工能令人满意地执行。经理Role`s 也可通过 `SUPERVISES_ACTIVITY
链接连接:在这种情况下,可能期望员工在指导活动方面具有良好能力,但不一定要求其直接执行。
最后,每个Activity
只能通过IN_AREA
链接连接到一个Competence Area
节点(即,在此模型中不允许不同能力领域之间存在重叠,但此假设显然可以放宽)。Competency Areas
应理解为组织执行的不同`Activitie`s的高级分类。
过滤掉不合格的候选人 目录
从搜索中排除某些员工是首先要完成的任务。此要求可能源于常识性推理、内部规章或人力资源部门提出的请求。此外,这将最小化后续查询中需要遍历的节点和链接数量,从而提高性能。
频繁调动职位或提拔新入职员工通常不是期望的结果。因此,第一个查询将搜索刚加入组织或最近开始新职位的员工,并将这些候选人从潜在池中过滤掉。为了跟踪不合格的候选人,在图中的这些员工节点上设置了一个附加属性exclude
。在此,该属性是二元的:“exclude=1”表示该人员已被排除,至少目前如此。用于添加exclude
属性的Cypher查询将是
MATCH (n:Employee)
SET n.exclude=1
WITH n AS person
MATCH (person)-[r:WORKS_AS]-()
WHERE r.duration>1
SET person.exclude=0
RETURN person.name AS `Matching Candidate`
结果表只包含满足在组织工作一年以上的初步条件的候选人。
推荐职位候选人的另一个筛选条件是要求特定学位。这在公开招聘广告中非常常见,但也可能是内部晋升的基本要求。因此,为了排除那些不具备此类学位的人,查询
MATCH (n:Employee {exclude:0})
WHERE NOT (n)-[:HAS_DEGREE]-(:Degree {area:"area 1"})
SET n.exclude=1
这些过滤器可以使用其他数据库管理系统轻松实现。例如,可以在SQL中使用WHERE
查询,将degree
和duration
属性都设置为员工担任最后一个职位的列值。一个简单的电子表格就可以执行这些操作。
然而,关键在于只选择在特定能力领域内拥有活动所需技能的候选人。因此,不是通过节点属性,而是通过它们的链接或数据关系进行过滤。此外,还将搜索范围扩展到技能、活动和领域之间的三度(以及更高)连接至关重要。换句话说,我们正在寻找潜在候选人如何与能力领域连接,深度为3。SQL数据库需要执行更多的JOIN
操作才能提供答案——这项任务编码困难且查询耗时。随着查询连接深度的增加,使用RDBMS进行此搜索将变得越来越困难,并导致性能极差。
更定量地说,假设组织具有以下属性:
-
10,000名现有员工
-
每名员工平均拥有1个学位和13项不同的个人技能
-
每个团队由5人组成,平均活跃1年
-
活动是分配给团队的单个任务[[5]],速率为每天1个。
运营1年后,这些参数产生了一个大约100万个节点的图。对于如此规模的图,遍历深度为3的路径的查询(见上文),RDBMS需要超过30秒才能完成,而Neo4j只需不到0.2秒[6]。当查询数据库是在线工具的一部分时,这种差异可能是关键的。例如,向下钻取过程的最佳内部使用应避免过滤掉过多候选人(以免组织中没有人符合所需特征)。如果对预过滤的网络查询连接到深度为3的能力区域的候选人,则目前为止过滤结果返回零个符合所有要求的候选人。
MATCH (n:Employee {exclude:0})
WHERE (n)-[:HAS_SKILL]-(:Personal_Skill)<-[:REQUIRES]-(:Activity)-[:IN_AREA]->(:Competence_area {name:'Competence Area 2'})
SET n.exclude=1
RETURN DISTINCT count(n) AS Candidates
组织(特别是其人力资源部门)将需要能够与同事共享其候选人画像。这需要通过在线工具处理向下钻取,以便可以实时更新画像的任何修改,并根据现有员工的可用性进行评估。为了实现这一特定目标,我们可以将查询精简为
MATCH (n:Employee)-[:HAS_DEGREE]-(:Degree {area:"area 1"})
WHERE (n)-[:HAS_SKILL]-(:Personal_Skill)<-[:REQUIRES]-(:Activity)-[:IN_AREA]->(:Competence_area {name:'Competence Area 2'})
WITH n AS person
MATCH (person)-[r:WORKS_AS]-()
WHERE r.duration>1
RETURN person.name AS `Matching Candidate`
此查询结果为空表,这立即突出了排除某些模式匹配要求的必要性。作为Cypher查询,这可能看起来微不足道:即使编码知识很少的人也很容易接受培训来更新此类查询,以便尝试不同的要求组合。相反,同样的查询不建议在基于RDBMS的在线系统中实现,因为查询时间很长。
候选人排名:“社交”方法 目录
在上一段中,列出了可以轻松排除候选人的查询,并展示了某些请求组合可能过于严格。回到我们的示例,现在有趣的是看看根据不同方法对可用候选人进行排名的几种选择。现在需要对可用候选人进行排名,为此,有必要放宽关于个人技能的最终条件[7]。完成此任务的两个选项是协同排名和基于内容的过滤。
能力管理的协同排名
为了对最佳候选人进行排名,第一种方法是组建一个由可能或将与候选人在团队内合作的员工组成的招聘委员会。为了展示协同排名的优势,假设提供空缺职位(团队3)的团队目前只有一名员工。
MATCH (n:Employee)-[:IN_TEAM]-(m:Team {name:'Team 3'})
RETURN n.name AS `Team Member`
这说明了引言中概述的偏见问题^(前往)^:在选择理想候选人时,我们必须将已在空缺职位团队工作的员工(员工5)的知识整合进来。在这种情况下,一个直观有效的解决方案是依赖于如下数据关系:
(员工 A)-[:Endorses {级别:x}]-(个人技能 a)-[:HAS]-(员工 B)
其中属性 level x 是员工 A 对员工 B 的个人技能
的评价。这种Cypher查询提供了对候选人技能的了解,正如他们的同事所感知的那样。
为了使分析定量化,将引入员工之间的差异或相似度度量,以了解哪些员工对同事的看法相似。有了这个度量,即使团队中的人并不直接认识候选人,也可以查询在一个特定群体中最适合空缺职位的人员排名。这种方法因此非常类似于基于用户的推荐系统,一种基本的协同过滤技术。为了关联一个定量距离度量,一个简单的解决方案是应用余弦相似度(这种方法在此GraphGist中由Nicole White进行了详细解释)。基本概念是,某个团队成员的同事,如果他们以类似的方式评估了其他员工,则很可能是加入招聘委员会的合适人选。因此,委员会会扩展到非团队成员,但仍然非常适合加入团队招聘委员会的员工。
余弦相似度排名也可以作为推荐分析的基础。然而,重要的是要记住,在我们的数据模型中,员工认可的是个人技能,而不是其他员工。因此,必须包含员工A和B之间的额外有向关系([:RATES {rating: …}]
),其中:
\( rating_{ A \to B }= \frac{ \sum_{ i=1 }^{ N } \textrm{ level }(\textrm{ Personal Skill }(i))} {N} \)
其中 \(N:= \textrm{# A认可的B的个人技能数量}\),并且属性rating
是A对B的单个个人技能认可级别的平均值。
MATCH (u1:Employee)-[x:ENDORSES]->(:Personal_Skill)<-[:HAS_SKILL]-(u2:Employee)
WITH AVG(x.level) AS rating_score,
u1, u2
CREATE UNIQUE (u1)-[:RATES {rating:rating_score}]->(u2)
这些初步计算能够计算员工5的余弦相似度。然而,增加一个额外的步骤可以帮助表达更通用的查询。该查询还应该能够处理团队3由多个成员组成的情况。在这种情况下,所需的方法是为每个不在团队中但至少被一个团队成员评估过的员工计算一个平均团队评分向量。此平均分数标记为team_rating,并设置为从团队到正在被评估的Employee
的数据关系上的一个属性。
MATCH (u1:Employee)-[x:RATES]->(u2:Employee)
WHERE (u1)-[:IN_TEAM]-(:Team {name:'Team 3'}) AND NOT (u2)-[:IN_TEAM]-(:Team {name:'Team 3'})
WITH AVG(x.rating) AS team_score,
u2
MATCH (t:Team {name:'Team 3'})
CREATE UNIQUE (t)-[:RATES {team_rating:team_score}]->(u2)
带有[:ENDORSES]
和[:RATES]
数据关系的图的这部分可以可视化为
MATCH (t:Team)--(u:Employee)
OPTIONAL MATCH (u)-[:ENDORSES]-(p:Personal_Skill)
RETURN t,u,p
计算出团队评分后,现在可以引入团队3整体与那些不是团队3成员的其他员工之间的相似度。这种相似度的计算方式与单个员工的相似度计算方式相同。请注意,为了检索共同评分,必须针对二阶连接执行MATCH子句,并根据数据关系的类型进行显式过滤。使用图数据库,这很简单,因为数据关系本身就是对象。
MATCH (t:Team {name:'Team 3'})-[x:RATES]->(:Employee)<-[y:RATES]-(u2:Employee)
WHERE not (u2)-[:IN_TEAM]-(t)
WITH SUM(x.team_rating * y.rating) AS xyDotProduct,
SQRT(REDUCE(xDot = 0.0, a IN COLLECT(x.team_rating) | xDot + a^2)) AS xLength,
SQRT(REDUCE(yDot = 0.0, b IN COLLECT(y.rating) | yDot + b^2)) AS yLength,
t, u2
MERGE (t)<-[s:SIMILARITY]-(u2)
SET s.similarity = xyDotProduct / (xLength * yLength)
为了考虑团队成员的直接推荐,将团队3成员与团队本身的相似度设置为s.similarity=2。由于图中所有其他员工的similarity<1,因此优先考虑团队成员的评估非常简单。
MATCH (t:Team {name:'Team 3'})-[x:IN_TEAM]-(u1:Employee)
MERGE (t)<-[s:SIMILARITY]-(u1)
SET s.similarity = 2.0
一旦团队3与所有其他员工之间的相似度[8]已知,就可以就哪些员工可能是空缺职位的理想人选提出初步建议。
为了计算此初步分数,假设团队3之外的所有同事在评估其他同事的技能方面具有同等的 Kompetenz。从算法上讲,这意味着对于那些直接由员工5评估的人员将不会有额外的权重或分数。为了限制考虑的评分数量,可以根据提供这些评分的员工的相似度来限制它们。采用k近邻[9](k-NN)算法将允许查询仅选择k个最相似同事的评估。如何选择k?一个简单的选择是将一个小团队视为在评估其下一位成员方面至少与组织中的平均团队一样有能力。如果团队规模大于平均规模,则可以只选择团队成员进行的评估。对于此示例[10],k=5,包括员工5,前提是他至少评估过一些候选人。
选择k值后,下一步是对图模型进行查询,找到k个最近邻员工,然后计算他们评估的平均值,作为某个员工在拥有空缺职位的团队中表现如何的可能估计。如前所述,首先将考虑团队内部员工的评估。
MATCH (b:Employee)-[r:RATES]->(m:Employee), (b)-[s:SIMILARITY]-(t:Team {name:'Team 3'})
WITH m, s.similarity AS similarity, r.rating AS rating
ORDER BY m.name, similarity DESC
WITH m.name AS candidate, COLLECT(rating)[0..5] AS ratings
WITH candidate, REDUCE(s = 0, i IN ratings | s + i)*1.0 / LENGTH(ratings) AS reco
ORDER BY reco DESC
RETURN candidate AS Candidate, toFloat(reco) AS Recommendation
此查询产生了将空缺职位分配给现有员工的初步推荐。请注意,即使团队3中没有人直接认识员工1,员工1获得的推荐分数甚至高于员工3。团队3唯一直接认识的人是员工3,如果没有推荐系统,这将是唯一的可能选择。使用图模型,组织现在可以探索整个员工网络寻找候选人,并消除由小型招聘委员会带来的偏见。
在本节中,最重要的是构成数据模型本身的网络和数据关系,而不是单个成员的属性和特征。这种方法尚未考虑空缺职位所在的能力领域。使用图数据模型的优点是,即使在几乎不了解单个员工的活动和专业领域的情况下,该方法也能根据相互评分连接进行排名。
改进排名:基于路径的加权 目录
然而,本例中的图数据模型可以提供更多洞察。可以使用其他标准来改进候选人排名。最直观的选择是基于员工图的社交数据关系,为推荐引入基于内容的加权。事实上,最初是一个纯粹的“社交”协同过滤,其中没有考虑评估员工的专业知识。当没有关于空缺职位所需或期望的技能和经验信息时,这种方法是可行的。然而,现在可以使用更多能够描述理想候选人和有空缺职位的团队的特征,通过各种方法进一步改进排名。
例如,强调能力领域节点而非员工节点的作用,可以根据组织图中的某个员工与空缺职位关联的Competence Area
之间的距离,来加权候选人的推荐分数。权重将基于路径 (Employee)--(Competence Area) 的长度。考虑到角色6的空缺职位,我们知道:(角色 6)-[:RELATED_ACTIVITY]-(活动 6)-[:IN_AREA]-(能力领域 2),改进的推荐查询如下:
MATCH (b:Employee)-[r:RATES]->(m:Employee), (b)-[s:SIMILARITY]-(t:Team {name:'Team 3'}), p=shortestPath ( (n1:Competence_area {name:"Competence Area 2"})-[*..5]-(b) )
WITH m.name AS candidate, s.similarity AS similarity, r.rating AS rating, p
ORDER BY candidate, similarity DESC
WITH candidate, COLLECT(rating*1.0/(length(p)-1))[0..5] AS ratings
WITH candidate, REDUCE(s = 0.0, i IN ratings | s + i)*1.0 / LENGTH(ratings) AS reco
ORDER BY reco DESC
RETURN candidate AS Candidate, toFloat(reco) AS Recommendation
受 shortestPath 约束,可以:
-
将评估限制在距离能力节点不超过5跳的员工(通过在shortestPath
MATCH
子句中指定长度[*..5],不符合此要求的员工将被排除在进一步评估之外) -
对于所有满足条件的员工,查询将他们的评分权重设置为与他们到相关
Competence Area
的距离(表示为最短可用路径[11])成反比。
在计算候选人评分权重时,减去1,因为在此GraphGist中,任何员工到能力领域的最短路径长度恰好是2:((员工)-[:CAN_PERFORM]-(活动)-[:IN_AREA]-(能力领域))。来自最小化此主题距离的员工的评分不受影响。特别在此示例中,上面的纯协同排名得到了进一步证实,甚至将优先级分配给了对空缺职位所涉能力领域更熟悉的员工的评估。员工1仍然被计算为最佳选择,即使现在他对其他同事的优势较小。
改进排名:Jaccard相似度 目录
另一种可能的细化策略依赖于所谓的“Jaccard相似系数”。在第一段中使用的余弦相似度确实源自此指数,该指数在社会和经济科学中被广泛用于评估两个样本的多样性或相似性。在此,可以使用最简单的情况:实际上,我们可以将与所需特征的匹配/不匹配视为一个二元值,说明该特征是否属于样本。另一种细化策略将使用Jaccard相似系数。此GraphGist中早先使用的余弦相似度源自该指数,该指数在学术界被广泛用于评估两个样本的多样性或相似性。在此,它被用于最简单的情况:使用主题特征构建样本,二元值说明特征是否属于样本。这将构建两类集合:
-
T (代表团队3)
-
Ei (用于评估的第ith个
Employee
)
集合T中包含评估候选人的所有必要标准,例如在特定Competence Area
中拥有的个人技能、执行过或与其自身角色相关的活动、在相关能力领域获得的学位。这些共同描述了团队3中现有员工的整体特征。包含在T中的标准将与第ith个Employee
拥有的特征进行匹配,并且仅当某个路径将该标准与此Employee
连接时,才将结果过滤到集合Ei中。
检索到这两个集合后,可以使用Jaccard公式计算系数J:
\( J = \frac{|T \; \cap \; E_i |}{|T|} \)
(记住,根据定义 \(T \cup E_i = T\) [12].)
现在,已经介绍了此细化查询的所有要素。首先,为所有值得包含在候选人评估中的节点设置二元属性pool。为了细化结果,对本次初步筛选采用与上面相同的标准:最多5个最近邻员工,即那些在评估其他同事时与团队3余弦相似度最高的员工。
MATCH (b)-[s:SIMILARITY]-(t:Team {name:'Team 3'})
WITH DISTINCT b, s.similarity AS similarity
ORDER BY similarity DESC LIMIT 5
SET b.pool=1
接下来设置属性t_feature来标记代表所选团队特征的节点。例如,可以包括通过个人技能和活动与团队员工相关的能力领域、在特定领域获得的学位以及执行特定活动的能力。
MATCH (u1)-[:IN_TEAM]-(:Team {name:'Team 3'})
WITH u1
OPTIONAL MATCH (u1)-[:HAS_SKILL]-(:Personal_Skill)-[:REQUIRES]-(:Activity)-[:IN_AREA]-(c1:Competence_area)
OPTIONAL MATCH (u1)-[:CAN_PERFORM]-(:Activity)-[:IN_AREA]-(c2:Competence_area)
OPTIONAL MATCH (u1)-[:HAS_DEGREE]->(d:Degree)
WHERE d.area="area 1" OR d.area="area 2"
OPTIONAL MATCH (u1)-[:CAN_PERFORM]-(a1:Activity)
OPTIONAL MATCH (u1)--(:Role)--(a2:Activity)
SET c1.t_feature=1, c2.t_feature=1, d.t_feature=1, a1.t_feature=1, a2.t_feature=1;
现在,为了计算Jaccard系数,评估参与评估的每个`Employee`拥有多少团队特征。这可以通过查询集合T中的节点来完成:
MATCH (feats {t_feature:1})
WITH count(distinct feats) AS T_size
MATCH (u2 {pool:1})
WITH u2, T_size
OPTIONAL MATCH (u2)-[:HAS_SKILL]-(:Personal_Skill)-[:REQUIRES]-(:Activity)-[:IN_AREA]-(c3:Competence_area {t_feature:1})
OPTIONAL MATCH (u2)-[:CAN_PERFORM]-(:Activity)-[:IN_AREA]-(c4:Competence_area {t_feature:1})
OPTIONAL MATCH (u2)-[:HAS_DEGREE]->(d2:Degree)
WHERE d2.area="area 1" OR d2.area="area 2"
OPTIONAL MATCH (u2)-[:CAN_PERFORM]-(a3:Activity {t_feature:1})
OPTIONAL MATCH (u2)--(:Role)--(a4:Activity {t_feature:1})
WITH u2, count(distinct d2) AS counter, [a3,a4] AS activity, [c3,c4] AS competence, T_size
UNWIND activity AS activities
UNWIND competence AS competences
WITH u2, (counter+count(distinct activities)+count(distinct competences))*1.0/T_size AS jaccard
SET u2.jaccard=toFloat(jaccard)
最后一步是使用Jaccard系数作为权重:这可以通过一个与基于路径的细化非常相似的查询来完成。在这里,一个额外的WHERE子句会过滤掉那些无法提供Jaccard系数的员工的评估。
MATCH (b:Employee)-[r:RATES]->(m:Employee), (b)-[s:SIMILARITY]-(t:Team {name:'Team 3'})
WHERE b.jaccard>0
WITH m.name AS candidate, s.similarity AS similarity, b.jaccard AS jaccard, r.rating AS rating
ORDER BY candidate, similarity DESC
WITH candidate, COLLECT(rating*jaccard*1.0)[0..5] AS ratings
WITH candidate, REDUCE(s = 0.0, i IN ratings | s + i)*1.0 / LENGTH(ratings) AS reco
ORDER BY reco DESC
RETURN candidate AS Candidate, toFloat(reco) AS Recommendation
查看结果,员工3现在获得了略高的排名,考虑了与同一能力领域相关的Degree
或Personal Skill
等标准。请注意,这挑战了之前将员工1排名为最优选择的结论。
在本例中,最短路径和Jaccard距离仅作为改进k-NN和余弦相似度推荐的度量。然而,这些基于既定标准的度量在处理冷启动问题时,也可以替代基于协同过滤的推荐。当组织或评估团队刚开始运行,对其他同事在不同活动中的表现没有足够多的评估时,就会出现冷启动问题。这可能会阻碍上面概述的相似度方法的成功应用。但如果组织保留了员工档案的最新详细记录,则可以使用基于特征的相似度对(少数)评估进行排名,从而帮助解决该问题。
超越职位推荐:能力管理工具 目录
在此GraphGist的前面部分,主要目标是通过根据现有员工与新Role
及其相关团队的兼容性对其进行排名来处理内部招聘晋升的情况。然而,组织可能还需要执行与能力管理相关的其他任务。这在以下活动中可能非常有用:评估Employee
在Role
内的绩效、评估团队是否具备所有必要的能力、改进培训课程的组织。通过理解前面介绍的能力管理代数模型的细节,可以发现图数据模型的其他优势。
原始的图数据模型非常适合之前的任务,但在专注于能力管理时,还需要引入通用技能节点,这些节点之前是作为个人技能节点上的属性嵌入的。个人技能由单个员工拥有,但需要根据特定的技能集来导航和遍历图,而无需处理重复项(组织中可能有多个员工拥有相同的技能集)。这种简单的修改在RDBMS中会非常繁琐,因为需要查询整个数据库以检索个人技能节点的数据关系,然后将其中一些连接重新分配给新添加的技能节点。在图数据模型中,此更新只需几行Cypher代码即可表达并快速执行:
MATCH (a:Activity)-[rel:REQUIRES]-(ps:Personal_Skill)
MERGE (s:Skill {name:ps.set})
MERGE (a)-[:REQUIRES]->(s)<-[:IN_SKILLSET]-(ps)
DELETE rel
REMOVE ps.set;
在新模型中,Activities 可以 [:REQUIRES] 一个通用 Skill,并且员工的各种 Personal Skills 可以 [:IN_SKILLSET] 或不 [:IN_SKILLSET]。请注意,此查询轻松地将属性更新为个人技能的链接分类。如何计算一个 Employee
执行某个 Activity
的能力?首先,根据 Activity
所需的 Skills
查询图。然后对于每项 Skill,评估该 Employee
是否有一个对应的 Personal_Skill
位于相应的技能集中——如果没有,则分配一个空分。如果此 Personal Skill
也得到了其他同事的认可,则他们级别的平均值将作为该员工的能力水平分数。否则,此分数将为空。以 Employee 1 和 Activity 1 为例,此 Cypher 查询如下所示:
MATCH (a:Activity {name:"Activity 1"})-[:REQUIRES]->(s:Skill)
WITH a, count(s) AS skill_req
MATCH (a)-[:REQUIRES]-(r:Skill)-[:IN_SKILLSET]-(p:Personal_Skill)-[:HAS_SKILL]-(u:Employee {name:"Employee 1"})
OPTIONAL MATCH (:Employee)-[x:ENDORSES]->(p)<-[:HAS_SKILL]-(u)
WITH a, u, p.name AS personal_skill, toFloat(AVG(x.level)*1.0) AS rating, skill_req
WITH a, u, REDUCE(a=0.0, b IN COLLECT(rating)|a+b)*1.0/skill_req AS comp_level
MERGE (u)-[r:CAN_PERFORM]-(a)
ON CREATE SET
r.comp_level=comp_level,
r.bin_threshold=(-1)
ON MATCH SET r.comp_level=comp_level
请注意,计算员工(k)与某个活动(i)相关的能力级别如何更新了图中的[:CAN_PERFORM]链接。这种基于技能的评估代表了员工执行某项活动的能力[13],以及具备何种程度的能力。要评估员工对于某个Role
\(R_j\)(包含活动集 \(A(R_j)\))的能力如何,可以使用三个参数:新计算的能力级别 (\(l_{ik}\))、每项活动的复杂度 (\(K_i\)),以及是否存在主管作为参考[14]。此模型中嵌入的是通过[:RELATED_ACTIVITY]数据关系的属性level_weight (\(v_{ij}\))评估活动集\(A(R_j)\)中每项活动(i)所需的最大能力级别。可以假设通过条件hierarchy:"manager"标识的主管角色与每项所需活动的level_weight相匹配。因此,主管角色指数为
\( SupR_j = \sum_{ i \in A(R_j)} K_i v_{ ij}\)
类似地,Employee(k)`
对于employee
级别的Role(j)
的角色指数将是:
\( R_k = \sum_{i \in A(R_j)} K_i \tilde{l}_{ik}\)
其中 \(\tilde{l}_{ik}=min(l_{ik},v_{ij})\)。最后,Employee(k) 对 Role(j) 的态度可以通过以下比率衡量:
\( LR_{kj} = \frac{R_k}{SupR_j} \)
现在,在Neo4j图中用Cypher查询重现这些计算:
MATCH(r:Role {name:"Role 1"})-[l:RELATED_ACTIVITY]->(a:Activity)
WITH a, l.level_weight AS v_param, toFloat(l.level_weight*a.complexity*1.0) AS sup_param
MATCH (u:Employee {name:"Employee 1"})-[x:CAN_PERFORM]->(a)
WITH u.name AS Employee, a, sup_param,
CASE
WHEN toFloat(x.comp_level)>toFloat(v_param) THEN v_param*a.complexity*1.0
ELSE x.comp_level*a.complexity*1.0
END AS role_param
WITH Employee, REDUCE(a=0.0, b IN COLLECT(role_param)|a+b)*1.0 AS role_index, reduce(a=0.0, b IN COLLECT(sup_param)|a+b)*1.0 AS sup_index
RETURN Employee, toFloat(role_index/sup_index) AS `Competency Ratio`
鉴于能力比率受主管角色专业水平阈值的限制,其范围在[0,1]之间变化。接近0的值意味着该员工不应被考虑担任该角色,而接近1的值则表明该员工有可能晋升为这些活动的主管角色。通过删除上面查询第3行对单个员工的指定,可以使用相同的查询直接搜索对特定Role
具有最佳能力的员工[15]。
最后,可以编写一个非常简单的查询,该查询还可以突出显示与他们监管的Activity
的预期专业水平相比评分不足的经理:
MATCH (u:Employee)-[:WORKS_AS]->(:Role)-[s:SUPERVISES_ACTIVITY]-(a)
OPTIONAL MATCH (u)-[t:CAN_PERFORM]-(a)
WHERE toFloat(t.comp_level)<s.level_weight
RETURN u.name AS `Flagged Manager`
根据我们的图数据模型,查询突出显示的经理可能需要进一步培训,或者让他们的同事认可他们的能力[16]。
结论
本GraphGist的范围是通过示例说明以下几点:
-
员工、他们的活动和能力网络可以轻松地用图数据库建模,从而使得跨网络编写查询简单直观;
-
与查询RDBMS相比,通过图数据库可以更快更有效地提取一些信息;
-
图数据库查询可以提高对选拔模型 formulation 中隐藏问题的认识。数据库或查询可以实时更正,而其他数据库可能是单体的,在执行修改和更新时会造成严重的性能问题。
首先,演示了图数据模型如何完美适用于表示组织的内部结构。节点可以分配给员工、角色、活动和能力领域。数据关系及其属性可用于指示某个职位已担任多久、员工执行了哪些活动以及员工如何被同事或主管评估。在从该图开始建模职位推荐系统时,还包含了制造业企业能力管理代数模型的元素。
根据空缺职位的要求过滤和排名候选人是一项从复杂的遍历查询中受益匪浅的任务。这些查询搜索的深度可以远远超过图中节点的最近邻居。在此GraphGist中,遍历查询用于:
-
过滤掉一些员工
-
计算员工之间(或团队与员工之间)在评估其他同事时的相似度
-
推断员工与某个能力领域的“接近度”,从而推断其自身与该领域相关的能力
-
推断员工之间的基于特征的相似度(或比较单个员工与整个团队)
所有这些查询对于成功构建一个能够根据其能力分配或重新分配内部人力资源的内部职位推荐系统至关重要。本GraphGist的目的不是提供可能在该系统中发挥作用的所有可能推荐机制[17]的全面回顾,而是概述一些可用于提供必要推荐的方法的实现。在我们的示例中,员工“1”和“3”根据不同标准的优先级以及所使用的特定推荐方法获得了不同的排名。
将组织网络表示为图数据模型,使得根据每个内部职位搜索的具体需求进行探索和导航更加容易和快速。查询图数据库——将空缺职位与拥有适当能力的员工匹配,或提供团队内的更好整合——通常需要高度复杂的遍历查询。在在线系统中实现此推荐工具,使用关系数据库解决方案将需要大量的编码工作,并且查询性能较慢,更新数据模型也更加困难。使用Neo4j,内部推荐工具提供了更快的查询响应速度,并具有适应数据模型实时更改的灵活性。
Employee
进行比较可能会导致系数被低估的问题。然而,再次请注意,该系数将用于排名应用,而不是作为其自身的度量:因此,重新缩放或其他归一化程序当然是可能的,但它们不会改变我们的结论,因此在此省略。Activity
的匹配程度进行的评估。Activity
没有[:CAN_PERFORM]链接的员工,以及那些迄今为止没有对其Personal_Skills进行[:ENDORSES]的人。此页面有帮助吗?