第六章:使用特雷诺-布莱克模型和 ResNet 的自动化投资组合管理

在上一章中,我们介绍了投资银行的基本概念。我们还学习了并购M&A)和首次公开募股IPO)的概念。我们探讨了聚类模型,它是人工智能中的一种建模技术。我们查看了详细的步骤和例子,解决了自动化联合的问题。我们实现了一个示例,识别了收购方和目标方。因此,前两章主要针对投资银行证券方面的发行人。

本章将探讨投资者的动态。投资者以战略方式推动投资行为。股权或债务的发行可以通过两种方式进行——通过一级市场或二级市场。一级市场的角色是代表公司、政府或其他团体发行新证券,以通过债务或股权导向的证券获得融资。二级市场的角色是为有兴趣的各方提供买卖已发行证券的便利。投资组合经理的角色是根据证券的价格波动做出更智能的决策,以增加客户的利润。投资组合经理试图了解投资者的需求,并将资金投入那些能够产生最大回报的投资。

本章将涵盖以下主题:

  • 金融概念

  • 马科维茨均值方差模型

  • 特雷诺-布莱克模型

  • 使用特雷诺-布莱克模型的投资组合构建

  • 趋势预测

金融概念

在本节中,我们将探索各种金融概念。若要深入了解该领域的知识,建议参考特许金融分析师CFA)的课程大纲。

资本资产定价模型中的 alpha 和 beta 回报

根据资本资产定价模型CAPM),投资回报等于risk-free rate + alpha + beta * 市场回报 + 噪声(噪声的均值为零)。Alpha 是公司或投资者优异表现所赚取的回报,而 beta 是资产相对于整体市场回报的风险性。投资风险较高时,beta 值较高,表明投资比市场平均风险更大。噪声是随机波动或运气,长期回报为零。

资产管理行业,尤其是专业的投资经理,通常根据 alpha 向客户收费。这也解释了人们为何如此关注 alpha。

已实现和未实现的投资回报

投资回报(收益)可以是已实现的或未实现的。已实现回报是实际获得并已收入囊中的回报。未实现回报是如果今天卖掉资产并以现金结算,我们本应获得的回报。

投资政策声明

投资行业的运作是代表资产所有者进行投资。作为资产管理者,我们的受托责任是为客户提供建议并代表其进行投资。到目前为止,在本书中,我们通过观察行为/交易数据来理解投资者的投资需求。然而,关键数据实际上是投资者将要制定的投资政策声明IPS)。

一份 IPS 包含投资者制定的回报目标、风险承受能力和约束条件。回报目标和风险承受能力都是可以量化定义的变量。回报可以定义为扣除通胀率后的净年回报率。如果目标回报率为 1%,通胀率为 1%,这意味着随着物价水平按通胀率增长,资本的价值保持不变。从长远来看,我们投入投资组合的购买力保持不变,因为其价值与物价水平同步增长。

这些变量可以用数学方式表示如下:

  • 回报目标:这个回报目标叫做资本保值。1%的回报率叫做名义回报率。从名义回报率中扣除通胀率之后,得到的叫做实际回报率:
  • 风险承受能力:风险承受能力可以定义为回报的波动性。我们通常这样定义它:

风险承受能力的选择是主观的——有些人喜欢伴随兴奋而来的起伏。而有些人则喜欢坐在沙发上阅读这本书(挺无聊的,是吧?),有些人则喜欢坐在桌子旁的椅子上阅读。有人喜欢在枯燥的 9 到 5 工作中稳定拿薪水,而另一些人则喜欢创业公司的刺激,抱有迅速致富的希望,同时承担失败的风险。

也就是说,无聊并不意味着被解雇的风险较低,而令人兴奋的工作并不意味着失业的风险较高。有些明显的情况是,我们可以拥有令人兴奋的工作、高潜力和稳定性。这正是通过这个资产配置过程所希望达到的目标结果。

www.wiley.com/en-us/Managing+Investment+Portfolios%3A+A+Dynamic+Process%2C+3rd+Edition-p-9780470080146

在 AI 时代的挑战是如何将这个政策转化为机器能够理解的代码形式。实际上,投资界的任务是将投资政策数字化。

区块链的最新进展带来了智能合约,其基于某些声明可以作为逻辑进行数字化的假设。如果合同可以在区块链上作为智能合约进行编码并执行,那么为什么不可以是投资政策呢?假设在本章剩余部分中,投资政策被编码化。

资产类别

投资组合管理是根据资产类别或风险因素的特征,将资金分配到不同投资资产的过程。我们将从资产类别分配开始讲解。资产类别被定义为具有相似特征的资产组合。实际上,这听起来很像聚类模型的结果。

为了融入我们的金融知识,资产类别通常指的是股票、债券、货币市场和另类投资。另类投资可以细分为房地产、私人股本、对冲基金和商品。股票是指在公开交易市场上发行的股权,而债券是指公司发行的债务。货币市场是指期限在一天到一年之间的短期债务。它们不同于债券,因为货币市场具有高度流动性(市场交易活跃,定价公允),而债券市场则可能非常不流动,或者由某些投资者主导。债券通常指期限较长的债务,例如 10 年期或更长的到期债务。当然,它也可以包括任何超过 1 年的债务,通常称为票据

投资行业的参与者

投资者在金融行业中扮演着核心角色。然而,同样重要的是要了解其他主要参与者——投资经理(管理投资者资金的人)、被称为卖方的经纪人(通常是投资银行或证券公司),以及为投资者提供如何选择投资经理的专业建议的顾问和顾问公司。保管人指的是负责投资交易和与交易所市场的结算及行政事务的方。

如果投资经理来自机构,他们被称为机构投资者,而如果是个人自己操作,则被称为个人投资者。机构投资者对投资资金的受益所有者负有受托责任。这些受益者是投资经理的真正客户。例如,在杜克能源的案例中,最终的受益者可能是杜克能源的员工。在这其中,可能是管理基金的财务主管作为投资经理,也可能是外包的投资基金经理作为选定的投资经理。

在行业的销售方面,基金可以面向机构投资者、个人投资者,或通过银行或保险公司面向零售分销。在零售分销的情况下,确保投资符合所有者需求的责任在于分销商。虽然机构投资者或个人投资者是与投资经理直接接触的对象,但匹配的责任则由投资经理或顾问来承担。

基准 – 比较的基础线

基准被投资组合用来定义他们应该与之对比的市场平均回报。它可以指市场回报或 CAPM 中的 beta。任何高于平均水平的部分被称为alpha。在本章的示例中,我们假设全球股票交易型基金ETF)是市场基准。

如果我们要为全球资产中的投资者构建全球市场基准,我们可以通过分析创建这样一个指数,权重分配不同的指数或回报篮子。

投资者追求回报

国际结算银行的一项研究显示,投资者表现出追逐回报的行为。这意味着投资的一个关键原则是跟随市场(回报)。这也意味着,如果我们仅仅依赖回报来驱动我们的资产配置决策,我们将永远比市场慢。所以,在人工智能的世界里,可能有两种方式来提升:

  • 使用超快速的机器迅速跟随回报趋势

  • 比大众更好地预测市场

ETF 承诺做前者,前提是我们足够快速地将资金分配给 ETF——这反而违背了跟随市场的初衷,因为市场上有太多不同种类的 ETF。只有当我们投资于真正的市场代表时——例如,一个主要的市场指数 ETF——我们才能实现这一目标;否则,我们仍然会面临同样的挑战,即试图分配到正确的证券/投资,以产生 alpha(战胜市场)。

在大多数交易书籍中,作者会隐藏他们的获胜策略——这使得我们理解什么是策略变得困难。为了保持实际性,我们将从一个失败的策略开始,您可以在此基础上进行改进。这至少向您展示了从头到尾的策略开发过程,并给您一个全面的交易工作方式。

趋势跟随基金

在将资产配置给基金经理之后,我们来深入探讨所投资的基金。如果我们是 ETF,我们的一个关键需求是跟踪基础证券。例如,如果基金的任务是根据一组规则跟踪一篮子证券的表现,我们可以简单地购买并持有这些基础资产直到赎回(即投资者提取他们的钱)。

然而,如果我们尝试提前预测价格波动并据此采取行动,我们有可能获得超越基准的收益——这就是我们所说的阿尔法

使用技术分析作为生成阿尔法的手段

一种交易思维方式认为证券定价中展现出的趋势是非常重要的。这就是所谓的技术分析。它假设过去的定价走势可以预测未来的走势。以下图表展示了证券价格在某一时期内的趋势:

从一个非常高的层次来看,我们可以看到证券价格是按趋势波动的,但趋势的持续时间并非总是相同的。关于如何解读价格波动中的模式,已有大量研究。然而,这难道不是一个计算机视觉的挑战吗?与我们手动挑选无数特征不同,是否应该让计算机来读取图表并学习如何画出趋势线?

关于模式类型,一个好的起点是*《金融市场的技术分析:交易方法与应用的综合指南》(纽约金融学院)。有关用于检测模式的精确数据处理的信息,请参考《机器学习进展》*。在这里,Prado 博士通过在数据输入机器之前,给你提供深入的见解,将这一领域提升到了另一个层次。

交易决策 – 策略

交易策略是指在交易活动中需要考虑和采取的行动。因此,在本章中,我将展示一个在设计时失败的实际策略,而不是排除这些策略。对于真实的交易员来说,公开成功的交易策略会导致其失效,因为别人可以反其道而行之——例如,反向交易者可以在你预期买入时卖出,反之亦然。

我们在这里提出的简短策略,与使用相同资产的简单买入持有策略相比,并未产生正的阿尔法。然而,我会指出改进它的方法。

onlinelibrary.wiley.com/doi/abs/10.1111/jofi.12372

理解马克维茨均值-方差模型

投资组合管理的目标是通过最小化风险来确保目标回报,在这个过程中,我们根据特定投资者的目标回报和风险容忍度(从投资政策声明(IPS)和历史回报中获取)来进行决策。行业中常用的典型投资组合优化模型包括马克维茨均值-方差模型和特雷诺-布莱克模型。

一位名叫哈里·马克维茨(Harry Markowitz)的经济学家在 1952 年提出了均值-方差分析,这也被称为现代投资组合理论MPT)。由于这一理论,他获得了诺贝尔经济学奖。

均值-方差模型是一个用于组建资产组合的框架,以便在给定的风险水平下最大化回报。它是投资多样化的扩展。投资多样化是一种建议投资者应投资于不同类型金融资产的理念。与仅投资单一类型资产相比,投资多样化的风险较低。

投资者选择最大化回报的资产配置,这也被称为回报方差。在进行资产投资时,风险与回报的比率成为关键决策因素。风险与回报比率是预期回报与可能损失的比率。预期回报与实际回报之间的差异被称为风险。关键挑战是计算目标组合的回报方差。例如,它可能是 40%的股票和 60%的债券,或者是一个更复杂的资产类别配置,如房地产、商品等。要得出 40%股票和 60%债券的回报方差,我们首先需要分别计算股票和债券的回报方差。同时,我们还需要考虑股票和债券之间的协方差,即股票和债券的回报是如何同步或完全不同步的。

关于资产和财富管理行业如何发展的详细见解,请参考普华永道,2017 年,《资产管理 2020:回顾与展望,资产与财富管理见解》

想象一个团队中的每个人(每个人代表一个资产类别)共同完成一项任务,以提供回报。投资组合经理的工作是确定团队内每个人在组内的发言权大小(资产配置工作)。这取决于个人的生产力(回报)和表现波动性:有些人表现极端,而有些人在生产力(方差)方面相当稳定。我们还需要了解个人团队成员之间的互动——这种互动还必须考虑每个成员如何互补或增强彼此的生产力(相关性)。一些团队成员之间表现出强烈的化学反应,能够共同取得极好的结果(正相关),有些人则在一天的不同时间工作——一个是夜猫子,另一个是晨型人——他们各自有不同的工作时间(负相关),还有一些人没有任何一致的相似性或不相似性模式(零相关)。

下图展示了两个资产(i 和 j)之间的相关性矩阵。灰色的对角线表示证券的回报方差,剩余的单元格表示证券间的回报协方差。黑色单元格是多余的,因为它们与对角线对面的值是镜像关系。对于仅 20 个证券,我们将需要估算 190 个值:

为了进一步说明这个问题,假设证券20是非流动性的,我们无法可靠地估计它与另一证券的协方差。我们可能已经影响了与其他 19 个证券的协方差数据质量。在实际应用中,这个模型的问题如下:

  • 一些资产没有足够的数据点来计算它们与其他资产的相关性(例如,团队中新加入的成员)。

  • 在金融市场中,资产之间的相关性是动态变化的,且很难预测未来的相关性。

  • 相关性不是线性的。

该模型适用于具有高效定价和大量数据点的公共股权市场,但不适用于非流动性资产——例如初创公司的私人股本、发展中市场的证券或债券,这些资产的定价往往无法完全透明,且很多情况下需要通过分析重建。

风险中的一种特定类型的相关性是信用风险——在经济景气时,资产间的风险相关性较低;而在危机时,相关性飙升并朝着相同方向变化。有关违约相关性的示例,请参考 Duffie D. 和 Singleton, K.J.的*《信用风险定价、衡量与管理》*。

一些成熟企业的财务主管负责管理自己的养老金资金。我们假设财务主管需要处理养老金基金的目标资产配置。我们将使用每个资产类别的指数回报数据。我们将使用 Quandl 提供的 ETF 订阅数据作为数据来源。

