pltf-mdl-dsn-resp-ai-merge-2

102 阅读1小时+

响应式人工智能的平台和模型设计指南(三)

原文:annas-archive.org/md5/1d3ba6203573861788b1a8cda3eef226

译者:飞龙

协议:CC BY-NC-SA 4.0

第九章:模型可解释性

“如果你不能简单地解释它,那说明你还没有完全理解它。”

– 阿尔伯特·爱因斯坦

模型可解释性机器学习ML)和人工智能AI)领域的重要话题。它指的是理解和解释模型如何做出预测和决策的能力。可解释性很重要,因为它使我们能够识别模型中的潜在偏见或错误,并能提高 AI 模型的性能和可信度。

在本章中,我们将探索不同的解释和理解机器学习模型的方法和技术。我们还将探讨模型可解释性面临的挑战和局限性,并考虑改善机器学习算法可解释性的潜在解决方案。

在本章中,我们将涵盖以下主题:

  • 可解释 AI 简介

  • 像我五岁一样解释 (ELI5)

  • 本地可解释的模型无关 解释 (LIME)

  • 使用 XAI 技术理解客户流失建模

  • CausalNex

  • 用于因果推理的 DoWhy

  • AI 可解释性 360 用于解释模型

技术要求

本章要求你安装 Python 3.8,并使用以下 Python 包:

  • NumPy

  • Matplotlib

  • Scikit-learn

  • pandas

  • 按照以下方式安装 ELI5:

    pip install eli5
    
  • 安装 LIME,请使用以下命令:

    pip install lime
    
  • 可以使用以下命令安装 SHAP:

    pip install shap
    
  • 使用以下命令安装 DoWhy:

    pip install dowhy
    
  • AI 可解释性 360

可解释 AI 简介

考虑一个预测患者是否可能患某种终末期疾病的模型,一个帮助决策是否认定被告有罪的模型,以及一个帮助银行决定是否给某人贷款的模型。这些模型所做出的决策可能会对多个人的生活产生深远的连锁反应(与 Netflix 推荐电影的模型不同)。因此,拥有决策模型的机构必须能够解释其预测和决策背后的理由。模型可解释性或可解释 AIXAI)旨在开发能够帮助我们理解和解释模型预测和决策背后原因的算法和技术。正如我们在前面的例子中看到的,XAI 在医疗保健、金融和刑事司法等领域尤为重要,因为模型决策的后果可能对个人和社会产生重大影响。

目前,由于机器学习模型复杂的内部机制和缺乏透明度,许多模型被视为黑箱。这可能引发关于问责制和偏见的担忧,并可能阻碍利益相关者采纳这些模型并信任它们。为了解决这些问题,越来越需要能够为机器学习模型提供可解释性和解释能力的方法和技术。

XAI 是一种机器学习可解释性技术,重点在于理解机器学习模型的预测,并以人类能够理解的方式解释这些预测是如何得出的,从而建立对模型的信任。顾名思义,XAI 广泛关注模型解释,并提供接口以解读这些解释,从而有效地架起机器学习与人类系统之间的桥梁。它是更广泛的人本责任 AI 实践的关键组成部分。

图 9.1展示了构建以人为本的 XAI 系统所涉及的不同领域:

图 9.1 – 以人为本的 XAI 系统

图 9.1 – 以人为本的 XAI 系统

XAI 的发展与应用 AI/深度学习DL)系统的发展同步,始于大约 2015 年。越来越复杂的 DL 模型,如深度神经网络,为开发者和模型相关方揭示了新的可解释性挑战。在 AI 的实施过程中,由于神经网络的黑箱特性,即使是工程师或数据科学家也无法清楚了解其背后的实际情况。因此,理解一个模型的预测变得困难,且在高风险场景中难以信任这些预测。

XAI 是当我们想要判断是否可以信任我们的 AI 模型的结果,并且如何确定我们有多大的信心相信该模型是正确的时的一种解决方案。它使我们能够理解 AI 模型在某种情况下如何得出结果,从而建立对这些结果的信任。

要实现一个可靠的 XAI 系统,我们应该关注三个主要组成部分:预测准确性、可追溯性和决策理解,如图 9.2所示:

图 9.2 – XAI 系统的三个主要组成部分

图 9.2 – XAI 系统的三个主要组成部分

让我们讨论一下这些组件:

  • 预测准确性涉及技术要求,毫无疑问,它是人工智能在日常操作中成功应用的关键组成部分。预测准确性可以通过将 XAI 输出与训练/测试数据集中的结果进行比较来确定。例如,我们可以使用 LIME 等算法来解释 AI/DL/ML 分类器做出的预测。

  • 决策理解涉及人类需求,旨在通过教育和信息传递,克服对 AI 的不信任,帮助团队理解决策是如何做出的。这些信息可以通过仪表盘的形式展示给最终用户,显示影响某一决策的主要因素,以及每个因素对决策的影响程度。

  • 可追溯性可能影响并限制决策过程,为机器学习规则和特征设定更窄的范围。像深度学习重要特征DeepLIFT)这样的技术可以通过显示可追溯链接和依赖关系,比较神经网络中每个神经元与其参考神经元的激活情况。

如果用户对 AI 决策的生成过程缺乏理解,信任框架将受到损害,并最终可能导致模型被拒绝。考虑一个向用户推荐社交网络连接或购买产品的系统。对这些推荐的解释将成为机器学习系统采纳的催化剂,使信息对用户更具意义。

XAI 不仅仅是建立模型信任,它还涉及故障排除和提高模型性能。它使我们能够通过追踪模型在部署状态、公平性、质量和模型漂移等方面的洞察来调查模型行为。通过使用 XAI,可以分析模型性能,并在模型偏离预期结果并表现不佳时生成警报。

XAI 的范围

理解模型对于构建和操作机器学习系统中的许多任务至关重要,XAI 可以用于以下任务:

  • 完善建模和数据收集过程:在对数据集进行拆分聚合和比较后,XAI 提供了一种方法,可以识别并提醒用户注意常见的机器学习问题,如数据偏斜和漂移。

  • 调试模型性能:XAI 使我们能够调试模型的意外行为,并监控更深层次的特征级洞察,以指导修正行动。

  • 建立信任:通过解释预测,XAI 支持决策过程,帮助与最终用户建立信任,使得模型决策更加公正和可靠。

  • 识别意外的预测:它验证模型行为并提供修改措施。例如,它可以帮助监管机构有效地验证机器学习决策是否符合相关法律,以减少对最终用户产生不良模型结果的风险。

  • 充当催化剂:XAI 通过建立用户信任,并以易于理解的形式向利益相关者展示模型结果,促进了机器学习系统的采用。

在理想的世界中,一个可解释且透明的模型可以在不同的行业中使用,例如在医疗健康领域,通过加速诊断、处理图像、简化药品审批流程,以及在制造、金融、物流和刑事司法领域做出关键决策,如加速 DNA 分析或监狱人口分析的结论。

可解释性可以帮助开发人员确保系统按预期工作,符合监管标准,甚至允许受决策影响的人挑战该结果。理解和解释模型预测的能力使公司和机构能够做出明智的决策,尤其是在利益相关者需要证明的情况下,如战略商业决策中。

XAI 的挑战

实施 XAI 解决方案时面临的一些具有挑战性的困境如下:

  • 算法机密性:通常,由于安全问题,所使用的模型和算法的细节是保密的。在这种情况下,确保 AI 系统没有因为训练数据、目标函数或模型的缺陷而学到偏见观点(或一个有偏见世界的无偏见观点)就成为了一项具有挑战性的任务。

  • 公平性:对于 XAI 来说,判断 AI 框架所做的决策或得到的输出是否公平是一项挑战,因为公平的印象是主观的,且依赖于用于训练 AI/ML 模型的数据。此外,公平性的定义可能会根据使用场景、文化等发生变化。

  • 可靠性:如果不评估 AI 系统如何得出某个结果,就很难依赖该系统,因为需要澄清该系统是否合法。

构建一个可以轻松解释和解读的模型是克服上述挑战的关键。高度复杂的算法可以通过更简单的方式重新创建或替代,这些方法借助 XAI 可以更容易地解释。

XAI 技术分类

XAI 技术可以根据两个主要标准进行分类——范围和模型。请参见图 9.3

图 9.3 – XAI 技术分类

图 9.3 – XAI 技术分类

让我们讨论每种技术:

  • 范围:XAI 技术可以根据其解释的范围进行分类。在范围上,XAI 技术主要分为两大类:局部全局。局部解释侧重于描述 AI 模型在特定输入或输出下的行为。这些解释提供了有关模型如何针对特定输入做出决策的见解,有助于理解模型在特定情况下的行为。另一方面,全局解释则提供有关 AI 模型在广泛输入和输出下的一般行为的见解。这些解释有助于理解 AI 模型的整体决策过程及其如何处理不同类型的输入。

  • 模型:XAI 技术也可以根据应用的模型类型进行分类。在模型的上下文中,XAI 技术主要分为两类:特定模型无关模型。特定模型的解释是针对特定 AI 模型的架构和设计量身定制的。这些解释通常具有局部性质,提供有关特定输入或输出的模型行为的见解。特定模型的 XAI 技术的例子包括特征重要性分析和显著性图。另一方面,无关模型的解释并不特定于任何特定的 AI 模型,可以应用于广泛的不同模型。这些解释通常具有全局性质,提供有关 AI 模型在各种输入和输出情况下的整体行为的见解。无关模型的 XAI 技术的例子包括反事实分析和模型蒸馏。

图 9.4 扩展了特定模型与无关模型的 XAI 技术之间的差异:

图 9.4 – 特定模型与无关模型的 XAI 技术

图 9.4 – 特定模型与无关模型的 XAI 技术

总体而言,XAI 技术可以根据其范围(局部或全局)以及它们与所应用模型的关系(特定模型或无关模型)进行分类。了解不同类型的 XAI 技术以及它们如何应用,可以帮助从业者为特定情境选择最合适的技术,并更好地理解他们 AI 模型的行为。

现在让我们探讨一些可以用于模型可解释性的 Python 库。

解释像我五岁一样(ELI5)

这个 Python 库使我们能够可视化和调试机器学习模型。它提供了本地和全局解释的功能。XGBoost、LightGBM、scikit-learn、Lightning 和 CatBoost 是 ELI5 支持的库之一。ELI5 的目标是使解释对普通观众易于理解,包括那些没有人工智能或机器学习背景的人。

这是一个示例,展示了如何使用 ELI5 来提供对 AI 模型预测的解释。

假设一个 AI 模型已经被训练用来预测一个病人根据多种医疗特征(如年龄、性别和病史)患某种特定疾病的可能性。该模型预测某个特定病人患该疾病的可能性较高。为了提供这个预测的 ELI5 解释,模型可以给出一个简单易懂的解释,比如:根据你的年龄、性别和病史,我们的模型预测你患该疾病的几率较高。这是因为根据我们的数据,具有类似特征的人患此病的风险较高。这个 ELI5 解释为模型做出的预测提供了清晰简洁的说明,使用了普通观众可以理解的语言和概念。它还突出了模型在做出预测时考虑的因素,有助于增加 AI 系统的透明度和问责性。

以下是我们介绍 ELI5 如何在代码中实现的一个大致框架:

  1. 首先,您要解释的 AI 模型应已经过训练并部署。这个模型可以是机器学习(ML)模型、深度学习(DL)模型或其他类型的 AI 模型。

  2. 然后,你需要选择你想要解释的模型输入或输出。这可以是模型做出的单个预测,也可以是一批预测。

  3. 接下来,你需要选择一个适合你的模型和你想要提供的解释类型的 ELI5 解释方法。有许多不同的 ELI5 方法,包括提供特征重要性解释、显著性图和反事实解释等方法。

  4. 一旦你选择了一个 ELI5 方法,你就可以用它来生成模型输入或输出的解释。这可能涉及将输入或输出通过 ELI5 方法进行处理,然后对生成的解释进行进一步处理,使其简单易懂,适合一般观众。

  5. 最后,您可以清晰简洁地将 ELI5 解释呈现给用户,使用普通观众可以理解的语言和概念。这可能涉及将解释显示在用户界面中、打印到控制台或保存到文件中。

然而,ELI5 存在一些局限性。其中一个局限性是,可能无法为 AI 模型做出的每个决策提供一个简单且易于理解的解释。在某些情况下,AI 模型的决策过程可能过于复杂或细微,无法简单地解释。另一个局限性是,ELI5 解释可能不足以完全理解 AI 模型的行为,尤其是对于那些具有更技术背景的人。在这些情况下,可能需要更详细和技术性的解释。另外,请注意,它并不适用于所有模型——例如,在 scikit-learn 中,它仅适用于线性分类器、回归器和基于树的模型。在 Keras 中,它支持使用 Grad-CAM 可视化来解释图像分类器。

LIME

LIME 是一种流行的 XAI 技术,用于为 AI 模型的预测提供局部解释。LIME 的目标是提供一个简单、易于理解的解释,帮助普通观众理解 AI 模型是如何从特定输入中得出某个预测的。

LIME 是与模型无关的,这意味着它可以应用于各种不同的 AI 模型,而不受其架构或设计的限制。这使得 LIME 成为一个灵活且广泛适用的工具,用于解释 AI 模型的行为。

在使用 LIME 生成解释时,该技术首先生成一组扰动版本的输入数据,称为 扰动。这些扰动是通过随机改变某些输入特征的值(每次一个特征),同时保持其他特征不变来获得的。然后,使用 AI 模型对每个扰动做出预测,结果的预测被用来构建一个简单的线性模型,该模型近似原始输入附近的 AI 模型行为。这个线性模型接着被用来为 AI 模型做出的预测提供解释。解释可以以一个特征列表的形式呈现给用户,这个列表列出了对预测贡献最大的特征,并显示每个特征的相对重要性。

例如,考虑一个使用 AI 模型对电子邮件进行分类的系统,该系统将电子邮件分类为垃圾邮件或非垃圾邮件。为了使用 LIME 解释某个特定电子邮件的分类,算法可能通过随机更改电子邮件中的一些单词,同时保持其他特征不变,生成一组扰动。然后,AI 模型将对每个扰动做出预测,结果的预测将用来构建一个简单的线性模型,该模型近似原始电子邮件附近的 AI 模型行为。

LIME 生成的线性模型随后可以用于解释原始电子邮件的分类结果,例如一份最重要词汇的列表,展示这些词汇对分类的贡献,并附上每个词汇的相对重要性。这个解释将在局部区域内忠实地反映 AI 模型的行为,意味着它能准确地体现 AI 模型在电子邮件周围局部区域的行为,并且是在电子邮件的可解释表示(即一份词汇列表)上学习得出的。

LIME 是一个用于理解 AI 模型行为的有用工具,它可以为这些模型做出的预测提供简单且易于理解的解释。然而,它也有一些局限性,例如它只能提供局部解释,可能无法捕捉到 AI 模型决策过程的全部复杂性。

现在让我们继续介绍工具箱中的下一个工具:SHAP。

SHAP

SHAP(即Shapley 加性解释)是另一种流行的 XAI 技术。SHAP 的目标是解释 AI 模型的整体决策过程以及它如何处理不同类型的输入,并为这一过程提供一个简单且易于理解的解释,面向一般观众。

SHAP 基于博弈论中的 Shapley 值概念,Shapley 值提供了一种公平地分配不同参与者对集体结果贡献的方法。在 XAI 的背景下,SHAP 利用 Shapley 值计算输入数据点中每个特征对 AI 模型预测的相对重要性。

为了使用 SHAP 生成解释,技术首先计算输入数据中每个特征的 Shapley 值。这是通过考虑所有可能的输入特征组合以及 AI 模型的相应预测,然后使用这些组合计算每个特征对预测的相对贡献。

SHAP 计算的 Shapley 值随后用于为 AI 模型的预测提供解释。这个解释可以以一份最重要特征的列表呈现给用户,这些特征对预测的贡献以及每个特征的相对重要性也会一并显示。

Shapley 值与合作博弈

Shapley 值基于一种合作博弈的概念,在这种博弈中,一组参与者合作以达成共同的目标。Shapley 值是衡量玩家对集体结果贡献的指标,考虑到所有其他成员的努力。Shapley 值为每个玩家提供了公平的价值,依据他们对集体结果的贡献。这意味着每个参与者只因自己对结果的贡献而获得功劳,同时考虑到其他玩家的努力。假设一组人正在合作建造一座房子。考虑到所有其他参与者的努力,每个参与者的 Shapley 值将代表他们对房屋建造的贡献。一个负责打地基的人会因地基的价值而获得功劳,但不会因为房顶或墙壁的建设而获得功劳,后者是由其他人贡献的。

SHAP 是一个强大且广泛适用的工具,用于理解 AI 模型的行为,并为这些模型所做的预测提供全球性的解释。然而,它也有一些限制,例如,计算大数据集的 Shapley 值可能在计算上非常昂贵。此外,对于技术背景有限的用户来说,SHAP 的解释可能并不总是易于理解。

现在我们已经了解了一些可以用来解释模型预测的工具,让我们看看如何使用它们。

使用 XAI 技术理解客户流失建模

现在你对 ELI5、LIME 和 SHAP 技术有了一定了解,让我们在实际问题中使用它们。为了演示,我们将考虑客户流失建模的问题。

客户流失建模是一种预测建模方法,用于识别可能停止使用公司产品或服务的客户,也称为流失。客户流失建模通常用于电信、金融服务和电子商务等行业,这些行业中客户保持是商业成功的重要因素。

客户流失建模通常包括使用机器学习或其他统计技术构建预测模型,以识别最可能导致客户流失的因素。该模型在涵盖过去客户的数据显示进行训练,其中包括关于客户的基本信息、使用模式和流失状态(即,是否流失)。然后,该模型将用于根据客户的特定特征和行为预测未来客户流失的可能性。

它可以用来识别高风险的可能流失客户,从而公司可以对这些客户采取主动措施来保留他们,例如提供折扣和激励,鼓励他们继续使用公司的产品或服务。它还可以更广泛地帮助理解导致客户流失的因素,这样公司可以采取措施应对这些因素,从而提高客户的总体留存率。

我们将开始构建一个预测流失的模型。在这个示例中,我们使用的是来自 github.com/sharmaroshan/Churn-Modeling-Dataset 的流失建模数据集。该数据集包含 10,000 个数据点和 14 个特征。图 9.5 显示了一些数据探索的结果:

图 9.5 – 在流失模型数据集上的数据探索

图 9.5 – 在流失模型数据集上的数据探索

让我们开始构建模型。

构建模型

既然我们已经查看了数据,接下来我们开始构建一个模型来使用这些数据。由于我们的重点是解释如何使用之前讨论的 Python 库,因此我们将使用 scikit-learn 构建一个简单的 随机森林 分类器。

这是实现的步骤:

  1. 首先,我们导入构建模型所需的所有包,以及构建解释所需的包(即 ELI5、LIME 和 SHAP):

    import numpy as np
    import matplotlib.pyplot as plt
    import pandas as pd
    from sklearn.model_selection import train_test_split
    from sklearn.ensemble import RandomForestClassifier
    from sklearn.metrics import make_scorer
    from sklearn.metrics import accuracy_score, confusion_matrix, roc_curve, auc, roc_auc_score
    import pickle
    import eli5
    from eli5.sklearn import PermutationImportance
    import lime
    from lime import lime_tabular
    import shap
    
  2. 接下来,我们下载数据并从中获取特征和输出;然后,对分类变量 GeographyGender 进行独热编码:

    dataset = pd.read_csv('https://raw.githubusercontent.com/krishnaik06/Lime-Model-Interpretation/main/Churn_Modelling.csv')
    X = dataset.iloc[:, 3:13]
    y = dataset.iloc[:, 13]
    geography = pd.get_dummies(X["Geography"],
            drop_first=False)
    gender=pd.get_dummies(X['Gender'],drop_first=False)
    
  3. 让我们也删除数据框中所有不相关的列:

    X=pd.concat([X,geography,gender],axis=1)
    X=X.drop(['Geography','Gender'],axis=1)
    
  4. 现在,我们将数据分成训练集和测试集:

    X_train, X_test, y_train, y_test = train_test_split(X,
            y, test_size = 0.2, random_state = 0)
    
  5. 现在,让我们定义随机森林分类器并在训练数据集上进行训练:

    Classifier=RandomForestClassifier()
    classifier.fit(X_train,y_train)
    
  6. 接下来,我们使用训练好的模型在测试集上进行预测。我们可以看到它在测试集上的准确率为 86%:

    y_predict = classifier.predict(X_test)
    y_prob = [probs[1] for probs in
            classifier.predict_proba(X_test)]
    
  7. 我们还可以看到在测试集上的 ROC 曲线:

    # Compute area under the curve
    fpr, tpr, _ = roc_curve(y_test, y_prob)
    roc_auc = auc(fpr, tpr)
    # Plot ROC curve
    plt.figure()
    plt.plot(fpr, tpr, color='orange',
            lw=2, label='ROC curve (area = %0.2f)' %
            roc_auc)
    plt.plot([0, 1], [0, 1], color='navy', lw=2,
            linestyle='—')
    plt.xlim([0.0, 1.0])
    plt.ylim([0.0, 1.05])
    plt.xlabel('False Positive Rate')
    plt.ylabel('True Positive Rate')
    plt.title("Churn Modeling")
    plt.legend(loc="lower right")
    plt.show()
    

这是 ROC 曲线的显示方式:

图 9.6 – ROC 曲线

图 9.6 – ROC 曲线

ROC 曲线下的面积大约为 0.87,通常认为这是一个相当好的分类器的标志。

  1. 由于我们使用的是随机森林分类器,接下来让我们基于默认的 平均减小不纯度MDI)标准来探索特征重要性。以下是获得该信息的代码。为了方便理解,我们将特征重要性以条形图的形式进行展示:

    # Feature importance in a dataframe
    imp_df = pd.DataFrame({
            'feature': X_train.columns.values,
            'importance':classifier.feature_importances_})
     # Reorder by importance
    ordered_df = imp_df.sort_values(by='importance')
    imp_range = range(1,len(imp_df.index)+1)
    ## Bar chart with confidence intervals
    height = ordered_df['importance']
    bars = ordered_df['feature']
    y_pos = np.arange(len(bars))
    plt.barh(y_pos, height)
    plt.yticks(y_pos, bars)
    plt.xlabel("Mean reduction in tree impurity in random forest")
    plt.tight_layout()
    plt.show()
    

这是条形图的显示方式:

图 9.7 – 使用 scikit-learn 的 MDI 标准的特征重要性

图 9.7 – 使用 scikit-learn 的 MDI 标准的特征重要性

在前面的图中,我们可以看到,影响客户是否留存或流失的五个最重要特征分别是他们的年龄、估计薪资、账户余额、信用评分以及他们购买的产品数量。

接下来,我们使用 ELI5 来理解分类器。

使用 ELI5 来理解分类模型

