哪里有钱,哪里就有欺诈。为了打击如此大规模的欺诈行为,优步工程公司的欺诈预防平台团队建造策划,一个规则引擎它可以在几分之一秒内检测出高度进化的欺诈形式。在本文中,我们将解释Mastermind是如何工作的,以及为什么我们首先选择了一个规则引擎。
因为我们不想中断优步为乘客和司机合作伙伴提供的无缝体验,我们的算法必须在几分之一秒内推断出骑手的支付能力——并检测出任何欺诈行为。欺诈防范范围包括付款欺诈,账户接管,司机-合伙人/骑手串通,滥用促销。Mastermind帮助我们实现这一宪章,同时保持无缝的客户体验。
为什么规则引擎需要规则
为了理解为什么我们要使用规则引擎,让我们来看看Uber pre-Mastermind的欺诈预防情况。类似规则的逻辑分散在优步的代码库中,破坏了我们防止欺诈的努力。一个团队使用规则类型的逻辑来接受或拒绝司机注册,而另一个团队有规则来处理行程,另一个团队有规则来处理另一件事,在Uber的许多团队中都是如此。
另一个问题是,分析师不能自己制定规则。他们必须寻求那些拥有包含相关逻辑的代码的工程师的帮助。工程师将不得不花时间编写或修改代码,这变得非常乏味。一个工程师花了大约一个小时来编写和部署一个规则。犯错误的风险也增加了,因为工程师和分析师之间的沟通可能会丢失重要的细节。
这个系统充满了低效。很明显,我们需要一种方法,让分析人员自己尽可能快地编写、测试和部署规则,并且几乎不需要工程师的参与。
乍一看,机器学习似乎是解决这个问题的最佳方法,而不是规则引擎。欺诈活动是如此的多变和广泛,以至于规则不可能捕捉到每一种场景。防止欺诈需要明智的决策,我们正在广泛使用机器学习,那么为什么我们要建立一个规则引擎呢?
首先,骗子的行动速度比我们训练机器学习模型的速度还要快。其次,在某些情况下,启发式方法比训练数据更准确。第三,我们的欺诈系统目前涉及大约20多个用户事件(例如,登录、注册和骑行请求),像我们这样的小团队无法为每一个事件建立机器学习模型。相反,我们只为重要和复杂的事件构建模型,比如旅行请求,而对其他所有事情使用规则。
建筑策划
2015年,Uber Engineering在实施Mastermind时有几个选择:
- 为Uber的目的修改现有的规则引擎。有几个开放源码的规则引擎可用。然而,它们通常具有有限的逻辑,并且没有包含自由形式的编程语言。后者对我们来说是一个致命伤。我们希望分析人员能够编写他们想要的任何规则,这就需要一种自由形式的语言。
- 为规则引擎重新使用现有的Uber服务.一些内部服务已经类似于基于规则的系统。但他们都不具备打击高级欺诈形式所需的复杂逻辑。
- 从头开始构建一个规则引擎。我们可以创造出能够容纳复杂逻辑和自由形式语言的东西。我们的工程师团队将负责从架构设计到系统维护的所有工作,但我们对这个系统非常了解。
考虑到像Uber这样的大型国际平台所吸引的各种欺诈活动,我们不能满足于第一种或第二种选择,而是选择从头开始构建一个新系统,将Uber的欺诈预防作为原始和预期的应用程序。
两年后的2017年初,我们有了一个先进的规则引擎,它不仅运行规则,而且:
- 将不同类型和级别的风险映射到不同的行动
- 允许分析人员在几分钟内编写、测试和部署规则
例如,如果Mastermind确定用户有中度欺诈活动风险,它会减慢他们的乘车请求速度,让系统有更多时间分析用户。在极端情况下,如果Mastermind认为用户有高风险,它可能会拒绝他们的骑行请求并禁止他们骑行。
对于分析师来说,Mastermind也非常容易使用。他们可以在几分钟内编写、测试和部署规则。给定一个问题、一组用户特性和一个业务模型,分析人员可以编写一个规则,并通过在Mastermind中运行规则来测试它评估模式。一种状态评估意味着规则正在运行,但不会实际影响用户;我们只是记录数据以便以后分析。这使得分析人员可以看到规则触发的频率以及它的总体执行情况。一旦他们知道规则是有效的,他们可以给规则一个状态活跃的并在生产环境中运行。工程师们不需要参与其中,整个过程也简化了。
在Mastermind上迭代
在实现我们的目标之前,我们必须创造出两个版本的《Mastermind》。第一个版本花了我们两个月的时间来构建,并为我们服务了一年多一点。在这个版本中,规则被配置为Python字典。设计并不完美——它需要分析人员实现、测试和部署一个规则大约需要一个小时,但是使用规则仍然比让工程师每次都编写新代码要快得多,因为在这个模型中,组成规则的特性、谓词和操作都可以重用。
《Mastermind》的第二个版本必须比第一个版本性能更高,但也完全兼容。我们使用阴影测试来实现这一点。我们将所有现有规则迁移到新系统中,并通过两个版本的Mastermind路由生产流量。新版本并没有真正做出决策,而是记录了它可能做出的决策的结果。之后,我们比较了每个系统的结果,看看它们是否相同。一旦我们确定第二个版本能够做出准确的预测,我们就将第一个版本下线。我们花了4个月时间构建第二个Mastermind版本,又花了2个月时间进行迁移,但现在创建和部署规则比第一个版本快多了。
策划事件流程
以下是《Mastermind》如何融入我们的大系统:
分析师在前端编写规则。然后将规则存储在数据库中。前端可以验证规则的语法,作者也可以通过输入特征值来测试规则。Mastermind定期将规则从数据库刷新到内存中。它只需要一分钟就可以将前端更改投入生产,这比起《Mastermind》的第一个版本所需要的一小时来说是一个巨大的进步。
第二个版本不仅存储和运行规则;它还提供了获取特征(例如,最近一小时的乘车请求数量)、运行机器学习模型并采取行动的框架。请求评估的典型事件流如下所示:
- 一个请求来了。
- Mastermind将请求信息发送到我们的特性聚合服务。
- 特征聚合服务从不同的服务中获取实时特征,并并行地从数据存储中获取预先计算的特征。
- 一旦Mastermind获得了所有的功能,它就会将它们发送给机器学习服务。
- 机器学习服务运行一个或多个模型并返回风险评分。
- Mastermind将风险分数添加到功能中,运行规则,并输出操作。
有些操作是同步的,比如当Mastermind拒绝一个请求并将其返回给调用者时。有些操作是异步的,比如禁止用户。策划者调用欺诈行动服务来做这件事。
让我们仔细看看Mastermind的规则控制流是如何工作的。
规则控制流
我们通过分析所有分散在Uber代码库中的硬编码规则开始构建Mastermind。我们在逻辑中发现了一些有用的模式,并将其抽象出来构建当前的规则控制流(RCF)。RCF由一系列检查点组成。每个检查点包含一组规则,每个规则包含一组属性。这里有一个例子:
检查点(1)
规则(1):属性(1)->谓词(1,2)->动作(1,2)
规则(2):属性(2)->谓词(2,3)->动作(2,3)
运行所有规则=>输出动作(1,2,3)
检查点(2)
规则(3):属性(3)->谓词(1,4)->动作(4,5)
规则(4):属性(4)->谓词(4,5)->动作(3)
运行所有规则=>输出动作(3,4,5)
RCF元素
让我们分解一下RCF的元素:
检查点是Mastermind进行欺诈检查的用户事件(例如,用户注册)。每个检查点包含一个或多个规则,并且每个规则都是独立的。
规则是包含三个构建块的条件:属性、谓词和操作。
- 财产控制规则在不同城市和国家的状态。例如,规则的状态可以为活动/活动,这取决于规则是否在指定位置运行。规则也可以有状态评估出于测试目的,如前所述。属性还保存与位置关联的任何常量。
- 谓词是逻辑表达式。所有谓词都需要输出真正的用于规则触发操作。谓词是用我们内部特定于领域的语言谓词-eval编写的,我们将在下一节中讨论。
- 行动是规则触发时的输出(例如禁止用户或要求额外验证)。一条规则可以输出多个动作。在这些情况下,将聚合操作,并输出最后一组操作。如果多个操作在移动端使用多个错误消息拒绝当前请求,则只选择第一个消息。
注意,谓词和操作可以跨规则重用,而每个属性都属于一个规则。
下面是一个规则示例:
属性:city= ' Daresbury ', status= ' Active ', SPEC={' threshold ': 10}
Predicate_A:名字!= "查尔斯·道奇森"
Predicate_B:' num_days_since_jabberwock_sighted > SPEC[" threshold "] and domain(email) == " lewiscarroll.org " '
Action_A:拒绝旅行请求
Action_B:加入黑名单
这里,SPEC是一个与位置关联的常量位于达斯伯里.我们将SPEC解析为一个属性,因此规范(阈值]将决定为达斯伯里10。域(电子邮件)用户定义函数是否打开电子邮件.
策划者说话的谓词-评估
有了这个规则控制流,我们如何构建Mastermind,以便我们的分析师可以在几分钟内编写规则并部署它呢?
就像我们之前说的,我们在设计阶段的优先事项之一是让分析人员更容易在没有工程师帮助的情况下编写自由形式的规则。要做到这一点,我们需要Mastermind理解一种自由形式的语言(我们现在称之为谓词-eval),分析人员可以很容易地使用这种语言进行编写。这将大大减少编写、测试和部署规则所需的时间。话虽如此,我们真的不想从头开始构建一种编程语言,考虑到这将是多么困难和耗时。
经过多次无果的研究,我们终于偶然发现了雷竞技是骗人的Python抽象语法树(AST)模块。AST是一个表示程序结构的树。例如,使用ast,您可以编写一个Python程序,将另一个程序作为输入。
ast将允许我们在Python的基础上进行构建,并根据我们的目的修改/定制语言,而不必自己编写一种全新的语言。我们使用它来构建谓词-eval,这是一种自由形式的语言,供分析人员编写和评估他们的规则。
在Python的基础上构建谓词-eval非常适合我们的目的,因为:
- 谓词-eval的目标用户是分析人员(尽管工程师有时也使用它),因此语法需要简单明了。
- Python是一种动态语言,它支持在运行时解析和计算表达式字符串。这允许用户在前端编写规则,并且无需重新启动服务器即可使用规则。
- Uber Engineering有很多面向python的工程师,所以他们不需要学习谓词-eval。
在Python中,您可以只使用内置的eval ()函数。然而,这引入了一个安全漏洞.相反,我们采用白名单方法并使用PythonAST模块将表达式解析为抽象语法树。我们定义了树中节点的处理程序以进一步保护自己。可用于访问基类的危险操作(例如,属性访问)没有实现,因此不可能实现。
通过这种方法,我们不仅使谓词-eval更安全,而且使用起来也更安全。你知道表达式None < 1在Python中求值为true吗?考虑以下规则:如果feature < 1,则禁用该用户.如果这个功能因为这样或那样的原因而缺失,那么用户就会被错误地禁止使用。谓词-eval禁止这种不安全的求值。
我们还在Predicate-eval中引入了一些用户定义的函数,比如用于字符串的lower()和upper()。这样,分析人员就不需要导入这些功能。
由于谓词-eval构建在Python之上,所以Mastermind也需要用Python编写。与Python吉尔在美国,我们不能访问多个核,也不能并行运行规则。所以我们做了一些优化,比如在内存中缓存经过解析的抽象语法树。现在,运行300个复杂的规则只需要30毫秒。
下一个步骤
我们面临的最大问题是,大多数规则的有效期只有几周;然后欺诈者会适应,规则最终会产生更多的假阳性。因此,我们需要不断改进Mastermind,以便随着时间的推移自动评估规则的有效性。如果对规则的信心不够高,我们还计划将案例发送给人工审查。
另一个问题是,目前谓词只能与AND逻辑组合,这限制了我们可以检查的标准。为了增加灵活性并使组件更具可重用性,可以允许将谓词用作变量,以便它们可以嵌套在其他谓词中。嵌套语法看起来像这样:Predicate_B = (Predicate_A == True)或(feature < 3)。
结论
策划使我们能够快速反应,提高我们的欺诈分析师的生产力。在《策划》的第一版中,分析师们用了一年半的时间来实施300条规则。在第二个版本中,在我们推出前端后仅仅三个月,分析师就能够实施200条新规则。如果您想帮助我们更快地检测和预防欺诈,请查看我们的欺诈工程空缺.
diyifu Diao是Uber欺诈预防平台团队的软件工程师和Mastermind项目负责人,并与专注于该领域的技术作家Isabel Geracioti共同撰写了本文超级工程.欲了解更多团队信息,参见欺诈预防团队简介.