ETF 是指可以在公共交易所(如纽约证券交易所NYSE))买卖的基金。它是一种基金,因为它投资于更多的基础证券,如股票或债券。随着它允许投资者专注于基金所投资的主题,而不是单一股票,因此变得越来越受欢迎。例如,我们可以通过购买投资美国最大 500 只股票的基金,来对美国经济的强势做出明确判断。

探索特雷诺-布莱克模型

由于马克维茨均值-方差模型在处理多资产类别投资组合相关问题时的不稳定性,特雷诺-布莱克模型应运而生。特雷诺-布莱克模型适用于现代投资组合配置方法,其中某些投资组合是主动的,另一些则是被动的。这里的“被动”指的是一种跟随市场回报率的投资方式——目标不是超过市场平均回报,而是紧密跟随市场回报。

主动投资组合是指我们力求实现超过市场平均回报的投资组合。市场回报越低、市场风险水平越高,投资组合越大。然后,我们将总资本分配到一个主动投资组合中。那么,如果市场回报已经足够好,为什么还要承担更多的风险呢?Treynor-Black 模型旨在将更多的权重分配给那些能够在总风险/回报水平下提供更高回报/风险水平的资产。

介绍 ResNet——用于模式识别的卷积神经网络

应用计算机视觉类型的神经网络的特殊之处在于,我们可以使用以下隐藏层。在我们的例子中,我们将使用 Keras 实现的 ResNet 作为示例来说明这些概念。我们还将展示一种提高性能的方法——然而,您需要深入研究超参数调优。

卷积层就像是对输入图像的一个子集进行处理。在技术分析中,它就像使用滑动窗口来计算统计值。每种类型的滑动窗口都会被训练来检测某种模式,比如上升、下降和平坦的线条。在神经网络术语中,每种类型被称为过滤器。对于每种类型的过滤器,都会有多个窗口来完全运行(或滑动)整个输入图像;这个数字由层中的神经元数量表示。

为了说明术语,我们以一个大小为3 × 3的输入图像和一个2 × 2的卷积核形状为例。在编码示例中,我们的实际输入比这个大小要大。

输入图像是一个3 × 3的图像,图像中有一条从左下角到右上角斜着穿过的黑线(由 3 个像素表示)。它显示了股价每天上升 1 个像素:

滑动窗口的形状叫做卷积核。卷积核是一个函数,它可以将输入的矩阵/向量转换为另一种形式,如下图所示:

为了说明,我们假设卷积核大小为2 × 2步长 = 1,并且默认使用零填充,除非另有说明。

下图中的数字显示了卷积核移动的顺序。每次移动都会由卷积层中的一个神经元表示:

下图显示了2 × 2的卷积核,且卷积核移动了 4 次(即需要 4 个神经元):

  • 卷积核形状:当卷积核移动时(我们称之为滑动),它可能会覆盖相同的输入像素,也可能不会,这使得蓝色变得更深,我们想显示哪些像素被多次覆盖:

卷积核形状 = 2 × 2,它需要 4 次移动才能覆盖整个图像:

卷积核形状 = 1 × 1,它需要 9 次移动才能覆盖整个图像。

  • 步幅:这表示每次向右和向下移动多少像素:

这里,步幅 = 1,需要 4 步才能覆盖整个图像。注意,每次移动时,像素会有所重叠:

这里,步幅 = 2,需要 4 步才能覆盖整个图像。注意,每次移动时,滤波器覆盖的像素不会有任何重叠。

  • 填充:这表示输入图像周围有多少个白色像素:

以下图展示了零填充:

这里,填充 = 1,这允许边缘单元格被不同的神经元覆盖。

池化层

池化层的含义非常直白——它的作用是从输入中池化结果。想象一下,在卷积层之后,对于每种滤波器,都会有多个输出——例如四个。我们能否将这四个输出压缩为一个变量,而不是四个输出变量?池化可以起到压缩这些信息的作用。例如,可以取四个输出中的最大值(最大池化)或四个输出的平均值(平均池化)。从视觉角度来看,池化层的意义在于模糊图像或计算移动平均趋势。

ReLU 激活层

对于金融专业人士来说,整流线性单元ReLU)层就像一个看涨期权的支付结构——一旦超过某个阈值,输出值就会随着输入的增加线性变化。它的意义在于减少定价中的噪音,确保只考虑强烈的市场趋势。

Softmax

Softmax 是我们在本书早些章节中接触的逻辑回归模型的超级增强版,能够进行多个预测结果——例如,逻辑回归模型中的第一版二元结果。在我们的案例中,我们希望确定下一天的定价。

使用特雷诺-布莱克模型的投资组合构建

假设我们给定了 10 天的定价数据,技术分析的工作就是画出右侧的趋势线,以理解趋势并生成第 11 天的定价。很明显,这正是卷积神经网络可以处理的任务。

事实上,我们所看的时间单位可能是每 100 毫秒或每 10 毫秒,而不是 1 天,但原理是一样的:

继续以杜克能源为例。在这个假设的案例中,我们假设我们是杜克能源的财务主管,管理着一个资产总额为 150 亿美元的养老金计划,且该计划为固定缴款计划。假设我们知道我们的投资政策声明(IPS)是数字化格式:

  • 目标回报 = 实际回报的 5%(即扣除商品通货膨胀后的回报)

  • 风险 = 回报波动率为 10%

  • 约束条件:不包括电力公用事业公司,以避免投资其他同行/竞争者

请注意,这是一个假设性的示例。不会对实际公司做任何推断。

使用 IPS,我们将首先展示如何将资金分配到各个资产类别作为第一个示例。然后,在第二个示例中,我们将探讨趋势跟踪策略,以帮助投资经理跟随市场,鉴于当前被动投资的趋势。

解决方案

我们创建了两个独立的 Python 文件,因为资产参数应该独立于资产如何分配。这个过程有四个步骤,其中两个主要步骤(即文件)如下:

我们将下载并估计资产参数,并生成目标资产配置:

  1. 为了下载并估计资产参数,我们将导入库和关键变量值。然后,我们将定义函数以下载每个资产的数据、市场回报、无风险利率、资产回报以及其他参数。

  2. 为了生成目标资产配置,我们将导入库和关键变量值,找出证券在活跃投资组合中的权重,并找出活跃投资组合在总投资组合中的权重。

随着章节的推进,我们将通过这个示例尝试展示传统数据库的使用,而不是创建一个没有数据库存储的数据转储。这也符合我们之前提到的观点:结构化的数据库(SQL 数据库)非常适合证券定价数据,因为这些数据是结构化的。我们使用 SQLite,它是数据库的轻量版。它的目的是向金融专业人士展示数据库在我们应用场景中的作用。对于实际的 IT 实现,当然可以使用许多企业级的数据库,它们既安全又快速。

下载目标资产的价格数据

本示例中使用的单个资产和市场资产都是 ETF。数据通过 Quandl 下载,包含免费和付费订阅数据——包括由美国国债代表的无风险数据和由全球股票 ETF 代表的市场回报。下载的数据是每日结束数据,我们还需要定义我们所称的价格。在我们的示例中,我们取每日最高价和最低价之间的中间点作为当天的价格。

步骤如下:

sqlite3
6A_1_cal_assetpara.py
'''*************************************
#1\. Import libraries and key variable values
'''
import quandl
import pandas as pd
import numpy as np
from sklearn import linear_model
from sklearn.metrics import r2_score
import sqlite3
import math
import os
#not needed when using database
import pickle

#API Key

#dates variables for all the download

#db file
  1. 定义函数以下载每个资产的数据:
'''*************************************
#2\. Define function to download data for each of the asset
'''

如果没有 Python,你也可以通过工具直接评估文件,例如 Chrome 浏览器的插件、SQLite 查看器等。

SHARADAR

它的功能是下载数据并计算回报序列。

计算无风险回报率并定义市场

在我们的示例中,我们以美国 3 个月期国库券作为无风险回报率的代表。在投资世界中,美国被认为是无风险的,政府永远不会违约。任何我们获得的超出无风险回报率的收益,都是我们承担更多风险所得到的回报。

整体市场可以通过全球所有投资资产的回报来表示——理论上这很简单,但在现实中却很难定义。最具挑战性的部分是定期生成这个市场回报,以便在下一步中使用。我们将采取捷径,使用 ETF 来代表市场回报:

'''*************************************
#3\. Market Return
'''

给定一个代码作为市场代理,运行前面的函数:

'''*************************************
#4\. Risk Free Rate
'''
#day count

#risk free rate

# override return of market

无风险回报率相对复杂。根据行业惯例,通常使用 3 个月期国库券。为了获得整个期间的无风险回报率,我们需要使用约 10 年的数据来计算该期间的无风险回报率。

然而,我们还需要将利率年化。根据 3 个月期国库券的定义,计算的天数是 360 天。利率是指每天都被计算在内的。

计算每种资产类型的阿尔法、贝塔和误差方差

在了解了无风险回报率和市场回报率之后,我们的下一个任务是通过回归市场回报与资产回报,找出阿尔法(alpha)、贝塔(beta)和误差方差:

投资回报 = 无风险回报率 + 阿尔法 + 贝塔 * 市场回报 + 噪声(误差方差)

在执行此计算后,我们将把数据保存在 SQLite 数据库中,以便以后检索。

我相信,在初创企业的未来,我们的机器人顾问将专注于 ETF/智能贝塔——也就是将各个行业配置在一起,以便对抗市场生成回报。因此,在这个示例中,我选择了 ETF 代码。

我们将对行业 ETF 与市场基准进行线性回归。然而,ETF 和市场的价格报价日期可能不同;因此,我们只在行业 ETF 和市场 ETF 都有价格时才进行回归——在 SQL 中使用内连接命令。

内连接隐式要求行业 ETF 和市场基准的索引在连接之前必须相同。数据集的索引是指回报的日期:

'''*************************************
#5\. Asset Return and parameters
'''
#list of stocks for selection in the active portfolio

#connect to the databases and reset it everytime with drop indicator

#write out the risk free and market parameters

#loop through the tickers
for tkr in list_tkr:
 #calculate the CAPM:
 #download data for the ticker

#make sure the ticket we select has market data

 #linear regression

#obtain the result and write out the parameters

计算最优投资组合配置

我们已经进入第二个主要过程——即计算投资组合配置。首先,我们将计算主动投资组合的规模和不同资产在主动投资组合中的权重。步骤如下:

  1. 导入所有相关的库:
6A_2_treynor_black.py
'''*************************************
#1\. Import libraries and key variable values
'''
import sqlite3
import datetime

#create a table to store weight
  1. 计算主动投资组合的参数,并将其与市场表现进行比较,以找出我们应该从总投资组合中分配给主动投资组合的权重:
'''*************************************
#2\. Find out the weight of the securities in the active portfolio
'''
#total alpha/variance of the active securities

#insert into the table the weight of each active securities

主动投资组合的权重通过聚合属于该投资组合的证券(行业 ETF)的参数来求解。

  1. 然后,根据市场回报/风险与主动投资组合回报/风险的比率,主动投资组合表现越强,分配给该组合的总投资组合权重就越大:
'''*************************************
#3\. Find out the weight of the active portfolio in the total portfolio
'''
#calculate the parameters of the active portfolio

#read back the risk free and market para

#calculate the weight of active portfolio

#display the result

获得最优投资组合后,下一步是根据 IPS 的回报和风险要求将其分配给

以下两个约束条件需要满足:

  • % 最优投资组合 x 最优投资组合的回报 + (1-%最优投资组合) x 无风险资产的回报 >= IPS 要求的回报

  • % 最优投资组合 x 最优投资组合的风险 <= IPS 要求的风险

恭喜!你已经学会了如何将资本分配到不同的投资资产上,从而获得最佳的回报和风险水平。在接下来的章节中,我们将通过一个示例来讲解如何预测证券的趋势,这将帮助投资者做出明智的投资决策。

预测证券的趋势

在前面的示例中,我们扮演了一个跟随财务主管设定的投资组合分配的交易员角色。假设我们的工作是跟随财务主管要求的证券,我们作为交易员的盈亏关键在于如何通过低买高卖获利。我们使用证券的日常定价历史数据来建立模型。在接下来的部分中,我们将展示如何在做出买入决策之前预测资产的趋势。

解决方案

有两个主要过程——一个是模型开发,另一个是模型回测。两个过程总共包括八个步骤,用于实时部署,这里我们不再包含。然而,它与模型回测非常相似。以下图示展示了该过程的流程:

加载、转换并存储数据

在这一步中,我们将加载数据,将数据转换为图像数组,然后将其存储为 HDF5 数据文件格式。首先,我们将从 Quandl 加载数据作为数据框架,然后将数据转换为数组——这将像之前展示的那样绘制数据。在我们的示例中,我们通过仅绘制一天的日终数据点来简化问题。我们只取当天的最高点和最低点的中间值,而不考虑其交易量。

当我们要在一个固定尺寸的数组上绘制价格时,在 y 轴——即价格——我们将开发一个函数,通过缩放数据点,将最大值和最小值固定到固定尺寸内。这称为 归一化。在 x 轴上,每一天由 x 轴上的一个点表示,最左边是给定窗口大小的最早日期,最右边是最新日期。在某一点上,价格点的颜色是相同的,颜色 = 255 用于显示图片,或者为 1 用于神经网络输入。

对目标变量也进行相同的处理——它仅是使用相同尺度的 y 轴表示的第二天图表。如果第二天的价格实际上高于最大值或低于最小值,我们可以强制它取当前的最大值和最小值。