我们使用 ELI5 的PermutationImportance方法来解释我们构建的分类模型。PermutationImportance是 ELI5 中实现的一个特征重要性度量方法,可以用来估算任何特征的重要性。PermutationImportance方法通过随机排列单个特征的值,然后测量排列对所选模型性能的影响。模型的性能受到排列影响越大,特征的重要性就越高。我们将训练好的模型和数据集作为输入传递给 ELI5 中定义的PermutationImportance类。让我们从这个开始:

  1. 在以下代码中,我们使用 ROC 曲线下面积作为度量来评估训练模型中不同特征的重要性:

    perm_test = PermutationImportance(classifier,
            scoring=make_scorer(roc_auc_score),
            n_iter=50, random_state=123, cv="prefit")
    
  2. 让我们使用训练数据集计算特征重要性:

    perm_test.fit(X_train, y_train)
    
  3. 我们现在可以使用explain_weightsshow_weights函数来获取每个特征的排列重要性:

    imp_df = eli5.explain_weights_df(perm_test)
    
  4. imp_df数据框包含估算器参数。同样,为了便于理解,最好重新排序它们并将结果绘制成条形图。这里是相关代码和条形图:

    label_df = pd.DataFrame({
            'feature': [ "x" + str(i) for i in range(
            len(X_test.columns))],
            'feature_name': X_test.columns.values})
    imp_df = pd.merge(label_df, imp_df, on='feature',
            how='inner', validate="one_to_one")
    # Reorder by importance
    ordered_df = imp_df.sort_values(by='weight')
    imp_range=range(1,len(imp_df.index)+1)
    ## Bar chart with confidence intervals
    height = ordered_df['weight']
    bars = ordered_df['feature_name']
    y_pos = np.arange(len(bars))
    plt.barh(y_pos, height)
    plt.yticks(y_pos, bars)
    plt.xlabel("Permutation feature importance training
            set (decrease in AUC)")
    plt.tight_layout()
    plt.show()
    

这里是条形图:

图 9.8 – 使用 ELI5 PermutationImportance 并以 AUC 作为评分计算特征重要性

图 9.8 – 使用 ELI5 PermutationImportance 并以 AUC 作为评分计算特征重要性

根据此图,年龄是最重要的因素,其次是购买的产品数量、余额以及是否为活跃会员。

现在,让我们尝试使用 LIME 来解释模型的预测结果。

实践 LIME

你可以将 LIME 应用于任何类型的数据集,无论是表格、文本还是图像数据。在本节中,我们将介绍如何使用 LIME 来理解我们的随机森林分类器在客户流失建模中的预测。

这里,我们有表格数据。通过使用 LIME,我们可以更好地理解模型如何做出决策,并识别出在预测客户流失时最重要的因素:

  1. 由于这是表格数据,我们将使用lime_tabular中定义的LimeTabularExplainer类:

注意

理想情况下,我们不应该对分类特征进行独热编码,因为当 LIME 尝试做出预测时,它可能会给出无意义的输入。更多信息,请参见github.com/marcotcr/lime/issues/323的讨论。

interpretor = lime_tabular.LimeTabularExplainer(
    training_data=np.array(X_train),
    feature_names=X_train.columns,
    mode='classification')
  1. 现在,我们可以使用 LIME 来解释一个实例的预测结果。我们选择了以下实例:

    X_test.iloc[3]:
    CreditScore           788.00
    Age                    32.00
    Tenure                  4.00
    Balance            112079.58
    NumOfProducts           1.00
    HasCrCard               0.00
    IsActiveMember          0.00
    EstimatedSalary     89368.59
    France                  1.00
    Germany                 0.00
    Spain                   0.00
    Female                  0.00
    Male                    1.00
    Name: 5906, dtype: float64
    
  2. 现在,我们使用 LIME 的explain_instance函数来概述其对输入的解释:

    exp = interpretor.explain_instance(
        data_row=X_test.iloc[3], #new data
        predict_fn=classifier.predict_proba
    )
    exp.show_in_notebook(show_table=True)
    

输出结果如下所示:

图 9.9 – 使用 LIME 解释器解释 X_test.iloc[3]实例的特征重要性

图 9.9 – 使用 LIME 解释器解释 X_test.iloc[3]实例的特征重要性

LIME 解释器告诉我们,对于给定的客户,流失的概率微乎其微(0.01)。此外,在前面的结果中,我们可以看到各个因素对每个类别的贡献以及它们的贡献性质。再次发现,年龄对预测的影响最大。

我们可以看到所有工具都指向了同一个方向:年龄 是流失建模的重要特征。让我们看看 SHAP 的解释。

SHAP 实践

在本节中,我们将向您展示如何使用 SHAP 来解释我们流失预测模型的预测结果。SHAP 是一种强大的可解释 AI(XAI)技术,可以帮助我们理解输入数据点中的每个特征对机器学习模型预测的相对重要性。通过使用 SHAP,我们可以更好地理解模型如何做出决策,并识别出在预测流失时最重要的因素:

  1. 我们将使用 SHAP 的 TreeExplainer 类,该类专门设计用于树模型。TreeExplainer 类通过遍历模型的决策树并计算每个特征对每个树节点的预测贡献,从而工作。然后将这些贡献聚合,以生成模型预测的全局解释:

    explainer = shap.TreeExplainer(classifier)
    shap_values = explainer.shap_values(X_test)
    
  2. 现在我们将对与 LIME 使用的相同实例 X_test[3] 进行操作:

    shap.initjs() #initialize javascript in cell
    shap.force_plot(explainer.expected_value[0],
            shap_values[0][3,:], X_test.iloc[3,:])
    

这将生成一个给定实例的 SHAP 力量图。该力量图直观地解释了各个因素对该特定实例预测的贡献。显示了输入数据中每个特征的相对重要性,以及每个特征如何影响预测。第一个参数 explainer.expected_value[0] 表示该实例的模型期望值为 0——也就是说,它属于 0 类,即没有流失。第二个参数 shap_values[0][3,:] 提供了我们给定实例的 SHAP 值数组。SHAP 值表示每个特征对模型为 0 类做出的预测的贡献。在这里,你可以看到这个图表:

图 9.10 – SHAP 力量图用于 X_test.iloc[3] 实例

图 9.10 – SHAP 力量图用于 X_test.iloc[3] 实例

如我们所见,SHAP 力图展示了一个线性坐标轴。这个坐标轴表示模型的输出。你还应该看到一组水平条形图,它们表示输入数据中的特征。该图还包括一个基准值,它是模型在为特定类别或标签进行解释时的预期输出值。每个水平条形图的长度表示相应特征对预测的相对重要性。较长的条形图表示更高的重要性,而较短的条形图表示较低的重要性。每个条形图的颜色表示该特征值如何影响预测结果。蓝色条形图表示该特征的较高值导致较高的预测值,而红色条形图表示该特征的较高值导致较低的预测值。

  1. 我们还可以使用 SHAP 的依赖图来了解输入数据集中特定特征与模型预测之间的关系。以下命令生成一个图,展示Age特征对 0 类别预测的影响:

    shap.dependence_plot("Age", shap_values[0], X_test)
    

这里是它的图示:

图 9.11 – SHAP 依赖图(Age 特征)

图 9.11 – SHAP 依赖图(Age 特征)

  1. 总结图使我们能够可视化所有输入特征的重要性。以下是相关代码:

    shap.summary_plot(shap_values[1], X_test, plot_type="violin")
    

图示如下:

图 9.12 – SHAP 总结图

图 9.12 – SHAP 总结图

SHAP 总结图由一个垂直坐标轴组成,表示模型的输出(通常标记为f(x)),以及一组水平的小提琴图,表示每个特征的 SHAP 值分布。小提琴图展示了每个特征在数据集中所有实例中的 SHAP 值分布,可以用来理解每个特征的值是如何影响模型的预测结果的。

到目前为止,我们所审视的库为我们提供了许多基于各特征重要性的模型预测见解。接下来,我们将探索一些提供因果关系分析的库。

CausalNex

CausalNex 是一个开源 Python 库,允许我们开发有助于推断因果关系的模型,而非仅仅观察相关性。CausalNex 提供的what if库用于测试场景,利用贝叶斯网络进行因果推理。一些 CausalNex 的突出特点如下:

  • 通过可视化简化贝叶斯网络中的因果关系理解:CausalNex 的主要特点之一是它通过可视化简化了贝叶斯网络中因果关系的理解。该库提供了一系列可视化贝叶斯网络的工具,包括网络图、影响图和决策图,允许用户查看不同变量之间的连接及其相互影响。

  • 理解变量之间的条件依赖关系:CausalNex 还提供了用于理解变量之间条件依赖关系的工具。该库包括最先进的结构学习方法,这些算法可以从数据中自动学习贝叶斯网络的结构。这些方法使用户能够识别变量之间的关系,并理解它们如何受到网络中其他变量的影响。

  • 增强领域知识:CausalNex 还提供了增强领域知识的工具,领域知识指的是用户在建模过程中所带入的特定知识和专业技能。该库允许用户将其领域知识融入贝叶斯网络的结构中,从而帮助提高模型的准确性和可靠性。

  • 评估模型质量:CausalNex 包括用于评估模型质量的工具,如统计检查和模型选择方法。这些工具使用户能够确保他们构建的模型是准确的,并且适用于他们特定的问题。

  • 基于结构关系构建预测模型:该库还包括基于贝叶斯网络中结构关系构建预测模型的工具,这对于预测未来结果或以“假设如果”的方式测试场景非常有用。

在下图中,你可以看到一个显示学生表现与可能影响因素之间因果关系的图:

图 9.13 – 子图显示影响学生表现的不同因素之间的因果关系

图 9.13 – 子图显示影响学生表现的不同因素之间的因果关系

该结果来源于 CausalNex 的入门教程,causalnex.readthedocs.io/en/latest/03_tutorial/01_first_tutorial.html。我们可以看到,过度的互联网使用会导致学生缺课增加。同样地,如果学生增加学习时间,他们的成绩(G1)会提高。

总体而言,CausalNex 是一个强大的贝叶斯网络因果推理工具包。它提供了一系列功能,用于简化因果关系的理解,理解变量之间的条件依赖关系,增强领域知识,评估模型质量,以及基于结构关系构建预测模型。

现在让我们探索下一个用于因果推断的 Python 库——DoWhy 库。

DoWhy 用于因果推断

DoWhy 是一个用于因果推断和分析的 Python 库。它旨在支持与其他因果估计库的互操作性,如 Causal ML 和 EconML,使用户能够轻松地在分析中结合不同的方法和途径。

DoWhy 的主要特点之一是专注于稳健性检验和敏感性分析。该库包括一系列方法来评估因果估计的稳健性,如自助法和安慰剂测试。这些方法帮助用户确保他们的估计是可靠的,不受偏差或混杂因素的影响。

除了稳健性检验外,DoWhy 还提供了一个 API,涵盖因果分析中的常见步骤。这些步骤包括创建因果模型、确定感兴趣的效应、使用统计估计方法估计效应,并通过敏感性分析和稳健性检验验证估计结果。

要创建因果模型,用户可以使用 DoWhy 的因果图和结构假设工具来表示变量之间的关系并指定模型的基本假设。一旦模型创建完成,用户可以使用 DoWhy 的识别工具来确定预期效应是否有效,然后使用该库的估计工具来估算效应。最后,用户可以使用 DoWhy 的验证工具,通过敏感性分析和稳健性检验确保估计结果的准确性和可靠性。

该库为因果推断领域做出了三大主要贡献:

  • 将问题建模为因果图:DoWhy 允许用户将问题表示为因果图,这些图是变量之间因果关系的图形表示。通过将问题建模为因果图,用户可以明确表达他们的所有假设,从而帮助确保这些假设是透明的并且易于理解。

  • 统一接口:DoWhy 结合了图模型和潜在结果这两个主要框架,提供了一个统一的接口,支持多种因果推断方法。这使得用户能够轻松地将不同的方法和途径结合到分析中,并选择最适合其特定问题的方法。

  • 自动测试假设有效性:DoWhy 包括一系列测试假设有效性的工具,如稳健性检验和敏感性分析。通过自动测试假设的有效性,用户可以确保他们的估计是可靠的,不会受到偏差或混杂因素的影响。

DoWhy 将因果推断过程分为四个步骤:建模识别估计反驳。在建模步骤中,用户创建因果图以编码他们的假设。在识别步骤中,用户制定他们希望估算的内容。在估计步骤中,用户使用统计估计方法计算效应估计值。最后,在反驳步骤中,用户通过敏感性分析和稳健性检验验证假设。

让我们动手试试,玩一玩 DoWhy。

DoWhy 的应用

我们将使用一个简单的合成数据集来演示 DoWhy 库的功能。

  1. 首先,导入 DoWhy 库以及我们将使用的组件,如下所示:

    import dowhy
    import dowhy.datasets
    from dowhy import CausalModel
    
  2. 接下来,使用 DoWhy 的 linear_dataset 函数,我们生成一个合成数据集,使得干预和感兴趣结果之间的关系是线性的,这也称为线性处理效应(在我们的例子中,我们选择了 beta=10,因此真实的干预效应为 10)。这将创建一个具有指定干预效应的线性模型,并生成符合此模型的一组合成数据点。生成的 DataFrame 包含表示干预的列、表示结果的列,以及一组表示常见原因和工具变量的列。此外,num_effect_modifiers 参数指定了影响干预效应的效应修饰符或变量的数量,num_samples 参数指定数据集中样本的数量,treatment_is_binary 参数指示干预是二元的还是连续的。如果干预是二元的,则它只能取两个值:有效或无效、开或关;如果干预是连续的,则它可以取多个值。stddev_treatment_noise 参数指定了干预噪声的标准差,这个噪声会添加到干预效应中,生成合成数据。生成的数据是 dictdata 类型。然后从中提取 DataFrame (df):

    # Generate data
    data = dowhy.datasets.linear_dataset(beta=10,
            num_common_causes=5,
            num_instruments = 2,
            num_effect_modifiers=2,
            num_samples=6000,
            treatment_is_binary=True,
            stddev_treatment_noise=9,
            num_discrete_common_causes=1)
    df = data["df"]
    
  3. df DataFrame 将有 11 列,其中 v0 列是干预名称,结果在 y 列,W0-W4 代表五个常见原因,Z0Z1 是两个工具变量,X0X1 是两个效应修饰符。现在,我们使用 CausalModel 类为我们的合成数据创建因果模型。CausalModel 类使用以下参数:

    1. data:一个 pandas DataFrame,包含数据。

    2. treatment:DataFrame 中将被视为 treatment 变量的列。它代表的是正在采取的干预或措施,目的是影响结果。

    3. outcome:DataFrame 中将被视为结果变量的列。

    4. common_causes:将被视为常见原因的列。这些变量既能影响干预,也能影响结果,通常也称为 instruments(工具变量):这些是用来推断因果关系的变量。

这将创建一个图形模型,表示数据中因果关系的结构。graph 参数指定了因果图,它编码了模型中变量之间因果关系的结构。这里,我们使用的是图形建模语言GML)文件格式的因果图:

# Input a causal graph in GML format
model=CausalModel(
        data = df,
        treatment=data["treatment_name"],
        outcome=data["outcome_name"],
        graph=data["gml_graph"]
        )

让我们查看 model.view_model() 图形:

图 9.14 – 数据集的因果图

图 9.14 – 数据集的因果图

  1. 接下来,我们查看目标变量和识别它们所需的假设。结果告诉我们估计量(模型估计的因果估计量,描述了感兴趣的因果效应)、它们的名称、表达式(用模型变量表示的估计量的数学表达式)以及所需的假设:

    # Identification
    identified_estimand =
            model.identify_effect(
            proceed_when_unidentifiable=True)
    print(identified_estimand)
    >>>
     Estimand type: EstimandType.NONPARAMETRIC_ATE
    ### Estimand : 1
    Estimand name: backdoor
    Estimand expression:
      d
    ─────(E[y|W0,W1,W3,W2,W4])
    d[v₀]
    Estimand assumption 1, Unconfoundedness: If U→{v0} and U→y then P(y|v0,W0,W1,W3,W2,W4,U) = P(y|v0,W0,W1,W3,W2,W4)
    ### Estimand : 2
    Estimand name: iv
    Estimand expression:
     ⎡                              -1 ⎤
     ⎢    d        ⎛    d          ⎞  ⎥
    E⎢─────────(y)⋅ ─────────([v₀])    ⎥
     ⎣d[Z₁  Z₀]     ⎝d[Z₁  Z₀]       ⎠  ⎦
    Estimand assumption 1, As-if-random: If U→→y then ¬(U →→{Z1,Z0})
    Estimand assumption 2, Exclusion: If we remove {Z1,Z0}→{v0}, then ¬({Z1,Z0}→y)
    ### Estimand : 3
    Estimand name: frontdoor
    No such variable(s) found!
    
  2. 现在让我们使用estimate_effect方法来识别估计量,以计算治疗效应的估计值。我们可以看到估计的均值是9.162,这表示治疗对结果的平均效应,在整个群体中的所有个体上都适用:

    # Estimation
    causal_estimate =
            model.estimate_effect(identified_estimand,
            method_name="backdoor.propensity_score_stratification")
    print(causal_estimate)
    >>>
     *** Causal Estimate ***
    ## Identified estimand
    Estimand type: EstimandType.NONPARAMETRIC_ATE
    ### Estimand : 1
    Estimand name: backdoor
    Estimand expression:
      d
    ─────(E[y|W0,W1,W3,W2,W4])
    d[v₀]
    Estimand assumption 1, Unconfoundedness: If U→{v0} and U→y then P(y|v0,W0,W1,W3,W2,W4,U) = P(y|v0,W0,W1,W3,W2,W4)
    ## Realized estimand
    b: y~v0+W0+W1+W3+W2+W4
    Target units: ate
    ## Estimate
    Mean value: 7.151535367146138
    
  3. 你可以使用refute_estimate函数来测试治疗效应估计在数据或模型假设的各种扰动下的稳健性。

总的来说,DoWhy 是一个强大的因果推断和分析工具。它提供了用于创建因果模型、识别效应、估计效应和验证估计的多种功能,是因果推断领域的研究人员和分析师的宝贵资源。

用于解释模型的 AI Explainability 360

AI Explainability 360 是一个开源工具包,提供了多种用于解释和理解机器学习模型的技术。它支持模型特定和模型无关的方法,以及局部和全局解释,为用户提供多种理解模型的选项。此外,该工具包构建于流行的机器学习库之上,包括 scikit-learn 和 XGBoost,方便与现有管道集成。

AI Explainability 360 的一些特点包括:

  • 模型无关和模型特定的可解释性技术:AI Explainability 360 提供了模型无关和模型特定的可解释性技术,可以用来理解和解释任何 AI 模型的预测。模型无关技术,如 LIME 和 SHAP,可以用来解释任何模型的预测,而模型特定技术,如特征重要性和部分依赖图,针对特定类型的模型进行定制。

  • 局部和全局解释:AI Explainability 360 提供了 AI 模型的局部和全局解释。局部解释侧重于理解模型对单个实例所做的特定预测,而全局解释则侧重于理解模型的整体行为。

  • 支持多种数据类型:AI Explainability 360 支持多种数据类型的解释,包括表格数据、文本、图像和时间序列数据。它提供了一系列针对每种数据类型特征的可解释性技术。

  • 与流行的 AI 框架集成:AI Explainability 360 被设计为可以轻松与流行的 AI 框架集成,包括 TensorFlow、PyTorch 和 scikit-learn,方便在实际应用中使用。

  • 广泛的文档和示例:AI 可解释性 360 配备了丰富的文档和示例,帮助用户在自己的项目中开始探索可解释性。

总体而言,AI 可解释性 360 是一个强大的工具包,用于理解和解释人工智能模型所做的预测,并构建透明、可信、公平的人工智能系统。

摘要

人工智能的未来在于使人们能够与机器协作解决复杂问题。像任何高效的合作一样,这需要良好的沟通、信任、清晰度和理解。XAI 旨在通过结合符号 AI 和传统机器学习的最佳特点来解决这些挑战。

在本章中,我们探讨了多种 XAI 技术,这些技术可以用于解释和解读机器学习模型。这些技术可以根据其范围(局部或全局)和模型类型(特定模型或无关模型)进行分类。

我们介绍了几种提供 XAI 功能的 Python 库,并解释了如何使用 ELI5、LIME 和 SHAP 探索模型预测中的特征重要性。LIME 可以为任何分类器做出基于实例的解释。LIME 使用可解释模型局部地近似分类器,并生成一个特征列表,列出在给定实例中对预测有贡献的特征。SHAP 使用 Shapley 值来解释每个特征对预测的贡献,支持局部和全局的解释,并且可以与各种模型类型一起使用。

DoWhy 是另一个因果推断和分析库。它提供了一个 API,涵盖因果分析中的常见步骤,包括建模、识别、估计和反驳。最后,我们介绍了 AI 可解释性 360,这是一个综合性的开源工具包,用于解释和解读机器学习模型。它支持特定模型和无关模型的解释,以及局部和全局的解释。

总之,市场上有多种工具和库可用于解释和解读机器学习模型。这些工具(如 ELI5、LIME、SHAP、CausalNex、DoWhy 和 AI 可解释性 360)提供了多种选项,用于理解模型如何做出预测,并且对于在 XAI 领域工作的研究人员和从业者非常有用。然而,必须注意的是,这一领域仍然存在一些局限性和挑战。

在下一章中,我们将深入探讨模型风险管理,并探索模型治理的最佳实践。

参考文献

  • 黑盒与白盒:从实践角度理解它们的优缺点,Loyola-Gonzalez, Octavio。IEEE Access 7(2019):154096-154113。

  • 可解释人工智能(XAI)中的机遇与挑战:一项调查。arXiv 预印本 arXiv:2006.11371,Das, Arun 和 Rad Paul。(2020)

  • 人机交互与可解释人工智能在医疗保健中的系统性回顾与人工智能技术。IEEE Access 9(2021):153316-153348,Nazar, Mobeen 等人。

  • 为什么我应该信任你?解释任何分类器的预测。Ribeiro, Marco Tulio,Singh Sameer 和 Guestrin Carlos。《第 22 届 ACM SIGKDD 国际知识发现与数据挖掘会议论文集》,2016 年。

  • 统一的模型预测解释方法。《神经信息处理系统进展》30。Lundberg, Scott M. 和 Lee Su-In(2017)

  • 通过定量输入影响实现算法透明性:学习系统的理论与实验。2016 IEEE 安全与隐私研讨会(SP)。Datta, Anupam,Sen Shayak 和 Zick Yair。IEEE,2016 年。

  • 通过特征贡献解释预测模型和个体预测。《知识与信息系统》41.3 (2014):647-665。Štrumbelj, Erik 和 Kononenko Igor。

  • 贝叶斯网络,Pearl, Judea. (2011)

  • 基于贝叶斯网络的学习教程。《贝叶斯网络的创新》(2008):33-82。Heckerman, David。

  • 概率图模型:原理与技术。MIT Press,2009 年。Koller, Daphne 和 Friedman Nir。

  • 统计中的因果推断:概述统计调查 3:96-146。Pearl, Judea. (2009)

  • CausalNex 文档:causalnex.readthedocs.io/en/latest/

  • DoWhy GitHub 仓库:github.com/py-why/dowhy

  • 介绍 AI 可解释性 360www.ibm.com/blogs/research/2019/08/ai-explainability-360/

第十章:道德与模型治理

本章提供了模型风险管理MRM)的详细概述,并介绍了最佳的治理实践,以帮助组织降低成本并提高效率。本章的主要目标是通过确保遵循正确的模型指标,展示 MRM 技巧,同时使用来自模型和数据两个角度的工具,帮助我们培养正确的风险缓解和治理实践。你将学习如何设计和制定风险管理记分卡,以帮助防止企业损失额外的资金。

此外,本章还强调了正确的策略和对数据或模型变化模式的了解在识别模型风险方面的有效性。这使我们能够量化部署在生产中的模型及其在模型库存中的风险。本章还解释了如何更好地管理和共享大量运行多个实验的模型库存,以便团队间可以协作共享。

