我想要做的是按照他们的角色对员工进行分类 在一个组织中。这是通过获取所有权限来计算的,或者 访问列表,它们用于目标企业软件。
每个用户可能有10000个用户和几十个权限。
编辑:当有大量用户时,绝大多数用户将拥有有限的设置权限。例如,他们可能都只有Employee
。更复杂的情况是高级用户,而且会更少。
另外,不要被我给出的权限名称误导,比如Acct1 / Acct2,它们只是为了感受域名。我正在寻找的解决方案应该在概念上工作,即使是在许多ORM存储中看到的随机分配的主键整数 - 权限之间存在无隐含关系。
import pprint
pp = pprint.PrettyPrinter(indent=4)
def classify(employees):
"""employees assigned the same set
of permissions are grouped together"""
roles = dict()
for user, permissions in employees.items():
permissions = list(permissions)
permissions.sort()
key = tuple(permissions)
members = roles.setdefault(key, set([]))
members.add(user)
return roles
everyone = {
"Jim": set(["Employee","Acct1","Manager"]),
"Marion": set(["Employee","Acct1","Acct2"]),
"Omar": set(["Employee","Acct1"]),
"Kim": set(["Employee","Acct1"]),
"Tyler": set(["Employee","Acct1"]),
"Susan": set(["Employee","Marketing","Manager"]),
}
result = classify(everyone)
print("pass1")
pp.pprint(result)
此时,分类系统返回以下内容:
{ ('Acct1', 'Acct2', 'Employee'): set(['Marion']),
('Acct1', 'Employee'): set(['Kim', 'Omar', 'Tyler']),
('Acct1', 'Employee', 'Manager'): set(['Jim']),
('Employee', 'Manager', 'Marketing'): set(['Susan'])}
由此,我们可以关注数据并手动为这些角色分配一些有意义的名称。
Senior Accountants - Marion
Accounting Managers - Jim
Accountants - Kim, Omar, Tyler
Marketing Manager - Susan
作业是手动的,但意图是即使人们被雇用或离开以及许可改变时,它仍然保持“粘性”。
让我们做第二遍。
有人决定将Acct2
重命名为SrAcct
。人们被雇用,金离开。
这由以下员工权限表示:
everyone2 = {
"Jim": set(["Employee","Acct1","Manager"]),
"Marion": set(["Employee","Acct1","SrAcct"]),
"Omar": set(["Employee","Acct1"]),
"Tyler": set(["Employee","Acct1"]),
"Milton": set(["Employee","JuniorAcct"]),
"Susan": set(["Employee","Marketing","Manager"]),
"Tim": set(["Employee","Marketing"]),
}
这次的输出是:
{ ('Acct1', 'Employee'): set(['Omar', 'Tyler']),
('Acct1', 'Employee', 'Manager'): set(['Jim']),
('Acct1', 'Employee', 'SrAcct'): set(['Marion']),
('Employee', 'JuniorAcct'): set(['Milton']),
('Employee', 'Manager', 'Marketing'): set(['Susan']),
('Employee', 'Marketing'): set(['Tim'])}
理想情况下,我们认识到
Senior Accountants - Marion
Accounting Managers - Jim
Accountants - Omar, Tyler
Marketing Manager - Susan
new role - Tim
new role - Milton
Tim的角色现在命名为Marketer
,而Milton命名为Junior Accountant
。
重要的是,角色名称分配足够稳定,即使在人们被雇用和离开(最常见)以及添加或重命名权限(更不频繁)时,也可以推断员工人数。可以不时地要求最终用户分配新的角色名称或在关系之间做出决定。但大多数时候,它应该顺利进行。什么不应该做错误并错误地将一组用户标记为错误的角色名称。
我遇到的问题是它容易引人注目,但是权限集和定义角色的用户集都可能发生变化。分类时间很重要,但随着用户数和权限的增加,这种分类机制的价值会上升。
我尝试过提取“定义角色的权限子集”。例如,Employee
被分配给每个人,因此可以忽略。虽然(Manager, Acct1)
,(Manager, Marketing)
唯一属于吉姆和苏珊。麻烦的是,一旦你轻松获得20-30%的案例并且它永远不会结束,就会遇到组合爆炸。
我现在想的是支持并计算每一代的新员工权限角色分类,然后回溯以获得与上一代相比“最佳匹配”的模糊匹配。选择那些合理明确的,并要求用户决定关系并根据需要分配新的角色名称。
例如,权限的完全匹配和员工的合理匹配意味着'Omar', 'Tyler'
在第2阶段仍然是Accountants
。另一方面,如果Marion已经离开,我有{{1我必须要求最终用户进行仲裁并将她识别为"Jane": set(["Employee","Acct1","SrAcct"])
。
我过去曾使用 Jaccard Similarity (https://en.wikipedia.org/wiki/Jaccard_index),但我不确定它如何适用于双方都可以更改的情况(Senior Accountant
=&gt ; Acct2
以及员工变更)。
我很确定之前需要这种逻辑,因此我希望能够提供有关算法的建议以及要遵循的策略。
哦,我正在寻找合理的独立方法,我可以在更大的Python应用程序的上下文中实现和推理。不适用于机器学习有关如何配置 TensorFlow 之类的建议来为我执行此操作。但是,如果推动推进,我可以调用批处理进行匹配。
答案 0 :(得分:1)
这将是一个马马虎虎的答案,所以道歉,但你的问题非常广泛,需要一些逻辑而不是某些特定的代码。
也许这个问题会更好地解决,因为"标签"?我的意思是一个人可以同时是一个雇员,一个营销人员和一个经理人(我认为他们将拥有所有3个人的权限)。
所以我建议采用不同的方法 - 而不是按照各自的权限对帐户进行分组,然后手动命名,首先对权限进行分类和命名(至少在其中更受欢迎和稳定),然后将每个员工分配给通过为每个员工提供每个封装多个权限的标签来更正类别(或多个)。
然后,您将有相当多的用户或权限未分类,但希望您可以要求用户为您做一些分类(例如,描述他们的位置/权限)并在更小的范围内使用您的方法问题集。
通过这种方式,您可以确定当新员工进入时,通过查看他的权限并确定他适合的位置给予他正确的标签。当员工离开时,它没有任何区别,因为他没有&#39 ; t单独影响权限和标签。
答案 1 :(得分:1)
您在这里真正创建的是一个组织层次结构树。您的分组算法已经具备了这一功能。您并未在单个层次结构中显示它们,但可以轻松地以这种方式显示它们。
"主观"您的组织的一部分是决定何时将分支组合成单个组织角色,并决定在创建分支时对权限进行排序的顺序(即,您是否希望拥有单个经理分支,其下方的分部,或者你想拥有部门分支,每个分支都包含一个经理分支。)
不幸的是,机器无法知道这些偏好。您将不得不做出所有这些决定,特别是如果您需要0%的误报率。
我能想到的最简单的方法是向算法提供这种偏好信息,就是给它一个有序的权限列表"权重'它将在构建层次结构时使用。对于第一次通过,您可以根据有多少人拥有该权限来订购它们。您可能需要更复杂的“加权”和#34;而不是一组有序的权限。对于更复杂的权重,您需要指定更复杂的规则"检查多个权限集中的成员资格(或非成员资格)。
第二部分信息可能会以交互方式提供。给定整个组织结构图的显示,您可以选择将哪些权限集合并到一个组织集中。您还可以在此处将角色的显示名称分配给每个权限集组。
只要能够响应雇佣/火灾,只要权限相同,就不应该成为问题。至于添加和删除用户的权限,您必须存储以前的权限和分组,并将它们与每个用户的当前权限相匹配,以提示某人正确更改角色权限集,或者创建一个新的分支。新的许可。
答案 2 :(得分:0)
这就是我最终做的事情:
在计算新用户/访问集的分类之前,请保存旧的用户/访问权限及其指定的名称。
计算新分类后,找到新旧分类中最接近的匹配,如果置信度足够高,则转移名称。
完整的用户匹配?然后它就是一场比赛。我将用户集转换为已排序的用户元组,以便通过字典进行匹配。
完全权限匹配?再次,这是一场比赛。再次,通过设置检查对字典的排序元组转换查找。
对于每个不匹配的电流,我分别计算每个不匹配的前一个的Jaccard相似度,分别对其用户及其权限进行计算。所以,这可能是O(N2)的无与伦比的数字。将每个匹配附加到该分类的列表。按照分数顺序对列表进行排序(来自下面的calc
功能),最后一步,如果与下一个最接近的匹配存在足够大的差异,则仅自动选择一个。
`
class Match(object):
#these are weighing coefficients - I consider roles/permissions more important because of the expected user churn.
con_roles = .7
con_users = .3
con_other = .07
threshold = .7
def calc(self):
#could have anything you want here, really.
self.similarity = self.con_roles * self.simroles + self.con_users * self.simusers
好的,我要离开很多,但基本上,你可以将一个简单的Jaccard相似度算法应用于用户和角色方面,并将这些数字放入一个合适的等式中,看看它是一个非常接近的匹配。如果不满意,请让用户再次指定名称,作为最后的手段。
希望如果他们最终找到类似的东西,他们会帮助别人。