在准备好数组后,我们将按指定的持续时间堆叠数组——每一天由一个图表表示,展示过去的 X 天,其中 X 是窗口大小。堆叠完成后,我们将整个数组放入 HDF5 文件中——这是一种分布式文件格式,允许文件存储在多个物理位置。

定义库和变量。我们已经定义了一个股票代码列表用于下载步骤:

6B_1_trendFollowing.py
'''*************************************
#1\. Import libraries and key variable values

'''
import quandl
import plotly
import plotly.graph_objs as go
import numpy as np

from datetime import datetime
try:
    import Image
except ImportError:
    from PIL import Image
import os
import h5py

#dates parameters
...
#quandl setting
...
#parameters for the image generation
...
#create path for the output dataset
...
#ticker lists
...
#generate png file for each of the input or now
...
#generate interactive plot to the ticket stock price or not
...

定义函数将股票价格的变量范围转化为固定高度和宽度的固定尺寸图像。它将返回一个已经按比例缩放的数值列,并附带缩放因子:

  • 像素值 = (价格值 - 列的最小值) x 每个值的像素数

  • 像素数 = (列的最大值 - 列的最小值) / 总像素数

代码如下:

'''*************************************
#2\. Define the function to rescale the stock price according to the min and max values

'''
#input_X is a series of price
#output_X is a series of price expressed in pixel
def rescale(input_X, pixel, min_x,max_x):
...

逐个股票代码,我们将下载并转换数据,作为机器学习的输入图像和目标结果。代码中最具技术性的部分与 HDF5 文件保存有关。在文件内部,它进一步划分为数据集,在数据集内我们可以存储文件。数据集的一个特性是,它的大小在创建时一旦定义就固定。此外,它不应当动态更新——尽管从技术上讲,这是可能的。

彩色图像存储在三个通道中——红色、绿色和蓝色——每个通道都是一个矩阵,其中每个像素的值在 0 到 255 之间。然而,在我们的示例中,我们将只使用一个通道来处理黑白图像。在将图像存储到 HDF5 之前,所有数字会被除以 255,这样输入变量就会被归一化到 0 和 1 之间,方便后续神经网络训练。

ploty

请参考图像处理相关书籍进行深入讨论——我最喜欢的是 Nixon M.S. 和 Aguado, A.S. 的*《计算机视觉中的特征提取与图像处理》*,因为它更侧重于提取我们需要的特征,而不是仅仅阐述理论背景。

然而,缺点是本书中的代码不是用 Python 编写的——考虑到学习原理比演化中的代码更为重要,这是一个可以接受的挑战:

'''*************************************
#3\. Go through the tickers
'''
for tkr in tkr_list:
    ...
    #if the ticker has been downloaded, skip the ticket and go for the next 
     one
    ...
    #download and create dataset
    ...
    #sort the date from ascending to descending...
    ...    
    #charting interactive chart for viewing the data
    ...
    #calculate mid price of the day
    ...    
    #remove the file if there is one
    ...
    #remove the file if there is one
    ...
    #create dataset within the HDF5 file
    #now we create the dataset with a fixed size to fit all the data, it 
     could also be create to fit fixed batches    
    ...

    #loop through the dates
    for i in range(num_img):
        ...
        #create min and max values for the mid price plot within a given 
         timeframe
        ...
        #in case of low liquidity ETF which has the same price, no graph be 
         drawn
        ...
        #draw the dot on the x, y axis of the input image array
        ...
        #output the image for visualization
        ...        
        #draw the dot on the target image for training
        ...        
        #stack up for a numpy for Image Recognition
        ...

设置神经网络

根据 Keras 示例中的 ResNet 代码,我们不会对网络设计做任何修改。我们同时使用版本 1 和版本 2,并禁用批量归一化,因为数据点的颜色相同,并且y轴已针对给定的窗口大小进行归一化,因此进一步归一化没有太大意义。

批量归一化与在当前批次记录中协调网络中看到的值有关——如果我们绘制的图像中包含不同颜色,它的效果会很好。然而,由于我们已经在每个数据点的y轴上对定价进行了归一化,因此目前代码保持不变,因为我们需要这种处理,当输入具有不同规模和分布的数据时。

将数据加载到神经网络进行训练

我们之前从 HDF5 文件中获取了数据,并将其放入在前一步中刚设置好的网络中。数据会被分成训练集、测试集和验证集。然而,在我们的案例中,我们将所有数据同时作为训练集和测试集。验证集可以是另一只股票——因为我们仅在训练一般智能来观察股票的技术走势。

我们将批量归一化和一定的训练周期数一起输入到网络中。这一步需要耗费最多的时间。

在训练过程中,我们保持一个性能日志,以便后续可视化:

6B_2_TrainCNN.py
'''*************************************
#1\. Import libraries and key variable values
'''
'''*************************************
#2\. Define functions
'''
def lr_schedule(epoch):
def resnet_layer(inputs,
                 num_filters=16,
                 kernel_size=3,
                 strides=1,
                 activation='relu',
                 batch_normalization=True,
                 conv_first=True):
def resnet_v1(input_shape, depth, num_classes=10):
def resnet_v2(input_shape, depth, num_classes=10):

arxiv.org/abs/1512.03385keras.io/applications/#resnet50

代码本质上是创建两个不同结构的神经网络设计——鉴于我们有一个相当大的数据输入,且数据源可用,读者只要数据量足够,便会在版本 2 中体验到更好的性能:

#3\. Execute the model training
'''
# Computed depth from supplied model parameter n

# Model name, depth and version

# create list of batches to shuffle the data

#check if the prev step is completed before starting

#decide if we should load a model or not

#loop through the tickers

#load dataset saved in the previous preparation step

#start if both file exists:

#calculate number of batches
 #do it at the first one

# Input image dimensions.
        # Prepare model model saving directory.

        # Prepare callbacks for model saving and for learning rate 
          adjustment

        # loop over batches

            # Run training, without data augmentation.

        #when model training finished for the ticket, create a file to 
         indicate its completion

# Score trained model.

保存并微调神经网络

www.deeplearning.ai/machine-learning-yearning/

加载运行时数据并通过神经网络进行处理

网络可以重新加载并在新数据集上运行作为验证集。然而,在我们的示例中,我们使用另一只股票来测试这个通用的技术分析机器是否有效。网络的输出是对第二天价格的预测。

在这个程序中,最特别的数据将是策略参数。一切从一个货币值开始。我们正在测试三种策略——一种买入并持有,作为基准,另外两种根据不同的价格输出进行交易。

相关步骤如下:

  1. 导入所有必要的库和变量:
6B_3_RunCNN.py
'''*************************************
#1\. Import libraries and key variable values
'''
#folder path

#date range for full dataset

#Create list of dates

#API key for quandl

#Parameters for the image generation

#model path

#number of channel for the image

#strategies parameter

使用 ResNet v2,我们有接近 100 万个参数,而我们正在输入大约 300 万条记录 ~14.5 年 x 200 个交易日 x 125 个股票代码(但某些股票代码不具备流动性进行交易)。

  1. 然后,定义将价格点适配到具有固定高度的图像的函数:
'''*************************************
#2\. Define functions
'''
  1. 获取新数据并运行预测价格的函数。从票据中加载数据并准备数据;然后运行从训练过程中构建的模型:
'''*************************************
#3\. Running the test
'''
#Get the data

#write header for the log of the strategy back-testing

#loop through the dates
 #make sure both start and end dates are valid

#prepare the input data

#if no trend, then drop this data point

#stack up for a numpy for Image Recognition
 #print the historical data

#make prediction
#Obtain predicted price

从结果中生成交易策略并进行绩效分析

对于给定的价格预测,我们可以设计出不同的操作方式来利用这个价格预测。

该循环的目标是通过依赖前一部分模型的预测来衡量交易策略的盈亏。

在任何给定的日期,只有一个价格预测,其形式为一个 1D 数组,表示在给定比例下每个价格点的概率。各种策略(1 和 2)处理如何使用该预测:

#calculate expected values

#Strategy Back-Testing
 #Benchmark - Strategy 0 - buy and hold

#Testing of strategy1

#Testing of strategy2

#print the final result of the strategies

恭喜!你已经完成了使用计算机视觉模型进行价格预测的过程。

在现实世界中,可能会有更多由不同模型做出的预测,这将增加测试的策略复杂度。我们需要一个基准来判断这些策略是否优于正常的市场情况,也就是买入并持有策略。如果我们的策略成功,它们应该能够通过显示更高的盈亏数字来超越市场。

银行业的人工智能实用指南(二)在策略回测中,我们通常将其部署到一个未见过的、未来的数据样本中。

概述

在本章中,我们学习了多种投资组合管理技巧。我们将它们与人工智能结合,以实现自动化决策过程,特别是在购买资产时。我们了解了用于投资组合构建的 Markowitz 均值方差模型和 Treynor-Black 模型。我们还看了一个使用 Treynor-Black 模型进行投资组合构建的实例。我们还学习了如何预测证券交易的趋势。

在下一章,我们将探讨资产管理中的卖方部分。我们将了解情绪分析、投资产品的算法营销、网络分析,以及如何提取网络关系。我们还将探索如 Network X 等技术和 Neo4j、PDF Miner 等工具。

第七章:在卖方感知市场情感的算法营销

在上一章中,我们了解了投资组合管理。我们还学习了一些投资组合管理技术,例如马克维茨均值-方差模型和特雷诺–布莱克模型,用于投资组合构建。我们还了解了如何预测证券的趋势。因此,上一章是基于市场的买方部分,描述了投资组合经理或资产管理人的行为。

在本章中,我们将探讨市场的卖方部分。我们将了解投资组合经理对手的行为。卖方指的是证券公司/投资银行及其主要服务,包括销售、交易和研究。销售指的是向投资者营销证券,告知他们可以出售的证券。交易指的是投资者用来买卖证券的服务,以及为了帮助投资者评估证券而进行的研究。银行的一个关键职能是以客户为中心,感知终端投资者的需求和情感,进而推动资产管理人从银行购买产品。我们将通过几个概念和技术来开始本章的讨论。我们将通过一个例子来说明如何感知投资者的需求。我们还将通过另一个例子分析年报并从中提取信息。

本章将涵盖以下主题:

  • 了解情感分析

  • 使用情感分析感知市场需求

  • 使用 Neo4j 进行网络构建与分析

了解情感分析

情感分析是一种文本挖掘技术,用于提取上下文信息。上下文信息从源材料中识别并提取出来。它帮助企业理解其产品、证券或资产的情感。利用人工智能的先进技术进行深入研究,在文本分析领域非常有效。对交易进行分类时,重要的是围绕以下概念进行分类:

  • 买卖双方关心的证券方面

  • 客户对证券的意图和反应

情感分析被认为是最常见的文本分析和分类工具。它接收一条传入的消息或交易,并根据该交易所涉及的情感是积极、消极还是中性进行分类。通过使用情感分析技术,可以输入一句话并理解该句背后的情感。

既然我们已经理解了什么是情感分析,接下来我们来看看如何在以下章节中感知市场需求。

使用情感分析感知市场需求

一家证券公司/投资银行在卖方的一个关键要求是为市场制造相关的证券。我们在第四章《机械化资本市场决策》和第五章《预测投资银行家未来》中探讨了公司在这方面的基本行为和责任。我们在第六章《使用 Treynor-Black 模型和 ResNet 的自动化投资组合管理》中了解了动量方法。尽管市场并不总是理性运作,但听听市场的情绪可能会很有趣。这也是我们在本章中要做的。

在这个例子中,我们将扮演投资银行交易大厅的销售员角色,进行股票交易。我们想要了解的是市场对证券的喜好和厌恶,以便能够营销相关证券,包括衍生品。我们的见解来自 Twitter Search,股价数据来自 Quandl。所有这些数据都需要付费许可。

解决方案与步骤

使用编码实现获取市场情绪的过程总共有三个主要步骤。数据如下面的图所示:

步骤如下:

  1. 数据将从 Twitter 获取并以 JSON 文件格式保存在本地。

  2. JSON 文件将被读取,进一步处理,通过计算正面和负面词汇的数量,并作为记录输入到 SQL Lite 数据库中。

  3. 最后,情感将从数据库中读取,并与从 Quandl 获取的股票价格进行比较。

我们将在接下来的部分中更详细地阐述这些步骤。

从 Twitter 下载数据

通过使用 Twitter Search 商业许可,我们下载与 Shalender(Quandl)行业分类定义的相同行业的数据。我们将使用 API 密钥逐一搜索并下载包含公司名称或标记为公司名称的最新 500 条推文。所有推文都以 JSON 格式接收,看起来像一个 Python 字典。然后,JSON 文件将保存在计算机中,供进一步处理。

github.com/twitterdev/search-tweets-python
'''*************************************
#1\. Import libraries and key variable values

'''
from searchtweets import ResultStream, gen_rule_payload, load_credentials
from searchtweets import collect_results
import json
import os

script_dir = os.path.dirname(__file__)
#Twitter search commerical accounts credential
premium_search_args = load_credentials("~/.twitter_keys.yaml",
                                      env_overwrite=False)
MAX_RESULTS=500 #maximum at 500

#list of companies in the same industry
...

'''*************************************
#2\. download tweets of each company

'''
for comp in comp_list:
   ...

将下载的推文转换为记录

推文的消息及任何链接的页面将被一个简单的语言处理程序加载并读取,该程序将计算消息和链接页面正文中正面和负面词汇的数量。解析后的推文将被转换为结构化的 SQL 数据库格式并存储在 SQL Lite 数据库中。

以下是将推文转换为记录的代码片段:

'''*************************************
#1\. Import libraries and key variable values