在本章中,以下主题将在接下来的章节中进行讲解:

  • 模型风险 管理(MRM)

  • 模型版本控制

  • 特征存储简介

技术要求

本章要求你安装 Python 3.8,并安装以下内容:

本章的代码可以在 GitHub 上找到:github.com/PacktPublishing/Designing-Models-for-Responsible-AI/tree/main/Chapter10

模型风险管理(MRM)

在本节中,我们首先讨论为什么有必要为模型中的风险开发一个具体的框架,这一框架最早由顶级机构和金融行业提出。这使得银行和保险公司能够对 MRM 施加额外的控制。然而,这一框架可以扩展并应用到其他行业(如零售、媒体和娱乐),这些行业由于每天发生大量交易,已广泛采用持续监控和模型重训练管道。尽管我们将审视来自金融行业的一个真实案例,组织和领导层应该努力在任何 AI 产品和服务中采纳这些建议,因为 AI 的指南、法律和法规变得越来越严格。

现在我们已经了解了模型库存风险管理的重要性,接下来简要看看模型库存如何管理。模型库存管理是 MRM 的一个子部分。让我们了解它的类型。

模型库存管理的类型

AWS 提供了生产模型的目录管理和版本控制,支持模型库存管理,详细信息见此。模型注册表将元数据与模型关联,包括其训练指标、所有者名称和批准状态:

  • 分布式模型库存管理方法:该方法允许将模型文件和工件存储在它们生成所在的同一账户中。此外,模型会注册到与每个账户关联的 SageMaker 模型注册表中。因此,任何业务单元都可以拥有自己的机器学习测试账户进行用户验收测试(UAT),并允许将训练过程中生成的模型注册并保存在业务单元自己的 UAT/测试账户中。

  • 集中式模型库存管理方法:该方法允许所有生成的模型与关联的推理 Docker 容器镜像一起存储在共享服务账户中。此外,通过模型包组启用版本管理。任何在生产账户中进行的生产部署/升级,都可以通过来自中央模型包库的**Amazon 资源名称(ARN)**来实现版本控制。

模型风险管理监管指南SR 11-7)于 2011 年 4 月由美国联邦储备系统理事会发布。该文件阐述了模型风险的概念,并已成为行业标准。它列出了模型中存在的固定风险,以及由于基于错误或不当使用模型输出和报告的决策,在模型开发生命周期的任何阶段可能引发的不良后果。

该文件还强调了决策者理解模型局限性的重要性,并避免将模型用于其原本不适用的领域。随着模型风险的量化,欧洲银行管理局的监管审查与评估流程也应运而生,该流程规定应识别、映射、测试和审查模型风险,以便机构能够量化市场风险对资本的影响。同时,它还提供了在无法量化特定风险的实际资本金额时分配特定预算的灵活性。

在制定模型风险时,当局已经意识到在评估过程中考虑风险,以简化评估流程。当不同的操作风险因使用预测模型影响到企业时,需要采取措施,如下所述:

  • 当组织或银行低估自身资金,使用监管批准的模型时,风险就会产生。内部评级基础法IRB)模型在信用风险和资本充足性评估中尤为明显,便是这种情况的例子。

  • 风险与缺乏知识以及在定价产品和评估金融工具时不当使用模型相关。

让我们看看 MRM 所能提供的潜在节省。

MRM 的成本节约

MRM 的主要目标是通过提高构建、验证和部署模型的操作和流程效率来降低成本并防止损失,其中无效的模型将被淘汰。除了成本降低之外,由于减少了不必要的资本缓冲和附加费用,还带来了资本改善。一个定义明确的 MRM 职能通常能增强监管者的信心,减少罚款,并避免不合规带来的支出。MRM 显著改善了盈亏P&L),因为当解决了模型所有权分散的问题时,建模成本(以百万计)将大幅降低。复杂模型被替换,并增加了更具可解释性的版本,并将其分配给合适的业务单元。研究结果表明,一家全球银行在四年内额外花费了4400 万欧元,相比原本的700 万欧元(总计5100 万欧元),这显示出在模型上的资本预算花费几乎增长了七倍。得益于 MRM 框架,银行在现有模型环境中获得了信心,这有助于他们将模型投资与业务风险及其优先事项对齐,并减少盈亏波动。这不仅将重点放在模型的透明度上,还为他们提供了培养机构风险文化的方法。接着,成本节省释放了可以分配给高优先级决策模型的资源和资金。

明确定义和结构化的模型风险管理(MRM)方法的优势在于,它通过将机器学习开发成本降低20-30%,使得银行在面对模型不当使用的风险时更加谨慎,并使其将重点转向模型验证预算,以优化具有更高质量、一致性和韧性的模型库。另一个日益受到关注的重要因素是基于业务决策优先级的风险识别。在这里,我们可以看到模型风险分类技术(也称为分层技术)的出现,这种技术可以通过战略性地利用资源并建立强有力的治理,进一步提高速度和效率。

在金融行业,AI/ML 驱动的解决方案和自动化在管理与银行客户关系方面产生了巨大影响。投资组合管理和优化通过使用验证计划、流程和矩阵,已展示出为企业减少25%成本的效果,从而减少了低效性。通过自动化明确且重复的验证任务,测试和编码成本也显著节省了25%。例如,标准化测试和模型复制机制也已被引入。

图 10.1展示了模型风险的五大基石,具体如下:

  • 模型定义

  • 模型治理

  • 模型验证

  • 操作风险

  • 模型校准

这些可以在下图中看到:

图 10.1 - MRM 框架的四大支柱

图 10.1 – MRM 框架的四大支柱

每个模型定义(包括已退役、新模型和现有模型)都存储在模型清单中。模型清单包含与其相关的所有术语,以便为利益相关者提供一个关于模型的高层次概览,包括模型的作用和局限性。模型清单存储所有在生产中运行的 ML 模型,并允许我们创建依赖关系树,展示它们如何相互作用。

因此,它有助于绘制出哪些模型具有最大固有风险,主要是由于潜在的级联故障。

模型清单包括模型名称和描述、开发阶段(当前在用、开发中或已退役)、高级风险评估、模型目标、关于模型的假设及其局限性、模型的使用量、使用背景和财务影响。模型清单通常会随着时间的推移而过时,因此,管理清单的最佳方式是将责任分配给云/DevOps 工程师,由其负责模型清单管理,并与模型所有者紧密协调,确保每个模型的文档是最新的。文档还提供了模型创建过程中的尽职调查证据,并详细说明了验证的结果。

模型治理涉及与政策、控制、版本、角色与责任、文档、度量过程、报告、通知、模型的深入细节、风险评级以证明模型目标、模型的目标和局限性及其对其他模型的依赖等相关的所有活动和细节。由于模型治理控制模型版本和角色变更,它还负责量化模型的风险聚合,以及连续发布的模型版本。此外,模型执行的所有活动也都属于模型治理的范围。因此,它包括与变更控制过程、主要挑战、供应商使用、利益相关者凭证、生命周期过程和法规解释相关的所有信息。SR 11-7 中可用的 MRM 策略的正式化建议银行应专注于“测试与分析,主要目标是促进 准确性”(www.afponline.org/ideas-inspiration/topics/articles/Details/model-governance-and-model-risk-management)。

以下是建议的用于区分角色和责任的行动步骤:

  • 建立第二道和第三道防线,与高级管理层、模型开发者和模型验证人员合作,确保团队组成有适当的文档记录。这是为了为负责内部模型治理和监督的委员会提供授权和报告线,即使随着 ML 模型的变化,团队也会发生变化。

  • 模型所有者负责模型的开发、实施和使用。他们与高级管理层密切协调,以定义部署新模型的签字政策。

  • 模型开发者按照模型所有者的指导创建和实施机器学习模型。

  • 模型用户可以属于与业务对接的内部团队,或是需求和期望已经明确的外部团队。他们还可以参与模型的开发过程,以验证模型在训练过程中的假设。

  • 绘制出你的组织架构,包括能够快速识别并缓解与模型不确定性和缺陷相关的性能问题的外部资源。

模型验证过程不仅涉及模型的性能指标,还包括与设计过程、使用的数据评估方法、模型测试和文档(实际记录的内容)相关的所有细节。这是一个审计步骤,确保模型的表现符合文档中提到的输入数据和过程。

在模型验证过程中,会将模型的使用程度与预期的模型用途进行对比,这有助于我们决定风险评级;其局限性使我们能够进一步调整并记录设计控制。在验证阶段,所有与编程过程、将模型纳入网络、测试实施标准、基准测试以及每个模型的错误处理过程相关的信息都会得到验证。

组织可以选择定义内部和外部验证流程,以确保模型在部署之前达到期望的性能基准。通过结合外部验证(由外部审计人员或独立方执行验证)和内部验证(由同一团队或部门执行验证),可以实现双方验证策略。尽管验证通常由内部团队进行,但监管机构要求进行外部验证。验证的目标是揭示偏差、极限情况或文档、模型构建或版本控制中的遗漏,找出未考虑的情况,而无需模型所有者的输入。

操作风险识别所有涉及运行模型基础设施测试、模型版本管理、执行不同测试策略以及重新训练或更新模型的步骤。它不仅量化了由于数据本身存在固有问题或模型对另一个模型的依赖而产生的风险,还突出显示了由于微服务、延迟以及分布式拒绝服务DDoS)攻击对生产环境造成的风险。

模型校准 调整模型、模型的时机及建议模型需要重新训练和校准的特征,并衡量其可解释性与所需文档。此外,它还通过监控工具展示了模型重新校准的原因,例如数据和概念漂移。它处理模型跟踪方案,以便在发现模型偏离预期结果或模型误用时立即加以纠正。这需要使用持续的模型监控工具来检测和解决潜在问题,帮助保持模型的条件和性能一致且可重复,即使模型的输入或依赖发生任何变化。

现在,让我们看看一个组织如何在模型开发生命周期的后续阶段中演变其 MRM 框架。

MRM 的转型之旅

MRM 从起步到转型与差异化的旅程经历了三个不同的阶段。如图 10.2所示,MRM 设计框架包含以下几个阶段:

  • 基础阶段:该阶段建立了 MRM 政策、模型库存、基本的模型工作流工具以及模型治理标准。

  • 实施与执行的成熟阶段:MRM 框架在大规模应用于大量复杂的机器学习模型时得以实施。本阶段还需要利益相关者的培训,并实施自动化工作流工具,定义数据血缘、模型治理以及其生命周期中的其他控制和流程。

  • 通过价值进行转型/差异化:这一阶段涉及在卓越中心内开展 MRM 的研究和开发,推动工业化验证、透明度、流程效率以及资源的优化使用。

图 10.2 – 将 MRM 实践化

图 10.2 – 将 MRM 实践化

现在我们已经了解了 MRM 框架及其增强方式,接下来让我们学习两个可以帮助模型风险分级的重要工具。本章中描述的大多数模型风险分级工具和技术都受到了模型风险分级:行业实践与 原则www.risk.net/journal-of-risk-model-validation/6710566/model-risk-tiering-an-exploration-of-industry-practices-and-principles)的启发和/或改编。

模型风险分级

模型风险分层,从绝对的角度来看,是对模型库存风险的抽象外部表现,能够识别并区分一个模型的使用风险与其他模型的风险。评估指标是业务中(特别是在银行)需要考虑的重要参数,能够确定并对比单一业务用例的模型风险,反映任何问题的严重性。这直接取决于我们如何评估模型库存并定义风险分类因素。它与业务的其他外部和内部因素、市场条件以及其他财务风险因素密切相关,这些因素根据模型的重要性排序。

例如,规模、复杂性、年度/季度收入以及涉及的资本量等因素在为组织各部门设计定制化的 MRM 框架时都起着重要作用。例如,一家资产为 10 亿美元的地区性银行,其客户互动、机器学习模型行为、风险敞口和复杂性,与一家资产为 1 万亿美元的大型银行有所不同。

如果考虑这些因素,有助于根据业务的目的平衡 MRM 的层级结构。这些以业务为驱动的需求促使将模型划分为高风险层级、中风险层级和低风险层级,并能在一个稳健的 MRM 框架中共存,无论是对于小型企业,还是大型和复杂企业。

一个模型风险分层工具有助于通过考虑模型对企业决策的影响和重要性,明确模型的实质性(即根据使用量、使用背景和财务影响来衡量模型风险)和复杂性。输出模型的决策和模型质量也起着重要作用。模型分层过程还通过根据模型度量的优先级标准(由业务方规定)定义模型的等级,帮助模型风险的优先级排序。

  • 专家判断是设计一个分类工具的主要驱动力,该工具通过经验量化、评估和排序模型风险。它推动了工具的工作哲学,并由业务和功能决策驱动。

  • 一个模型风险分层工具应该简单易用、透明,并通过广泛地对所有库存模型进行分类,提供一致、可靠且公正的结果。

  • 它更侧重于模型的固有风险,而非模型的剩余风险。这里,固有风险指的是由于使用过时的模型验证技术、完全没有模型验证方法或未解决的问题所导致的模型风险和资本成本。模型的剩余风险则主要指的是当前模型与组织库存中其他模型相比的风险。

  • 模型风险类别帮助数据相关方了解模型中存在的相对风险,以及工具标记的不同层级中,预测所带来的间接风险。

  • 模型风险分层工具的设计过程应允许团队在组织内的不同业务单元和法务实体之间,强烈关联并链接模型中存在的相对风险。

  • 模型风险分类设计过程应生成并解释与管理层预期和业务结果一致的结果。该工具应能够解释所有库存模型的结果,并根据不同的权重因素进行分析。

模型风险分层为组织带来显著好处,尤其是在关键利益相关者意识到不同层级的模型失败所导致的业务损失时。可能包括以下内容:

  • 你可以评估和估算模型对当前(账面或市场)价值的影响。财务影响可以通过预测结果的单位(美元价值)以及被建模实体的单位(美元价值)进一步量化。

  • 你可以考虑因模型错误(由输入特征的敏感性引起)而导致的潜在业务损失(例如,因需求变化而失去客户)。计算得到的风险指标通常能够揭示模型由于外部波动性所导致的敏感性。

  • 你可以理解直接或间接消费预测结果的客户数量对建模实体的影响,或者被建模实体的数量。

  • 你可以基于结果分析模型的依赖关系,并评估对业务的影响。

现在,让我们来看看不同类型的风险分类工具。

模型风险树

模型风险树MRT),由 Mankotia 和 Joshi(2013 年)首次提出,如图 10.3所示,采用决策树方法进行分类,以评估模型使用的不同维度。这是一个双重过程,具有透明性,易于理解。它考虑了不同的暴露阈值来标记并分类模型为高风险、中等风险或低风险。

在树的第一层,维度评估模型是否量化风险、延迟、时机、价格或任何其他值——一个指定模型领域覆盖范围整体风险的指标。这为进一步的分类类别铺平了道路。回答“”得出结论,模型属于低风险层级,而回答“”则推动进入下一阶段。下一个评估指标尝试确定模型的使用维度,以判断模型是用于关键决策还是用于监管或财务报告。如果答案是“”,则该模型被标记为高风险或中等风险层级,而“”则将模型标记为低风险到中等风险层级。如果模型属于中等风险到高风险层级,则需要对相对于阈值的暴露水平进行测试。如果暴露水平较高,监管或财务决策模型将被归类为高风险,而暴露有限的相同类别模型则被标记为中等风险。未参与关键决策过程的模型将再次根据暴露水平进行测试,并被分类为低风险或中等风险。这种 MRT 完全依赖于判断输入,并且结果只有二元分类,没有空间容纳多于两种答案。

基于决策树的风险树面临的主要挑战之一是当涉及多级分类变量时,它会迅速使决策树变得非常复杂,导致其偏倚,且更难以表示和解释。它还未能充分区分模型的重要性(相关风险),这导致更多的模型被分配到更高的层级(聚类)。

图 10.3 – 模型风险分类

图 10.3 – 模型风险分类

随着多变量的可视化表示变得越来越具有挑战性,解决这一问题的最佳方式是使用更简单的基于评分卡的方法,如图 10.4所示。

模型风险评分卡

图 10.4展示了一个有效地将模型分类为不同风险类别的模型风险评分卡MRS)。该评分卡基于因子/元素方法原理,其中包含四个相关因子。因子可以通过单一元素表示,也可以通过多个元素表示:

  • 值范围列包括可以作为模型输入的值的可能范围。其中一些变量直接从模型配置文件中获取,而另一些则是在预处理后获得。数据转换步骤帮助我们将变量转化为连续、离散或多个级别或类别。这些包括美元影响或暴露、使用模型的用户数量以及广泛的输入变量类型和数量。

  • 权重列表示每个贡献因素(以黄色标注)对最终得分的相对重要性。通过将其量化为百分比,我们可以表示每个元素对整体评分结构(以粉色标注)的重要性。

  • 有两个调整,其中之一是资本压力测试指标,在模型分类过程中起着重要作用。它解释了模型在特定类别中的存在,无论其得分如何,以及它对其他因素的影响。

  • MRM 调整是一种得分覆盖度量,它覆盖基础结果并允许将配置的值添加到基础度量中。在这个例子中,赋予 MRM 小组负责人灵活性的值已固定为总体可能值的 50%。

  • MRS 会生成一个计算的风险分数,以得出模型所属的最终风险类别。如在图 10.4的风险等级分配中所示,它还包含模型的当前风险评级。

分配预处理阈值边界的过程,以及某些元素、因素权重和总体风险评分分类阈值的重要性,反映在评估矩阵中。

图 10.4 – 模型评分矩阵

图 10.4 – 模型评分矩阵

样本 MRS 将二元变量与多级分类变量混合使用。它还考虑了加权方案,帮助确定不同重要性的参数。MRS 有明显的优势,特别适用于那些希望在不同类别中包含多个分类变量的组织。MRS 具有清晰的表示风格,使得团队更容易解读计划并考虑使用错误模型的影响。

重要性因素得分衡量货币单位中的估计财务影响(范围从 1 到 4),而监管曝光因素得分则涵盖与 AI/ML 和财务报告相关的曝光因素(得分为 0 或 1)。操作因素得分对模型风险分级过程的总体贡献为 10%,其中 50%由最终用户计算EUC)实施贡献(得分因素为 0 或 1),50%由用户数量(得分范围为 1 到 4)贡献,后者是一个多层次的分类变量。

计算此操作风险元素的总体值,以评估其对模型 1最终得分贡献的公式是:

(1 × 50% + 2/4 × 50%) × 10% = 7.5%

我们知道,调整前的总体得分是 100,而操作因素模型 1模型 1得分表中的第三行)贡献了 7.5 分。

计算该模型复杂度的总体得分的公式,复杂度会影响最终得分中的风险元素,对于模型 1的公式是:

(1 × 40% + 2/4 × 20%) × 30% = 15%

我们还可以看到,最终的模型层级记录在三种不同颜色(绿色、粉色和橙色)的高亮框中。模型 1得分为 69,已被归类为Tier 2,而模型 2得分为 66.5,已被归类为Tier 1,其中Tier 2的阈值设定为 48 分,Tier 1的阈值为 78 分。此外,模型 1模型 2当前的风险级别分别记录为Tier 1Tier 3

我们还观察到有关模型 2模型 3的例外情况。模型 2的整体评分为 66.5 分,这本应将其归类为Tier 2,但该模型被分配到了Tier 1资本压力测试的覆盖度量设置为 1,这会自动将所有用于资本压力测试的模型分配到最上层类别,在我们的案例中即为最高风险层级。对于模型 3,整体得分为 22.5 + 8.75 + 3 = 34.75 分。MRM 团队的风险量化人员为其增加了 10 分,将得分提升到 44.75 分。然而,这个得分仍不足以影响最终的模型层级分配,因为它未达到 48 分的阈值。

在这个例子中,一个操作因素在解释模型失败风险方面起着明确的作用。它考虑了在受限环境中,模型给出意外结果时可能出现的问题,并探讨了生产环境中可能导致模型失败的因素。

模型风险校准

组织通常会把太多的模型归类为高风险,但这样做并不符合预期目的,也意味着 MRS 工具需要校准。校准的一种方法是保持模型的相对排名不变,从而最小化模型风险分配的变化。当风险层级的变化得到系统控制时,这减少了额外的工作,并使得可以在过程中使用已有的与风险相关的信息。校准通常是通过彻底的试错、对模型档案元素的迭代调整以及判断性过程来进行的,目的是对比、对照并评估不同风险类别中模型分布与库存的差异。

图 10.5 – 模型风险评分校准中的重要因素

图 10.5 – 模型风险评分校准中的重要因素

在模型重新校准中,模型在各层级之间的变动被记录下来,导致这些变动的主要因素也被记录。一些因素,如图 10.5所示,包括单个模型在多种产品或应用中重用的程度;模型库存的综合总结,其中缺失的模型被放置在低风险层级;帮助对齐模型的层级特定 MRM 要求;以及由于监管压力或承受压力测试而应被分类为高风险的库存比例。经过与业务和模型拥有者的审查后,组织可能仍然需要设置覆盖规则,以便 MRS 尽可能谨慎地将模型分配到各层级。这个多层级分类过程有助于解释由于合规要求、财务影响或其他业务因素,与某些类型或某些用途的模型相关的影响因素。

在本节中,我们学习了与模型风险分层相关的重要概念。现在,让我们学习模型的适应性和韧性,它们为强大的 MRM 框架奠定基础。

模型版本控制

模型管理是跟踪机器学习模型临时构建的重要环节。它促进了机器学习模型版本的管理、存储和索引,帮助在共享、查询和分析过程中发挥作用。在管理模型时,重新运行建模工作流变得越来越昂贵,这会消耗大量的 CPU/GPU 处理能力。为了使模型结果持久化,开发和部署能够自动构建、跟踪和负责模型开发生命周期中模型管理任务的工具是至关重要的。

模型管理通过生成每个机器学习模型的洞察,结合真实的版本控制,帮助减少开发和跟踪的工作量:

  • 数据科学家能够全面了解和洞察迄今为止构建的模型。

  • 它帮助我们通过版本化模型的预测结果来巩固和推断重要信息。检查版本化模型的指标使数据科学家能够利用当前模型对业务的影响。

  • 它帮助我们发现不同客户和市场细分的趋势与洞察,并加速跨模型的元分析。

  • 索引过程使数据科学家能够快速搜索模型库,以识别特征的正确或不当使用。

  • 它还促进了数据科学家之间的轻松协作。

现在,让我们讨论如何使用一种名为ModelDB的模型管理工具,在其本地环境中自动跟踪机器学习模型。

ModelDB

ModelDB 通过内置智能技术支持索引和模型探索,提供 SQL 查询和可视化界面。ModelDB 配备了不同的原生客户端学习环境(目前有spark.ml1scikit-learn2),一个优化存储模型的存储层,以及一个基于 Web 的可视化界面,可以在多个模型之间进行元分析。它可以记录涉及预处理、训练和测试步骤的多阶段流水线,通过管理与元数据(如预处理步骤的参数和模型超参数)、质量指标(如 AUC 和准确度)以及每个模型的训练和测试数据相关的信息。

图 10.6所示,ModelDB 有四个主要组件:适用于不同机器学习框架(如 Spark ML、scikit-learn 和 R)的原生客户端库,一个定义主要抽象的后台,作为存储层的中介访问器,以及一个用于可视化探索模型性能指标和元数据的 Web 用户界面。模型工件(数据样本、参数、属性、超参数、工件、模型指标以及所有涉及训练模型的元数据和参数的变更版本)通过 ModelDB 客户端提取,并通过 Thrift 接口存储在后台数据库中。

关系型数据库能够通过使用模型索引快速执行搜索操作,以检索模型工件。

图 10.6 – ModelDB 架构

图 10.6 – ModelDB 架构

所有模型和流水线都作为一系列动作存储,并通过一个分支模型来存储历史记录,以记录模型随时间发生的变化。后台的关系型数据库存储流水线信息,而一个自定义引擎则用于存储和索引模型。前端配备了一个易于导航的基于 Web 的可视化界面,允许进行模型和流水线的可视化探索和分析。我们来使用 ModelDB 进行一个实验:

  1. 要运行 ModelDB 实验,我们首先需要进行以下导入:

    import joblib
    from verta import Client
    from verta.dataset import Path
    from sklearn import ensemble
    
  2. 接下来,我们连接到 ModelDB 客户端,设置第一次实验,启动实验编号和数据集版本,以便记录与之相关的所有结果。我们还加载了用于训练和测试的 scikit-learn 糖尿病数据集:

    modeldb_client = Client("http://localhost:3000")
    proj = modeldb_client.set_project("Model Classification")
    expt = modeldb_client.set_experiment("ModelDB Experiment")
    run = modeldb_client.set_experiment_run("First Run")
    dataset = modeldb_client.set_dataset(name = "Diabetes Data")
    save_path = '/tmp/modeldb_model_artifacts/'
    dataset_version = dataset.create_version(Path(save_path))
    run.log_dataset_version("v1", dataset_version)
    diabetes = datasets.load_diabetes()
    X, y = diabetes.data, diabetes.target
    
  3. 加载数据集后,我们运行GradientBoostingRegressor(来自集成模型库),并使用交叉验证执行网格搜索:

    reg_model = ensemble.GradientBoostingRegressor()
    cv = RepeatedStratifiedKFold(n_splits=2, n_repeats=3, random_state=1)
    grid_search = GridSearchCV(estimator=reg_model, param_grid=params, n_jobs=-1, cv=cv, scoring='r2',error_score=0)
    grid_result = grid_search.fit(X, y)
    
  4. 在下一步中,我们记录最佳模型得分、损失值以及使用网格搜索结果优化模型时使用的不同超参数:

    print("Best: %f using %s" % (grid_result.best_score_, grid_result.best_params_))
    run.log_metric("r2", grid_result.best_score_)
    means = grid_result.cv_results_['mean_test_score']
    stds = grid_result.cv_results_['std_test_score']
    params = grid_result.cv_results_['params']
    i = 0
    for mean, stdev, param in zip(means, stds, params):
        print("%f (%f) with: %r" % (mean, stdev, param))
        run.log_observation("mean", mean)
        run.log_observation("stdev", stdev)
        param_dict = dict(param)
        param_dict['iter'] = str(i)
        i = i +1
        run.log_observation("lr", param_dict['learning_rate'])
        run.log_observation("loss", param_dict['loss'])
        run.log_observation("maxdepth", param_dict['max_depth'])
        run.log_observation("minsamplesplit", param_dict['min_samples_split'])
        run.log_observation("nestimator", param_dict['n_estimators'])
        run.log_observation("iter", param_dict['iter'])
    grid_result.fit(X_train, y_train)
    y_pred = grid_result.predict(X_test)
    train_score = grid_result.score(X_train, y_train)
    test_score = grid_result.score(X_test, y_test)
    run.log_metric("Accuracy_train", train_score)
    run.log_metric("Accuracy_test", test_score)
    
  5. 在获得训练和测试指标后,我们将它们记录在 ModelDB 中。此外,我们还会记录最佳的超参数和实际的模型文件(保存为joblib格式):

    run.log_metric("mse", mse)
    run.log_hyperparameters(grid_result.best_params_)
    filename_2 = "simple_model_gbr_2.joblib"
    joblib.dump(grid_result, filename_2)
    run.log_model(save_path, filename_2)
    test_score = np.zeros((grid_result.best_params_["n_estimators"],), dtype=np.float64)
    best_model = grid_result.best_estimator_
    print("test score shape", test_score.shape)
    for i, y_pred in enumerate(best_model.staged_predict(X_test)):
        test_score[i] = best_model.loss_(y_test, y_pred)
        run.log_observation("testscore", test_score[i])
    
  6. 我们可以绘制涉及的估计器与训练/测试得分的关系图(使用网格搜索结果返回的最佳参数)。该图会作为工件记录在 ModelDB 中:

    fig = plt.figure(figsize=(6, 6))
    plt.subplot(1, 1, 1)
    plt.title("Deviance")
    plt.plot(np.arange(grid_result.best_params_["n_estimators"]) + 1,
        best_model.train_score_,
        "b-",
        label="Training Set Deviance",
    )
    plt.plot(np.arange(grid_result.best_params_["n_estimators"]) + 1, test_score, "r-", label="Test Set Deviance"
    )
    plt.legend(loc="upper right")
    plt.xlabel("Boosting Iterations")
    plt.ylabel("Deviance")
    fig.tight_layout()
    plt.savefig(save_path + 'perf_gbr.png')
    run.log_artifact("perf_gbr", save_path + 'perf_gbr.png')
    

图 10.7 展示了 ModelDB 仪表板,识别模型的单个运行 ID,以及数据集版本、记录的工件、观察、指标和超参数:

图 10.7 – ModelDB 实验运行仪表板

图 10.7 – ModelDB 实验运行仪表板

以下图表帮助我们确定是否要研究随着训练轮次增加的任何模型指标:

图 10.8 – 随着训练轮次增加,ModelDB 仪表板上的性能指标

图 10.8 – 随着训练轮次增加,ModelDB 仪表板上的性能指标

在理解了 ModelDB 的架构和使用方式后,让我们来学习一下权重与偏差(Weights & Biases),它是另一个非常流行的用于跟踪机器学习模型的工具。

权重与偏差(Weights & Biases)

权重与偏差(Weights & Biases)是 MLOps 中的另一个实验跟踪工具,帮助对传统和深度学习模型进行版本管理。

让我们通过一个例子来了解如何跟踪和可视化结果:

  1. 首先,我们导入库并提供登录密钥,该密钥可以通过 wandb.ai/authorize 创建:

    import wandb
    wandb.login(key='') #please specify our own login key
    
  2. 在下一步中,我们通过为神经网络提供随机丢弃率来初始化一些实验。随机率在初始化 wandb 运行时作为参数提供:

    for _ in range(5):
    wandb.init(
    project="pytorch-intro",
    config={
    "epochs": 20,
    "batch_size": 64,
    "lr": 1e-3,
    "dropout": random.uniform(0.02, 0.90),
    })
    config = wandb.config
    
  3. 在接下来的步骤中,我们通过定义损失函数和优化器来训练我们的模型:

    model = get_model(config.dropout)
    loss_func = nn.CrossEntropyLoss()
    optimizer = torch.optim.Adam(model.parameters(), lr=config.lr)example_ct = 0
    step_ct = 0
    for epoch in range(config.epochs):
    model.train()
    for step, (images, labels) in enumerate(train_dl):
    images, labels = images.to(device), labels.to(device)
    outputs = model(images)
    train_loss = loss_func(outputs, labels)
    optimizer.zero_grad()
    train_loss.backward()
    optimizer.step()
    example_ct += len(images)
    metrics = {"train/train_loss": train_loss,
    "train/epoch": (step + 1 + (n_steps_per_epoch * epoch)) / n_steps_per_epoch,
    "train/example_ct": example_ct}
    if step + 1 < n_steps_per_epoch:
    wandb.log(metrics)
    step_ct += 1
    val_loss, accuracy = validate_model(model, valid_dl, loss_func, log_images=(epoch==(config.epochs-1)))
    
  4. 在最后一步,我们将训练和验证指标记录到 wandb 并结束 wandb 运行:

    val_metrics = {"val/val_loss": val_loss,
    "val/val_accuracy": accuracy}
    wandb.log({**metrics, **val_metrics})
    print(f"Train Loss: {train_loss:.3f}, Valid Loss: {val_loss:3f}, Accuracy: {accuracy:.2f}")
    wandb.summary['test_accuracy'] = 0.8
    wandb.finish()
    
  5. 它生成了以下汇总表,如图 10.9所示,包含来自 MNIST 数据集的每个数字。该表格可以通过以下代码获得:

    table = wandb.Table(columns=["image", "pred", "target"]+[f"score_{i}" for i in range(10)])
    for img, pred, targ, prob in zip(images.to("cpu"), predicted.to("cpu"), labels.to("cpu"), probs.to("cpu")):
    table.add_data(wandb.Image(img[0].numpy()*255), pred, targ, *prob.numpy())
    wandb.log({"predictions_table":table}, commit=False)
    

图 10.9 – wandb 跟踪数字 1-10 的预测概率

图 10.9 – wandb 跟踪数字 1-10 的预测概率

现在,所有模型实验都已经记录并通过 ModelDB 跟踪,模型的血缘信息可以得以维护。对于企业级 AI 应用程序,我们还可以借助数据血缘工具(如 Apache Atlas)建立级联血缘信息。

使用 Apache Atlas 的数据血缘

Atlas 可以与 Hive、Cassandra 及其他我们存储预测模型结果的数据库进行集成。Atlas 是一个可扩展的框架,满足 Hadoop 中的合规性要求,并与企业数据生态系统无缝集成。

Atlas 允许我们创建具有原始属性、复杂属性和对象引用的新类型的元数据。可以创建、组合和检索称为实体的实例类型,实体捕获元数据对象的详细信息及其关系。Atlas 提供了在动态创建分类时的极大灵活性,例如 PIIEXPIRES_ONDATA_QUALITYSENSITIVE,并支持 EXPIRES_ON 分类中的 expiry_date 属性。

谱系和搜索/发现操作可以通过 REST API 使用 SQL 自由支持。Atlas 的所有功能都具有内嵌安全性,允许其实体与多个分类相关联,而不会导致数据泄露。图 10.10 显示了当输出表 ML_O 被创建为两个输入表的联合时,谱系图的样子,ML_O 表示为 (select * from ML_I2) UNION ALL (select * from ML_I1)

图 10.10 – 使用 Apache Atlas 的模型谱系

图 10.10 – 使用 Apache Atlas 的模型谱系

在这里,我们能够看到由两个输入表生成的输出表的谱系。接下来,让我们看看如何通过命令来执行相同的操作:

  • 以下 curl 命令演示了谱系如何帮助定义一种结构,使得数据源可以被聚合,创建新的聚合源,检查源,或删除源。

lineage.json 中定义的 JSON 结构创建了两个输入 Hive 表,这些表可以组合成输出表:

curl -v -H 'Accept: application/json, text/plain, */*' -H 'Content-Type: application/json;charset=UTF-8' -u admin:admin -d @lineage.json
  • 可以通过点击实体找到 GUID,发现所有实体后,调用 API 如下:

    http://localhost:21000/api/atlas/entities
    
  • 在谱系中创建的任何实体都可以通过以下方式删除:

    curl -X DELETE -u admin:admin -H 'Content-Type: application/json; charset=UTF-8' 127.0.0.1:21000/api/atlas/entities?guid=febdc024-a3f8-4a66-be88-1e719c23db35
    

在检查了一些用于模型和数据治理的框架后,让我们简要了解特征库是什么,它们如何以可重用的方式连接数据和模型治理管道,从而在开发生产级 ML 模型时促进协作。

特征库简介

以数据驱动的组织,甚至是传统的组织,都已经意识到特征库在获取实时洞察中的作用和重要性。这些洞察对任何行业领域都非常有价值,因为它们传达了驱动业务的客户指标的有意义信息。这些洞察的实现得益于快速开发和使用预测微服务,能够处理批量数据和实时数据。云端可扩展特征库的主要目的是通过将业务利益相关者、架构师、数据科学家、大数据专业人士和分析专业人士汇聚到一个统一的基础构件下,节省精力和时间。这一特征库促进了数据、模型、特征、结果和报告的共享,从而实现了跨团队的协作,增强了模型部署生命周期。通过允许信息的重用、创建结构化文档、进行必要的版本分析和评估模型性能,特征库能够提升跨团队的协作效果。

特征库的主要目标是:

  • 移除各个团队定制系统的开发和维护,转而鼓励跨部门的协调空间,支持任何类型的数据共享。

  • 创建一个基于访问驱动的协作空间,便于发现和共享类似类型 ML 模型的特征。当数据来自相同的业务且预测面向相似的客户群体时,这可以节省时间、精力和构建新模型的开发成本。

  • 通过利用现有的微服务,在可扩展的大数据系统中复用数据。

  • 允许在微服务内部进行轻松集成和通信,具备更强的模型特征分析、再训练、度量比较、模型治理和可追溯性的能力,从而减少每一轮敏捷开发生命周期中所花费的时间。

  • 便于轻松跟踪、版本控制和重新训练具有季节性特征的模型,而无需重复进行特征工程和模型训练时涉及的非线性/指数成本。

  • 通过设置警报和触发器,跟踪模型训练中特征的添加和/或删除。

  • 基于传入的新数据推导特征和洞察,这些数据可以用来推算特征、预计算并自动填充特征。这包括在线计算和离线聚合,以确保训练和服务之间的一致性。

  • 确保个人身份信息(PII)的隐私和机密性(无论是在数据库、缓存还是磁盘中),并通过衡量隐私和公平度指标,以及预测模型的可解释性,确保遵循伦理特征存储设计。

现在,让我们通过图 10.11来说明 Comcast 开发的特征存储框架:

图 10.11 – 在线与离线特征存储

图 10.11 – 在线与离线特征存储

图 10.11所示的特征存储架构允许对流数据和按需特征进行持续的特征聚合。它可以帮助数据科学家复用版本化特征,上传在线(实时)/流数据,并按模型查看特征度量。特征存储是一个动态灵活的单元,能够支持多个可插拔单元。传入特征组装的负载(一个包含模型执行所需特征的仓库,其中包含模型名称和账户号)会被加入,使得特征存储能够持续刷新新数据和新特征,基于模型度量进行再训练,并验证伦理性与合规性。模型的元数据可以解释哪些特征对于哪些团队是必要的,并显著有助于推导模型的洞察。

内置的模型仓库(如图 10.12所示)包含与数据预处理(归一化和缩放)相关的工件,展示了执行模型所需特征的映射。该架构使用 Spark 在 Alluxio 上构建(Alluxio 是一个开源的数据编排层,将数据带到计算近处,以支持云中大数据和 AI/ML 工作负载),并结合了 S3、HDFS、RDBMS、Kafka 和 Kinesis。

这种特征存储可以为组织提供可扩展的、容错的、分布式的功能,帮助共享、处理、追踪和存储用例、模型、特征、模型与特征的映射、版本化模型和数据集。当与定义良好的编排服务(如 Kubeflow)集成时,它可以使模型部署容器、预测/结果接收器、容器仓库和 Git 集成数据、代码和运行时工件,以实现 CI/CD 集成。

图 10.12 – 在线和流数据的特征存储中的特征处理

图 10.12 – 在线和流数据的特征存储中的特征处理

现在,让我们通过示例代码来看如何从特征存储中检索历史数据并训练模型。在这里,我们使用了 Google 的特征存储 Feast,以及来自 BigQuery 数据集 feast_driver_ranking_tutorial 的司机排名数据:

  1. 在初始步骤中,我们导入必要的 Python 库,并从磁盘加载司机订单数据:

    import feast
    from joblib import dump
    import pandas as pd
    from sklearn.linear_model import LinearRegression
    orders = pd.read_csv("/content/feast-driver-ranking-tutorial/driver_orders.csv", sep="\t")
    orders["event_timestamp"] = pd.to_datetime(orders["event_timestamp"])
    
  2. 在下一步,我们连接到特征存储提供商并从 BigQuery 检索训练数据:

    fs = feast.FeatureStore(repo_path="/content/feast-driver-ranking-tutorial/driver_ranking")
    training_df = fs.get_historical_features(
    entity_df=orders,
    feature_refs=[
    "driver_hourly_stats:conv_rate",
    "driver_hourly_stats:acc_rate",
    "driver_hourly_stats:avg_daily_trips",
    ],
    ).to_df()
    print("----- Feature schema -----\n")
    print(training_df.info)
    

这将输出以下结果:

图 10.13 – 使用特征存储进行历史数据检索

图 10.13 – 使用特征存储进行历史数据检索

  1. 现在,我们使用以下代码片段来训练并保存我们的模型:

    target = "trip_completed"
    reg = LinearRegression()
    train_X = training_df[training_df.columns.drop(target).drop("event_timestamp")]
    train_Y = training_df.loc[:, target]
    reg.fit(train_X[sorted(train_X)], train_Y)
    dump(reg, "driver_model.bin")
    
  2. 训练后,我们需要通过以下命令将在线存储物化到 Firestore 中,数据科学家负责访问特征存储并选择将更新到在线存储的日期:

    !cd /content/feast-driver-ranking-tutorial/driver_ranking/ && feast materialize-incremental 2022-01-01T00:00:00
    

这将输出以下结果:

图 10.14 – 将数据保存到在线特征存储

图 10.14 – 将数据保存到在线特征存储

  1. 在最后一步,我们再次选择相同的特征存储来进行预测,并选择最佳的司机:

    self.fs = feast.FeatureStore(repo_path="/content/feast-driver-ranking-tutorial/driver_ranking/")
    # Read features from Feast
    driver_features = self.fs.get_online_features(
    entity_rows=[{"driver_id": driver_id} for driver_id in driver_ids],
    features=[
    "driver_hourly_stats:conv_rate",
    "driver_hourly_stats:acc_rate",
    "driver_hourly_stats:avg_daily_trips",
    ],
    )
    df = pd.DataFrame.from_dict(driver_features.to_dict())
    df["prediction"] = reg.predict(df[sorted(df)])
     best_driver_id = df["driver_id"].iloc[df["prediction"].argmax()]
    

在这个示例中,我们学习了在线特征存储如何在训练和预测任务中发挥作用。在 第十三章 中,我们将进一步了解如何使用特征存储的高级概念,促进团队间的合作并推动可持续的训练。

总结

本章中,我们学习了 MRM 指导方针以及组织如何使用这些指导方针节省成本。我们探讨了通过研究与 MRM 相关的不同概念(如模型风险分层、MRT、MRS 和模型风险校准)来减轻业务损失的过程、功能和清单。我们还了解了如何确保正确的目标、假设、限制、量级、政策、控制、角色与职责、文档、测量程序、报告、通知、风险量化和评估方法得以实施。 本章还深入探讨了如何监控模型指标以及理解为什么这很重要,因为模型会受到漂移和模型重训练的影响。

在本章的结尾,我们还学习了特征库。在下一章,我们将学习更多与模型漂移和模型校准相关的详细概念。

进一步阅读

第四部分:实施组织战略、最佳实践和应用案例

本部分提供了组织战略、可持续技术和最佳实践的全面概述,这些都是为了适应伦理 AI 在组织和政府大规模采用而应采纳的。本部分强调了如何设计稳健的机器学习模型,使其能够适应输入数据的各种变化。还介绍了不同专家小组和工作组织的倡议和行动计划,用于衡量和量化 AI 解决方案对客户、国家或环境可能产生的负面影响。此外,本部分还突出了实际的行业广泛应用案例,旨在加速伦理 AI 解决方案的使用,无论解决方案的规模和大小如何。

本部分由以下章节组成:

  • 第十一章模型适应性的伦理问题

  • 第十二章构建可持续的企业级 AI 平台

  • 第十三章可持续模型生命周期管理、特征库和模型校准

  • 第十四章行业广泛应用案例

第十一章:模型适应性的伦理

本章详细介绍了如何在组织中为模型治理目的检测不同类型的模型漂移。本章的主要目标是展示机器学习(ML)模型的变异,通过多个示例让你意识到检测数据变化和模型指标变动所需的不同统计量的重要性。这将帮助数据科学家和 MLOps 专业人员选择合适的漂移检测机制,并遵循正确的模型指标性能阈值,以控制由于错误预测带来的风险。你将学会如何量化和解释模型漂移,并解答与模型校准需求相关的问题。这还将使你能够理解设计合理校准模型的范围。

本章将覆盖以下内容:

  • 数据和模型漂移的适应性框架

  • 如何解释在漂移或校准条件下的机器学习模型

  • 理解模型校准的必要性

技术要求

本章要求你使用 Python 3.8 并在开始之前运行以下命令:

安装步骤中提到的alibi-detect包可以在 GitHub 上找到。作为参考,你可以在github.com/SeldonIO/alibi-detect查看该项目的更多细节。

数据和模型漂移的适应性框架

数据处理取决于数据访问的方式,基于其可用性,无论是顺序数据还是连续数据。随着不同模式的输入数据处理和建模技术的建立,各种因素(内部和外部)会导致数据分布发生动态变化。这种变化被称为概念漂移,它对生产中的机器学习模型构成了若干威胁。在概念漂移术语中,关于数据分布的变化,窗口一词用来指代用于训练当前或最近预测器的最新已知概念。

概念漂移的例子可以在电子商务系统中看到,其中机器学习算法分析用户的购物模式,并提供个性化的相关产品推荐。导致概念漂移的因素包括婚姻、搬迁到不同地理区域等事件。COVID-19 疫情导致了消费者购买行为的剧烈变化,因为人们被迫转向电子商务平台进行在线购物。这导致了对产品的需求远高于预期,从而在供应链网络中的需求预测中产生了高错误率。电子商务、供应链和银行行业已经经历了数据模式的变化,导致模型漂移。

图 11.1 – 四种概念漂移类型

图 11.1 – 四种概念漂移类型

图 11.1所示,概念漂移有四种类型,可能由各种内部或外部因素,甚至是对抗性活动引起:

  • 突变:由行为变化引起

  • 增量:突发变化,具有较慢的衰减

  • 重现:类似于季节性趋势

  • 渐变:缓慢、长期的变化

其他间接因素,如学习速度、报告正确特征(或度量单位)时的错误,以及分类或预测准确性的巨大变化,也可能导致概念漂移。图 11.2中进行了说明。为了解决概念漂移,我们需要更新导致漂移的模型。这可能是盲目更新或使用加权数据训练、模型集成、增量模型更新,或者应用在线学习模式。

图 11.2 – 漂移因素和补救措施的不同类型

图 11.2 – 漂移因素和补救措施的不同类型

我们根据数据到达模式(批处理或在线)对概念漂移检测器(如图 11.3所示)进行分类。批处理检测技术可以进一步分为全批次检测和部分批次检测技术。批次的大小和样本是将其分类为全批次或部分批次检测的两个因素。在线检测器则根据其调整参考窗口的能力来检测漂移。检测窗口通常是一个滑动窗口,随着新的实例到来而移动,通常被称为当前概念。然而,也有使用固定参考窗口来检测概念漂移的情况。

在线检测器通过评估前W个数据点计算的测试统计量来工作,然后更新测试统计量。更新可以以较低的成本按顺序进行,从而帮助我们检测测试统计量是否超出阈值。超过阈值的值表示已经发生了漂移。

图 11.3 – 常用的漂移检测器

图 11.3 – 常用的漂移检测器

图 11.3展示了无监督批量基础(固定窗口)和基于在线(固定和滑动窗口)漂移检测技术的概念,这些方法在必要的数据分布比较和显著性测试后,用来检测是否存在漂移。批量方法可能需要在批次上进行实例选择和统计计算,以确认漂移条件的测试,从而推断是否发生了漂移。这里的数字表示检测在线和离线漂移所需的步骤顺序。

图 11.4 – 在线和批量漂移检测方法