'''
import json
import os
import re
import sqlite3
import 7A_lib_cnt_sentiment as sentiment

#db file
db_path = 'parsed_tweets.db'
db_name = 'tweet_db'

#sql db
...
#load tweet json
...
#loop through the tweets
    ...
    for tweet in data:
        ...
        tweet_txt_pos,tweet_txt_neg = sentiment.cnt_sentiment(tweet_txt)
        keywords,sentences_list,words_list = \
                                           sentiment.NER_topics(tweet_txt)
        ...
        if len(url_link)>0:
            ...
            url_txt = sentiment.url_to_string(url)
            temp_tweet_link_txt_pos, temp_tweet_link_txt_neg = \
                                           sentiment.cnt_sentiment(url_txt)
            link_keywords,link_sentences_list,link_words_list = \
                                           sentiment.NER_topics(tweet_txt)
            ...

前面的程序调用了三个函数。一个是用于计算正面和负面词汇,另一个是分析关注的主题,最后一个是从推文中给定的 URL 中提取文本。

以下代码片段定义了程序中使用的函数:

import os
import requests
from bs4 import BeautifulSoup
import re
import spacy
import en_core_web_sm
nlp = en_core_web_sm.load()

...
#cal the positive and negative sentiment words given the text
def cnt_sentiment(text_to_be_parsed):
    ...

def noun_phrase(sentence,item_list,lower):
   ...

#NER
import spacy
from spacy import displacy
from collections import Counter
import math

#text has to be less than 1000000
def NER_topics(text_to_be_parsed):
    ...
    MAX_SIZE =100000
    ...
    for nlp_cnt in range(number_nlp):
        start_pos = nlp_cnt*MAX_SIZE
        end_pos = min(MAX_SIZE,txt_len-start_pos)+start_pos-1
        txt_selected = text_to_be_parsed[start_pos:end_pos]
        ...
        sentences_list = [x for x in article.sents]
        full_sentences_list+=sentences_list
        for sent in sentences_list:
            phrases_list =[]
            phases_list,items_list = noun_phrase(sent, items_list, \
                                                 lower=True)
     ...

#convert the URL's content into string
def url_to_string(url):
    ...

执行情感分析

存储解析过的推文的数据库将被另一个程序读取。对于每一条记录,情感将以每日汇总情感的形式表示。每条推文的情感得分是通过将负面情感的总数从正面情感的总数中减去来计算的。这个情感得分的范围应该在-1 到+1 之间,-1 代表完全负面,+1 代表完全正面。每一天的情感得分是所有推文的情感得分的平均值。相同领域中所有证券的情感得分将绘制在图表上,类似于以下内容:

例如,在我们覆盖的短时间段内,Dominion Energy(道明能源)有着最有利的情感评分(在 10 月 29 日至 10 月 30 日之间)。

Dominion Energy(道明能源)的示例输出如下图所示:

情感是橙色线,股价是蓝色线(请参阅本书提供的彩色图表)。

以下是情感分析的代码片段:

'''*************************************
#1\. Import libraries and key variable values

'''
import sqlite3
import pandas as pd
import plotly
import plotly.graph_objs as go
import quandl
import json

# Create your connection.
db_path = 'parsed_tweets.db'
cnx = sqlite3.connect(db_path)
db_name = 'tweet_db'

'''*************************************
#2\. Gauge the sentiment of each security

'''
...
sql_str = ...
...
print('Sentiment across securities')
field_list = ['positive','negative']
for sec in sec_list:
    ...

比较每日情感与每日价格

在我们获得每只股票的情感得分后,我们还想了解情感对股价的预测能力或影响。当天的股价是通过中午时分的最高价和最低价来计算的。对于每只股票,我们绘制并比较情感和股价在一段时间内的变化。以下截图展示了 PG&E 公司情感与股价的对比:

以下是针对每日价格的情感分析数据的代码片段:

#run it on different companies
print('Retrieve data')
df_comp = pd.read_csv('ticker_companyname.csv')
corr_results={}

for index, row in df_comp.iterrows():
    tkr = row['ticker']
    name = row['name']

    target_sec = '"'+name +'"data.json'

    corr_result = price_sentiment(tkr,target_sec,date_range)
    try:
        corr_results[name]=corr_result['close'][0]
    except Exception:
        continue

f_corr = open('corr_results.json','w')
json.dump(corr_results,f_corr)
f_corr.close()

恭喜!你已经开发了一个程序,帮助销售人员找到热门证券以开发产品。

从我们看到的情况来看,比较这个例子与技术分析例子,我们可以发现情感数据所提供的信息远高于技术趋势。到目前为止,我们只看到了趋势、基本面和情感的初步影响;然而,企业在我们的社会中是相互关联的。那么,我们如何才能建模公司和个人之间的关联呢?这将引出下一个话题——网络分析。

使用 Neo4j 构建和分析网络

作为卖方分析师,除了找出新闻对公司产生的主要影响外,我们还应该找出任何新闻的次级影响。在我们的例子中,我们将找出新闻对股票的供应商、客户和竞争对手的影响。

我们可以通过以下三种方法来实现:

  • 通过直接披露,例如年度报告

  • 通过次级来源(媒体报道)

  • 通过行业推断(例如,原材料行业,如石油行业,为交通行业提供输出)

在本书中,我们使用公司直接披露的信息来说明这一点。

我们扮演的是公司股票的股权研究员,其中一个关键角色是理解相关方与公司之间的联系。我们通过阅读公司年报,寻找公司——杜克能源的相关方。

解决方案

总共有四个步骤。下图展示了数据流:

接下来,我们将更详细地介绍以下各个步骤。

使用 PDFMiner 从 PDF 中提取文本

除了存储外,我们还需要从文本文档中提取关系。在开始处理文本之前,我们需要将 PDF 数据转换为文本。为此,我们使用一个叫做PDFMiner的库(具体来说,该模块叫做pdfminer.six,适用于 Python 3+)进行转换。PDF 是一种开放标准,用于描述文档。它存储了文档中的行、文本、图片以及它们在文档中的精确位置。我们仅使用 PDFMiner 中的一个基础函数来提取其中的文本。尽管我们也可以提取坐标,但为了简化工作,我们将跳过这一部分。在提取文本后,我们将所有行拼接成一行超长文本。

以下代码片段导入了必要的库,并初始化了一个待处理的 PDF 文件:

'''*************************************
#1\. Import relevant libraries and variables

'''
#custom made function
import 7B_lib_entitiesExtraction as entitiesExtraction
import 7B_lib_parser_pdf as pdf_parser
import json
import sqlite3

pdf_path = 'annualrpt/NYSE_DUK_2017.pdf'
...

实体提取

我们采用了一种叫做词性POS)标注的语言分析方法来决定词汇 X 和 Z 是公司还是个人,以及 Y 是产品还是服务。由于句子的结构,我们知道这些是名词,而不是因为我们知道 X、Y 和 Z 是什么。

然而,仅仅标注实体仍然不够。一个实体是一个独立的主语或宾语。由于实体种类繁多,我们应当仅仅标注首字母大写的实体,作为那些对我们的工作相关的独特组织或资产。

ORGPERSONFACNORPGPELOCPRODUCT

在从步骤 1 的 PDF 中获取文本片段后,我们运行 SpaCy 提取每个句子中的实体。对于每个句子,我们将实体类型和实体存储在数据库记录中。SpaCy 在分析文档时有技术限制,因此我们将非常长的文本片段切割成不同的块,以遵守技术限制。然而,这样做的代价是会在文本片段的切割点拆分句子。考虑到我们正在处理数百页的内容,我们将采取这个快捷方式。当然,最好的切割方法是大致围绕文本块切割,同时遵守标点符号,以保持完整的句子。

以下代码片段演示了如何提取各种实体:

'''*************************************
#2\. NLP

'''
#Named Entity Extraction
print('ner')
#see if we need to convert everything to lower case words - we keep the original format for this case
lower=False
common_words, sentences, words_list,verbs_list = entitiesExtraction.NER_topics(text,lower)
entities_in_sentences = entitiesExtraction.org_extraction(text)
...
#create this list to export the list of ent and cleanse them
...
print('looping sentences')
for sentence in entities_in_sentences:
    ents_dict[sentence_cnt] = {}
    for entity in sentence:
        ...
        if ent_type in( 'ORG','PERSON','FAC','NORP','GPE','LOC','PRODUCT'):
        ...
    #handle other type
    ...

通过词汇表进行实体分类: 在我们的用例中,我们需要进一步将组织分类为供应商、客户、竞争者、投资者、政府或姊妹公司/资产——例如,作为公司信用投资者的银行,首先会被分类为银行,然后在其年度报告中被推断为公司的信用投资者/银行家。因此,一些关系需要我们与组织数据库核对,以进一步分类它们。获取此类知识需要我们下载相关数据库——在我们的案例中,我们使用 Wikipedia 下载银行列表。只有在与银行名称列表核对后,我们才能将组织分类为银行与否。在我们的示例中,我们没有执行此步骤,因为我们没有通常可供银行使用的词汇集。

使用 NetworkX 存储网络结构

处理完数据后,实体将被存储在 SQL 数据库中,并通过 NetworkX 进一步分析——这是一个处理网络数据的 Python 包。边和节点是任何图的构建块;然而,还有许多其他指标可以用来衡量和描述图,以及节点和边在图中的位置。现在对我们工作来说,重要的是看看节点是否与我们关注的公司相连接,以及它们之间的连接类型。

在 NetworkX 的最终图中,数据仍然非常抽象。我们需要更好的交互式软件来查询和处理这些数据。因此,我们将把数据输出为 CSV 格式,供 Neo4j 进一步处理,因为它提供了与数据交互的用户界面。

然而,距离实际使用仍然很远——需要大量时间来清理数据集并定义所涉及的关系类型。Neo4j 是一个完整的图形数据库,能够满足复杂的关系结构。

必须在公司年报中提到的实体与数据库中存储的实体之间建立关系。在我们的示例中,我们没有对实体进行任何过滤,因为前一步的 NLP 模型具有 85% 的提升率,因此它在识别实体时并不完美。我们仅提取人物和组织作为实体。对于关系类型(边),我们不区分不同的边类型。

matplotlib

以下是生成实体网络的代码片段:

'''*************************************
#1\. Import relevant libraries and variables

'''
#generate network
import sqlite3
import pandas as pd
import networkx as nx
import matplotlib.pyplot as plt

#db file
db_path = 'parsed_network.db'
db_name = 'network_db'

#sql db
conn = sqlite3.connect(db_path)
c = conn.cursor()

...

network_dict={}
edge_list=[]
curr_source =''
curr_entity = ''
org_list = []
person_list = []

'''*************************************
#2\. generate the network with all entities connected to Duke Energy - whose annual report is parsed