图 11.4 – 在线和批量漂移检测方法

一个在线漂移自适应框架的例子是性能加权概率平均集成PWPAE)框架,能够在 IoT 异常检测应用场景中有效使用。

该框架可以部署在 IoT 云服务器上,利用来自 IoT 设备的无线媒介处理大数据流。这个集成自适应漂移检测器由四个基础学习器组成,帮助进行实时漂移检测:

  • 一个带有ADWIN 漂移检测器自适应随机森林ARF)模型(简称ARF-ADWIN

  • 一个带有DDM 漂移检测器的 ARF 模型(简称ARF-DDM

  • 一个带有ADWIN 漂移检测器流随机补丁SRP)模型(简称SRP-ADWIN

  • 一个带有DDM 漂移检测器的 SRP 模型(简称SRP-DDM

四个基础在线学习器通过根据它们的准确性和分类概率加权组合在一起。让我们在 CICIDS2017(www.unb.ca/cic/datasets/ids-2017.html)模拟入侵检测数据集上尝试 PWPAE 框架,该数据集包含良性和近期常见的攻击,类似于真实世界的例子:

  1. 为了运行 PWPAE,让我们首先从river包中导入必要的模块:

    from river import metrics
    from river import stream
    from river import tree,neighbors,naive_bayes,ensemble,linear_model
    from river.drift import DDM, ADWIN
    
  2. 然后,我们使用X_trainy_train设置 PWPAE 模型进行训练,并在X_testy_test上进行测试。以下代码片段展示了如何使用 PWPAE 模型:

    name = "Proposed PWPAE model"
    t, m = PWPAE(X_train, y_train, X_test, y_test)
    acc_fig(t, m, name)
    

训练结果和比较输出在图 11.5中进行了可视化。

图 11.5 – PWPAE 与 Hoeffding 树(HT)和提升袋装(LB)模型的性能结果

图 11.5 – PWPAE 与 Hoeffding 树(HT)和提升袋装(LB)模型的性能结果

PWPAE 的准确率为 99.06%,超越了其他模型的准确率。

让我们研究一些有监督的漂移检测策略,其中可以获得实际的预测反馈,并与预测结果一起使用,以产生误差指标。

统计方法

统计方法帮助我们比较和评估两种不同的分布。散度因子或距离度量可以用来衡量两种分布在不同时间点的差异,以了解它们的行为。这有助于及时检测模型的性能指标,并找出导致变化的特征。

库尔巴克–莱布勒散度

库尔巴克–莱布勒KL)散度,也通常称为相对熵,量化了一个概率分布与另一个概率分布之间的差异。数学上,它可以表示为以下公式:

Q 是旧数据的分布,P 是新数据的分布,我们为此计算散度,|| 表示散度。当 Px)很高而 Qx)很低时,散度会很高。另一方面,如果 Px)较低而 Qx)较高,散度会很高,但不会太高。当 Px)和 Qx)相似时,散度会很低。以下代码为一个均值为 5,标准差为 4 的(PQM)分布生成一个 KL 散度图:

x = np.arange(-10, 10, 0.001)
q = norm.pdf(x, 5, 4)
plt.title('KL(P||Q) = %1.3f' % kl_divergence(p, q))
plt.plot(x, p)
plt.plot(x, q, c='red')

由于 KL 散度导致的分布模式变化在图 11.6中有所展示:

图 11.6 – KL 散度

图 11.6 – KL 散度

还有更多形式的散度,接下来我们将讨论这些。

詹森–香农散度

詹森–香农JS)散度使用 KL 散度,并可以通过以下数学公式表示:

KL 散度与 JS 散度之间的一个区别是,JS 散度是对称的,并且具有强制性的有限值。由于 JS 散度导致的分布模式变化在图 11.7中有所展示:

图 11.7 – JS 散度

为了计算 JS 和 KL 散度,我们运行以下代码片段:

  1. 首先,我们为分布 1 创建一个正态分布:

    data1 = scipy.stats.norm.rvs(size=100000, loc=0, scale=1.5, random_state=123)
    hist1 = np.histogram(data1, bins=100)
    hist1_dist = scipy.stats.rv_histogram(hist1)
    import matplotlib.pyplot as plt
    X1 = np.linspace(-8.0, -2.0, 1000)
    plt.title("PDF")
    plt.hist(data1, density=True, bins=100,  color ='blue')
    plt.plot(X1, hist1_dist.pdf(X1), label='PDF', color = 'blue')
    
  2. 接下来,我们创建另一个正态分布,这就是我们的第二个分布:

    data2 = scipy.stats.norm.rvs(size=100000, loc=0, scale=5.5, random_state=123)
    hist2 = np.histogram(data2, bins=100)
    hist2_dist = scipy.stats.rv_histogram(hist2)
    X2 = np.linspace(4.0, 8.0, 1000)
    plt.title("Probability Density Function")
    plt.hist(data2, density=True, bins=100, color ='green')
    plt.plot(X2, hist2_dist.pdf(X2), label='PDF', color = 'green')
    plt.legend(['X1', 'X2'])
    
  3. 在下一步中,我们首先评估概率分布 1 与 Y1Y2 的均值之间的 KL 散度,同样地,我们也评估概率分布 2:

    Y1 = hist1_dist.pdf(X1)
    Y2 = hist2_dist.pdf(X2)
    M = (Y1 + Y2) / 2
    d1 = scipy.stats.entropy(Y1, M, base=2)
    print("KL div Y1 and M", d1)
    d2 = scipy.stats.entropy(Y2, M, base=2)
    print("KL div Y2 and M", d2)
    
  4. 上一步的输出如下所示:

    KL div X1 and X2 0.21658815880427068
    KL div Y1 and M 1.0684247605300703
    KL div Y2 and M 0.1571132219534354
    
  5. 在下一步中,我们首先评估分布之间的 JS 散度,也评估每个分布内部的 JS 散度:

    js_dv = (d1 + d2) / 2
    js_distance = np.sqrt(js_dv)
    print("JS Dist d1 and d2", js_distance)
    

我们将其与 SciPy 计算的分布之间的 JS 散度进行比较:

js_distance_scipy = scipy.spatial.distance.jensenshannon(Y1, Y2)
print("JS Dist d1 and d2 of Scipy", js_distance_scipy)
js_distance_scipy = scipy.spatial.distance.jensenshannon(X1, X2)
print("JS Dist X1 and X2 of Scipy", js_distance_scipy)
dx1 = scipy.stats.entropy(Y1, X1, base=2)
dx2 = scipy.stats.entropy(Y2, X2, base=2)
js_dv = (dx1 + dx2) / 2
print("JS Div X1 and X2", js_dv)

上述步骤的输出如下所示:

JS Dist d1 and d2 0.7827956254615587
JS Dist d1 and d2 of Scipy 0.6037262820103958
JS Dist X1 and X2 of Scipy 0.1941318696014193
JS Div X1 and X2 1.3749093686870903

第一个距离给出了对称的 JS 散度,而第二个评估的度量给出了 JS 距离,这是 JS 散度的平方根。评估出的第三个和第四个距离度量分别给出了 X1X2dx1dx2 之间的 JS 距离。这里的 dx1dx2 表示从 Y1X1Y2X2 分布中生成的熵。

科尔莫哥罗夫–斯米尔诺夫检验

两样本Kolmogorov-SmirnovKS)检验是一种常用的非参数方法,用于区分两个样本。通过 KS 检验识别的数据变化模式如图 11.8所示。累积分布函数CDF)表示在样本中低于x的观察值的百分比。这可以通过以下步骤获得:

  1. 对样本进行排序

  2. 计算样本内观察值的数量是否小于或等于x

  3. 将步骤 2 中计算的分子除以样本上的总观察值数量

漂移检测器的目的是在两个分布函数观察到变化时,检测漂移模式,这会导致两个样本形态的变化:

图 11.8 – KS 检验

图 11.8 – KS 检验

人口稳定性指数

人口稳定性指数PSI)是一种监测和衡量两个样本或两个时间段之间人口行为变化的指标。它作为一个风险评分卡指标,用于提供一个时间外验证样本与建模样本之间的风险估计,包括依赖变量和独立变量。PSI 的应用还可以扩展到社会人口学研究中比较两个或更多人口的教育、收入和健康状况。

模型蒸馏是一种技术,它允许将知识从一个大网络转移到一个小网络,该小网络在简化架构上使用从原始模型提取的软目标(输出分布或 logits)训练第二个模型。这为通过比较原始模型和蒸馏模型的输出分布来检测对抗性和恶意数据以及数据漂移铺平了道路。

现在让我们通过一个例子,看看如何在漂移检测的背景下通过模型蒸馏检测器检测对抗得分。KS 检验已被用作评分函数,以便在参考批次和测试数据的对抗得分之间进行简单的一维检验。较高的对抗得分表示有害的漂移,并为恶意数据漂移设置标志。在这里,我们可以从 Google Cloud 桶中提取预训练的模型蒸馏检测器,或者从头开始训练一个:

  1. 首先,我们从alibi_detect导入必要的包:

    from alibi_detect.cd import KSDrift
    from alibi_detect.ad import ModelDistillation
    from alibi_detect.models.tensorflow.resnet import scale_by_instance
    from alibi_detect.utils.fetching import fetch_tf_model, fetch_detector
    from alibi_detect.utils.tensorflow.prediction import predict_batch
    from alibi_detect.utils.saving import save_detector
    from alibi_detect.datasets import fetch_cifar10c, corruption_types_cifar10c
    
  2. 然后,我们定义并训练蒸馏模型:

    from tensorflow.keras.layers import Conv2D, Dense, Flatten, InputLayer
    from tensorflow.keras.regularizers import l1
    def distilled_model_cifar10(clf, nb_conv_layers=8, distl_model_filters1=256, nb_dense=40, kernel1=8, kernel2=8, kernel3=8, ae_arch=False):
        distl_model_filters1 = int(distl_model_filters1)
        distl_model_filters2 = int(distl_model_filters1 / 2)
        distl_model_filters3 = int(distl_model_filters1 / 4)
        layers = [InputLayer(input_shape=(64, 64, 3)),
                  Conv2D(distl_model_filters1, kernel1, strides=2, padding='same')]
        if nb_conv_layers > 2:
            layers.append(Conv2D(distl_model_filters2,
    kernel2, strides=2, padding='same', activation=tf.nn.relu, kernel_regularizer=l1(1e-5)))
        if nb_conv_layers > 2:
            layers.append(Conv2D(distl_model_filters3, kernel3, strides=2, padding='same',
                                 activation=tf.nn.relu, kernel_regularizer=l1(1e-5)))
        layers.append(Flatten())
        layers.append(Dense(nb_dense))
        layers.append(Dense(clf.output_shape[1], activation='softmax'))
        distilled_model = tf.keras.Sequential(layers)
        return distilled_model
    
  3. 接下来,根据我们的配置,我们可以选择加载一个预训练模型或训练一个新模型:

    load_pretrained = True
    detector_type = 'adversarial'
    detector_name = 'model_distillation'
    filepath = os.path.join(filepath, detector_name)
    if load_pretrained:
        ad = fetch_detector(filepath, detector_type, dataset, detector_name, model=model)
    else:
        distilled_model = distilled_model_cifar10(clf)
        print(distilled_model.summary())
        ad = ModelDistillation(distilled_model=distilled_model, model=clf)
        ad.fit(X_train, epochs=50, batch_size=128, verbose=True)
        save_detector(ad, filepath)
    
  4. 我们现在绘制每个严重程度级别的平均得分和标准差。我们将模型准确性图定义为有害和无害得分的均值和标准差:

    def evaluate_plot_model_accuracy():
    mu_noharm, std_noharm = [], []
    mu_harm, std_harm = [], []
    acc = [clf_accuracy['original']]
    for k, v in score_drift.items():
       mu_noharm.append(v['noharm'].mean())
       std_noharm.append(v['noharm'].std())
       mu_harm.append(v['harm'].mean())
       std_harm.append(v['harm'].std())
       acc.append(v['acc'])
    

图表(见图 11.9)展示了不同数据损坏严重度等级下的平均危害评分(从左侧开始的折线图)和 ResNet-32 准确率(右侧显示的柱状图)。级别 0 对应原始测试集。我们展示了不同恶意(损坏)数据及其严重度对模型的影响。

危害评分表示由于数据损坏而给出错误预测的实例。即使是无害的预测也存在,这些预测(如Y轴上标注为黄色的危害指数所示)在数据损坏后保持不变,这是由于恶意对抗样本的注入。进一步总结,我们可以在图 11.9中看到,随着危害评分的增加(由青色柱状图表示),损坏严重度加剧,准确率下降(由蓝色折线表示)。

图 11.9 – 提取型漂移检测器检测数据损坏严重度

图 11.9 – 提取型漂移检测器检测数据损坏严重度

还有一些其他方法可以归类为上下文方法。

上下文方法

这些方法的目的是比较并评估训练集与测试集之间的差异,并在预测结果存在显著差异时评估漂移情况。

树的特征

该方法允许你基于数据和预测时间戳训练一个简单的树模型,时间戳作为独立输入特征之一,与其他特征一起使用。通过分析树模型的特征重要性,显而易见,不同时间点的数据对模型的影响有助于揭示由概念漂移引起的差异。树的分裂以及基于时间戳的特征分裂,有助于解释漂移带来的变化。

洗牌与重采样(SR)

数据在假定的漂移点处被分为训练集和测试集,然后使用训练集训练模型,并通过测试集评估模型的错误率。通过洗牌相同的数据集并重新计算错误度量,重复相同的训练和测试机制。当天订单数据的错误率与洗牌数据的平均错误率之间的差异超过指定阈值时,认为检测到了漂移。这也是一个计算密集型机制,因为它涉及在漂移发生时训练多个模型。

统计过程控制

这种漂移检测器控制机制确保当生产中的模型随着时间产生变化的准确度指标时,模型的误差能够得到管理。尽管这种方法在短时间内有效检测到突发性、渐进性和增量性的漂移,但提取样本标签时可能存在较高的延迟。要求有标签数据的限制使得该方法更难以广泛应用。

漂移检测方法(DDM)

这种漂移检测方法是最早设计的方法之一。假设输入数据呈现二项分布,且伯努利试验变量(或单一数据点)根据预测误差率推断漂移的发生。

该算法记录最小误差概率p)率和二项分布的最小标准差s),当p + s达到其最小值时。若p + s的值超过最小误差概率(pmin)与最小标准差的倍数(smin)的和,则认为存在漂移。我们可以表示为(p + s)>(pmin + 3 ✶ smin)。

推荐的乘数因子是 3。当变化发生缓慢时,该方法有局限性,此时缓存/内存可能会溢出。

早期漂移检测方法(EDDM)

这种方法虽然与 DDM 类似,但通过计算两个误差之间的均值m)和标准差s)来关注渐进式漂移。它记录(m + 2 ✶ s),当该值达到最大值时,会将这两个值分别保存为 mmax 和 smax。当比率(m + 2 ✶ s)/(m + 2 ✶ smax)低于阈值(β;推荐值为 0.9)时,漂移被检测到,并应触发警报。

CUSUM 和 Page-Hinkley

累积和CUSUM)及其变种Page-HinkleyPH)都依赖于顺序分析技术,通常基于平均高斯信号。这些方法通过检测当观察值与均值之间的差异超过用户定义的阈值时发出警报。由于这些变化对参数值敏感,这种方法的一个缺点是可能会触发误报。这些方法可以广泛应用于数据流。

CUSUM

该漂移检测算法使用 CUSUM 检测均值的微小变化。当变化前后的概率分布已知时,CUSUM 过程通过考虑延迟和误报频率来优化目标函数。它具有额外的优点,即在最大似然的解释上简单直观。它是无记忆的、单侧的和不对称的,只能检测观察值与均值之间差异的增加。

CUSUM 检测器是一种基于核的方法,持续比较数据库中的样本。漂移判断的指标叫做最大均值差异MMD)。该程序非常适合大数据量,因为它无需比较变化前后的分布,而是集中于当前数据来识别漂移。CUSUM 已经被增强,使用嵌套滑动窗口的双均值方法,这被称为基于数据流的双 CUSUMDCUSUM-DS)。CUSUM 的另一个变体是 DCUSUM-DS,它使用双均值的 CUSUM。DCUSUM-DS 算法在嵌套滑动窗口中工作,通过两次计算窗口内数据的平均值来检测漂移。检测到平均值后,它提取新特征,然后生成累积和受控图表,以避免虚假推断。这种方法的一个主要优点是,它可以检测到新特征并重新运行分析,以确保正确检测漂移,而不仅仅依赖于检测到的平均值。

CUSUM 的基于核的变体不需要变化前后的分布,而是依赖于变化前分布中的样本数据库,利用该数据库与进入的观察样本进行持续比较。用户选择的核函数和比较的统计指标是 MMD。核累积和KCUSUM)算法在拥有大量背景数据的情况下效果良好,尤其是在需要检测与背景数据偏差的情况下。

该算法可以配置一个阈值,设置超过该阈值时触发警报。漂移阈值的大小(例如,80%、50%或 30%)帮助我们获得识别漂移的正确指标。因此,当数据或模型模式出现任何偏差时,需要触发警报。例如,算法可以设置为非常大的幅度,并且 80%的阈值边界将使其比设置为 30%时更频繁地检测到漂移。检测器返回以下值:

  • ta:变化检测指标 —— 返回值表示报警时间(检测到变化时的索引)

  • tai:变化的起始索引 —— 显示变化开始时的索引

  • taf:变化的结束索引 —— 表示变化结束时的索引(如果endingTrue

  • amp:表示变化的幅度(如果endingTrue

配置参数的一种方法是从一个非常大的threshold值开始,并将drift设置为预期变化的一半。我们还可以调整drift,使得g有超过 50%的时间为0。然后,我们可以微调threshold,以便获得所需的虚假警报或延迟检测漂移的数量。为了更快地检测漂移,我们需要减小drift,而为了减少虚假警报并最小化小变化的影响,我们需要增大drift

以下代码片段演示了如何使用 CUSUM 漂移探测器:

from detecta import detect_cusum
x = np.random.randn(500)/5
x[200:300] += np.arange(0, 4, 4/100)
ta, tai, taf, amp = detect_cusum(x, 4, .025, True, True)
x = np.random.randn(500)
x[200:300] += 6
detect_cusum(x, 3, 1.5, True, True)
x = 2*np.sin(2*np.pi*np.arange(0, 2.8, .01))
ta, tai, taf, amp = detect_cusum(x, 1.8, .05, True, True)

前面的代码能够检测出不同数据区间之间的漂移,通过漂移百分比、阈值和变化实例的数量来进行说明。

图 11.10 – CUSUM 漂移探测器变化检测

图 11.10 – CUSUM 漂移探测器变化检测

这里使用的基于阈值的漂移检测技术展示了(图 11.10)在检测漂移时,CUSUM 对正负变化的作用。

协变量和先验概率数据漂移

协变量漂移是由于内部或外部因素引起的一个或多个独立特征的分布发生变化,但输入X和目标Y之间的关系保持不变。当协变量数据漂移时,输入特征X的分布发生变化,而在先验概率变化下,输入变量的分布保持不变,但目标变量的分布发生变化。目标分布的变化导致了先验概率数据漂移。为了实现协变量漂移,我们将一个正态分布的均值进行偏移。

该模型现在正在新区域的特征空间中进行测试,导致模型错误分类新的测试观测。在没有真实测试标签的情况下,无法衡量模型的准确性。在这种情况下,漂移探测器可以帮助检测是否发生了协变量漂移或先验概率漂移。如果是后者,可以通过在参考集的标签上初始化探测器来监控先验漂移的代理,然后将其输入到模型的预测标签中,以识别漂移。

以下步骤展示了如何通过与初始数据集上训练的原始模型进行比较来检测数据漂移:

  1. 首先,我们采用多变量正态分布,然后指定参考数据以初始化探测器:

    shift_norm_0 = multivariate_normal([2, -4], np.eye(2)*sigma**2)
    X_0 = shift_norm_0.rvs(size=int(N_test*phi1),random_state=2)
    X_1 = ref_norm_1.rvs(size=int(N_test*phi2),random_state=2)
    
  2. 我们堆叠参考分布,并通过与true_slope进行比较来估计漂移,true_slope已被设置为-1

    phi1 = phi1*1.5
    phi2 = phi2*2.5
    true_slope = -1
    shift_norm_0 = multivariate_normal([3, -8], np.eye(2)*sigma**2)
    X_0 = shift_norm_0.rvs(size=int(N_test*phi1),random_state=2)
    X_1 = ref_norm_1.rvs(size=int(N_test*phi2),random_state=2)
    X_test = np.vstack([X_0, X_1])
    y_test = true_model(X_test,true_slope)
    plot(X_test,y_test,true_slope,clf=clf)
    print('Mean test accuracy %.2f%%' %(100*clf.score(X_test,y_test)))
    pred = detector.predict(X_test)
    print('Is drift? %s!' %labels[pred['data']['is_drift']])
    

该代码片段生成以下图表,以演示无漂移与协变量漂移的用例,显示出漂移情况下(右侧)均值准确度较低,而没有漂移时(左侧)较高。

图 11.11 – 协变量数据漂移

图 11.11 – 协变量数据漂移

  1. 图 11.11展示协变量数据漂移时,以下代码演示了 MMD 方法的使用,其中计算了Xref | CXtest | C的核条件均值嵌入之间的期望平方差,以评估测试统计量:

    def detect_prior_drift():
        label_detector = MMDDrift(y_ref.reshape(-1,1), backend='tensorflow', p_val=.05)
        y_pred = clf.predict(X_test)
        label_detector.predict(y_pred.reshape(-1,1))
    detect_prior_drift()
    
  2. 我们得到以下输出:

    {'data': {'is_drift': 1,
      'distance': 0.107620716,
      'p_val': 0.0,
      'threshold': 0.05,
      'distance_threshold': 0.013342142},
     'meta': {'name': 'MMDDriftTF',
      'detector_type': 'offline',
      'data_type': None,
      'version': '0.9.0',
      'backend': 'tensorflow'}}
    

MMD 探测器在0.1076的距离下检测到漂移,漂移检测的阈值为0.013342

最小二乘密度差异

[0,1]并预测相同的二元结果。

来自alibi_detect的 LSDD 在线漂移检测器需要一个期望运行时间ERT)(反向的假阳性率FPR)),使得检测器在没有漂移的情况下运行平均步数,之后才可能产生错误检测。若 ERT 较高,检测器的敏感度降低,响应变慢,因此该配置会在 ERT 和期望检测延迟之间调整权衡,以针对理想的 ERT 进行优化。模拟所需配置的最佳方式是选择比所需 ERT 大一个数量级的训练数据:

  1. 在以下代码片段中,模型在白葡萄酒样本上进行训练,这些样本形成了参考分布,而红葡萄酒样本则来自漂移的分布。接下来的步骤展示了如何运行 LSDD 漂移检测,并帮助比较无漂移与有漂移的情况:

    white, red = np.asarray(white, np.float32), np.asarray(red, np.float32)
    n_white, n_red = white.shape[0], red.shape[0]
    col_maxes = white.max(axis=0)
    white, red = white / col_maxes, red / col_maxes
    white, red = white[np.random.permutation(n_white)], red[np.random.permutation(n_red)]
    X = white[:, :-1]
    X_corr = red[:, :-1]
    X_train = X[:(n_white//2)]
    X_ref = X[(n_white//2) :(3*n_white//4)]
    X_h0 = X[(3*n_white//4):]
    X_ref = np.concatenate([X_train, X_ref], axis=0)
    
  2. 在第一次运行中,没有设置检测器,我们没有检测到任何漂移:

    n_runs = 550
    times_h0 = [time_run(cd, X_h0, window_size) for _ in range(n_runs)]
    print (f"Average run-time under no-drift: {np.mean(times_h0)}")
    _ = scipy.stats.probplot(np.array(times_h0), dist=scipy.stats.geom, sparams=1/ert, plot=plt)
    

上述代码产生如下输出:

Average run-time under no-drift: 47.72
  1. 以下代码片段从alibi_detect导入LSDDDriftOnline并通过参考数据、ertwindow_size、运行次数以及原始分布和当前分布的 TensorFlow 后端来设置漂移检测器。然后,在线漂移检测器以ert值为50window_size10运行:

    X_new_ref = np.concatenate([X_train, X_ref], axis=0)
    from alibi_detect.cd import LSDDDriftOnline
    def lsdd_detector():
        cd = LSDDDriftOnline(
            X_new_ref, ert, window_size, backend='tensorflow', n_bootstraps=5500,
        )
     times_h0 = [time_run(cd, X_h0, window_size) for _ in range(n_runs)]
        print(f"Average run-time under no-drift: {np.mean(times_h0)}")
        _ = scipy.stats.probplot(np.array(times_h0), dist=scipy.stats.geom, sparams=1/ert, plot=plt)
    

这将产生以下输出:

图 11.12 – LSDD 漂移检测器

图 11.12 – LSDD 漂移检测器

图 11.12 演示了使用 LSDD 进行在线漂移检测。在这里,我们让检测器运行可配置的次数(50)或迭代,并配置 5,500 次自助法(bootstraps)来检测漂移。自助法用于运行模拟并配置阈值。更大的数量有助于提高获取 ERT 的准确性,通常配置为比 ERT 大一个数量级。

我们得到如下输出:

Average run-time under drift: 54.39

此外,我们观察到,在第一次运行时,保留的参考数据上的检测器遵循几何分布,均值为 ERT,且没有漂移。然而,一旦检测到漂移,检测器反应非常迅速,如图 11.12所示。

Page-Hinkley

这种漂移检测方法通过计算观察值及其均值来检测变化,直到当前时刻。如果发现观察均值超过阈值 lambda 值,则不会发出任何警告信号,而是运行 PH 测试来检测概念漂移。数学上,它可以表示为:

当 gt– Gt > h 时,会触发警报。

现在,让我们逐步了解使用 PH 方法检测漂移的过程:

  1. 以下代码示例演示了我们如何模拟两个分布:

    import random
    from river import drift
    import matplotlib.pyplot as plt
    import numpy as np
    rng = random.Random(123456)
    ph = drift.PageHinkley()
    
  2. 现在,我们组合并绘制一个由三种数据分布组成的数据流:

    data_stream = rng.choices([50, 100], k=1200) + rng.choices(range(600, 900), k=5000) + rng.choices(range(200, 300), k=5000)
    plt.plot(data_stream)
    plt.show()
    
  3. 现在,我们更新漂移检测器并查看是否检测到变化:

    for I, val in enumerate(data_stream):
         in_drift, in_warning = ph.update(val)
         if in_drift:
           print (""Change detected at index {i}, input value: {val"")
    
  4. 我们得到以下输出。我们看到在不同时间点检测到图表的三个不同分布的漂移。变化检测点打印在图表的两侧。

图 11.13 – 使用 PH 探测器在分布的三个范围内检测到漂移

图 11.13 – 使用 PH 探测器在分布的三个范围内检测到漂移

快速 Hoeffding 漂移检测方法

快速 Hoeffding 漂移检测方法FHDDM)允许持续追踪正确预测概率的滑动窗口值以及观察到的最大概率值。当正确预测概率低于最大配置值,并且概率差异超过阈值时,就认为发生了漂移。

配对学习器

配对学习器PL)机制包括两个学习器,一个是对所有数据进行训练的稳定学习器,另一个是对最近数据进行训练的学习器。每当稳定学习器在预测中出错而最近学习器没有出错时,计数器就会递增。为了弥补错误,每当最近学习器在预测中出错时,计数器就会递减。一旦计数器的增量超过指定的阈值,就认为发生了漂移。该机制涉及大量计算,用于训练新模型并保持两个学习器。

指数加权滑动平均概念漂移检测

指数加权滑动平均概念漂移检测ECDD)方法中,通过连续计算预测的均值和标准差,使用指数加权滑动平均EWMA)预测。它通常用于监控和检测流分类器的误分类率。当预测值超过均值加上标准差的倍数时,就检测到漂移。

特征分布

这种漂移检测技术通过识别*p(y|x)由于p(x)*的相应变化来实现,无需反馈响应。可以使用任何多元无监督漂移检测技术来检测这种变化。

回归模型中的漂移

要在回归模型中检测漂移,您需要取回归误差(一个实数)并对误差数据应用任何无监督漂移检测技术。

集成和层次漂移检测器

集成检测器主要基于一致性水平工作,其中一致性可以从少数、全部或大多数学习者中得出。层次化检测器仅在第一级检测器通过任何先前讨论的漂移检测技术检测到漂移后才会起作用。然后,可以使用一致性方法在其他级别验证结果,从下一级开始。一些集成和层次漂移检测算法包括线性前馈率LFR)、选择性检测器集成eDetector)、漂移检测集成DDE)和层次假设测试HLFR)。

现在我们已经了解了不同类型的概念漂移检测技术,接下来我们讨论在漂移/校准时的模型可解释性。

使用 PCA 进行多变量漂移检测

为了从多变量数据分布中检测漂移,我们通过主成分分析PCA)将数据压缩到一个低维空间,然后再解压数据以恢复原始特征表示。由于我们在转换过程中仅保留相关信息,重建误差(通过原始数据和转换数据之间的欧氏距离评估)帮助我们识别一个或多个特征之间数据关系的变化。在第一步中,我们在原始参考数据集上计算 PCA,并存储带有允许上下限阈值的重建误差。然后对新数据重复此过程,在该过程中我们使用 PCA 对数据进行压缩和解压。当重建误差超过上限或下限阈值时,表示数据分布发生了变化。

以下代码演示了如何检测多变量特征漂移:

  1. 在第一步中,我们进行必要的导入:

    import numpy as np
    import pandas as pd
    import matplotlib.pyplot as plt
    import seaborn as sns
    import nannyml as nml
    from scipy.spatial.transform import Rotation
    
  2. 接下来,我们基于其三个特征进行随机数据设置:

    # analyze with reference and analysis periods
    # Days/week * Hours/day * events/hour
    DPP = 7*24*24
    np.random.seed(23)
    s1 = np.random.randn(DPP*22)
    x1 = s1 + np.random.randn(DPP*22)/8
    x2 = s1 + np.random.randn(DPP*22)/8
    x3 = np.random.randn(DPP*22)/8
    xdat = np.array([x1, x2, x3]).T
    rot = Rotation.from_euler('z', 90, degrees=True)
    # following matrix multiplication implementation, we need a 3xN data matrix hence we transpose
    ydat = np.matmul(rot.as_matrix(), xdat.T).T
    # drift is sudden and affects last 5-7 weeks
    dataar = np.concatenate(
    (xdat[:-5*DPP], ydat[-5*DPP:]),
    axis=0)
    datadf = pd.DataFrame(dataar, columns=['feature1', 'feature2', 'feature3'])
    datadf = datadf.assign(ordered = pd.date_range(start='1/3/2020', freq='5min', periods=22*DPP))
    datadf['week'] = datadf.ordered.dt.isocalendar().week - 1
    datadf['partition'] = 'reference'
    datadf.loc[datadf.week >= 8, ['partition']] = 'analysis'
    datadf = datadf.assign(y_pred_proba = np.random.rand(DPP*22))
    datadf = datadf.assign(y_true = np.random.randint(2, size=DPP*22))
    
  3. 接下来,我们可以进一步解释独立特征,但目标是按照以下方式设置漂移检测器:

    rcerror_calculator = nml.DataReconstructionDriftCalculator(
    feature_column_names=feature_column_names,
    timestamp_column_name='ordered',
    chunk_size=DPP
    ).fit(reference_data=reference)
    rcerror_results = rcerror_calculator.calculate(data=analysis)
    figure = rcerror_results.plot(plot_reference=True)
    figure.show()
    
  4. 这产生了图 11.14中所示的结果,在其中我们看到数据从 0.84 漂移到 0.80。

图 11.14 – 使用 PCA 的多变量漂移检测器

图 11.14 – 使用 PCA 的多变量漂移检测器

理解概念漂移/校准过程中的模型可解释性

在上一节中,我们学习了不同类型的概念漂移。现在,让我们研究如何通过可解释的机器学习来解释它们:

  1. 首先,我们导入创建回归模型和漂移解释库所需的包。加利福尼亚住房数据集已被用来解释概念漂移:

    from xgboost import XGBRegressor
    from cinnamon.drift import ModelDriftExplainer, AdversarialDriftExplainer
    from sklearn import datasets
    from sklearn.datasets import fetch_california_housing
    from sklearn.datasets import fetch_openml
    california = fetch_openml(name="house_prices", as_frame=True)
    california_df = pd.DataFrame(california.data, columns=california.feature_names)
    RANDOM_SEED = 2021
    
  2. 然后,我们训练 XGBoost 回归模型:

    model = XGBRegressor(n_estimators=1000, booster="gbtree",objective="reg:squarederror", learning_rate=0.05,max_depth=6,seed=RANDOM_SEED, use_label_encoder=False)
    model.fit(X=X_train, y=y_train, eval_set=[(X_test, y_test)], early_stopping_rounds=20, verbose=10)
    
  3. 在下一步中,我们使用 ModelDriftExplainer 拟合我们的训练模型,绘制预测图,并提取任何漂移,如果解释器观察到的话:

    drift_explainer = ModelDriftExplainer(model)
    drift_explainer.fit(X_train, X_test, y_train, y_test)
    drift_explainer.plot_prediction_drift()
    drift_explainer.get_prediction_drift()
    

下图说明了在两个不同数据集中的漂移检测差异。

图 11.15 – 两个数据集的输入特征或数据分布的漂移

图 11.15 – 两个数据集的输入特征或数据分布的漂移

图 11.15中,可以明显看出预测分布中没有出现明显的漂移。

  1. 然后,我们绘制目标标签来评估预测结果中是否有漂移:

    drift_explainer.plot_target_drift()
    drift_explainer.get_target_drift()
    

然而,如图 11.16所示,我们并没有观察到目标标签的明显漂移:

图 11.16 – 加利福尼亚住房数据集目标数据分布的漂移

图 11.16 – 加利福尼亚住房数据集目标数据分布的漂移

  1. 在接下来的步骤中,当我们评估加利福尼亚住房训练集和测试集的数据性能指标时,我们可以看到性能指标的均值和解释方差出现了数据漂移:

    drift_explainer.get_performance_metrics_drift()
    

在运行加利福尼亚住房数据集的漂移解释器时,我们得到以下输出:

PerformanceMetricsDrift(dataset1=RegressionMetrics (mse=10567733.794917172, explained_variance=0.9983637108518892), dataset2=RegressionMetrics(mse=540758766.1766539, explained_variance=0.9088298308495063))
  1. 我们的下一个任务是绘制基于树的方法计算出的漂移值,获取加利福尼亚住房数据集的特征重要性,并在数据集上使用AdversarialDriftExplainer。如图 11.17所示,Neighborhood_OldTownBsmtQual_Gd特征是受到漂移影响最大的特征:

图 11.17 – 结果漂移中的特征重要性

图 11.17 – 结果漂移中的特征重要性

  1. 最终,我们可以绘制每个特征并评估它们的漂移,如图 11.18所示。这里,Neighborhood_OldTown,第一个特征,在训练集和测试集之间没有显示出明显的漂移:

    drift_explainer.plot_feature_drift('Neighborhood_Old_Town')
    drift_explainer.get_feature_drift('Neighborhood_Old_Town')'
    

前面的代码片段输出以下结果,显示两个数据集之间的差异不显著,因为p_value是 0.996 > 0.05:

DriftMetricsNum(mean_difference=-0.022504892367906065, wasserstein=0.022504892367906093, ks_test=BaseStatisticalTestResult (statistic=0.022504892367906065, pvalue=0.996919812985332))

图 11.18 – 由于 Neighborhood_Old_Town 特征导致的分布差异/漂移

图 11.18 – 由于 Neighborhood_Old_Town 特征导致的分布差异/漂移

在了解漂移后,作为数据科学家,我们还需要理解在发生变化时,何时需要对模型进行校准。

理解模型校准的必要性

推荐系统(基于内容的过滤或混合系统)几乎在所有行业领域中都得到了应用,包括零售、电信、能源和公用事业。使用用户到用户或项目到项目嵌入的深度学习推荐模型,通过可解释性特征建立了信任和信心,并改善了用户体验。深度学习推荐系统通常使用注意力分布来解释神经网络的性能,但在自然语言处理NLP)的情况下,这种解释受到深度神经网络校准不良的限制。

已观察到,由于过度自信或缺乏自信,模型的可靠性会受到影响,特别是对于设计用于医疗保健(疾病检测)和自动驾驶等领域的模型。在模型的可靠性受到质疑的情况下,使用像模型校准这样的度量标准至关重要,因为它能够确保模型预测的概率与其真实正确性的可能性相关联,从而决定模型的性能。

换句话说,当一个经过校准的模型具有较高的置信度(比如超过 80%)时,可以称其为真实有效的模型,此时超过 80%的预测结果被准确分类。我们还可以通过模型校准来绘制可靠性图。这可以作为模型的准确性,通过将可靠性解释为模型对预测的置信度的函数来实现。过于自信的模型的可靠性图低于身份函数,而缺乏信心的模型的可靠性图则高于身份函数。我们还可以看到,经过校准的真实模型提供了完美的分类边界,其中可靠性图可以作为身份函数进行基准测试。

图 11.19包含了深度基于物品的协同过滤DeepICF)模型的可靠性图。DeepICF 通过使用非线性神经网络训练所有交互物品对,检查物品之间的非线性和高阶关系。它有助于我们理解如何在不同组中建模预测,并通过可靠性图研究准确性与置信度之间的权衡。

图 11.19 – DeepICF 模型的可靠性图

图 11.19 – DeepICF 模型的可靠性图

我们将模型的预测结果按置信度分成不同的区间,并计算每个区间的准确性。图 11.19展示了 DeepICF 模型(带有注意力网络:www.researchgate.net/publication/333866071_Model_Explanations_under_Calibration)随着置信度的增加,正负类别的预测变得过于自信。DeepICF 模型是一个深度神经网络,它通过学习用户和物品的潜在低维嵌入生成。通过逐元素点积,神经网络层捕捉用户和物品之间的配对交互。此外,该模型还使用基于注意力的池化方法生成固定大小的输出向量。这导致在不平衡和负偏态数据集上准确性下降,表明通过注意力分布生成的模型解释在过于自信的预测下变得不那么可靠。

现在,让我们讨论一下当我们看到模型预测结果出现漂移时,如何将可解释性和模型校准结合起来。

可解释性与校准

通过解决数据集中的不平衡问题并为注意力分布添加稳定性,可以实现模型可解释性和适当的模型校准。然而,另一个需要解决的问题是由概念漂移引起的校准漂移。在医疗行业中,一个明显的例子是由于患者特征和不同健康中心、地区及国家的疾病发生率或流行率变化,导致风险预测校准不佳。当一个算法在高疾病发生率的环境中训练时,它会受到模型输入的主导,导致风险估计过高。当这种校准漂移由于模型在非静态环境中的部署发生时,这些模型需要重新训练和重新校准。重新校准有助于修复模型的准确性和置信度,从而提高可靠性图。

现在,让我们通过一个例子来看看为什么在以下情况下有必要对推荐模型进行校准:

  • 当由于人口中新客户群体的加入而观察到用户偏好的变化时

  • 当观察到现有客户中用户偏好的变化时

  • 当有促销/活动或新产品发布时

在以下示例中,我们将研究如何将后处理逻辑嵌入到底层推荐算法中,以确保推荐结果变得更加校准。为了说明这个问题,我们将使用movielens-20m-dataset

  1. 为了计算推荐系统的效用指标,我们必须计算用户-项目交互分布与推荐分布之间的 KL 散度。在这里,我们选择了一个相关的 lambda 项,用来控制评分和校准之间的权衡。lambda 值越高,最终推荐结果被校准的概率越大:

    def compute_recommendation_utility(reco_items, interacted_distr, lmbda=0.65):
        total_score = 0.0
        reco_distr = compute_likely_genres(items_to_recommend)
        kl_div = evaluate_kl_divergence(interacted_distr, reco_distr)
        for item in items_to_recommend:
            total_score += item.score
        rec_utility = (1 - lmbda) * total_score - lmbda * kl_div
        return rec_utility
    
  2. 这里定义的效用函数在每次迭代时都会被调用,以更新列表并选择最大化效用函数的项目:

    def calibrate_recommendations(items, interacted_distr, topn, lmbda=0.65):
        calib_rec_items = []
        for _ in range(topn):
            max_utility = -np.inf
            for rec_item in items:
                if rec_item in calib_rec_items:
                    continue
                rec_utility = compute_recommendation_utility(calib_rec_items + [rec_item], interacted_distr, lmbda)
                if rec_utility > max_utility:
                    max_utility = rec_utility
                    best_item = rec_item
            calib_rec_items.append(best_item)
        return calib_rec_items
    
  3. lambda 项允许我们将控制器(lambda)调整到极高的水平,以生成修改后的校准推荐列表。现在,让我们对校准后的计算推荐进行区分和评估(以优化评分𝑠),并与原始推荐及用户与项目的历史关系进行比较。这里,𝑠(𝑖)表示推荐系统预测的项目评分,𝑖∈𝐼,s(I) = ∑i ∈ Is(i)表示新生成列表中所有项目评分的总和:

    calib_rec_item_distr = compute_likely_genres(calib_items_to_recommend)
    calib_reco_kl_div = evaluate_kl_divergence(interacted_distr, calib_rec_item_distr)
    reco_kl_div = evaluate_kl_divergence(interacted_distr, reco_distr)
    distr_comparison_plot(interacted_distr, calib_rec_item_distr)
    

在这里,我们观察到校准后的推荐在类型覆盖面上更广,并且其分布看起来类似于用户过去互动的分布和校准度量。KL 散度还确保从校准推荐生成的值低于原始推荐的分数。即使校准推荐分布的精度(0.125)低于原始分布的精度(0.1875),我们仍然可以进一步控制 λ,达到精度与校准之间的可接受平衡。

图 11.20 – 比较用户历史分布和校准推荐分布

图 11.20 – 比较用户历史分布和校准推荐分布

在前面的讨论中,我们看到了由于输入数据和模型的变化,开发校准模型的重要性。现在,让我们从伦理 AI 的角度,讨论如何将公平性纳入模型并构建校准模型。

校准和公平性的挑战

到目前为止,我们已经了解了什么是跨不同人群子群体的公平机器学习模型,使得预测结果在所有种族、民族、性别和其他人口类别中都不会存在偏差。从 AI 伦理的角度来看,我们还应尝试设计公平且校准的模型,并在过程中理解与其相关的风险。为了设计一个公平且校准的模型,至关重要的是,赋予预测概率为 p 的群体,在通用机器学习模型中能够看到公平的代表性。为了实现这一点,我们应该让这组成员的 p 部分属于分类问题中的正实例。

因此,为了证明两个组之间的公平性,G1 和 G2(例如非洲裔美国人和白人被告),满足两组公平性的最佳方式是校准条件在每个组内的每个个体上同时成立。

然而,校准和误差率约束有着相互冲突的目标。研究表明,校准仅在存在单一误差约束时是容忍的(即各组之间的假阴性率相等)。此外,在使用校准概率估计时,跨不同人群群体最小化误差差异变得越来越困难。即使目标得以满足,得到的解决方案也类似于一个通用分类器,它仅优化一部分预测结果。因此,总结来说,无法设计出一个完全公平且校准的模型。

总结

在本章中,我们学习了与概念漂移相关的不同思想。这些思想可以应用于流式数据(批处理流)、实时数据以及训练好的机器学习模型。我们还学习了统计方法和上下文方法如何在通过判断模型漂移来估计模型度量指标时发挥重要作用。本章还回答了一些关于模型漂移和可解释性的重要问题,并帮助你理解模型校准。在校准的背景下,我们还讨论了公平性与校准,以及如何同时实现两者的局限性。

在下一章中,我们将学习更多关于模型评估技术以及如何处理模型构建流程中的不确定性。

进一步阅读

第十二章:构建可持续的企业级 AI 平台

本章的主要目标是向你介绍可持续性最佳实践以及模型治理技术,以便将其与组织目标和计划对齐。你将了解到训练**深度学习(DL)**模型的环境影响以及你可以采取的可能补救措施。你还将熟悉不同平台的可持续性指标,这将有助于实现可持续的模型训练和部署。

到本章结束时,你将掌握**联邦学习(FL)**中的协作和去中心化学习技术,无论是模型训练发生在网络、边缘还是云端。最后,你还将了解帮助跟踪碳排放统计数据的工具。

本章将涵盖以下几个主题:

  • 可持续企业级 AI 平台的关键

  • 跨不同云平台的可持续实践和指标

  • 碳排放追踪器

  • 采用 FL 进行可持续模型训练和部署

技术要求

本章要求你安装 Python 3.8,并包含以下一些 Python 包:

  • Keras 2.7.0 和 TensorFlow 2.7.0

  • pip install CodeCarbon

可持续企业级 AI 平台的关键

可持续性在伦理 AI 时代中扮演着非常重要的角色,因为预测能源排放的能力可以支持保护环境和节约资源的倡议。AI 平台可以促进排放减少和二氧化碳(CO2)去除,这有助于建立更绿色的交通网络,并监测与控制森林砍伐。因此,通过以可持续的方式有效利用 AI 解决方案,我们可以努力预防极端天气情况。

作为第一步,我们应当理解为什么组织会设定无碳愿景。同时,理解领导层的愿景同样重要,以便将团队与高层领导和 CXO 们设定的可持续使命目标对齐。

因此,作为第一步,我们将探讨组织重构其路线图以构建可持续 AI 解决方案的动机。

将 AI 作为组织路线图的可持续解决方案

我们应非常小心地构建环保的解决方案。大量研究表明,仅仅 40 天的研究训练就能排放 96 吨 CO2。这一数值非常庞大,相当于 1,000 小时的航空旅行,约等于 23 个美国家庭的碳足迹(www.analyticsinsight.net/new-mit-neural-network-architecture-may-reduce-carbon-footprint-ai/inhabitat.com/mit-moves-toward-greener-more-sustainable-artificial-intelligence/)。进行神经网络搜索的碳排放量曾高达 600,000 CO2e(磅),相当于 5 辆汽车的生命周期。训练像**自然语言处理(NLP)**模型(或 transformer)这样的算法会消耗大量能量,因此数据科学家在设计此类 DL 神经网络架构时需要格外小心(aclanthology.org/P19-1355.pdf)。这种训练方式对环境可能构成威胁。如果我们继续以这种方式构建 AI 解决方案,未来的世代将面临不利的环境后果。

希望将 AI 应用于可持续发展的组织,不仅应关注可持续的银行业务、能源消费或医疗保健,还应开发最佳实践,通过衡量碳足迹和计算训练及评估数据中心管理方法所需的计算能力来量化 CO2e。