'''
target_name = 'Duke Energy'
#loop through the database to generate the network format data
for index, row in df_org.iterrows():
    ...

#Generate the output in networkX
print('networkx')

#output the network
G = nx.from_edgelist(edge_list)
pos = nx.spring_layout(G)
nx.draw(G, with_labels=False, nodecolor='r',pos=pos, edge_color='b')
plt.savefig('network.png')

使用 Neo4j 进行图形可视化和查询

我们将安装 Neo4j 并导入 CSV 文件,以在 Neo4j——这一行业级图形数据库中构建数据网络。不幸的是,Neo4j 本身需要另一套编程语言来操作其数据,称为Cypher。这使我们能够提取和搜索我们需要的数据。

我们生成 Neo4j 所需的文件。以下代码片段初始化 Neo4j:

#Generate output for Neo4j
print('prep data for Neo4j')
f_org_node=open('node.csv','w+')
f_org_node.write('nodename\n')

f_person_node=open('node_person.csv','w+')
f_person_node.write('nodename\n')

f_vertex=open('edge.csv','w+')
f_vertex.write('nodename1,nodename2,weight\n')
...

在终端中,我们将输出文件复制到 Neo4j 的主目录。以下是从终端执行的命令:

sudo cp '[path]/edge.csv' /var/lib/Neo4j/import/edge.csv
sudo cp '[path]/node.csv' /var/lib/Neo4j/import/node.csv

sudo service Neo4j restart

在 Neo4j 中,我们通过浏览器登录。以下是输入到浏览器中的 URL:

http://localhost:7474/browser/

以下是 Neo4j Cypher 的示例代码片段:

MATCH (n) DETACH DELETE n;

USING PERIODIC COMMIT
LOAD CSV WITH HEADERS FROM "file:///node.csv" AS row
CREATE (:ENTITY {node: row.nodename});

CREATE INDEX ON :ENTITY(node);

USING PERIODIC COMMIT
LOAD CSV WITH HEADERS FROM "file:///edge.csv" AS row
MATCH (vertex1:ENTITY {node: row.nodename1})
MATCH (vertex2:ENTITY {node: row.nodename2})
MERGE (vertex1)-[:LINK]->(vertex2);

MATCH (n:ENTITY)-[:LINK]->(ENTITY) RETURN n;

以下是结果输出的截图:

恭喜!你已经成功提取了年报中大量需要聚焦进一步分析的重要名称/主体。

总结

在本章中,我们学习了市场卖方的行为。我们了解了什么是情感分析,以及如何使用它。我们还看了一个例子,使用情感分析来感知市场需求。我们学习了使用 Neo4j 进行网络分析,Neo4j 是一种 NoSQL 数据库技术。我们学习了使用 PDF miner 工具进行文本挖掘。

在下一章,我们将学习如何使用银行 API 来构建个人财富顾问。本章将重点关注消费者银行业务。我们将学习如何访问开放银行项目(Open Bank Project)以获取财务健康数据。我们还将学习文档布局分析。让我们不再拖延,直接开始吧。

第八章:使用银行 API 构建个人财富顾问

在上一章中,我们分析了交易所卖方的行为。我们还学习了情绪分析,并通过学习如何使用情绪分析来分析市场需求,深入了解了这一主题。接着,我们学习了 Neo4j,这是一个 NoSQL 数据库技术。然后,我们使用 Neo4j 构建并存储了一个涉及证券交易的实体网络。

在本章中,我们将重点关注消费者银行业务,理解如何管理客户的数字数据需求。接着,我们将学习如何访问开放银行项目,这是一个开源平台,旨在促进开放银行业务。之后,我们将查看如何将人工智能模型与银行 API 结合使用的示例。最后,我们将学习文档布局分析。

本章将涵盖以下主题:

  • 管理客户的数字数据

  • 开放银行项目

  • 执行文档布局分析

  • 使用开放银行 API 进行现金流预测

  • 使用发票实体识别追踪日常开支

让我们开始吧!

管理客户的数字数据

在这个数字化时代,没理由认为资金不能做到 100%透明,也没有理由认为资金转账不能在实时、全天候(24/7)进行。消费者有权拥有自己的数据,因为数据代表了他们的身份。无论是否可能,我们都应该开始整合自己的数据——实际上,这应该在今天以及未来几年内实现。最好将我们的银行数据整合到一个地方;例如,我们的常客飞行里程。关键是要有两层数据架构——一层用于数据整合(包括存储),另一层用于运行将通过智能设备进行数据分析的人工智能服务,也就是所谓的移动应用程序。如果不了解数据整合层的运作,设计一个 AI 算法是很痛苦的。

在这里,我们的数据来源可以是身份数据、生物/心理数据、财务数据、可能影响这些静态数据的事件以及社交数据,后者代表我们与他人的关系(包括人类、物体、生命体等)。事实上,这与企业对企业B2B)环境非常相似,其中任何公司都可以通过其法律身份、股东/所有权结构、财务状况、事件以及商业关系来表示,正如在第七章《在卖方市场中感知市场情绪进行算法营销》中所概述的那样,利用情绪分析来理解市场需求。这也意味着我们在本章学到的内容可以帮助你更好地理解本书前几章的内容。

然而,对于所有个人,包括你和我们,我们的财务需求是相当基础的——它们包括支付、信用和财富。这些勾画了金融服务的核心活动。保险作为财富的一部分被纳入其中,因为它旨在保护我们的财富免受不良事件和风险的影响——这就像是第二章中关于采购成本风险对冲的衍生品,时间序列分析

然而,我也认为从消费者那里得出的数据同样属于处理交易的银行。这就像父母身份——所有关于数据(父母的孩子)的决策都是由数据所有者(消费者)和数据生产者(银行)之间达成的协议。目前缺乏的是能够迅速将这些数据以及其使用所带来的经济利益归属到某些经济活动(例如市场营销)中的技术。如果某个组织(例如超市)为消费者数据付费给社交媒体(例如谷歌、Facebook 和 Twitter)用于市场营销目的,那么数据所有者应当获得一定比例的经济利益。没有数据技术的进步,单纯的法律法规将不具备实际可操作性。

开放银行项目

www.ecb.europa.eu/paym/intro/mip-online/2018/html/1803_revisedpsd.en.html

这个项目面临的挑战是,现有的主导性银行几乎没有动力开放它们的数据。在消费者方面,数据整合的缓慢影响了银行服务中这种互联网络的经济价值。这遵循了梅特卡夫定律,即一个网络的价值等同于连接用户数量的平方(在我们的案例中是银行)。下表使用博弈论分析了这种情况,预期了银行和消费者的结果——假设消费者市场中只有两家银行,有四种可能的结果:

单元格值 = 银行 A/银行 B/消费者的收益银行 B:开放银行 API银行 B:未开放银行 API
银行 A:开放银行 API0.5\0.5\20.5\1\1
银行 A:未开放银行 API1\0.5\11\1\1

对于现状(即没有开放银行 API 的情况下),假设银行 A 和银行 B 将各自享有 1 个单位的收益,而消费者也将拥有 1 个单位的收益。

任何银行要开发开放银行 API,都需要消耗其 0.5 的资源。因此,我们将展示两种情况:银行 A 或 B 开发开放银行 API,而另一家则没有。开发开放银行 API 的银行将获得较少的收益,因为原本 1 个单位的 0.5 将需要用作维持 API 的资源。在这两种情况下,由于数据没有整合,消费者无法享受任何额外的收益。

只有在所有银行都采用开放银行 API 的情况下,消费者才能看到逐步增加的收益(假设再增加一个单位,使总数变为两个,仅为任意假设),而两家银行的收益却减少。当然,这种情况可能是错误的,因为整体市场会变得更加竞争激烈,这也是英国虚拟银行所发生的情况——由于这一举措,已经创造了一个新的子领域!所以,归根结底,所有银行的收益可能都会得到改善。

话虽如此,大多数现有银行的现实情况是,它们必须维持两套银行服务——一套完全虚拟,而另一套银行渠道仍然是传统的实体存在,且不可扩展。或许前进的道路是,在现有银行渠道之外再建立一个新的银行渠道,并将客户转移到那里。

uk.openbankproject.com/www.digidentity.eu/en/home/www.ihis.com.sg/

智能设备——使用 Flask 和 MongoDB 作为存储的 API

你的智能设备就是一位个性化的私人银行家:软件将与市场和你自己互动。在智能设备中,核心模块是持有模块和用户互动模块。持有模块将保障用户/客户的投资,而用户的互动和用户本身则由用户互动模块迎接并连接。

持有模块处理投资的定量方面——这正是我们在前两章中讨论的内容,但是在个人层面——通过管理投资组合并捕获各种市场数据。然而,区别在于,我们需要通过在用户互动模块中捕获的行为数据,更好地理解用户/客户。持有模块是智能设备的认知大脑。

用户互动模块提供了智能设备的互动方面——它理解用户在投资和互动中的偏好。这些投资偏好记录在投资政策声明(IPS)中。然后,这些互动通过行为分析器处理,分析用户偏好的时间、渠道和沟通方式,以及关于用户个性和风险偏好的财务行为,这些信息都来自于通过设备使用获得的外部数据源或用户生成的数据。最后但同样重要的是,沟通渠道Comm Channels)通过语音、文字或通过物理机器人与用户互动。

这很好地总结了我们在第一章《人工智能在银行业中的重要性》中提到的内容,作为人工智能的定义——一种能够像人类一样进行理性或感性(或两者兼具)思考和行动的机器。持有模块是人类的理性大脑,在市场中根据此理性行动,而情感则由用户互动模块处理——通过行为分析器同情并根据沟通渠道与用户互动。下图展示了通过银行功能实现的市场与用户互动:

由于我们在前两章中已经讨论过持有模块,主要聚焦于投资过程,因此在这里,我们将更多地关注用户互动模块。具体来说,我们将深入探讨投资政策声明(IPS),它记录了用户的投资需求。

理解 IPS

正如我们在第六章《使用 Treynor-Black 模型和 ResNet 的自动化投资组合管理》中提到的,我们将在这里开始研究个人的投资政策声明。为此,我们需要收集数据,以便为个别客户构建 IPS。

这是为一个家庭构建 IPS 所需的内容:

  • 回报和风险目标
目标注释
投资回报目标由投资者输入,并通过行为分析器——个性化分析
承担风险的能力由投资者输入,并通过行为分析器——个性化分析
承担风险的意愿由投资者输入,并通过行为分析器——个性化分析
  • 约束条件
约束条件注释
流动性资产的流动性可以通过智能设备中的价格来确定。
时间范围规划你孩子的未来——他们的学业(在哪里、上什么学校、学费等)、住房计划、工作、退休等。
税收(美国公民)通过 Digidentity 验证公民身份。
法律和监管环境这可能涉及商业交易、公民身份、就业和居住限制。你也可能需要考虑管理你财富的法律实体,如家庭信托。
独特情况兴趣和特殊情况没有被公开,包括社交媒体或与标准用户不同的医疗档案——这需要在用户之间匿名对比,提供真实的、独特的情况。

行为分析器 – 支出分析器

类似于第二章,时间序列分析,我们将预测市场中的日常现金流。由于大多数情况下的收入(甚至是大多数按月领薪的工作人群)是固定的,唯一变动的部分是支出。在这些支出中,可能有一些定期支出,如购买日常杂货,和一些不定期支出,如购买家电甚至是汽车。为了让机器追踪并预测定期支出习惯以及不常见的支出,实际的方法是当这些支出发生时,能够高效地记录这些习惯。

将 AI 服务暴露为 API

虽然我们在第六章,使用 Treynor-Black 模型和 ResNet 的自动化投资组合管理中建立的投资组合优化模型很出色,但本章将要讨论的关键技术是如何通过 API 将 AI 模型封装并提供给用户。关于技术建模技能,本章不会向我们的技能库中添加任何新技术。

执行文档布局分析

在机器学习中,有一门学科叫做文档布局分析。它实际上是研究人类如何理解文档的过程。它包括计算机视觉、自然语言处理和知识图谱。最终目标是提供一个本体,允许任何文档都能像文字处理软件那样被导航,但方式是自动化的。在文字处理软件中,我们需要定义某些词汇,这些词汇出现在标题中,也出现在不同层次的层级中——例如,一级标题、二级标题、正文文本、段落等。而没有人为定义的是句子、词汇、单词、字符、像素等。然而,当我们处理相机或扫描仪拍摄的图像时,最低级别的数据是像素。

文档布局分析的步骤

在本节中,我们将学习如何执行文档布局分析。步骤如下:

  1. 从像素形成字符:这项技术用于将像素转换为字符,称为光学字符识别OCR)。这是一个众所周知的问题,可以通过许多深度学习示例来解决,包括 MNIST 数据集。或者,我们可以使用 Tesseract-OCR 来执行 OCR。

  2. 图像旋转:当图像没有正确的垂直方向时,可能会给人们阅读字符带来挑战。当然,当前在这一领域的研究表明,有些技术似乎能够跳过这个步骤。

  3. 从字符形成单词:实际上,我们不能等待几分钟才能完成这个过程;在人类的表现下,我们可以做对这一点。我们怎么知道一个字符要与其他字符组合形成一个单词呢?我们知道这一点是通过空间线索。然而,字符之间的距离并不是固定的,那么我们如何教机器理解这个空间距离呢?这也许是大多数患有阅读障碍的人面临的挑战。机器默认也会遭遇阅读障碍。

  4. 从词语构建意义:这要求我们了解文章的主题和单词的拼写,这有助于我们查阅各种词典来理解文档的内容。学习(在本书中指深度学习)可能只是一个与教育相关的主题,而我们之所以知道这一点,是因为你理解到这本书是由 Packt 出版社出版的机器学习书籍——一个你以前学过的出版社名称。否则,仅仅通过阅读“Packt”这个词,我们可能会猜测它与一个包装公司有关(也就是 PACK-t)?此外,我们还可以从标签词中获得线索——步骤 3本身就像是标签词,用来引导右侧的实际内容。

将词语分类为各种通用类型的实体是有帮助的——例如,日期、序列号、金额、时间等等。这些是我们通常在开源领域看到的通用实体,比如我们在第七章中使用的 spaCy,在卖方算法营销中感知市场情绪

关于词语的空间线索,我们可能会在关注较大的词语时,忽视较小的词语。词语在页面上的位置也很重要。例如,在阅读英文时,我们通常是从上到下,从左到右,而在一些其他语言中,我们需要从右到左,从上到下阅读,比如古代汉语。

使用 Gensim 进行主题建模

在我们的主题建模示例中,我们将专注于步骤 4来限制我们的工作范围。我们在此过程中会默认步骤 1步骤 3的预工作,并跳过步骤 5步骤 6。我们将使用的数据集图像已经过清理、旋转和 OCR 处理——这包括将字符绑定成单词。我们手头的数据集每条记录由一个文本块表示,可能包含多个单词。Gensim 关注的是追踪文本中的名词。

Word2vec 的向量维度

Word2Vec 通过不同的特征定义单词——每个单词的特征值由出现在同一句子中的单词之间的距离定义。它的目的是量化概念和话题之间的相似性。在我们的 Word2Vec 示例中,我们将使用一个预训练模型将文本转换成单词。然而,对于每个文本块,可能涉及多个值。在这种情况下,这些向量会被压缩成一个值,使用一个叫做特征值的值。我们将采用这种简单的方法进行降维,这通常用于减少变量的特征数量(维度)。降维的最常见方法叫做主成分分析PCA)。它主要应用于标量,而不是变量的向量。想象每个单词都由一个向量表示。在这里,两个单词的文本块将由一个由两个向量组成的矩阵表示。因此,PCA 可能不是这种降维任务的理想解决方案。

在解释代表单词主题的向量时,分析涉及的维度非常重要,因为每个维度代表一个语义/意义组。在我们的 Word2Vec 示例中,我们将跳过这一步,以避免将过多的维度引入有意义的提取过程。这意味着我们会为说明目的缩小特征空间。

使用 Open Bank API 的现金流预测

未来,我们需要机器人顾问能够理解我们的需求。最基本的步骤是能够从不同银行提取我们的财务数据。在这里,我们假设我们是来自美国的消费银行服务客户,当前居住在英国。我们正在为一个四口之家——一对已婚夫妇和两个孩子——寻找财富规划。我们希望机器人顾问为我们执行所有的财务活动。

www.federalreserve.gov/econresdata/2016-economic-well-being-of-us-households-in-2015-Income-and-Savings.htm

以下表格展示了美国家庭的典型数值,帮助我们了解消费银行的一般需求:

收入/支出数值(单位:美元)数据来源(OBS)
收入102.7
工作人员工资102.7每月最大自动支付,月薪固定。
生活费用67.3
年度支出57.3从信用卡、储蓄和活期账户中提取所有交易。
债务偿还10.0与债务账户相关的交易。
净资产97
资产189.9
金融资产23.5证券账户的未偿还余额。401 计划无可见性。
非金融资产158.9由 Zillow 提供的房产估值。
负债92.6
抵押贷款59.5债务账户的未偿还余额。
汽车贷款和教育债务32.8汽车贷款:债务账户的未偿还余额;学生贷款(联邦),对应为联邦学生贷款;学生贷款(私人):债务账户的未偿还余额。
www.zillow.com/howto/api/APIOverview.htm

所涉及的步骤

使用开放银行 API,我们需要做以下操作:

  1. 注册使用开放银行 API。

  2. 下载所需数据。

  3. 创建一个数据库来存储这些数据。

  4. 设置一个预测用的 API。

让我们开始吧!

注册使用开放银行 API

demo.openbankproject.com/

创建并下载示例数据

github.com/OpenBankProject/Hello-OBP-DirectLogin-Pythonhello_obp.py
# -*- coding: utf-8 -*-

from __future__ import print_function    # (at top of module)
import sys
import time
import requests

# Note: in order to use this example, you need to have at least one account
# that you can send money from (i.e. be the owner).
# All properties are now kept in one central place

from props.default import *

# You probably don't need to change those
...

#add the following lines to hello-obp.py before running it
#add lines to download the file
print("")
print(" --- export json")
import json
f_json = open('transactions.json','w+')
json.dump(transactions,f_json,sort_keys=True, indent=4)

创建 NoSQL 数据库以本地存储数据

我更倾向于使用 MongoDB,因为它能够以层级方式导入 JSON 文件,而我们无需提前定义结构。即使我们需要将 NoSQL 文件以 SQL 数据库格式存储(就像在上一章中那样),每当需要使用 ML 模型进行预测时,它仍然有助于我们在运行预测之前将下载的数据物理缓存起来。

所以,你可能会想知道为什么我们需要将数据存储在 NoSQL 数据库中——难道我们不能像上一章处理推文数据时那样直接保存吗?不——我们希望使用数据库,因为为了更快地检索数据,我们将存储数十万个 JSON 文件,而不是批量下载的数据。这也取决于我们希望多频繁地下载数据;如果我们希望每天更新数据库,可能就不需要将 JSON 数据存储在 NoSQL 数据库中,因为我们处理的数据文件不会很多。然而,如果我们需要查询数据或持续向训练数据集中添加新特征,存储原始数据可能更有利。

以下代码用于建立与 MongoDB 服务器的连接:

from pymongo import MongoClient
import json
import pprint

#client = MongoClient()
client = MongoClient('mongodb://localhost:27017/')
db_name = 'AIFinance8A'
collection_name = 'transactions_obp'

f_json = open('transactions.json', 'r')
json_data = json.loads(f_json)

...

#to check if all documents are inserted
...

以下代码用于创建数据库:

#define libraries and variables
import sqlite3
from pymongo import MongoClient
import json
from flatten_dict import flatten

client = MongoClient('mongodb://localhost:27017/')
db_name = 'AIFinance8A'
collection_name = 'transactions_obp'

db = client[db_name]
collection = db[collection_name]
posts = db.posts

...

#flatten the dictionary
...

#create the database schema
#db file
db_path = 'parsed_obp.db'
db_name = 'obp_db'

#sql db
...
sqlstr = 'drop table '+db_name
...
print('create')
...
#loop through the dict and insert them into the db
...

for cnt in dict_cnt:
    ...
    for fld in tuple_fields_list:
        ...
    ...
    sqlstr = 'insert into '+ db_name+ '(' + str(fld_list_str)+') VALUES \
                                       ('+question_len[1:]+')'
    ...

设置预测用 API

为了进行支付预测,我们需要知道我们想要构建什么样的预测模型。我们是想要一个时间序列模型,还是机器学习模型?当然,我们希望有一个能够提供更多信息的模型。

在我们的示例中,我们没有为此准备任何模型,因为我们将使用的方法与我们在第二章中使用的模型类似,时间序列分析。这里的主要目的是说明如何设置 API 服务器,以及如何使用另一个程序来调用该 API。请确保这两个程序同时运行。

服务器将被设置为监听请求,以便它可以运行预测。我们将简单地加载模型,而不运行任何预测。以下代码片段用于将我们连接到 Open Bank API 服务器:

#Libraries
from flask import Flask, request, jsonify
from sklearn.externals import joblib
import traceback
import pandas as pd
import numpy as np

# Your API definition
app = Flask(__name__)

@app.route('/predict', methods=['POST'])
def predict():
    ...

#Run the server
if __name__ == '__main__':
    ...

以下代码片段用于从客户端应用程序创建请求:

import requests

host = 'http://127.0.0.1:12345/'

r = requests.post(host+'predict', json={"key": "value"})
print(r)

恭喜!你已经建立了一个能够读取银行数据的机器人,并使其能够在这些数据上运行 AI 模型。

对于家庭来说,限制支出以增加现金流变得至关重要。在接下来的部分,我们将探讨如何使用发票实体识别技术来追踪日常支出。

使用发票实体识别技术追踪日常支出

虽然我们一直在梦想通过 AI 在金融领域实现数字化的最终目标,但现实是有些数据被困住了。而且这些费用往往以纸质的形式存在,而不是 API 数据流。如果我们要转型为一个完全数字化的世界,所有信息都存储在 JSON 文件或 SQL 数据库中,处理纸质文档将是不可避免的。我们无法避免处理现有的纸质信息。通过一个纸质文档数据集的例子,我们将展示如何建立发票实体提取模型的引擎。

machinelearning.inginf.units.it/data-and-tools/ghega-dataset

涉及的步骤

我们必须遵循六个步骤,使用发票实体识别来追踪每日开销。这些步骤如下:

Word2vecgensimre
import os
import pandas as pd
from numpy import genfromtxt
import numpy as np
from gensim.models import Word2Vec
from gensim.models.keyedvectors import WordEmbeddingsKeyedVectors
import gensim.downloader as api
from gensim.parsing.preprocessing import remove_stopwords
from gensim.parsing.preprocessing import preprocess_string, strip_tags, remove_stopwords,strip_numeric,strip_multiple_whitespaces
from scipy import linalg as LA
import pickle
import re
from sklearn.model_selection import train_test_split
from sklearn.neural_network import MLPClassifier
from sklearn.preprocessing import StandardScaler
from sklearn.metrics import classification_report,roc_curve, auc,confusion_matrix,f1_score

#please run this in terminal: sudo apt-get install libopenblas-dev
model_word2vec = api.load("text8") # load pre-trained words vectors
2A2B
#2\. Define functions relevant for works
##2A Neural Network
##2A_i. Grid search that simulate the performance of different neural network design
def grid_search(X_train,X_test, Y_train,Y_test,num_training_sample):
...
##2A_ii train network
def train_NN(X,Y,target_names):
...
#2B: prepare the text data series into numeric data series
#2B.i: cleanse text by removing multiple whitespaces and converting to lower cases
def cleanse_text(sentence,re_sub):
...
#2B.ii: convert text to numeric numbers
def text_series_to_np(txt_series,model,re_sub):
...

numpypandas
#3\. Loop through the files to prepare the dataset for training and testing
#loop through folders (represent different sources)
for folder in list_of_dir:
    files = os.path.join(path,folder)
    #loop through folders (represent different filing of the same 
     source)
    for file in os.listdir(files):
        if file.endswith(truth_file_ext):
        #define the file names to be read
         ...

        #merge ground truth (aka target variables) with the blocks 
         ...

        #convert the text itself into vectors and lastly a single 
        value using Eigenvalue
        text_df = f_df['text']
        text_np = text_series_to_np(text_df,model_word2vec,re_sub)

        label_df = f_df['text_label'] 
        label_np = text_series_to_np(label_df, model_word2vec, \
                                     re_sub)
         ...
Y_pd = pd.get_dummies(targets_df)
Y_np = Y_pd.values
  1. 执行模型。在这里,我们使用之前步骤中定义的函数来执行我们准备的模型。以下代码片段用于执行该模型:
#4\. Execute the training and test the outcome
NN_clf, f1_clf = train_NN(full_X_np,Y_np,dummy_header)
...

恭喜!到此为止,你已经构建了一个能够从扫描图像中提取信息的模型!

  1. 从单词的空间和视觉环境中提取线索。前述这一行明确区分了步骤 4步骤 5。注意这些线条如何被投射出来,也有助于我们将相似的单词分组。对于需要原件的文档,我们可能需要查看签名和标志,并将其与真实的已验证签名或印章进行比对。

  2. 构建这些文档的知识图谱。这是我们可以深入了解文档中所蕴含的知识的时候。在这里,我们需要使用图形数据库来追踪这些知识(我们在前一章中已介绍过)。

这就结束了我们关于追踪每日开销的示例,也结束了这一章的内容。

总结

在这一章中,我们介绍了如何使用 API 提取数据并提供 AI 服务。我们理解了管理客户数字数据的重要性。我们还理解了开放银行项目和文档布局分析。通过两个示例我们学习了这些内容——一个是关于现金流投影,另一个是关于追踪每日开销的。

下一章将继续聚焦于消费者银行业务。我们将学习如何为客户资料中缺失的信息创建代理数据。我们还将查看一个示例聊天机器人,用于服务和与客户互动。我们将使用图形和自然语言处理技术来构建这个聊天机器人。

第九章:客户终身财富的大规模定制

在上一章中,我们学习了如何管理客户的数字数据。我们还介绍了开放银行项目和开放银行 API。此外,我们还学习了文档布局分析,并查看了一个投影典型家庭现金流的示例。然后,我们查看了另一个使用发票实体识别跟踪日常支出的示例。

在本章中,我们将学习如何结合来自调查的数据进行个人数据分析。我们将学习 Neo4j 等技术,这是一个图数据库。我们将构建一个全天候为客户服务的聊天机器人。我们还将学习如何使用 NLP 和 Neo4j 预测客户响应,以一个示例为例。之后,我们将学习如何使用 Cypher 语言操作来自 Neo4j 数据库的数据。

本章将涵盖以下主题:

  • 财富工具的金融概念

  • 集成学习

  • 预测客户的响应

  • 构建一个全天候为客户服务的聊天机器人

  • 使用自然语言处理(NLP)和图表进行知识管理

财富工具的金融概念

在这一部分,我们将回答消费银行营销人员提出的一些问题。然后,我们将研究另一个重要的模型开发技术——集成学习,这在将不同模型的预测结合起来方面非常有用。

零售银行客户分析中最常见的任务之一是获取额外数据,以帮助解释客户的投资行为和模式。毫无疑问,我们将了解客户的响应,但模型的工作是找出他们为什么做出这样的响应。令人惊讶的是,关于个人行为的聚合信息有很多,例如人口普查数据。我们还可以从社交媒体获取数据,用户使用社交媒体进行身份验证。然后,可以将相关的社交媒体信息与我们在组织内部观察到的个人级交易数据进行链接。为了解释个人银行行为,我们最希望的相关补充数据是关于他们财富的信息。

客户生命周期

典型的生命周期包括三个主要阶段——获取、交叉销售/增值和保留。以下图表说明了这三个阶段:

获取是我们开始与客户建立商业关系的时刻。然后,我们进入交叉销售向上销售。交叉销售是提高向客户销售的产品/服务数量。向上销售是通过同一产品与其他产品/服务加深客户的资金份额。保持是指维持关系,这是银行保护关系的防御性举措。我们的第一个例子(将在后面的章节中描述)涉及交叉销售(如果客户没有该产品)和向上销售(如果客户拥有该产品)。

集成学习

集成学习是一种提升技术,可以帮助我们提高预测的准确性。我们还将学习如何使用图数据库进行知识存储。知识存储是当前知识表示中的挑战,可以用来增强人工智能在专业级金融服务中的应用。

scikit-learn.org/stable/

通过图数据库进行知识检索

要使机器在客户服务中像人类一样交流,其中一个关键要素是对话组件。当我们进行对话时,正常情况下人类客户可能无法提供处理所需的全部信息。人类能够应对模糊性。人类能够理解上下文,因此可以推断出意义,而无需明确提及概念。知道机器只能解决明确的问题,而人类能够处理模糊性,机器的任务是从它所拥有的知识图谱中推断出客户的意义。图数据库就是为此目的而使用的工具。

预测客户响应

到目前为止,我们还没有讨论银行的日常营销活动。现在,我们终于来看看如何确定营销前景。尽管每个客户都是独特的,但他们仍然是通过算法以相同的方式处理的。

archive.ics.uci.edu/ml/datasets/bank+marketingwww.census.gov/data/tables/time-series/demo/income-poverty/historical-income-households.html

解决方案

完成此示例有四个步骤:

  1. 我们引入了随机森林,它是一种机器学习算法,利用集成学习,使得可以通过多个模型进行预测。最终的模型是多个模型结果的组合。以下是导入所需库并定义变量的代码片段:
#import libraries & define variables
import pandas as pd
import os
from sklearn.ensemble import RandomForestClassifier
from sklearn.datasets import make_classification
  1. 人口普查数据提供了关于年龄段存款和财富的信息,这些数据被存储在银行中。以下是处理人口普查数据的代码片段:
cat_val = ''
cat_dict = {}
for index, row in df_xtics.iterrows():
    ...

df_bank['age_c'] = pd.cut(df_bank['age'], [0,35,45,55,65,70,75,200])

#ID Conversions
df_bank['age_c_codes']=df_bank['age_c'].cat.codes.astype(str)
age_map={'0':'Less than 35 years'
,'1':'35 to 44 years'
,'2':'45 to 54 years'
,'3':'55 to 64 years'
,'4':'.65 to 69 years'
,'5':'.70 to 74 years'
,'6':'.75 and over'}
  1. 我们希望通过使用年龄来引入财富数据,说明如何将一列数据映射。以下是将人口普查数据与银行数据结合的代码片段:
#3\. map back the survey data
df_bank['age_c1']=df_bank['age_c_codes'].map(age_map)
df_bank['age_c1_val']=df_bank['age_c1'].map(cat_dict['Age of Householder'])

X_flds = ['balance','day', 'duration', 'pdays',
       'previous', 'age_c1_val']
X = df_bank[X_flds]
y = df_bank['y']
  1. 以下是训练模型的代码片段:
X, y = make_classification(n_samples=1000, n_features=3,
                           n_informative=2, n_redundant=0,
                           random_state=0, shuffle=False)
clf = RandomForestClassifier(n_estimators=100, max_depth=2,
                             random_state=0)
clf.fit(X, y)
print(clf.feature_importances_)

恭喜!你已经将外部数据集与内部数据集合并,增强了我们对客户的理解。

建立一个 24/7 服务客户的聊天机器人

当我们与机器人互动时,我们期望它能够理解并与我们对话。机器人为我们工作的好处在于它可以 24 小时全天候为我们服务。实际上,现在的聊天机器人与客户的互动表现较差,因此我们应该尝试拆解这些聊天机器人的组成部分,并将其标准提高。对于应用类型的开发,你可以使用谷歌助手、亚马逊的 Alexa 或 IBM 的 Watson。但为了学习目的,让我们拆解这些组成部分,并集中关注关键挑战:

聊天机器人执行两个高级操作。一个是将语音输入转为文本,另一个是将文本输出转为语音。这两个操作都涉及提取实体和理解意图。在这个例子中,生成的文本是一个实体,而文本的意义则是意图。它代表了服务请求者和服务提供者之间的对话。当面对一个服务请求时,聊天机器人将语音指令转为文本,并为接收到的信息添加上下文。一旦上下文构建完成,聊天机器人就会处理这些信息并生成文本格式的输出。然后,聊天机器人必须将其转换为可听见的语音输出,呈现给服务请求者。整个场景在前面的图示中已做解释。

现在,让我们只专注于聊天,不考虑语音识别和语音输出——也就是说,我们忽略语音转文本和文本转语音。在我看来,由于这个任务涉及大量的机器运算和内存消耗,而且数据在许多地方都可以获取,这个任务不适合初创公司去做;相反,我们应该将其交给具备强大基础设施的主流云服务提供商来提供服务。

对于仅文本聊天,关键的重点应放在意图分类和实体提取上。虽然我们在上一章中已提及实体提取,但输入仍然需要在提取之前进行分类。意图分类与实体提取的工作原理类似,但将整个句子作为一个实体进行分类。

虽然使用 ChatterBot 或 RasaNLU 来运行聊天机器人是非常常见的,但我们可以从下往上分解这些组件来运行。

假设我们是一个简单的银行,提供存款和贷款服务。我们正在构建一个只能为现有客户服务的简单聊天机器人,目前我们只有两个客户,一个叫做abc,拥有存款账户,另一个叫做bcd,拥有贷款账户:

abc 的存款余额为 100 个单位,定价为 1,而 bcd 的贷款余额为 100 个单位,定价为 2。

使用自然语言处理和图谱进行知识管理

从本质上讲,我们有两种方法来检索和更新我们现实世界的知识。一种是将知识存储在向量空间中,并在运行时使用诸如 Word2Vector 和 BERT 等程序将文件读取到内存中。另一种方法是将知识加载到图数据库中,例如 Neo4j,并检索和查询数据。这两种方法的优势和劣势在于速度和透明度。对于高速主题分类,内存模型表现更好,但对于需要透明度的任务,例如银行决策,数据更新需要完全透明和永久记录。在这些情况下,我们将使用图数据库。然而,就像我们在第七章中简要介绍的例子Sensing Market Sentiment for Algorithmic Marketing at Sell Side一样,需要使用 NLP 从文档中提取信息,然后才能将信息存储为图格式。

实际实现

以下是完成此示例的步骤:

csv
sudo cp dataset.csv /var/lib/Neo4j/import/edge.csv
sudo cp product.csv /var/lib/Neo4j/import/product.csv
sudo cp customer.csv /var/lib/Neo4j/import/customer.csv
http://localhost:7474/browser/usernamepassword
username: test, password: test
  1. 删除所有节点:
MATCH (n) DETACH DELETE n;
  1. 创建客户数据:
LOAD CSV WITH HEADERS FROM "file:///customer.csv" AS row
CREATE (c:Customer {customer_id: row.customer});
  1. 创建产品数据:
LOAD CSV WITH HEADERS FROM "file:///product.csv" AS row
CREATE (p:Product {product_name: row.product});
  1. 加载 CSV 文件:
LOAD CSV WITH HEADERS FROM "file:///edge.csv" AS line
WITH line
MATCH (c:Customer {customer_id:line.customer})
MATCH (p:Product {product_name:line.product})
MERGE (c)-[:HAS {TYPE:line.type, VALUE:toInteger(line.value)}]->(p)
RETURN count(*);
  1. 匹配并返回数据:
MATCH (c)-[cp]->(p) RETURN c,cp,p;

Cypher 本身是一种语言;我们所做的基本上是创建产品和客户。然后,我们加载另一个连接客户和产品的文件。

Neo4j
#import libraries and define parameters
from Neo4j import GraphDatabase
import spacy

#define the parameters, host, query and keywords
uri = "bolt://localhost:7687"
driver = GraphDatabase.driver(uri, auth=("test", "test"))
session = driver.session()

check_q = ("MATCH (c:Customer)-[r:HAS]->(p:Product)" 
 "WHERE c.customer_id = $customerid AND p.product_name = \
  $productname" 
 "RETURN DISTINCT properties(r)")
...
intent_dict = {'check':check_q, 'login':check_c}

#list of key intent, product and attribute
product_list = ['deposit','loan']
attribute_list = ['pricing','balance']
intent_list = ['check']
print('loading nlp model')
nlp = spacy.load('en_core_web_md')
GraphDatabaseGraphDatabase
if name == '' or reset:
    name = input('Hello, What is your name? ')
    print('Hi '+name)
    #check for login
    query_str = intent_dict['login']
    result = session.read_transaction(run_query, query_str, name, \
                                 product, attribute, attribute_val)

句子意图和实体提取利用 spaCy 进行相似性分析。基于预训练的词向量模型,意图和实体的保留词与输入的句子进行比较,以提取相关的意图和实体。该模型过于简化,读者有足够的创作空间,通过使用更好的语言模型,如 BERT,来增强提取工作,假设我们已经制作了相关的模型来执行相关的分类任务。

以下是提取实体并添加意图的代码片段:

#Sentences Intent and Entities Extraction
input_sentence = input('What do you like to do? ')
if input_sentence == "reset":
    reset = True 
entities = intent_entity_attribute_extraction(nlp, input_sentence, \
                         tokens_intent, tokens_products, tokens_attribute)
#actually can build another intent classifier here based on the scores and words matched as features, as well as previous entities
intent = entities[0]
product = entities[1]
attribute = entities[2]
attribute_val = entities[3]

交叉检查并进一步请求缺失信息

程序将不断地请求意图、产品和属性,直到这三项信息对程序明确为止。在每个参数的分类下,我们使用 Word2vec 进行简化的分类。实际上,我们可以运行一个一流的话题分类模型,例如 BERT,来理解语言和话题。

以下是请求用户提供缺失信息的代码片段:

while intent == '':
    input_sentence = input('What do you want to do?')
    entities = intent_entity_attribute_extraction(nlp, input_sentence, \
                     tokens_intent, tokens_products, tokens_attribute)
    intent = entities[0]

while product == '':
    input_sentence = input('What product do you want to check?')
    entities = intent_entity_attribute_extraction(nlp, input_sentence, \
                     tokens_intent, tokens_products, tokens_attribute)
    product = entities[1]

while attribute == '':
    input_sentence = input('What attribute of the ' + product + \
                        ' that you want to '+intent+'?')
    entities = intent_entity_attribute_extraction(nlp, input_sentence, \
                      tokens_intent, tokens_products, tokens_attribute)
    attribute = entities[2]

提取答案

当所有信息填写完成后,将执行 Cypher 查询,信息将呈现给用户。以下是提取答案的代码片段:

#execute the query to extract the answer
query_str = intent_dict[intent]
results = session.read_transaction(run_query, query_str, name, \
                                    product,attribute,attribute_val)
if len(results) >0:
    for result in results:
        if result['TYPE'] == attribute:
            print(attribute + ' of ' + product + ' is '+ \
                  str(result['VALUE']))
else:
    print('no record')

交互样本脚本

以下片段展示了用户的输入和输出。它旨在展示 NLU 如何使用密切相关的词汇提取意图和实体,得益于 spaCy 字典使我们能够找到相似的词汇。这个示例的关键是展示,对于那些需要在做出决策之前获得完整信息的情况,图数据库允许我们管理对话并在执行任何指令以服务用户之前跟进缺失的信息。这在做出专业决策时非常重要,因为我们需要其推理过程对机器能够理解的语言具有较高的透明度和准确性。以下是聊天机器人的样本对话片段:

loading nlp model
Hello, What is your name? testing
Hi testing
Failed to find testing
Hello, What is your name? abc
Hi abc
What do you like to do? do sth
matching...

What do you want to do?check sth
matching...
check 
What product do you want to check?some product
matching...

What product do you want to check?deposit
matching...
 deposit 
What attribute of the deposit that you want to check?sth
matching...

What attribute of the deposit that you want to check?pricing
matching...
 pricing
pricing of deposit is 1

恭喜!你已经构建了一个非常简单的聊天机器人,它可以向你展示聊天机器人的核心功能。

我们使用的示例非常好地反映了我们在商业银行中使用借款人和存款人数据结合强化学习的起点。当时,数据是在运行时存储在变量中的。现在,我们展示了将数据存储在图形数据中的另一种可能性。事实上,与第三章中“使用特征和强化学习来自动化银行融资”的示例相比,如果我们将数据存储在图数据库中,而不是 Python 程序中的变量中,强化学习的速度会较慢。因此,我们将使用图数据库,但仅在生产和应用级别使用,当个别对话可以容忍相对于计算密集型训练阶段的延迟时。

总结

在本章中,我们学习了自然语言处理(NLP)和图数据库,并了解了分析客户数据所需的金融概念。我们还学习了一种名为集成学习的人工智能技术。我们通过一个例子来预测客户的响应,使用了自然语言处理技术。最后,我们构建了一个聊天机器人,能够 24/7 为客户提供服务。这些概念非常强大。NLP 能够让程序理解人类自然使用的语言。而图数据库则有助于设计高效的算法。

在下一章中,我们将学习在构建模型来解决日常挑战时需要考虑的实际因素。此外,我们还将讨论在为数据科学家提供与 IT 开发人员互动的语言时,涉及到的实际 IT 考虑因素,这些开发人员将算法应用到现实生活中。

第十章:现实世界中的考量

本章是本书的结论。它总结了我们即将生活的近未来银行世界。我们还将提供一些有用的提示,介绍在日常生产环境中融合这些人工智能引擎所需的考量因素。这部分对应于 CRISP-DM 中的业务理解步骤,CRISP-DM 是我们在第一章中介绍的实现任何数据挖掘项目的方法,人工智能在银行业中的重要性

在本章中,我们将首先总结你在第 2 至第九章中学到的技术和知识,然后我们将讨论一些前瞻性话题,这些话题将延续我们在银行业的旅程。这些将要讨论的主题和知识包括:

  • 涵盖的技术总结

  • 对银行从业人员、监管者和政府的影响

  • 如何提出特征并获取领域知识

  • 与人工智能部署相关的 IT 生产考量

  • 寻找更多应用场景的地方

  • 哪些领域需要更多的实践研究?

涵盖的技术总结

在银行业务领域,我们已经涵盖了相当多的数据和人工智能技术。我们也通过了模型,但极少使用复杂的公式或术语。

人工智能建模技术

我们已经涵盖了统计模型、优化和机器学习模型。在机器学习模型中,我们涵盖了无监督学习、监督学习和强化学习。关于监督学习模型运行的数据类型,我们涵盖了结构化数据、图像和语言(自然语言处理)。关于数据处理,我们也介绍了帮助我们的多种抽样和测试方法。现在,我们将回顾本书中迄今为止涵盖的人工智能建模技术:

  • 从监督学习开始,这是一个在处理之前对输入数据进行标记的技术。模型被构建以从标签中学习,以便下一个输入数据集可以自动完成标记。另一方面,无监督学习不对输入数据进行标记。它没有标记或经过训练的数据。处理是通过基于模式和重复识别对象来进行的。

  • 强化学习基于实现下一个即时目标并评估与最终目标的距离。这项技术需要来自用户的即时反馈或输入,以达到最终目标。

  • 人工神经网络是一个模仿人脑神经网络的概念。人脑中的神经元在人工神经网络中由节点表示。

  • 深度学习是机器学习和人工神经网络的一个领域。深度学习算法使用多个层次从原始输入数据中提取更高层次的信息。

  • CRISP-DM 是数据挖掘的标准,代表跨行业数据挖掘标准。它提供了一个结构化的方法来规划数据挖掘和数据分析项目。

  • 时间序列分析是一种预测技术,依赖于特定时间间隔内捕捉的历史数据。在时间序列分析中,我们决定一个观察参数,并在特定时间间隔内捕获该参数的值。例如,这可以是银行分支机构记录的每月支出。

  • 自然语言处理(NLP)关注人类语言与机器语言之间的对话。一个能够理解并解释人类语音并执行命令的语音转文字引擎可以是 NLP 的一个例子。

  • 最后,集成学习通过使用多个机器学习算法,获得比单一机器学习算法预测更优的预测结果。

对银行业从业人员、监管机构和政府的影响

我们已开始了在商业银行(第二章,时间序列分析和第三章,使用特征和强化学习自动化银行融资)、投资银行(第四章,资本市场决策的机械化和第五章,预测投资银行家的未来)、证券销售与交易(第六章,使用 Treynor-Black 模型和 ResNet 进行自动化投资组合管理和第七章,感知市场情绪以支持卖方算法营销)、以及消费银行(第八章,通过银行 API 构建个人财富顾问和第九章,客户生命周期财富的批量定制)等领域的银行业。此部分通过一位企业客户——杜克能源公司——的案例,展示其从商业银行业务到投资银行业务的过程。在投资银行中,我们首先介绍购买公司发行证券的投资群体,然后在第六章,使用 Treynor-Black 模型和 ResNet 进行自动化投资组合管理和第七章,感知市场情绪以支持卖方算法营销中完全转向投资方的内容。讨论投资话题时,我们会将其延续到最后两章编程内容——第八章,通过银行 API 构建个人财富顾问和第九章,客户生命周期财富的批量定制——并深入聚焦财富管理的视角。

最后一章帮助我们聚焦于客户端的数据聚合问题。从本质上讲,所有银行的客户——个人、企业和机构——都将以集中化的方式拥有并管理他们的数据,以培养他们自己的资产——数据。

消费者市场帮助我们看到推动数据管理前沿的各种组件类型。而对于机构和企业而言,涉及法律实体的数据要复杂得多,因此需要更好的知识管理模型来组织描述企业数据的深度。

实际上,如何组织与商业和机构相关的数据已经不再是知识管理时代讨论的话题,尽管它曾是 2000 年代初商业学校中一项蓬勃发展的议题。

在知识管理领域曾提出了许多模型和框架,但许多组织缺乏通过最小化努力来收集这些知识的技术解决方案。当时我在一家咨询公司工作,亲眼目睹了维护知识体系的痛苦,而知识体系是咨询行业的核心资产——商业诀窍。现在,随着我们计划让机器变得智能并做出专家级别的金融决策,我们将重新回到这一话题。当我们能够明确地以数据质量管理的名义维护这些机器时,机器人的边界将得到拓展。

对银行从业者的影响

关于银行当前使用的商业模式的不断争论正在进行中。我个人的观点是,关于前瞻性风险和回报预测的核心决策依然存在。归根结底,我们需要一家银行来为未来的活动提供资金,而在做出金融决策时,这些活动并非完全确定。我们还在做出有关未来财富的决策,而我们也无法完全掌控这些财富。变化的是,随着机器的出现以及这些专家决策数量的快速增加,这些决策逐渐被交给了外行人,风险和回报视角的更新速度也变得更快。

今天的银行业,不仅是银行从业者,政府、监管机构以及消费者也将共同推动边界的扩展,创造更加高效的金融市场,实现数据的自由流动,并明确数据的所有权和技术,以便在各行各业的决策中赋予数据的价值。

在整个行业中,根据 Michel E. Porter 的五力模型,开放 API 仍然是现有企业的痛点,而对于新入行的公司来说,这是一个竞争定位中的争议话题。

除了开放银行 API,它只是获取数据的一个通道,目前并没有对银行数据标准进行有价值的讨论,尤其是对于客户和客户而言。的确,API 看起来很时髦,但它们也带来了一个巨大的问题,那就是如何处理客户为自身利益存储数据的问题。考虑到数据的可用性将会在能够组织和不能组织的群体之间产生分化,个体客户考虑这个话题似乎并不理想。

监管者的影响

曾经银行的指令是尽力而为的时代已经过去;如今,模型和验证机制已经到位,以保证服务质量并保护投资者利益。投资者需要知道哪些特征可能会在金融估值中引发波动。也许时效性成为了关键,而不是期待银行对可能发生的事件有明确看法?银行设定的关于风险事件的概率是可以验证的。

政府的影响

我们如何提供技术,允许个人拥有自己的数据?政府在存储个人身份以及所有足迹方面如何发挥主导作用?个人数据标准有助于减少分享、存储和让个人管理自己数据的经济成本。

欧洲的 GDPR 是一项很好的法规,但它本质上缺乏执行它所需的技术,就像知识管理的情况一样。同样,描述公司、企业、机构和公共市场之间互动的数据将被视为政府提供的公共设施,因为证券交易所拥有这些数据。

按照公共利益的理念,目标不是赚取巨额利润,而是提供促进其他经济活动的公共服务。我认为,政府在公共领域数据分发方面应有更多干预。这将为机器人提供更为友好的工作环境,因为数据可用性问题是整本书的核心。我们不难发现,它在所有经济活动领域中对 AI 应用的推动产生了更大的阻力。为了平衡这种与数据相关的开放性,我们同样需要对数据进行更好的控制——无论是对公司还是个人来说。

开放数据运动已经成为一个热门话题,旨在使数据更易获取。开放政府数据可能涉及诸如证券交易所数据等问题,这些数据有时由某些准政府组织在特定的许可证或规定下运营。同样,开放银行数据也是全球金融监管机构的推动力,目的是为银行客户提供他们自己的数据。

从实践层面来看,数据是人工智能的关键要素,在某些情况下,数据经过清理、维护,并作为一种费用由纳税人支付!然而,数据维护所花费的资源也取决于能够在自动化和更好决策方面节省成本的人工智能应用场景。根据这一简单逻辑,必须有人来付费:要么通过政府预算中的共享资金池(即纳税人,包括你),要么通过使用数据的人(又是你!)。而数据可访问性面临的挑战之一就是跟踪其使用情况。如果我们想让任何使用过数据的人为每个特定数据点甚至字段层级支付,这就容易得多。

人工智能可能是明日的电力,但数据将首先作为今天的电力提供。

如何提出特征并获取领域知识

在到目前为止的所有章节中,我们并没有解释我们从哪里获得这些领域知识。一个典型的人工智能项目需要我们站在金融专业人士的角度来思考。那么从哪里开始呢?以下是一个帮助你入门的清单:

  • 教科书和培训课程:最简单的路径是遵循这些专业人士的培训方式。这些课程包含了各自工作类型所需的术语、方法和流程。

  • 银行与金融领域的研究论文:当谈到寻找正确的数据时,金融和银行领域的研究可以证明是一个非常有价值的资源。它不仅能告诉你从哪里获取数据,还能展示那些具有强大预测能力的特征。然而,我通常不会迷失在各作者和市场之间特征的不一致性中。我只是尽可能多地将它们全部包含在内,并且有研究者的理论支持。

  • 观察仪表盘:商业智能(BI)捕捉了对人类用户有意义的关键特征。这些 BI 报告中使用的数据字段是能够生动描述由人类专家规定问题的好特征。

  • 程序手册:如果你在一个已经建立了流程和程序的组织中工作,那么程序手册就是一个宝贵的资源,能够描述人类如何工作,尤其是那些处理密集型工作的过程。

  • 机构:有些人说设计思维,有些人说这仅仅是将自己置于他人角度,试图以假设性的方式进行任务处理。

  • 观察儿童发展:如果任务涉及感知和传递信息等方面,我们可以观察人类如何学习构建这些要素,并理解神经网络架构应该是什么样子的。

  • 寻找 Excel:Excel 已成为商学院中的主流工具,是一种半标准化的决策方式,尤其在金融建模领域。这是理解人类如何做出决策及其复杂规则的一个良好起点。

以上几点涉及商业领域的考量,但我们还需要考虑推出该模型的 IT 方面。

与人工智能部署相关的 IT 生产考虑事项

如果算法没有在银行的日常决策中运行,那么人工智能只是一个文件。当然,趋势是将人工智能作为服务提供给编写程序的软件开发者。除此之外,还有一系列需要关注的事项:

  • 加密:数据至关重要,所有人工智能都运行在敏感数据上。尽管数据在通过 Scaler 将其转换为 0 到 1 的范围时已经在一定程度上匿名化,然而,确保数据在网络传输过程中加密并且保存在加密的数据库中,仍然至关重要。

  • 负载均衡:需要正确处理请求的容量,并且创建足够的服务器来运行算法。随着越来越多的公司采用云服务商的无服务器架构,这个问题在一定程度上得到了缓解。然而,这个问题仍然存在,只是被外包了。作为一名工程师,要理解容量和如何处理负载,体现的是服务的水平。我们希望的是一台永远在线的智能机器人,而不是一个在关键时刻消失的智能引擎。为了实现这一点,需要理解使用流量、硬件和软件容量规划,并能够根据流量变化执行这些任务。

  • 认证:组织通常会有自己的认证偏好,这可能会对客户体验产生较大影响,同时安全问题仍然是关注的重点。

如何寻找更多的使用案例

本书列出的人工智能应用主要集中在前台银行服务,后台处理工作没有被详细讨论。退一步来说,如果你想启动自己的项目,你应该在哪些方面寻找机会呢?

  • 长时间工作;枯燥的工作:枯燥意味着重复,而这正是机器能够发挥优势的地方,数据也非常丰富。

  • 庞大的劳动力:在商业案例中,寻找就业量大的职位是比较容易的。这意味着巨大的商业潜力和易于证明的实施可行性。这对人力资源专业人士来说构成了巨大的挑战。

  • 高薪:如果我们希望让金融变得更加可及,是否能使这些高薪工作更具生产力?以投资银行家、安全结构师和对冲基金交易员为例,如何减少他们的非生产性时间?

  • 独特的数据集:如果数据集无法为外部人员所访问,那么领域可能不会得到关注,因为研究人员和初创公司无法发现这个问题。

哪些领域需要更多的实际研究?

在某些领域,本书已经达到了研究的瓶颈,这些研究领域可能有助于推动银行业中人工智能应用的发展:

  • 自主学习:人工智能将取代人工智能工程师的工作——因为机器将能够学习。鉴于如今数据的丰富性,机器将自行采用其网络结构。

  • 透明 AI:随着机器开始做出决策,人类将要求关于决策过程的透明性。

  • 知识体系:在专家知识的情况下,进一步的研究将探讨组织如何利用人工智能生成知识体系。从实践角度来看,存储在 BERT 或任何语言模型中的 Wikipedia 形式并不适合人类消费或知识培养。那么我们如何将知识图谱压缩成神经网络,反之亦然?

  • 数据掩码:为了使数据能够自由流动和交换,一个灵活的数据掩码机制至关重要,该机制可以保留字段内及字段之间的分布特征。它允许数据与研究人员共享,甚至开放给智能数据科学家进行攻击。与良好掩码机制相关的一个次要问题是,数据拥有者是否可以与研究社区共享其数据,以便解决现实世界的挑战?这是否被视为捐赠,因此可以税前扣除?

  • 数据聚合与标准化:如本章前面所述,这描述了客户数据如何被标准化,以及个人和公司如何拥有并管理其数据。

  • 跨学科任务聚焦应用:为了发现更多的研究课题,来自不同学科的研究人员合作解决任务聚焦问题至关重要,而不是仅仅围绕解决单一研究课题的数据集进行工作。

  • 数据生命周期技术:由于数据在许多地方被使用,并且在不同系统间被修改、更新和复制,我们是否拥有合适的技术来跟踪所有这些数据的流动?一旦我们能够跟踪其流动,就可以将数据的价值归属于供应链中的数据贡献者,从而激励数据生产。有人提倡使用区块链,但将大量数据保存在区块链上似乎不太实际。

摘要

本书旨在通过公共领域信息,展示目前在技术方面的可能性。我希望它能够帮助培养人才和研究人员,以支持行业发展。同时,它也为任何潜在的初创企业创建了一个基准水平,企业需要超越这个水平才能够符合资格。由于书中的所有代码现在都是开源的,我很高兴在技术解决方案方面处于性能的底部!

有很多书籍仅仅是富有远见的,还有一些书籍讨论了技术考虑,但却未触及问题的核心。还有一些书籍充满了数学和公式,涉及加密知识。这本书的目的是填补远见和技术考量之间的空白。我相信,未来的世代应当在一个 AI 乌托邦中学习,为改变我们的工作世界做准备。对于行业专业人士和希望提升技能的人们,我希望这本书能够提出一些值得关注的领域,进一步巩固他们的知识。

这只是一个开始。