此外,数据科学家和工程师应首先评估是否需要使用 DL 模型。对于某些应用场景,使用标准模型即可保证相似的性能,而无需训练 DL 模型。因此,在训练 DL 模型之前,组织需要建立正确的实践和审核机制,以避免造成过大的碳足迹。

一旦数据科学团队最终确定了模型(无论是在集中式还是 FL 设置中使用传统模型还是 DL 模型),超参数的选择和精确调优在碳排放中起着重要作用。对于 FL 来说,调优超参数可能在能耗方面变得非常昂贵,因为这会导致调优数百个不同的模型(包括客户端中的本地模型)。

FL 中的调优过程可能会变得越来越复杂,这主要是由于聚合策略中的参数化以及客户端各个数据集的异质性。两种学习方式中超参数调优的复杂性必须仔细设计,以尽量减少 CO2e 排放。

团队应该注意数据集的选择以及所涉及的预处理和特征工程的程度。一个例子是,使用金融和零售数据来开发推荐系统时,特征工程技术变得更加详尽和昂贵,而不仅仅是使用零售数据。

让我们研究能够支持这些框架构建的组织标准。

可持续框架的组织标准

高管和领导层必须参与将可持续数据和模型实践作为组织目标的强制性要求。这些可伸缩云平台的可持续实践源于设定正确的目标和基于当前业务需求的服务级别协议(SLAs)。这可能需要通过优先考虑业务关键功能并允许非关键功能的较低服务级别来影响可持续性指标,来选择正确的权衡。至关重要的是,企业应通过定义适用于可持续模型训练和部署的架构设计模式来处理跨部门的孤立数据。

现在,让我们开始研究在不同云平台上测量的指标。

不同云平台的可持续实践和指标

在本节中,我们将探讨如何评估以下内容:

  • 谷歌云的有用排放指标

  • 无碳能源的最佳实践和策略

  • 数据中心的能源效率

首先,我们将讨论谷歌云的一些指标,并引用微软推广的一些倡议和工具。

谷歌在可持续云解决方案中的角色是巨大的,它一直是领先的云服务提供商,在购买足够的可再生能源方面超过任何其他组织。从 2007 年宣布成为到 2017 年第一家主要碳中和公司的承诺开始,现在其所有电力消耗都来自可再生能源。在没有足够的风能和太阳能或可再生资源的情况下,谷歌从当地电网获取电力来运行本地数据中心的操作。相反,当有足够的电力可用时,多余的电力会反馈到当地电网用于其他用途。以 2030 年实现全天候无碳能源的愿景,谷歌使用以下各节提到的指南使其数据中心和电网无碳。

微软还为 Azure 推出了其 Power BI 应用程序,被称为 Microsoft 可持续性计算器,该应用程序提供了有关每个区域数据中心碳排放量的见解。即使是购买碳中和的可再生能源等举措也有助于推动其年度云消费。

谷歌云的排放指标

为了在 2030 年实现碳自由能源,Google Cloud 提出了一个倡议,帮助客户实现 24/7 利用碳自由能源。客户可以在设计解决方案时考虑碳影响,分析一种叫做 CFE% 的指标。该指标量化了每小时消耗的碳自由能源,通过将其大致分为两大类:CFE% 和碳强度。CFE% 的计算是基于任何时候向电网供应的能源以及 Google 提供的可再生能源资源供给所做的碳自由能源贡献。

  • Google CFE%:该指标提供了碳自由能源的平均百分比。按小时计算时,这一指标为客户提供了一个估算,表明他们的应用程序能够在多长时间内使用碳自由能源,这取决于该地区电网投资的碳自由能源比例。

  • 电网碳强度(gCO2eq/kWh):该指标量化了在特定位置从电网获取的单位能源的平均生命周期排放。通过这个指标,我们可以比较在同一电网中表现相似的不同位置的电力碳强度。利用这一点,当两个或更多地点的 CFE% 相似时,我们可以选择一个生产应用的部署区域。例如,我们经常会看到法兰克福和荷兰的 CFE% 得分相似,但荷兰的排放率较高。

现在,来讨论一下如何利用碳自由能源的最佳实践。

碳自由能源的最佳实践和策略

随着 Google Cloud Platform 积极专注于提升每个 Google Cloud 区域的 CFE%(碳自由能源比例),碳自由能源的比例增加有助于提升部署的可持续性。以下是针对云 AI 专家和架构师的一些独特建议:

  • 选择低碳区域:在低碳区域(如芬兰或瑞典)建立并运行新应用程序,且该区域具有较高的 CFE%,有助于实现目标碳自由能源排放。

  • 在低碳区域运行批处理任务:通过精心规划运行批处理工作负载,可以最大限度地利用碳自由能源。这意味着我们无需将低至中等负载的任务分开运行,通过将高负载和低负载的任务结合起来,可以确保高 CPU 利用率。

  • 推动绿色云应用的组织政策:领导团队和组织应该设定优先级,允许在特定区域使用资源和服务,同时限制在其他区域的访问和使用。

  • 高效使用服务:有效地规划虚拟机大小,并结合使用无服务器产品如 Cloud Run 和 Cloud Functions,可以进一步减少碳排放,因为它们会根据工作负载自动扩展,并尽可能节省能源。

数据中心的能源效率

为了运行高效的数据中心,我们需要精心规划并选择虚拟机在多站点云中的部署位置。除了选择合适的数据中心来托管虚拟机外,虚拟机的大小同样重要,因为它可以防止额外计算资源的浪费,并提高应用程序的执行速度。通过允许并行化并采用合适的技术来合并云资源,我们可以提高数据中心的效率,从而减少能源消耗。

物理机器PMs)占数据中心总能源消耗的 35%。它们消耗的能量可以分为静态(虚拟机空闲时消耗的能量)和动态两部分。动态功率消耗主要依赖于各个组件的使用情况,占最大功率消耗的 50%以上,而空闲功率消耗则保持在最大功率消耗的 50% 以下。此外,睡眠模式下也会消耗少量电力。我们需要在空闲和动态功率消耗之间找到合适的平衡,以实现高利用率的工作负载,从而使 PMs 通过保持与利用负载成比例的能耗,贡献于高能源效率比。我们需要考虑优化以减少能耗,确保空闲功率消耗为 0 W(当 PMs 未使用时),在其他时候,根据工作负载的增加来相应调整,直到达到最大利用负载。虚拟化资源具有将用户任务合并到较少 PMs 中的灵活性。我们还必须仔细决定如何减少 PMs 的使用,以减少空闲功率,从而降低整体消耗。除了 PMs,在确定数据中心的整体效率时,以下是一些需要关注的指标:

  • 功率使用效率PUE)指标是一个依赖于云服务提供商的可变因素,表示数据中心的能源效率。它通过评估进入数据中心的总电力中,用于使 IT 设备完全正常运行的部分,来估算每个计算周期的开销。一个高效的数据中心将具有接近 1.0 的理想值。

  • 总功率使用效率TUE)指标用于弥补由 PUE 指标产生的差距。TUE 通过计算数据中心消耗的总能量与单个计算元素消耗的能量之比来获得。因此,它在评估环境影响时更有帮助,因为它只考虑执行工作负载所消耗的能量,而不是整个 IT 设施的能耗。

  • 绿色能源系数GEC)指标通过百分比估算来自绿色能源来源的能量,其中一些来源受天气条件影响,如太阳能电池板和风力发电机。使用可再生能源的驱动数据中心对环境的负面影响较小,因此更具吸引力。

确保数据中心的高效性还需要遵循一些与我们如何构建程序以在云端运行,以及如何衡量电力消耗相关的最佳实践或技术。以下是值得遵循的一些最佳实践:

  • DevOps 和云架构师无需考虑虚拟机的启动成本,因为这几乎可以忽略不计。

  • 开发人员应确保所有程序自动利用虚拟机中可用的所有核心。

  • 在工作流的每个步骤中,强烈建议指定计算资源,以便为创建虚拟机(VM)提供支持。实现这一目标的最佳方法是确保有足够的磁盘空间和内存可用,以支持程序的执行。当可用资源准备好执行任务时,允许应用程序开始处理。

  • 允许提交的应用程序执行任务的所有步骤,直到任务结束。

  • 启用动态电压和频率调整DVFS)以减少 PM(物理机)上虚拟机的功耗,通过动态调整 CPU 的电压和频率来实现。

  • 禁止在 PM 上过度分配资源,以免影响资源密集型应用程序的执行速度。

现在,让我们估算如何追踪碳排放量。

碳排放跟踪器

通过深入了解 Google Cloud 上的碳度量,我们的下一课将集中在单个虚拟机(VM)能效计算机制上,我们已经通过 GitHub 上的示例进行了说明。我们的下一步是通过嵌入碳排放跟踪器来计算碳排放量,碳排放跟踪器可以提供来自源代码中的详细排放统计分析。

现在,让我们探索一些可以用于联邦学习(FL)和集中学习的排放工具。

FL 碳排放计算器

在一组设备进行联邦学习(FL)时,碳排放量可以通过一种 FL 碳排放计算器来追踪(mlsys.cst.cam.ac.uk/carbon_fl/github.com/mlco2/codecarbon),其中需要指定以下参数:

  • 设备:设备使用的硬件类型。

  • 国家: 由燃烧化石燃料产生的能源生产量取决于国家。第一个参数用于获取该国的电力/碳转化率,第二个参数用于估算客户端与服务器之间通信所产生的碳排放量。

  • 数据集: 用于指定平衡的、非独立同分布 (IID) 数据集,如 ImageNet 和 CIFAR-10。与 IID 数据集不同,非 IID 数据集包含随机变量,这些变量之间没有相互独立性,也不是同分布的。这使得它们与 IID 数据集有很大不同,因为它们似乎并非来自同一分布。

  • 轮次数: 用于指定中央服务器通过聚合过程构建全局模型所使用的总迭代次数。

  • 本地纪元数 (LEs): 用于指定每个客户端在将本地模型发送到服务器之前进行训练的迭代次数。

  • 活跃设备数量: 用于指定每一轮中活跃客户端设备的数量,这通常是所使用的设备总数的一部分。

  • 网络: 用于定义给定设备集的互联网上传/下载速度。

图 12.1 演示了在一个具有 5 个客户端、10 个本地纪元和 10 轮训练的 FL 设置中,总共排放的碳量为 2.51 gCO2eq。这里,CO2eq 用于衡量硬件(如 CPU 和 GPU)的能耗,并确定硬件的位置。结合该地区的平均 CO2 排放(以 gCO2eq/KWh 为单位)和 ML 模型架构,可以帮助确定部署的地区。例如,对于需要高能耗的部署,可以选择像加拿大魁北克这样的地区,但在某些其他情况下,可能会被迫将解决方案部署在美国爱荷华州,该地区的 CO2 排放高达 735.6 gCO2eq/KWh:

图 12.1 – 来自一个具有 5 个客户端、10 个本地纪元和 10 轮训练的 FL 设置的碳排放

图 12.1 – 来自一个具有 5 个客户端、10 个本地纪元和 10 轮训练的 FL 设置的碳排放

现在,让我们看看如何计算集中式学习的 CO2 排放。

集中式学习碳排放计算器

就像 FL 一样,我们也可以对集中式学习做同样的计算,正如 图 12.1 所示,使用 ML CO2 影响计算器(mlco2.github.io/impact/github.com/mlco2/codecarbon)来计算不同云平台的碳排放。

我们还展示了以下示例,说明如何使用 CodeCarbon 工具来衡量碳排放,该工具可以轻松地集成到自然工作流中。它从代码内部捕捉排放指标,并帮助开发人员在函数或模块级别跟踪这些指标:

  1. 首先,让我们导入所有必要的库:

    import tensorflow as tf
    from codecarbon import EmissionsTracker
    from tensorflow.keras.wrappers.scikit_learn import KerasClassifier
    from sklearn.model_selection import cross_val_score, StratifiedKFold,RandomizedSearchCV
    
  2. 在接下来的步骤中,以下代码演示了使用 MNIST 数据集训练深度学习模型:

    def train_model():
        mnist = tf.keras.datasets.mnist
        (x_train, yv_train), (x_test, y_test) = mnist.load_data()
        x_train, x_test = x_train / 255.0, x_test / 255.0
        model = tf.keras.models.Sequential(
            [
                tf.keras.layers.Flatten(input_shape=(28, 28)), tf.keras.layers.Dense(128, activation="relu"),
                tf.keras.layers.Dropout(0.2),
                tf.keras.layers.Dense(10),
            ])
        loss_fn = tf.keras.losses.SparseCategoricalCrossentropy(from_logits=True)
        model.compile(optimizer="adam", loss=loss_fn, metrics=["accuracy"])
        model.fit(x_train, y_train, epochs=10)
        return model
    
  3. 最后,使用以下代码,我们可以追踪训练深度学习代码时的排放数据:

    with EmissionsTracker(project_name="mnist") as tracker:
        model = train_model()
    print(tracker.final_emissions)
    

这里是以千克二氧化碳(kg CO2)为单位的输出:

0.0001063754808656955

我们可以看到,深度学习(DL)模型产生了 0.0001063 千克的二氧化碳排放。

现在,我们已经具备了可持续机器学习的指标来控制我们的能耗。然而,研究表明,联邦学习在不同情况下对控制二氧化碳当量(CO2e)排放起着重要作用。让我们现在来看如何在使用联邦学习进行模型训练和部署时融入可持续性。

采用可持续的模型训练和部署方式,使用联邦学习(FL)

随着机器学习训练量的指数级增长,从 2012 年到 2018 年增长超过 300,000 倍——即 3-4 个月翻倍(远超摩尔定律的 2 年翻倍周期)——数据科学家和算法研究人员越来越多地研究去中心化的模型训练方法,以试图遏制深度学习模型在数据中心的专用硬件加速器上运行时产生的巨大热量。这些专用硬件消耗大量能源(200 太瓦时TWh)),高于一些国家的国家电力消费,并占全球碳排放的 0.3%(2018 年《自然》期刊中引用)。例如,谷歌的 AlphaGo Zero 和训练自然语言处理(NLP)模型已经排放了大量的二氧化碳当量,突显了采用去中心化机制的紧迫性。

移动设备和物联网设备数量的指数级增长意味着联邦学习及其协作训练方法在降低能耗和碳排放方面发挥了重要作用。此外,研究发现,与集中式学习相比,联邦学习的设计具有更绿色的环境影响,因为它的碳排放较少。

现在,让我们理解模型训练过程中的排放指标。

二氧化碳当量(CO2e)排放指标

要量化在数据中心或边缘服务器中训练深度学习模型的环境影响,只有考虑以下指标时,才能真正理解其环境影响,因为能源消耗会根据地理位置转化为二氧化碳当量(CO2e)排放:

  • 集中式学习和联邦学习系统硬件消耗的总能量,以及联邦学习系统的通信能量

  • 数据中心因冷却效应而消耗的能量,特别是在集中式学习的情况下

现在,让我们隔离出导致集中式学习和基于联邦学习的训练系统能耗的因素。

比较排放因子——集中式学习与联邦学习(FL)

以下因素总结了集中式学习与联邦学习在能源消耗上的主要区别点。

硬件依赖性

集中式学习训练过程中的能耗可以通过在训练期间采样 GPU 和 CPU 的功耗来推算。可以查询 NVIDIA 系统管理界面,以平均所有样本在训练期间的 GPU 功耗。然而,对于 FL 来说,除了配备 GPU 的聚合服务器和客户端之外,这部分能耗可以安全地忽略。

在一个具有分布式训练设置和来自异构边缘设备的多个通信轮次的 FL 环境中,训练时间可能远远超过集中式训练的时间。这是因为集中式训练收敛得更快。对于 FL 来说,训练时间以及能耗与每次迭代中选择的客户端数量、客户端的数据分布(通常是非 IID 的)以及参与训练过程的具有不同计算能力的异构客户端设备密切相关,因为客户端的计算能力各不相同。

除了这些因素外,实际消耗的能源还受到每个客户端设备所使用的硬件设备(RAM 或 HDD)、基础设施和设备分布的影响。在扩展 FL 设置时,我们需要在做出正确的硬件选择之前,仔细评估所有可能的选项。因此,为了区分集中式学习和 FL 的能耗指标,我们需要基准测试 FL 客户端的硬件,以验证比较指标。

数据中心冷却

数据中心的冷却过程在整体能源利用中起着重要作用,其贡献高达总能源消耗的 40%(Capozzoli 和 Primiceri, 2015: www.researchgate.net/publication/290010399_Cooling_Systems_in_Data_Centers_State_of_Art_and_Emerging_Technologies0)。这一过程主要由数据中心的效率决定,并通过 PUE 比率进行估算,2019 年全球 PUE 的平均值为 1.67,并且在不同的云服务提供商之间有所不同(2020 年 Google 记录为 1.11,Amazon 为 1.2,Microsoft 为 1.125)。FL 训练过程没有关联的冷却过程。然而,中央聚合服务器也可以配备冷却功能。

一些数据中心的冷却技术通过使用最佳控制机制来实现,如热冷通道布局(不分隔冷热通道以促进空气自由混合)、封闭(通过隔离冷热空气)、机架摆放(促进机架热点的热循环)、电缆整理(确保数据中心内空气流畅通行)以及使用空白面板(防止热空气进入数据中心的气流)。这些高效的冷却方法有助于维持数据中心内的温度。甚至部署监控工具来管理数据中心的气流、湿度、温度、气压和热点,也能通过更好的温度和压力控制提高效率。

数据交换过程中的能量利用率

当训练发生在中央服务器上时,肯定不涉及数据交换。相比之下,在 FL 生态系统中,数据和模型会在中央聚合服务器与分布式客户端之间传输、下载或上传。除此之外,能量利用率还考虑了由于下载和上传,路由器和硬件所消耗的能量。

说明 FL 比集中学习更有效

Xinchi 团队进行的实验结果(arxiv.org/pdf/2102.07627.pdf)解释、比较并评估了集中学习与 FL 的影响:

  • 达到目标精度所需的通信轮次

  • 集中学习和 FL 相关的能量

  • 集中学习和 FL 的训练时间

  • 与 FL 一起使用的不同训练优化器

在 FL 设置中,每个客户端都使用低功耗、支持 GPU 的边缘设备进行小数据集的训练。该设置在一个或五个 LE(训练周期)内达到了目标精度。相比之下,在集中训练环境中,一个 LE 相当于标准的训练周期,这一周期应用于整个数据集的训练过程中。

此外,研究表明,在 FL(联邦学习)设置中,能量利用率甚至比使用节能训练优化器(如 FedAdam)的集中学习设置还要低。FedAdam 因其在初始收敛速度上表现优于联邦平均法FedAvg)而广为人知,甚至在与非自适应优化器的比较中也表现更好。这种自适应优化技术不会导致额外的客户端存储或通信成本,而是确保与跨设备 FL 的兼容性。

在 FedAvg 中,参与训练的客户端通过多个随机梯度下降SGD)步骤将本地更新共享给服务器。这种方法在异构环境(如具有不同用户和词汇的 NLP 领域)下表现不佳,因为它使用共享更新的简单平均值来升级初始模型。

一种基于梯度的优化技术,如 FedAdam,专注于通过每个坐标的方法来平均客户端的模型更新,从而实现自适应服务器优化过程。在这里,服务器端的优化旨在通过 FedAvg 和服务器动量,从全局视角优化聚合后的模型。另一方面,个别客户端在本地训练期间通过多次迭代使用客户端优化器。通过这种方式,它在有限参与过程中尽可能减少本地数据的总体损失。

在 FL 中,相比集中式学习,更多的 LE 通常会导致 ML 模型在较少的 FL 轮次中更快地收敛。尽管这并不能确保更低的能耗,但像 FedAdam 这样的自适应聚合策略在全局模型收敛速度上表现更好。

此外,非 IID 数据集需要比 IID 数据集更多的 FL 轮次,而 IID 数据集的收敛速度比非 IID 数据集更快。

FedADAM 优化器的有效性在 Xinchi 小组研究中得到了验证(实验结果摘自《Federated Learning 碳足迹初探》的研究结果,arxiv.org/pdf/2102.07627.pdf),我们看到它在 CIFAR-10 和 SpeechCmd 数据集上都表现优于 FedAvg。此外,使用五个 LE 时,FedAdam 的 CO2e 排放量低于集中式学习和使用 FedAvg 的 FL。对于 ImageNet 实验,为了在非 IID 数据情况下达到所需的测试准确率,FedAdam 的排放量高于 FedAvg。这是因为该数据集天然不平衡,导致需要多轮训练才能达到目标测试准确度,这导致了更长的训练时间,从而产生更高的 CO2e 排放。例如,使用 FedAdam 优化器时,IID SpeechCmd 数据集的排放量显著更低。

因此,我们可以看到能效取决于集中式学习和 FL 中的多个因素,其中主要因素是 FL 中使用的优化器。在非 IID 数据集(例如,SpeechCmd)中,使用 FedAdam 优化器、较简单的模型架构以及较少的通信轮次,FL 的 CO2 排放量往往低于集中式学习。因此,我们可以得出结论,使用轻量级神经网络时,FL 在能效方面似乎优于集中式学习。

让我们了解如何通过权衡并优化 FL 中的以下因素来减少 CO2 排放。

FL 的 CO2 足迹

决定集中式学习和 FL 训练 CO2 足迹的一些主要因素如下,这些因素导致了不同水平的 CO2e 排放:

  • 硬件的地理定位:例如,研究发现,在法国进行训练时会产生最低的 CO2e 排放,因为核能是法国的主要能源来源,这也导致了最低的能量转 CO2e 的转换率。

  • 深度学习模型的类型,特别是模型架构:例如,基于 FedAvg 的联邦学习优化在使用 ResNet-18 进行图像任务时比现代 GPU 和集中式训练排放更多 CO2。而在 SpeechCmd 数据集上训练 LSTM 模型时,相同的联邦学习优化反而排放较少的 CO2。如果联邦学习中的本地训练任务较轻,通信和数据交换较少,研究表明,这将导致更低的 CO2 排放。

  • 硬件效率:像 Tegra X2 这样的芯片可能会嵌入到智能手机、平板电脑和其他物联网设备中。当使用这种先进的芯片时,联邦学习将继续减少排放。

  • 数据中心的冷却需求和可用性:联邦学习在数据中心没有集中式的冷却过程;这些冷却需求分布在联合中的各个设备上,并根据每个设备的需求而变化。集中式学习的分布式设置需要冷却设施。高性能 GPU 或TPU张量处理单元)需要大量计算能力,要求更高的冷却需求,从而导致更高的能量消耗。

  • 联邦学习中的通信轮次:在集中式学习中,一个 LE 产生的 CO2 比五个 LE 更多,无论是聚合策略还是设备类型。这是因为较少的本地训练 epoch 会导致模型收敛所需时间增加,从而导致更多的数据交换和本地客户端与全球服务器之间的通信轮次。使用五个 LE 时,单个设备训练时间更长,导致较少的通信轮次和较低的排放。

  • 联邦学习中的数据交换:正如我们之前所看到的,CO2e 排放的百分比也主要由广域网络WAN)排放所驱动,这些排放源自数据集和联邦学习设置之间的交换。例如,通信的能量利用可能占总排放的 0.4%(五个 LE 的 ImageNet)和 95%(一个 LE 的 CIFAR-10)。

为了在比较 CO2e 排放时达到对等性和一致性,联邦学习中的通信轮次被转换为集中式训练的 epoch。CO2e 排放与集中式 epoch 的数量直接相关。Xinchi 团队提出的一些 CO2 排放增加的关键因素如下:

  • 集中式 epoch 的数量

  • 硬件的热设计功耗

  • 模型大小的增加,增加了通信所消耗的能量

  • 训练数据集的大小

  • 使用更好的基于深度学习的优化器,例如 FedAdam,它能够优于集中式学习

我们知道,过去十年气候变化的毁灭性影响迫使我们在部署架构之前重新思考和审视我们的排放指标。气候变化和对更绿色星球的关注将推动设计新指标时的研究和创新。所有这些因素汇聚在一起,促使我们选择更好的硬件,以便能够看到 CO2 足迹并提供可能的修正建议。现在,我们必须了解如何部署用于训练 FL 模型的流行设计模式。

我们还应考虑其他可再生能源发电方式,这些方式可以在说服组织控制排放并鼓励投资可再生能源方面发挥重要作用。

因此,让我们探讨如何补偿 CO2e 排放。

如何补偿等效 CO2e 排放

为了补偿 CO2e 排放,我们需要理解如何处理有关能源电网的信息或将能源转化为 CO2e 的转换率。由于公共信息来源的匮乏,有一些推荐的实践方法需要牢记:

  • 我们必须假设,所有连接到本地电网的数据中心和边缘设备都直接与其物理位置相关联。特定于电力的 CO2e 排放因子以 kg CO2e/kWh 表示,不同国家的排放因子各不相同,例如法国(0.0790)、美国(0.5741)和中国(0.9746)。

  • 排放技术(包括计算电力传输和分配时能量损失的适当指标)以及热电厂的吞吐量或生产力可能会影响整体能源利用情况。

  • 考虑到上述假设,评估 FL 和集中式学习的转换因子可以帮助我们计算并设定一个具有最少 CO2 排放的能源利用指标。在 FL 中,通信所需的能源因数据分区类型(IID 数据集需要更多能源)、通信轮数、硬件类型、位置及我们已经讨论过的其他因素而有所不同。

  • 作为可持续发展专家,我们的下一个目标是通过购买美国的可再生能源凭证RECs)或欧盟的可交易绿色证书TGCs)来补偿由此产生的 CO2 排放。即使是支持环保项目的倡议,如可再生能源项目或大规模植树活动,也可以得到鼓励。

我们现在需要考虑如何通过考虑不同的参数来训练 FL 模型,这些参数会影响 CO2 排放。

基于 FL 的模型训练设计模式

到目前为止,我们一直在集中讨论从可持续性角度看,FL 是一种非常好的方法。然而,除了可持续性之外,FL 还从数据隐私的角度提供了巨大的好处,这与负责任的人工智能(Responsible AI)相关。在 FL 中,客户端能够分享来自本地数据的匿名化学习,而无需将潜在敏感的数据与集中式处理过程共享。在这一部分中,我们将进一步了解这一点,并深入了解 FL 的不同设计模式。

FL 有不同的设计和部署策略,这些策略将影响其二氧化碳排放指标。以下是一些关键指标:

  • 每个客户端中非 IID 数据集的大小

  • 参与的客户端数量

  • 客户端参与训练之前的等待时间,这影响模型的收敛性

  • 本地客户端的训练时间以及聚合全局模型的时间

现在让我们来看一下基于 FL 的训练的不同模式。

当我们考虑使用 FL 进行模型训练和数据处理模式时,我们需要考虑数据类型,以及客户端参与本地训练的动机。因此,我们可以将它们主要分为三种类型:

  • 一个多任务模型训练器,用于训练非独立同分布(non-IID)数据集

  • 一种用于训练异构数据集的异构数据处理器

  • 一个激励注册系统,通过奖励机制激励客户端

在每个与设计模式对应的示意图中,我们使用了以下的 FL 序列:

  1. 一个通用的全局模型由中央服务器训练。

  2. 在特定训练轮次中选择的每个客户端下载全局模型,并启动本地训练过程。

  3. 客户端本地训练的模型随后会在全球服务器上进行更新。

  4. 服务器使用 FedAvg 算法聚合全局模型,以改进共享版本的模型。

  5. 然后,本地设备将被更新为最新的重训练全局模型,这为它们的本地重训练做准备,并更新它们以进行后续迭代。

多任务模型训练器

这种训练模式的主要目标是提高学习效率和模型性能指标。此外,它最适合在本地设备上训练独立的相关模型。具体而言,当客户端的数据分布模式有所不同,并且全局模型无法代表每个客户端所展示的数据模式时,我们会使用这种方法。例如,正如下图所示,在计算机视觉、强化学习、语音识别和自然语言处理(NLP)上训练独立的模型,对于建模和展示每个模型的目的至关重要:

图 12.2 – FL 模型训练设计模式 – 一个多任务模型训练器

图 12.2 – FL 模型训练设计模式 – 一个多任务模型训练器

一个现实世界的例子是使用机器学习(ML)解决下一个词预测任务(涉及自然语言处理的相关机器学习任务),通过使用设备数据,如文本消息、网页浏览器搜索字符串和电子邮件。

为了获得更高的准确性,该设计每一轮都涉及更多的训练时间、计算和能源资源,这与其他传统联邦学习(FL)技术的期望一致。该方法的主要挑战是本地客户容易受到数据隐私威胁的影响,并且训练只能应用于凸损失函数。

一个异构数据处理器

这种训练模式通过应用诸如数据增强和使用生成对抗网络进行对抗训练等特殊处理技术,保持数据隐私,并在数据分布非独立同分布(non-IID)和偏斜的情况下,找到更好的基本 FL 使用方法:

图 12.3 – FL 模型训练设计模式 – 一个异构数据处理器

图 12.3 – FL 模型训练设计模式 – 一个异构数据处理器

由于客户的个性化数据导致数据分布不均衡和偏斜,在设备上训练的本地模型在聚合时往往会降低全局模型的准确性。因此,必须通过插入一个异构数据处理器来提升数据效率,该处理器可以正确地增强和提炼联邦数据,同时仍然保持数据隐私。提炼过程使客户端设备能够定期从其他参与设备收集信息,而无需直接访问其他客户的数据。

该机制试图以训练时间和计算资源为代价,提供更好的模型性能指标,最终导致较低的能源效率和较低的可持续性指标。

一个激励登记

如下图所示的训练模型根据参与客户在数据量、模型性能、计算资源等方面的贡献进行奖励。这是一种激励客户并提高全局模型性能的措施。下图展示了基于区块链和智能合约的激励机制:

图 12.4 – FL 模型训练设计模式 – 一个激励登记

图 12.4 – FL 模型训练设计模式 – 一个激励登记

激励机制能激励更多客户端参与,因为这种训练策略并不是通过每个客户端在每次迭代中都完全参与来驱动的。此外,激励机制需要客户端和学习协调者之间达成共识,以决定评估标准。制定激励机制的一些常见方法包括强化学习、区块链/智能合约和斯塔克尔伯格博弈模型。基于区块链的 FL 激励机制的一个具体应用是 FLChain,它支持协作训练和模型交易市场。该模型同样面临着长时间训练和计算资源挑战的问题。

在本节中,我们了解了控制 FL 训练设置的重要因素,包括参数、客户端数量、时间和训练的时期周期。所有这些因素都影响着训练环境中的能量消耗,从而加剧了全球变暖。除了模型训练,我们还将了解不同的模型部署模式如何影响能源排放。在接下来的章节中,我们将主要讨论一种 FL 环境中的策略,其中只有选定的客户端参与训练。尽管我们将提到参与训练过程的个别客户端,但我们的主要目标是理解那些能促使客户端启动本地训练过程的操作或部署模式。

模型部署中的可持续性

在上一节中,我们了解了 FL 在可持续性方面的重要作用。现在,让我们探讨一个可持续的 FL ML 框架。我们将看到如何使用能够从环境中积累能量并在间歇性训练期间有效利用这些能量的可充电设备。

这种框架可以扩展到跨设备和跨信息孤岛的 FL 设置,包括无线边缘网络中的 FL、物联网和医疗设备互联网IoMD)。单个本地设备的训练可以推动模型的收敛,并使其适应以下设置:

  • 通过允许随机选择少量客户端来最小化每次迭代中的通信开销。

  • 启用客户端选择,以最大化学习速率,加速收敛速度。

  • 基于每个客户端的能源到达过程启用客户端选择过程。这是为了应对间歇性和非均匀的能源到达模式,以有效管理客户端掉线。

该部署框架非常适合异构设备可用且每轮训练独立进行的场景。这使得框架更加灵活,因为每个参与训练过程的设备在某一轮中不会被未来的连续轮次所约束或依赖。训练过程(由随机的能量供应驱动)由中央服务器协调,服务器汇总客户端的本地模型并将更新的全局模型发送给它们。各个客户端使用自己的数据集进行本地训练,并通过多次 SGD 迭代更新收到的全局模型。该框架不仅有助于节能的可持续 FL 训练,而且在设备通过间歇性和非同质的能量更新过程生成能量的场景下,能够最小化训练的总能量成本。

该框架允许不同类型的客户端具有不同的能量生成水平以参与训练,提供两种不同的配置:

  • 一种有偏的模型预测策略,其中全局模型偏向于那些能量供应更频繁的客户端。这种模型在预测结果的准确性上会有性能损失,但能够提供更好的收敛速度。

  • 一种无偏的模型预测策略,其中允许所有客户端在每次参与训练过程之前,等待足够的能量生成。这种模型基于最慢客户端的等待时间,会有最长的等待时间。然而,这种训练尽管收敛速度较慢,但在性能指标上表现更好。

提出的框架配备了四个不同的实体,如下所述,以促进一个能量感知的客户端调度和训练策略:

  • 客户端的能量配置:考虑所有客户端的能量供应是最重要的因素,因为它决定了客户端基于从环境中获得的能量(如太阳能、动能、环境光或射频能量)参与训练的情况。能量配置是一种研究能量模式的机制,用于推断是否有足够的能量来训练本地模型并将更新发送给中央服务器。任何参与的客户端从初始时刻 t 开始参与全球轮次的训练过程,确保客户端在该全球轮次的整个时段内参与训练,{t, . . ., t+T −1},期间客户端正在训练本地模型。此外,参与任何全球轮次训练过程的客户端,在该指定的全球轮次训练的整个过程中保持不变。

  • 客户端调度:该框架具有灵活性,允许客户端根据其能量状态决定是否参与当前迭代的训练过程。随机参与过程在客户端本地估计能量到达过程后,将其纳入调度,以最大化收敛速度或减少训练的通信开销。调度过程无需客户端之间的协调,使得在大规模网络中更容易扩展。

  • 客户端本地训练:此阶段允许参与的客户端使用 SGD 训练本地数据集,然后将其更新到中央服务器。

  • 服务器更新模型:此阶段允许服务器聚合本地模型,以整合全球模型并发送到各个设备。

在研究了影响能量智能客户端调度的主要因素后,我们将在此讨论基于客户端能量可用性如何进行调度的过程。

图 12.5 说明了两种不同的预测策略,其中客户端要么在能量到达时立即参与,要么等到所有客户端积累了启动训练所需的能量后再开始。图的左侧部分对模型收敛持乐观态度,在能量可用时立即开始客户端调度(由不同颜色的 t1、t2、t3 和 t4 表示)。而右侧子图则比较保守,等待所有客户端都具备可用能量后再统一调度,它们的颜色都是相同的橙色,其中 t1、t2、t3 和 t4 表示不同的时间点:

图 12.5 – 基于能量到达模式的客户端调度

图 12.5 – 基于能量到达模式的客户端调度

本节中,我们已经学习了如何通过使用随机能量到达过程,在大规模网络中部署可持续的 FL。此外,结合模型量化和压缩技术,利用客户端间完全随机的能量可用性,能够更好地描述能量更新过程与训练性能之间的关系。

我们已经理解了基于能量调度客户端的训练过程。现在,让我们看看这些训练模式如何根据架构进行调度,以及如何扩展 FL 模型。

基于 FL 的模型部署设计模式

让我们深入探讨一旦 FL 模型在生产环境中上线后,如何管理和聚合它们。在这里,我们将讨论两种架构设计,主要从数据通信、模型管理和治理的角度出发,探讨这些模型如何被聚合并分发给本地客户端:

  • 基于 FL 的模型管理模式:我们需要模型管理模式来建立与本地客户端的数据或模型大小相关的规则和流程。大小在数据或模型交换中起着至关重要的作用,因此影响能耗。此外,替换模型的频率以及更新全局模型的频率是决定 CO2e 排放量和 FL 可持续性的关键因素。

  • 基于 FL 的模型聚合模式:我们需要 FL 中的模型聚合模式,将来自单个客户端的学习整合起来,以创建更新后的全局模型。模型聚合过程的模式——无论是异步的、分层的,还是去中心化的——都会影响时机和延迟。所有这些因素共同作用,导致不同水平的 CO2e 排放。

让我们在接下来的部分中讨论这些设计。

基于 FL 的模型管理模式

模型管理模式负责模型的传输、部署和治理。根据消息传输方式或客户端如何在本地存储模型,我们可以将它们分为四个大类,如下所述:

  • 消息压缩器,减小传输消息的大小

  • 一个模型共版本注册表,参与模型版本管理,通过接收客户端的模型更新,帮助促进模型聚合

  • 一个模型替换单元,监控全局模型的性能,并在模型性能下降时启动新的训练

  • 部署选择器,将改进后的全局模型推送到客户端

让我们详细讨论这四个类别中的每一个。

消息压缩器

图 12.6所示,这一设计模式在每轮模型交换过程中压缩消息,以减小数据大小:

图 12.6 – FL 模型部署设计模式 – 消息压缩器

图 12.6 – FL 模型部署设计模式 – 消息压缩器

这个过程通过有效地压缩模型参数或梯度,帮助在带宽有限的情况下提高通信效率。然而,当服务器必须聚合大量的模型参数时,该模式会带来额外的计算成本。此外,它还会增加消息压缩和解压缩的开销,可能会丢失一些关键信息。

一个模型共版本注册表

模型共版本注册表,如图 12.7所示,通过跟踪每个客户端的模型版本并将其与相应迭代的全局模型对齐,帮助本地模型治理过程:

图 12.7 – FL 模型部署设计模式 – 模型共版本注册表

图 12.7 – FL 模型部署设计模式 – 模型共版本注册表

这有助于同步和异步模型更新、客户端掉线、模型选择以及提前停止复杂模型训练。此外,这种模式具有独特的优势,可以跟踪模型质量(包括全局模型、客户端设备更新以及应用程序或设备操作系统/固件的版本),以及客户端的对抗性行为(当客户端充当对手时),以增强系统的问责性。注册表用于收集本地模型更新并将其映射到全局模型,从而确保模型版本号和客户端 ID 保持不变。此模式还可以通过区块链实现,以提供模型来源和共同版本管理。该架构所需的额外存储量,用于存储所有版本的全局和本地模型,带来了额外的好处,即为系统安全提供保障,能够检测出可能导致系统故障的不诚实客户端。这个模式的一个典型例子是基于 Databricks 构建的 MLflow 模型注册表,它提供了一个高效的集中式模型存储,用于跟踪模型的时间线、版本管理和阶段过渡。

一个模型替换触发器

这个联邦学习设计模式通过在新的模型任务上设置触发器来启动模型的替换,当模型的性能降到可接受阈值以下时。为了解决模型准确度下降等问题,这个模式提供了机制,在建立新的模型训练过程之前,先调查这种准确度下降的原因。只有在连续几轮注意到模型性能退化时,才会启动重新训练过程,从而强烈推断性能下降是全局性的。重新训练模型会增加通信和计算成本,但在处理具有异质非独立同分布(non-IID)数据集的联邦学习环境中的客户端时非常有效,因为这些客户端拥有个性化数据集,并且随着多轮迭代,全球模型的性能会更快衰退。微软 Azure 机器学习设计器和 Amazon SageMaker 是基于模型性能退化触发模型重新训练的知名平台。

一个部署选择器

图 12.8所示,这种部署策略能够使全局模型收敛,并根据所运行的应用将全局模型推送到选定的客户端。因此,不同组的客户端接收到不同版本的收敛模型,目的是提高模型的性能指标。模型选择解决了客户端之间非 IID 数据分布的问题,使得不同定制的收敛模型能够更好地服务于不同的客户端组。然而,这一过程会增加服务器的开销,因为中央服务器需要正确识别客户端,以便为它们提供不同版本的全局模型,同时训练和存储适用于不同客户端的不同模型。尽管训练成本增加,但我们根据客户端的 ML 任务得到了更好的泛化模型。此策略需要内置额外的隐私保护措施,以防止在服务器尝试分组客户端时出现隐私泄露。这种 FL 训练可以在 Amazon SageMaker 和 Google Cloud 上进行,它们可以训练和管理多个模型版本,并将其部署到不同的端点:

图 12.8 – FL 模型部署设计模式 – 模型部署选择器

图 12.8 – FL 模型部署设计模式 – 模型部署选择器

基于 FL 的模型聚合模式

这种设计模式采用不同的策略进行模型聚合,以减少聚合延迟并提高系统的效率、可靠性和可追溯性。主要目标是通过有效利用最佳资源来改善模型的性能指标。它们可以大致分为以下四种模式:

  • 异步安全聚合器

  • 去中心化聚合器

  • 安全聚合器

  • 分层聚合器

我们在以下小节中展示了四种模式;最后两种模式可以组合成一个混合的分层安全聚合器。

异步聚合器

这种异步全局模型聚合策略,如下图所示,使我们能够在新的模型更新到来时加速模型聚合,而无需等待在客户端本地训练的模型。

图 12.9 – FL 模型部署设计模式 – 异步聚合器

图 12.9 – FL 模型部署设计模式 – 异步聚合器

这一机制与传统的 FL 有所不同,它允许客户端跳过第一次聚合轮次,在下一次(第二次或后续)聚合阶段中客户端异步地更新模型。因此,它能够适应客户端在计算资源、带宽可用性和通信能力方面的差异。客户端在参与全局模型聚合时享有明显优势,因为服务器的模型收敛过程不受延迟的影响。

使用此策略所面临的挑战会导致全局模型产生偏差,如果重要信息被消除,可能会影响模型的质量。此外,服务器上的最大聚合延迟由最慢客户端发送更新的时间决定,从而导致模型收敛速度缓慢。

然而,这种方法的一些主要优点包括在每轮聚合中都进行集中聚合,而不是等待最慢的客户端。我们还看到,每轮的带宽使用量减少,因为只有少数客户端异步发送它们的更新。

设计模式的例子包括异步在线联邦学习异步 联邦优化

去中心化聚合器

如下图所示,这种聚合策略遵循去中心化联邦学习(FL)方法,通过去除对中央服务器的依赖,避免了单点故障的风险。在这种架构中,中央服务器可能会遇到额外的负载,因为它需要接收并聚合来自所有客户端的更新。图示展示了区块链和智能合约如何在更新共享给相邻设备时接收模型更新。在传统的 FL 训练中,当并非所有参与的客户端都信任中央服务器时,系统可能会受到隐私限制的影响。

图 12.10 – FL 模型部署设计模式 – 去中心化聚合器

图 12.10 – FL 模型部署设计模式 – 去中心化聚合器

推荐使用这种去中心化方法,其中允许客户端设备之间进行模型更新。然而,这种架构还需要合理定义去中心化的模型管理系统,在该系统中,同行设备能够收集、存储、检查并聚合本地模型。此外,我们还需要定义系统所有权,通过该方式随机选择一个客户端执行来自本地相邻客户端的聚合操作,并将聚合后的模型发送到客户端网络。区块链作为去中心化 FL 的最佳选项之一,可以存储不可变的模型,学习协调者可以维护区块链。区块链机制可靠、可追溯且值得信赖,从而增强了对抗攻击的韧性、信任度和透明度。

该系统的主要缺点之一是由于区块链共识协议在模型聚合过程中的延迟。此外,客户端设备还可能因为参与训练和模型聚合的并行性而导致电池耗电。即便是这种去中心化架构,也存在客户端可能泄露其同伴的敏感信息的风险。此类点对点学习模式的一个实际例子是 BrainTorrent,在该模式中,客户端之间直接进行学习和交流。

安全聚合器

这种聚合策略支持内置的安全协议,比传统的联邦学习(FL)更好地保护模型,且不需要数据加密的支持。这与传统的联邦学习形成对比,后者没有考虑数据加密和参数的安全交换,容易留下未经授权的数据访问空间。为了防止恶意客户端加入训练过程并遏制对数据/模型的污染攻击,我们需要确保在模型向中央服务器发送更新时,合适的安全协议已到位。确保模型参数和梯度不被第三方访问的最佳方式是采用安全的多方计算来进行模型交换和聚合,确保每个参与客户端都能意识到自己的模型输入和输出。我们还可以使用同态加密,使客户端能够加密,服务器能够解密模型。应用级安全机制,如成对遮蔽和差分隐私,有助于减少数据泄露给外部对手的风险。

这种架构模式的一些缺点包括由于增加额外的安全协议和加密方法,导致系统效率降低和模型准确性下降。因此,我们需要选择合适的隐私阈值,以平衡模型性能和隐私之间的权衡。谷歌开发的安全聚合协议(Secure Aggregation)就是联邦学习中一种安全聚合协议的典型例子。

层次化聚合器

这种聚合技术增加了一个额外的层次化聚合器层(如边缘服务器),以减少非独立同分布(non-IID)对全局模型的影响,并提高系统效率。下图展示了我们如何使用边缘网络 1 和边缘网络 2 在触发全局聚合过程之前,先从附近的客户端设备进行部分聚合。这种设计模式引入了位于边缘网络的中间服务器,用于处理客户端与远程服务器之间的慢速通信,从而提高系统效率。引入层次化聚合器有助于扩展联邦学习系统,并促进更好的全局模型聚合,因为服务器可以将来自数据异质性相似的客户端的本地模型进行组合。

这种架构的主要缺点是当设备与边缘服务器断开连接时,系统的可靠性受到影响,进而影响模型的训练和性能。此外,我们还需要特别小心安全协议,因为边缘服务器可能会出现安全漏洞,并且更容易受到网络安全威胁。

一个直接使用这种架构的联邦学习模型的实际例子是层次化联邦平均(Hierarchical FedAvg),在该模型中,根据从客户端逐步接收的更新,采用多个边缘服务器进行部分模型聚合:

图 12.11 – FL 模型部署设计模式 – 层级聚合器

图 12.11 – FL 模型部署设计模式 – 层级聚合器

摘要

在本章中,我们了解了在开发 AI 解决方案时可持续性日益重要的背景,以及可以帮助我们减少二氧化碳排放的所需云计算指标、架构和操作技能。我们详细概述了如何根据客户端的能源可用性训练 FL 模型,以减少较高二氧化碳排放的负面影响。现在我们已经了解了高效的基于 FL 的设计模式,无论是训练、模型管理,还是模型聚合模式。

在联邦学习(FL)的训练和部署策略的背景下,我们还获得了探索基于深度学习(DL)的不同训练优化器的优势及其对解决方案可持续性影响的机会。此外,我们还探讨了集中式学习与联邦学习(FL)中的可持续性因素,这有助于我们使用硬件规格、效率、活动运行时、模型架构、冷却需求、云服务提供商和地区等信息来估算 GPU 计算的二氧化碳排放量。我们还探索了如何计算总能耗、可以使用的不同排放指标,以及我们可以遵循的最佳实践,以最大化数据中心的效率。

在下一章中,我们将深入探讨在创建特征存储时如何确保可持续性。

进一步阅读