Web3 的数据科学(二)_web3 的科学数据研究方法论
原文:
annas-archive.org/md5/ba7a54fa0e0446c3eff08a0164e548be
译者:飞龙
协议:CC BY-NC-SA 4.0
第六章:准备和探索我们的数据
数据准备是数据科学中的一个常见主题,超出了与机器学习流程的关联。它有各种不同的名称,如数据整理、数据清洗和特征工程的数据预处理。
在这里,我们强调将会投入大量时间进行数据清洗、特征工程和探索性分析,并且我们认识到强有力的预处理对结果的积极影响,无论是面向业务利益相关者的展示,还是与机器学习模型的整合。
数据清洗包括专注于识别和修正数据问题的任务,特别是错误和伪影。错误通常是由于在获取过程中数据丢失,而伪影则来源于生成数据的系统。清洗的工作涉及处理缺失数据、处理异常值、去除重复数据,以及为数据的可读性和转换执行必要的翻译。
数据准备涵盖了理解和转化接收到的数据,以使其与后续的流程步骤对接。这一章节深入探讨了在理解、预处理和从链上数据中提取信息时常见的情景。具体话题包括十进制处理、智能合约演变的方法和校验和验证。此外,本章还介绍了探索性数据分析(EDA)的概念,并利用汇总统计和异常值检测技术来展示其优势和见解。
本章探讨了准备链上数据的复杂性,并引入了 EDA 概念,促进了从分析到机器学习的过渡。由于这个数据科学领域的广泛性,本章并不旨在提供所有工具和方法的详尽概述。
总结来说,本章将涵盖以下主题:
-
链上数据准备
-
探索性数据分析介绍
技术要求
我们广泛使用 Pandas 库,它是一个流行且实用的 Python 库,用于处理 DataFrame 和系列。Pandas 提供了众多函数来分析、总结、探索、归一化和操作它们。系列是一个一维的类似数组的对象,而 DataFrame 是一个二维的表格结构,包含行和列。本书中的所有练习都将使用 Pandas 来执行上述活动。
如果你还没有安装 Pandas,可以通过以下代码片段来安装:
pip install pandas.
Pandas 的文档可以在 pandas.pydata.org/docs/
查阅。
对于数据可视化,我们使用 Matplotlib 和 Seaborn 库。Matplotlib 提供了广泛的工具和对我们构建图像的控制,而 Seaborn 构建在 Matplotlib 之上,更加用户友好,但灵活性较差。
两个库的文档分别可以在seaborn.pydata.org/
和matplotlib.org/
找到。
你可以在本书的 GitHub 仓库中找到本章的所有数据和代码文件,网址为github.com/PacktPublishing/Data-Science-for-Web3/tree/main/Chapter06
。我们建议你阅读Chapter06
文件夹中的代码文件,以便跟随学习。
数据准备
在处理来自不同数据源的信息时,确保所有记录和字段的一致性和统一性非常关键,这样才能提取出有价值的见解或将数据输入到机器学习模型中。在这一部分,我们将探索与链上数据特别相关的各种数据准备任务。
十六进制值
十六进制表示法是一个基于 16 的系统,使用符号表示从 0 到 9 的数字值和从 A 到 F 的字母值。相比之下,我们日常使用的十进制表示法使用 10 个符号表示数字值(0-9)。十六进制表示法通过包括 A 到 F,将范围扩展到 10 到 15。这种表示法通常用于数据存储,因为它能够高效地表示二进制数字,每个十六进制数字表示 4 位二进制数。
在Chapter06/Preparation
中的示例中,我们通过遵循developers.rsk.co/rsk/public-nodes/
提供的文档,从 Rootstock 公共节点检索最新的区块编号。
结果值以十六进制数字的形式呈现,例如0x4e07d0
:
https://github.com/OpenDocCN/freelearn-ds-pt4-zh/raw/master/docs/ds-web3/img/B19446_06_01.jpg
图 6.1 – 十六进制区块编号
这个十六进制数字可以通过以下代码片段解码为十进制数字,基数为(16
):
https://github.com/OpenDocCN/freelearn-ds-pt4-zh/raw/master/docs/ds-web3/img/B19446_06_02.jpg
图 6.2 – 解码后的十六进制区块编号
按照这些步骤,我们能够将 RSK 节点返回的十六进制响应转换为我们的十进制系统。为了验证转换后的信息的准确性,我们可以将结果与链上浏览器中的数据进行对比,浏览器网址为explorer.rsk.co/blocks
或rootstock.blockscout.com/
。我们会看到该区块刚刚被添加到链上:
https://github.com/OpenDocCN/freelearn-ds-pt4-zh/raw/master/docs/ds-web3/img/B19446_06_03.jpg
图 6.3 – 区块浏览器
某些 SQL 数据库引擎具备将十六进制值直接转换为人类可读格式的能力。例如,Covalent 使用的 ClickHouse 系统提供了unhex
方法。你可以在clickhouse.com/docs/en/sql-reference/functions/encoding-functions#unhex
的文档中找到更多详情。
校验和
校验和是一种哈希地址的算法,使得以太坊可以验证地址是否有效。在以太坊中,校验和地址包含了特定模式的大小写字母。
0x95222290DD7278Aa3Ddd389Cc1E1d 165CC4BAfe5
0x95222290dd7278aa3ddd389cc1e1 d165cc4bafe5
表 6.1 – 地址之间的区别
以太坊将小写字母和校验和地址视为有效地址,发送到任一版本的资金将会被定向到同一接收者。然而,使用校验和地址能提供额外的安全层,防止意外地将资金发送到不存在的地址。
本节有两个重要的意义。首先,Python 和许多 SQL 引擎一样,区分大小写。因此,在比较或合并来自不同源的数据时,管理小写和校验和地址之间的差异变得至关重要。这可以保证数据分析的兼容性和精确性。第二个方面是区分有效和无效地址,这在保持数据完整性和加速查询方面非常关键。
在 Chapter06/Preparation
中,我们测试一个地址是否是有效的校验和以太坊地址。为此,我们利用 test()
函数将一个小写字母地址转换为其校验和版本。
另一个例子请参见Chapter10/EDA
,在该章节中我们演示了如何在过滤器中应用校验和地址,以移除无效的以太坊地址。
小数处理
Solidity 是 EVM 区块链中最常用的智能合约编程语言,但它不支持浮动数值。为了在 Solidity 中表示小数,我们使用整数。在 Jupyter Notebook 中的 Chapter04/Art
部分,在 Chainlink 小节中,我们可以看到来自预言机的响应是以以下方式表示的:
https://github.com/OpenDocCN/freelearn-ds-pt4-zh/raw/master/docs/ds-web3/img/B19446_06_04.jpg
图 6.4 – Chainlink 底价响应
这样大的数字在经济学背景下没有意义,无法直接包含在仪表盘或报告中。因此,有必要将其转换为我们的十进制系统,使其更具实用性。
智能合约通过特定的函数提供小数位数。在 Chainlink 的数据馈送智能合约中,decimals()
函数告知我们定点数,或者在实际应用中,告诉我们应该将小数点向左移动多少位才能将响应转换为我们的十进制系统。在第二章 探索状态数据 一节中解释了如何查询智能合约,正如 Jupyter Notebook 中所展示的,结果是 18
:
https://github.com/OpenDocCN/freelearn-ds-pt4-zh/raw/master/docs/ds-web3/img/B19446_06_05.jpg
图 6.5 – 数据馈送小数
以下图展示了我们可以在数据管道后续部分使用的转换后的数字:
https://github.com/OpenDocCN/freelearn-ds-pt4-zh/raw/master/docs/ds-web3/img/B19446_06_06.jpg
图 6.6 – 结果
通过应用fromWei()
函数,可以按照以下代码片段实现相同的结果:
Web3.fromWei(latestData), \'ether\')
我们刚刚探讨的小数处理方法对于代币也同样适用。decimal()
,它返回代币使用的小数位数,例如 8,这意味着将代币数量除以 100000000(10 的 8 次方)来获得其 用户表示。
更多标准内容已在第五章中进行了分析。
小数位说明
以太坊智能合约最常见的十进制基数是 18,而比特币使用 8,USDT 则使用 6 个小数位。
在本节中,我们了解到,消费链上数据通常需要进行大量转换。如果我们的数据集包含过于庞大的字符串且缺乏经济意义,我们可能需要查找智能合约的十进制值,以正确定位小数点位置。此外,如果我们的数据集包含十六进制值,我们需要将其解码为十进制系统。最后,我们还发现了如何将小写地址转换为校验和地址,以确保与区分大小写的编程语言兼容。
从 Unix 时间戳到日期时间格式
Unix 时间戳在数据分析中常被使用,但为了在仪表盘和报告中进行可视化,需要将其转换为人类可读的格式。Unix 时间表示自 1970 年 1 月 1 日以来已过去的秒数,提供了一种通过单一整数值来追踪时间的系统。
在大多数 SQL 引擎中,可以利用truncate
函数从时间戳中提取相关的日期部分。
在 Python 中,我们可以使用datetime
模块的fromtimestamp()
函数,将 Unix 时间戳转换为本地日期时间,使用utcfromtimestamp()
函数,将其转换为 UTC 日期时间。
在 Jupyter Notebook 的Chapter06/Preparation
部分,我们使用以下代码将 Unix 时间戳转换为日期时间:
https://github.com/OpenDocCN/freelearn-ds-pt4-zh/raw/master/docs/ds-web3/img/B19446_06_07.jpg
图 6.7 – 日期时间转换
为了验证我们的结果,我们可以将其与www.unixtimestamp.com/
网站上的数据进行对比,该工具展示了相同的信息:
https://github.com/OpenDocCN/freelearn-ds-pt4-zh/raw/master/docs/ds-web3/img/B19446_06_08.jpg
图 6.8 – Unix 时间戳转换器
智能合约的演变
智能合约和任何软件产品一样,可能会因为业务需求、安全事件或减少燃气费用等多种原因而发生变化和需要升级。然而,根据设计,区块链上部署的一切都是不可变的。以下信息来自Ethereum.org,概述了多种实现升级的方法。内容引用自创意共享署名 4.0 国际(CC BY 4.0)许可协议,符合使用条款。原文可以在本章的进一步阅读部分找到。
智能合约的升级可以通过以下方式实现:
-
创建多个版本的智能合约,并将状态(即数据)从旧合约迁移到新合约实例
-
创建独立的合约来存储业务逻辑和状态
-
使用代理模式将函数调用从不可变的代理合约委托给可修改的逻辑合约
-
创建一个不可变的主合约,该合约通过灵活的卫星合约执行特定功能
-
使用钻石模式将代理合约的函数调用委托给逻辑合约
总之,升级智能合约的方法并不涉及修改已部署的代码,而是用一个合约替代另一个。目前,升级智能合约最流行的方法是代理模式。这种模式将代理合约和包含逻辑的执行合约分离。代理合约代表逻辑智能合约,将前端的交易重定向到后端正确的智能合约。可以在后端交换逻辑智能合约,并更新代理合约,使其开始将交易重定向到新部署的智能合约,该合约包含最新的逻辑。
合约可能发生变化,这意味着我们的查询需要适应这些变化。例如,如果一个智能合约在某个区块开始触发事件,我们需要意识到这一点,以便捕捉新的信息。正如我们在第二章中看到的,我们需要应用程序二进制接口(ABI)来解码智能合约,这些合约需要在升级后适当地更新以解码交易。如果我们没有意识到正在解析的合约已经发生了变化,可能会错过某些事件,并且可能对我们的分析产生负面影响。
在分析具体项目时,重要的是要关注新闻发布、项目代表和官方信息渠道,了解是否有任何新开发,这样我们可以将查询指向更不容易变动的智能合约。
总之,尽管智能合约设计为不可更改,但在某些情况下,升级和更改变得必要,我们需要做好准备,调整我们的查询或代码以适应这些变化。例如,如果我们正在分析以太坊,我们需要意识到整个区块链在 2022 年 9 月的合并(Merge)后发生了变化,并且这种变化会在数据层面产生影响。
探索性数据分析
在数据清洗阶段和建模或正式统计分析之间,存在一个中间步骤,称为 EDA,这是数据科学的一个基本方面。EDA 作为理解和解释数据集的主要方法,提供了关于“样本之外的总体”的洞察,并将原始数据转化为可供企业使用的可操作信息。EDA 可以包括多种技术和方法:
-
数据摘要或描述性统计:用于总结数据集中的中心趋势。
-
数据可视化:采用直方图、箱形图、散点图和折线图等图形技术来可视化数据,帮助识别模式、检测异常值,并理解变量之间的关系。此外,数据可视化在向非技术性观众展示结论时特别有效。
-
数据探索:帮助我们理解变量的分布,评估其形态和偏斜度,识别异常的存在。
-
处理缺失数据:这使我们能够识别缺失的行并评估它们对结果的影响。它有助于确定缺失值的模式,并制定有效处理它们的策略。
-
异常值检测:识别与数据集其他部分显著偏离的值,并评估其对分析的影响。这些异常值可能来自多种原因,我们将在后续部分讨论这些原因。
-
相关性和模式:通过相关分析和散点图等技术,探索变量之间的关系。此外,它们有助于识别数据随时间变化的趋势或季节性。
有关 EDA 的简要描述可以在towardsdatascience.com/exploratory-data-analysis-8fc1cb20fd15
找到:“探索性数据分析是指对数据进行初步调查,以发现模式、识别异常、测试假设和检查假设,借助于汇总统计和 图形表示法。\"
在本章中,我们将简要介绍汇总统计和利用图形表示法进行异常值检测。我们选择这两个主题,因为它们可能适用于我们在旅程中遇到的所有数据集。有关 EDA 主题的进一步探索,欢迎参考进一步阅读部分中的书籍,它们非常有用。
为了举例说明本节中学到的概念,我们将使用 Kaggle 上提供的Witches数据集(www.kaggle.com/datasets/harrywang/crypto-coven?select=witches.csv
)。该数据集包含关于 Crypto Coven NFT 项目的信息,每一行代表一个女巫 NFT。Witches 项目的主页可以在www.cryptocoven.xyz/
找到。
数据汇总
我们的数据集将包含分类变量或定量变量。分类变量是指可以分为组的变量,例如颜色或品牌。另一方面,定量变量代表数值量,例如价格或销售数量。df.describe()
代码片段返回定量变量及其分布情况。
计算分类数据的分布涉及确定每个类别的频率。这种分析可以提供有意义的见解。例如,在市场营销中,理解年龄组、收入水平或消费者偏好等分类变量的分布可以帮助企业有效地细分目标受众,并制定更具针对性和成功的营销活动。另一个例子是在欺诈检测中,分类变量如交易类型或用户行为模式在识别欺诈活动中至关重要。通过研究这些变量的分布,可以识别出异常或不寻常的模式,从而使组织能够开发出有效的欺诈检测模型和策略。
在 NFT 领域中的一个应用是帮助确定一个系列是由零售公众拥有,还是由少数收藏者(集中化)持有。关于艺术品收藏的所有权特征的了解,可以帮助投资者评估项目价格是否与市场价值一致,或者是否容易受到操控。更加去中心化的所有权结构意味着价格更接近市场价值。
在Chapter06/EDA.ipynb
中,我们通过创建两类持有者来研究 NFT 的分布:那些拥有超过三个同系列 NFT 的地址,我们称之为收藏者,以及那些持有少于三个 NFT 的地址,也就是普通公众。我们遵循三个步骤:
-
我们统计每个地址持有的 NFT 数量,相当于 SQL 查询中的
GROUP BY
操作。这使我们能够了解每个地址的持有情况。 -
我们创建了一个地址列表,这些地址持有来自同一系列的超过三个 NFT。每个地址持有的 NFT 数量是我们分析的一部分,也是我们在 EDA 过程中做出的决策。这些微小的决策会影响最终结果,文档化它们是一个良好的实践。
-
我们根据地址是否在步骤 2 的列表中,分别构建
collectors_df
和distributed_df
数据集。
通过这些简单的步骤,我们可以计算项目中收藏者和分布所有者的百分比。图 6.9 显示,收藏者的百分比只有 32%,而其余的 68% 是由公众持有的。
https://github.com/OpenDocCN/freelearn-ds-pt4-zh/raw/master/docs/ds-web3/img/B19446_06_09.jpg
图 6.9 – 收藏者和分布百分比
为了总结定量变量,我们引入了均值、平均值、偏差、异常值等概念。我们从集中趋势或总结性统计量开始,它们用于用单一的数值来描述一组值。这些统计量包括均值、中位数和众数。
平均数,即算术平均数,是最常用的度量方式。它是通过将数据集中所有值相加,并除以值的个数来计算的:
Formula: Mean = (Sum of all values) / (Total number of values)
例如:如果我们的值是 5
、7
、2
、10
和 6
,则平均数为 (5 + 7 + 2 + 10 + 6) / 5 = 6。
Pandas 提供了 mean()
函数,它返回传递给列的均值。如果我们计算 Witch 数据集中的价格均值,我们将所有价格相加,然后将结果除以行数。请参见 Chapter06/EDA.ipynb
中的以下代码片段,我们在其中计算了 price
列的均值:
df[\'price\'].mean()
计算均值时,所有值都会被考虑在内,但计算出的数值可能不在分析的样本中。另一个重要的方面是,均值受到异常值的强烈影响。因此,在计算均值之前,需要清理数据集并删除异常值。
当数据存在偏斜时,均值并不是集中趋势的完美度量。一个更好的替代方案是中位数。
中位数被定义为按大小顺序排列后的列的中间值,从最小到最大。要手动计算中位数,我们可以按照以下步骤进行:
-
将
price
列中的所有值从小到大排序。 -
找到位于数据集中心的数值,将数据集分成两部分:
公式(奇数个值):中位数 =
中间值
公式(偶数个值):中位数 = (两个中间值的总和)/ 2
例如:对于数据集
5
、7
、2
、10
和6
,当按升序排列时,中位数将是 6。
Pandas 提供了 median()
函数来执行这个计算。例如,要计算 price
列的中位数,我们可以使用以下代码片段,这也显示在 Chapter06/EDA.ipynb
中:
df[\'price\'].median()
在处理偏斜数据或存在异常值的数据时,中位数通常优于均值。
在 Chapter04/Art.ipynb
中,当总结数据以寻找多个市场在一段时间内的最低价格时,我们选择显示中位数而不是平均值,结果如下:
https://github.com/OpenDocCN/freelearn-ds-pt4-zh/raw/master/docs/ds-web3/img/B19446_06_10.jpg
图 6.10 – 按市场划分的中位数最低价格
如果我们使用平均值,图形将显示市场之间的显著差异,如图 6.11 所示。基于平均值分析地板价格并不准确,特别是当我们提到 OpenSea 报价时。
https://github.com/OpenDocCN/freelearn-ds-pt4-zh/raw/master/docs/ds-web3/img/B19446_06_11.jpg
图 6.11 – 各市场的平均地板价格
众数是另一种集中趋势的度量,表示数据集中最频繁出现的值。从图形上讲,它由直方图中最高的柱形表示。它也可以与分类变量一起使用。要手动计算众数,我们需要识别数据集中最常出现的价格:
Formula: No specific formula
例如,在 15
、20
、18
、22
、15
、20
、18
、20
、22
和 25
的数据集中,出现频率最高的值是 20\\。它出现了三次。
Pandas 提供了 mode()
函数来计算某列的众数,如 Chapter06/EDA.ipynb
中的以下代码片段所示:
df[\'price\'].mode()[0]
缺失价格的说明
集中趋势的度量不仅有助于总结我们的数据集,还能帮助解决数据集中的缺失值问题。
例如,在极端波动期间,某些交易所可能会暂停商业化。这适用于传统市场和集中化的加密货币交易所。如果我们的数据库恰好从这种交易所获取价格数据,可能会出现缺失的数据行。在这种情况下,可以使用 pandas 函数,如 fillna()
或 interpolate()
,来填充缺失值。使用 fillna()
函数,我们可以指定是否用均值或中位数来填充 NaN 值。
总之,在我们的 EDA 中,我们探讨了集中趋势的度量方法,如均值、中位数和众数,这些方法提供了关于我们数据分布和特征的洞察。
在我们探讨集中趋势的基础上,现在我们将注意力转向异常值检测。异常值是偏离数据集整体模式的数据点,它们可能对我们的分析和解释产生重大影响。在接下来的部分中,我们将深入研究识别异常值的各种技术和方法。
异常值检测
根据 Rafael A. Irizarry 的《数据科学导论》一书,异常值被定义为 “与集中趋势相差较远的数据样本”。虽然异常值本身既不一定是好也不一定是坏的,但它们可以显著影响我们的分析,并导致不正确的结论。特别是在处理价格时,市场波动性可能会扭曲交易资产的真实价值。价格作为价值的代理,但重要的是要认识到,有些价格显著偏离实际价值,成为异常值。
在某些情况下,主要目标是识别和分析异常值,这通常是异常检测技术的重点,例如在第四章中讨论的技术,特别是用于揭露欺诈或洗钱。
异常值出现的原因有多种:
-
仪器测量误差,如 API 断开或不平衡的秤
-
数据录入错误
-
处理的样本或群体比最初假设的要不均匀
让我们探索一些识别数据集异常值的技巧:
- 箱线图(胡须图):这种图形表示法通过五个重要数字总结数据:最小值、第一个四分位数、中位数、第三个四分位数和最大值。我们可以将远离箱体的数据点识别为异常值:
https://github.com/OpenDocCN/freelearn-ds-pt4-zh/raw/master/docs/ds-web3/img/B19446_06_12.jpg
图 6.12 – 箱线图的部分
这张图像可以通过以下代码片段由 Pandas 自动生成:
Chapter06/Outliers).* `df.quantile()` function. Once we have them, we can calculate other parts of this formula. In `Chapter05/Outliers`, we calculate the IQR, bottom, and upper limits in this part of the code:<https://github.com/OpenDocCN/freelearn-ds-pt4-zh/raw/master/docs/ds-web3/img/B19446_06_13.jpg>Figure 6.13 – Calculation of IQR and limitsThe 1.5 multiplier is common practice but can be adjusted to adapt to our case.* **Three-sigma rule** (**Z-score**): The three-sigma rule states that 99.7% of data falls within three standard deviations (three-sigma) of the mean in a normal distribution. This rule is used for outlier detection because data points outside the three sigmas can be considered outliers. This method uses the mean as a starting point, which can be influenced by outliers. A more robust modified Z-score method can be employed, which incorporates the median and median absolute deviation in its formula. The metric is a statistical measure that helps identify outliers in a dataset by comparing each data point to the median and median absolute deviation. It provides a robust way to detect extreme values, especially in datasets with skewed distributions.SummaryThis chapter has addressed various preparation methods applicable to on-chain data scenarios. We explored techniques such as unhexing data, decimal treatment, handling checksum addresses, and converting Unix timestamps to datetime formats. These methods have proven foundational in preparing the on-chain data for subsequent analysis.Moreover, we introduced the concept of EDA as a crucial step in understanding and summarizing datasets, with a specific focus on central tendency metrics. Additionally, we delved into outlier detection techniques, such as box plots and the IQR method, aiding in the identification of extreme observations deviating significantly from the majority of the data.By applying these cleaning and EDA techniques, we have equipped ourselves with essential tools for the effective analysis and interpretation of on-chain data. These foundational concepts serve as building blocks for more advanced techniques and methodologies as we continue this journey. For more insights into these methodologies, please refer to the *Further* *reading* section.Further readingThe following links may help to complement this chapter:* Technical requirements: * *10 minutes to pandas, pandas 1.5.3 documentation, pandas - Python Data Analysis* *Library:* https://pandas.pydata.org/docs/user_guide/10min.xhtml#min* Evolution of smart contracts: * *Upgrading Smart Contracts,* *ethereum.org:* [`ethereum.org/en/developers/docs/smart-contracts/upgrading/`](https://ethereum.org/en/developers/docs/smart-contracts/upgrading/)* Exploratory Data Analysis: * *Introduction to Data Science: A Python Approach to Concepts, Techniques and Applications,* Laura Igual, Santi Seguí, Springer * *Three Ways to Detect Outliers, Colin Gorrie, Colin Gorrie’s Data* *Story:* [`colingorrie.github.io/outlier-detection.xhtml#modified-z-score-method`](https://colingorrie.github.io/outlier-detection.xhtml#modified-z-score-method) * *Python for Data Analysis: Data Wrangling With Pandas, NumPy, and Jupyter,* Wes McKinney, O’Reilly Media * *Box Plot Review, Khan* *Academy:* [`www.khanacademy.org/math/statistics-probability/summarizing-quantitative-data/box-whisker-plots/a/box-plot-review`](https://www.khanacademy.org/math/statistics-probability/summarizing-quantitative-data/box-whisker-plots/a/box-plot-review) * *Hands-On Exploratory Data Analysis With Python: Perform EDA Techniques to Understand, Summarize, and Investigate Your Data,* Usman Ahmed, Suresh Kumar Mukhiya, O’Reilly Media*:* [`www.packtpub.com/product/hands-on-exploratory-data-analysis-with-python/9781789537253`](https://www.packtpub.com/product/hands-on-exploratory-data-analysis-with-python/9781789537253) * *The Data Science Design Manual,* Steven Skiena, Springer* Cleaning: * *RSK* *Explorer*: [`explorer.rsk.co/blocks`](https://explorer.rsk.co/blocks) * *More on Time on the Blockchain, Nick Furneaux, Wiley*, *Chapter 9*, Investigating Cryptocurrencies, Understanding, Extracting, and Analyzing Blockchain Evidence, Page 156 to Page 161
第七章:机器学习与深度学习入门
在应用任何机器学习算法之前,全面理解数据集及其关键特征至关重要。这种理解通常通过探索性数据分析(EDA)得出。一旦熟悉了数据,我们必须投入时间进行特征工程,这包括选择、转换和创建新的特征(如果需要),以使所选模型能够使用或提升其性能。特征工程可能包括将类别转换为数值、对特征进行缩放或标准化、从现有特征中创建新特征等任务。这个过程针对每个特定的模型和数据集进行定制。一旦这个过程完成,我们就可以开始建模。
本章的目标是回顾机器学习和深度学习的基础概念,为本书的第二部分奠定基础。在第二部分中,我们将深入探讨人工智能在 Web3 数据中的各种应用案例。尽管不会详细介绍每一种可能的模型,但我们将简要描述项目的动机、模型本身以及使用的工具,并提供有价值的参考资料以供进一步阅读。
我们将探讨机器学习和深度学习的主要概念,讨论两个典型的机器学习管道——一个使用 scikit-learn,另一个使用 Keras。此外,我们为本章涵盖的每个主题编写了广泛的进一步阅读部分,以鼓励持续学习。
具体来说,以下主题将被讨论:
-
机器学习和深度学习的基本概念
-
使用 scikit-learn 和 Keras 的机器学习管道
技术要求
我们将使用scikit-learn,这是一个专为机器学习任务设计的流行 Python 库。它提供了数据预处理、特征选择、模型选择和模型评估的算法和工具。
如果你之前没有使用过 scikit-learn,可以通过以下代码片段进行安装:
pip install scikit-learn
scikit-learn 的文档可以在 https://scikit-learn.org/stable/找到。
对于深度学习,我们可以选择使用TensorFlow或Keras。TensorFlow 是一个强大的开源数值计算库,提供训练、测试和部署各种深度学习神经网络的解决方案。它作为基础设施层,使得在 CPU、TPU 和 GPU 上进行低级张量操作成为可能。另一方面,Keras 是一个建立在 TensorFlow 之上的高级 Python API。它专为快速实验而设计,并在发现错误时提供有用的反馈。根据 Kaggle 的 2022 年数据科学与机器学习现状调查,Keras 在机器学习开发者和数据科学家中达到了 61%的采用率。
如果你之前没有使用过 TensorFlow 或 Keras,可以使用以下代码片段进行安装:
pip install tensorflowpip install keras
对于深度学习来说,需要大量的计算能力;我们的普通 CPU 可能无法完全胜任任务,导致训练和推理速度较慢。另一种选择是本地或云端运行 GPU——可以通过 Kaggle Kernel 或 Google Colab 进行托管。它们有类似的用户界面,结构上类似于 Jupyter notebook,使得在这些平台上运行仓库中的代码变得更加容易。
你可以在本书的 GitHub 仓库中找到本章的所有数据和代码文件,地址为github.com/PacktPublishing/Data-Science-for-Web3/tree/main/Chapter07
。我们建议你阅读Chapter07
文件夹中的代码文件,跟随学习。
引入机器学习
计算机科学维基提供的机器学习定义是“一个致力于理解和构建能够‘学习’的方法的研究领域——也就是利用数据来提高某些任务表现的方法。它被视为人工智能的一部分。机器学习算法基于样本数据(称为训练数据)构建模型,从而在没有明确编程指令的情况下进行预测或决策。”
(来源:computersciencewiki.org/index.php/Machine_learning
)
杰森·布朗利教授将深度学习定义为“一种受大脑结构和功能启发的机器学习子领域,称为人工神经网络。”深度学习与其他机器学习方法的区别在于,它以人工神经网络为基础进行方法设计。
这两个领域之间的关系通常表示如下:
https://github.com/OpenDocCN/freelearn-ds-pt4-zh/raw/master/docs/ds-web3/img/B19446_07_01.jpg
图 7.1 – 人工智能的维恩图
让我们进一步分析机器学习的定义:
-
机器学习模型根据我们提供的数据创建自己的规则,正如“理解并构建能够学习的方法”以及“在没有明确编程指令的情况下进行预测或决策”这两句话所述。之前,我们在查询中使用了过滤器,或在程序中使用了if 语句。使用机器学习,特别是监督学习时,我们输入数据,让模型推断出规则。在《Python 数据科学手册》中,作者挑战了模型自动学习的观点,而是建议模型通过适应观察到的数据来调节我们提供的参数。一旦它将这些参数与已知数据进行拟合,就能根据未见过的数据推断出结果。
-
“机器学习算法基于样本数据构建模型,这些数据称为训练数据。” 传递给机器学习算法的数据需要至少分为两部分:训练数据和测试数据。训练数据集用于构建模型,测试数据集用于评估模型在未见过的数据上进行预测的能力。然后将模型的预测与真实数据进行比较,并计算评估指标。
机器学习技术可以分为监督学习、无监督学习和强化学习。通过机器学习技术解决的常见任务如图 7.2所示:
https://github.com/OpenDocCN/freelearn-ds-pt4-zh/raw/master/docs/ds-web3/img/B19446_07_02.jpg
图 7.2 – 机器学习应用
监督学习的目标是创建一个可以将输入映射到输出的函数,从而使模型能够根据未见过或相似的输入推断输出。在这个过程中,我们使用特征来描述变量的特性,标签或标记来识别预测的变量。通过这一过程,我们的模型能够学习特征与标签或标记之间的关系。
在 Web3 分析中,标签起着至关重要的作用,因为它使我们能够为那些由数字和字母组成、与外部世界没有直接联系的地址赋予身份。然而,创建一个标记地址库可能是一个挑战,最近,这已经成为一家名为 Arkham 的公司的业务,该公司通过公开数据激励“去匿名化区块链”。标记地址是像 Nansen 这样的公司主要的杠杆之一,它们在以太坊及其他链上标记了数百个地址,推动了机器学习技术和数据分析报告的进展。
标签也可以在 Etherscan 中找到,重要的项目会标记其地址以便进行公开审计。此外,Dune 和 Flipside 也有带标签的表格,研究团队在其中添加了相关信息,以帮助查询。如果你想了解更多关于身份归属的知识,可以参考 Nick Fourneaux 在《调查加密货币》一书中的方法,教你如何从论坛或软件下载网站提取地址,下载 HTML 原始文本,并执行正则表达式分析。
监督学习可以进一步分为回归和分类技术。在分类技术中,我们有一组离散的类别作为标签(例如欺诈交易或非欺诈交易)。在回归中,我们有定量标签,例如 NFT 艺术品或代币的价格。
无监督学习的目标是尝试识别数据集中可能不显式的结构或模式。无监督学习下的任务通常包括以下几种:
-
聚类 – 即在给定的数据集中识别出不同的群体
-
降维 —— 即,尝试用更少的特征表示数据集
-
新颖性检测 —— 即,尝试识别数据中何时发生变化
强化学习通过利用模型已知的信息以及通过与环境互动后获得的累计奖励来教导模型寻找问题的最佳解决方案。模型通过环境反馈(奖励或惩罚)来进行调整,目标是最大化总奖励。强化学习的核心思想是模仿人类通过试错学习的方式:
https://github.com/OpenDocCN/freelearn-ds-pt4-zh/raw/master/docs/ds-web3/img/B19446_07_03.jpg
图 7.3 – 智能体-环境循环(改编自 gymnasium.farama.org/content/basic_usage/
)
为了使一个项目变得生动起来,必须执行一些初步的业务/数据步骤:
-
定义一个 Web3 数据科学问题意味着精确地阐明我们希望用现有数据解决的问题。在这样的定义中,我们必须能够描述我们要解决的问题,为什么要解决它,以及我们所考虑的假设。
-
获取数据意味着获取我们将要处理的数据集。数据集可能已经包含了所有相关的行和列,或者我们需要通过结合多个数据源来构建它。初步的数据源列表列在第二章和第三章中。根据我们要解决的问题,可能需要更多的数据源。
-
EDA 用于通过总结统计和数据可视化技术来理解数据集。数据准备是一个预处理步骤,在这个步骤中,我们转换数据集以提高其质量或使其更容易为模型消化。链上数据可能需要大量的转换。我们在第六章中分析了一些这些方法。
现在,让我们分析选择、训练和评估模型的步骤。
构建机器学习流程
在清理数据并选择最重要的特征后,机器学习流程可以概括为以下几个步骤,如图 7.4所示:
https://github.com/OpenDocCN/freelearn-ds-pt4-zh/raw/master/docs/ds-web3/img/B19446_07_04.jpg
图 7.4 – 机器学习流程
要执行这个过程,我们必须进行以下操作:
-
根据问题和可用数据选择一个模型及其初始参数。
-
训练:首先,我们必须将数据分割成训练集和测试集。训练过程包括让模型从数据中学习。每个模型的训练过程在时间和计算消耗上可能有所不同。为了提高模型的性能,我们必须通过超参数调整技术(如网格搜索或随机网格搜索)来优化模型。
-
预测和评估:然后,使用训练好的模型对测试集进行预测,测试集包含算法未曾见过的数据行。如果我们使用训练数据评估模型,模型总是能够预测得很好,那么我们就无法进一步改进它。模型的表现通过特定任务的评估指标来评估。
当我们得到一个良好的模型时,必须保存它,以便在接收到未见数据时使用它。我们可以使用Pickle和Keras Tokenizer等工具来实现这一点。Pickle 将训练好的模型序列化并转换为文件,使其能够在另一个环境中使用。为了产生结果,我们必须传递结构相同的数据,使模型能够进行预测。
让我们通过一个实际示例来应用这个流程。在Chapter07/ML_warmup
中,我们的目标是使用一个名为以太坊欺诈检测数据集的 Kaggle 数据集,识别以太坊网络上的欺诈交易,其中只有 17%的行是欺诈的。这是一个典型的监督分类任务。
模型
根据手头的问题,我们必须选择一个或多个模型进行测试,以判断哪个模型在我们的数据上表现更好。如果我们不确定该选择哪个模型,可以查看 Kaggle 上已解决的相似结构问题。在 Jupyter notebook 中,我们选择了一个随机森林分类器,代码片段如下:
random_forest = RandomForestClassifier(random_state=42)
有许多算法可以用于训练,选择可能会很困难。选择多种模型的一种方法是减少可减少的误差。文献通常将这个问题称为偏差-方差权衡。在解决这个权衡之前,我们需要理解存在的不同类型的误差。任何机器学习算法的预测误差可以分为以下几类:
-
噪声或不可减少的误差:这种类型的误差无论我们如何实现模型,都无法消除。
-
偏差误差:这是可以减少的。维基百科将其定义为“由于学习算法中的错误假设而产生的误差”。高偏差的模型过于简化现实,导致预测值和真实值之间存在较大的误差。高偏差模型过度简化,意味着它们没有足够的参数来捕捉它们学习数据的复杂性,导致欠拟合。下一节将详细讨论这一概念。
-
方差误差:这也是可以减少的。维基百科将其定义为“对训练集中的微小波动的敏感性导致的误差”。这意味着模型过于深入地学习了训练数据集的特殊性,以至于无法对未见数据进行有效的泛化。这些模型高度依赖于精确的训练数据,无法做到泛化。当模型在训练数据上表现良好,但在测试/验证数据上表现不佳时,我们就会遇到这个误差,表明存在过拟合问题。
低方差高偏差的算法训练复杂度较低的模型,具有简单或刚性的基础结构 – 例如线性回归。另一方面,高方差低偏差的算法训练复杂、灵活的模型,可以在训练数据上准确,但在预测中不一致 – 例如 KNN。
如果我们理解了偏差和方差,并认识到两者都源于我们所做的模型选择,为了做出最优决策,我们将选择在两者之间进行总误差的权衡的模型:
https://github.com/OpenDocCN/freelearn-ds-pt4-zh/raw/master/docs/ds-web3/img/B19446_07_05.jpg
图 7.5 – 偏差-方差权衡
选择模型的另一个标准是其性能,这由所选的评估指标来衡量。我们可以运行多个模型,并使用相同的指标评估它们,性能更好的模型将被继续调优。我们将在后续章节讨论评估指标。
在Chapter07/ML_warmup
中,我们选择了随机森林分类器。这种算法旨在减少模型的方差而不损害偏差,并在被称为召回率的评估指标上表现良好。有关随机森林算法的更多信息,请参阅进一步阅读部分。
训练
开始训练过程时,我们将数据分为训练数据集和测试数据集。这样做可以使模型在训练过程中看不到部分数据,并且我们可以在训练后评估其性能:
X_train, X_test, y_train, y_test = train_test_split(X, y,\\ test_size=0.33, random_state=42)
训练过程包括将特征和标签传递给算法,使其从中学习。学习算法将尝试在训练数据中找到模式,将输入数据的属性映射到目标上。训练后的模型捕获这些模式。
在Chapter07/ML_warmup
中,我们使用以下代码片段指导模型学习:
random_forest.fit(X_train, y_train)
欠拟合和过拟合
考虑三种情景,模型由一条黑线表示。哪种情景能更好地进行分类?
https://github.com/OpenDocCN/freelearn-ds-pt4-zh/raw/master/docs/ds-web3/img/B19446_07_06.jpg
图 7.6 – 三种分类情景
让我们理解这些情景:
-
情景 A:模型非常简单,无法捕捉两个类别之间的边界。这被称为欠拟合。
-
情景 B:模型能够找到两类之间可接受的边界,尽管可能会误分类一些边界样本。总体上,它捕捉了数据集的复杂性。
-
情景 C:模型过度适应了训练数据集,并学到了所有细节,而不仅仅是区分一个类别与另一个类别的相关特征。它无法泛化。这被称为过拟合。
https://github.com/OpenDocCN/freelearn-ds-pt4-zh/raw/master/docs/ds-web3/img/B19446_07_07.jpg
图 7.7 – 模型过拟合时的表现(来源:https://twitter.com/MaartenvSmeden/status/1522230905468862464)
我们的目标是场景 B,在这个场景中,模型足够复杂,能够捕捉重要特征,但不会过度适应训练数据,因此在未见过的样本上表现良好。
预测与评估
在这里,我们将未见过的数据传入训练好的模型,并评估它的预测与实际情况的准确性。如果结果可接受,我们会保留模型;否则,我们将调整超参数并重新训练。超参数是在训练过程前设置的变量,在学习过程中不能更改。参数是那些在训练过程中调整的值。
在 Jupyter notebook 中,我们使用以下代码片段进行预测和评估:
y_test_pred = random_forest.predict(X_test)print(classification_report(y_test_pred,y_test))conf_mat=confusion_matrix(y_test_pred,y_test)
为了评估结果是否可接受并决定是否保留模型,我们可以使用二分类任务的混淆矩阵。在 Jupyter notebook 中,我们分析的数据集的混淆矩阵如图 7.8所示:
https://github.com/OpenDocCN/freelearn-ds-pt4-zh/raw/master/docs/ds-web3/img/B19446_07_08.jpg
图 7.8 – 混淆矩阵
让我们来理解混淆矩阵的组成部分:
-
真反例(TN):模型预测为负,并且预测正确。这些交易不是欺诈性的。
-
真正例(TP):模型预测为正,并且预测正确。这些交易是欺诈性的。
-
假反例(FN):模型未能预测,并且它们是欺诈性的。
-
假正例(FP):模型将这些交易标记为欺诈性交易,但它们并非如此。
基于这些数据,我们可以计算精确度和召回率。精确度回答的问题是:我们预测为正的所有类别中,实际为正的有多少?
TP _ TP + FP
我们的精确度是0.91
。
召回率回答的问题是:所有欺诈性类别中,我们的模型正确预测了多少?其公式如下:
TP _ TP + FN
我们的召回率是0.98
。
结果的评估取决于具体问题。正确选择评估指标非常重要,因为它将影响我们后续的决策。在Chapter07/ML_warmup
中,我们的目标是发现欺诈交易,因此我们更看重召回率高于精确度。我们更偏向召回率,因为漏掉一个欺诈交易的成本远高于错误标记一个可能无害的交易。然而,假正例(FP)的数量不能过大,因为这会带来交易成本并影响客户。
现实世界的数据集大多数是不平衡的,这意味着不同类别的样本数量不均衡。我们的任务是应用技术,让模型学习两种类别的存在和特征,特别是当我们试图检测的类别是较少出现的类别时。
关于平衡和不平衡数据集的说明
准确度,即正确预测的百分比,是另一个常用的评估指标。然而,如果数据集不平衡,准确度将无法得出好的结果。如果在不平衡数据集中将准确度作为评估指标,模型只需要识别出多数类,就能返回一个好的结果,这并不能保证这是一个好的模型。
在我们的 EDA(探索性数据分析)中,我们将检查每个类别的比例,并确定我们处理的是平衡数据集还是不平衡数据集。例如,在Chapter07/ML_warmup
中,我们知道欺诈性样本的比例是 17%。
我们可以通过在特征工程预处理步骤中使用过采样或欠采样技术来解决这个问题。必须谨慎进行,因为这可能会改变数据中的潜在关系,或者删除一些关键信息。
我们还可以使用已经为不平衡数据集优化的算法,并允许用户在训练过程中添加这些信息——例如,使用随机森林算法中的class_weight
参数。
此外,我们还可以通过在train_test_split
中使用stratify
来考虑类别的不平衡表示,从而优化拆分过程。
引入深度学习
在本书的第二部分中,我们在解决用例时也将使用深度学习方法。深度学习模型采用多个互联的节点(称为神经元),这些神经元处理输入数据,并基于学习到的权重和激活函数产生输出。神经元之间的连接促进了信息流动,网络的架构决定了信息如何被处理和转化。
我们将在各自的章节中详细研究三种神经网络架构。现在,让我们先介绍一下我们将在这些章节中使用的框架和术语。
神经元作为系统的基本构建单元,可以定义为一个节点,具有一个或多个输入值、权重和输出值:
https://github.com/OpenDocCN/freelearn-ds-pt4-zh/raw/master/docs/ds-web3/img/B19446_07_09.jpg
图 7.9 – 神经元的结构
当我们将多个具有这种结构的层叠加在一起时,它就形成了一个神经网络。这种架构通常由输入层、隐藏层和输出层组成:
https://github.com/OpenDocCN/freelearn-ds-pt4-zh/raw/master/docs/ds-web3/img/B19446_07_10.jpg
图 7.10 – 神经网络结构
输入层启动网络并将数据传递给隐藏层,隐藏层对特征和模式进行计算。隐藏层越多,执行的计算就越复杂。
输出层接收来自隐藏层的处理信息,并提供一个总结网络内已处理信息的结果或输出。
节点之间的连接包含权重,这些权重携带有关如何解决特定问题的信息。在模型训练过程中,我们调整这些权重以使模型适应我们的数据集。这些权重代表了模型的可学习参数。
这个灵活的结构允许用户调节多个超参数,以增强模型的表现。基本原理如下:
-
学习率:这个超参数控制模型在响应权重更新时的变化程度。找到正确的学习率非常重要,因为过小的学习率可能会导致训练过程过长,而较高的学习率可能会导致次优的权重集合和结果变化。学习率与优化器密切相关。
-
激活函数:这些函数决定神经元是否应该被激活,即它们决定神经元对网络的输入是否对预测过程重要,通常通过简单的数学运算来实现。激活函数从每层输入的值中得出输出。Keras 中的激活函数列表可以在
keras.io/api/layers/activations/
找到。 -
损失函数:这些函数量化了预测值与期望值之间的误差,将模型的表现总结为一个需要在训练过程中最小化的单一值。损失函数的选择取决于所解决的问题,常见的例子包括回归任务中的均方误差和分类任务中的交叉熵。Keras 列出了各种损失函数,详情请见
keras.io/api/losses/
。 -
优化器:这些算法通过调整神经网络的属性来帮助改善模型的表现。它在架构中的职责是调整学习率和神经元的权重,以达到损失函数的最小值。Keras 支持的优化器列在此:
keras.io/api/optimizers/
。 -
训练轮数:这表示算法遍历整个数据集的次数。
-
批量大小:指的是用于更新模型参数的样本数量。批量大小为N意味着将使用训练数据集中的N个样本来更新模型参数。请记住,这些样本会保存在内存中,因此更高的批量大小需要更多的内存。
我们使用的所有模型都将在 Keras 框架下进行分析,Keras 具有出色的文档。
模型准备
在Chapter07/DL_warmup
中,我们将使用与上一节相同的数据集——以太坊欺诈检测数据集。这一次,我们将选择更少的列,并使用RobustScaler()
来自 sklearn 对数字进行标准化。
与所有预测问题一样,我们希望通过train test
split ()
将测试集和训练集分开。
模型构建
我们将使用 Keras 创建一个顺序模型。顺序模型的结构由相同或不同的层堆叠而成,其中一层的输出进入另一层。
以下代码片段设置输入层,期望输入具有与数据集列数相同的行数据。在这种情况下,我们只处理 11 列数据:
model.add(Input(shape=(X_train.shape[1],)))
我们添加了三层隐藏层,每一层的节点数逐渐减少。所有这些层都使用relu
作为激活函数。Dense
层是一个全连接层,是多种类型层之一,例如卷积层
或LSTM
层:
model.add(Dense(30, activation=\'relu\'))model.add(Dense(10, activation=\'relu\'))model.add(Dense(5, activation=\'relu\'))model.add(Dense(1, activation=\'sigmoid\'))
由于这是一个二分类任务,在最后一层,我们将使用sigmoid
激活函数和输出层中的1
:
model.add(Dense(1, activation=\'sigmoid\'))
在训练模型之前,需要通过优化器、损失函数和评估指标来编译模型。编译器配置学习过程。值得一提的是,由于这是一个不平衡的数据集,我们关心的是精确度和召回率,因此我们必须利用keras
库来构建评估指标,具体如下:
metrics = [ keras.metrics.Precision(name=\"precision\"),\\ keras.metrics.Recall(name=\"recall\"),]
现在,我们必须将其添加到编译器中:
model.compile(optimizer=keras.optimizers.Adam(1e-2), \\ loss=loss_function, metrics=metrics)
训练和评估模型
一旦模型构建完成,我们需要将数据集输入模型进行训练。这是通过fit()
来完成的,在本例中,我们决定训练 90 个 epoch。
一旦完成训练,就需要通过预测未参与训练的数据来评估模型。我们可以使用X_test
和y_test
来实现这一点。
分类报告显示,少数类的召回率为 95%,这一结果非常好。通过更多的数据预处理,应用针对不平衡数据集的技术以及超参数调优,我们可以进一步提高结果。
在这个特定的练习中,Python Zen的原则之一得到了完美应用。简单优于复杂 —— 一个更简单的机器学习模型表现优于复杂的神经网络。
现在我们已经探讨了这两种方法,我们将重点介绍每个领域的附加特征:
表 7.1 – 机器学习与深度学习的区别
关于人工智能的伦理和社会影响的提示
关于伦理和社会影响的讨论可能离我们的日常工作较远,但考虑到我们的项目通常在商业环境中展开,因此建议考虑其更广泛的影响。机器学习和深度学习的伦理与社会影响涵盖了多个方面,包括以下内容:
偏差:与偏差误差类似,机器学习模型可能继承训练数据中的偏差,进而导致歧视性结果。偏差可以在机器学习生命周期的各个阶段引入,从数据收集到模型部署。为了训练我们的模型,获取无偏的数据非常重要,并且应定期审计模型以检测并修正偏差。
透明性:复杂机器学习模型的不透明性给监管机构带来了挑战,可能削弱用户的信任。许多 DeFi 项目正在积极寻求监管批准,以促进资金从传统银行体系流向 DeFi 世界。鉴于金融领域的高度监管性质,在该领域工作的数据科学家必须努力提升模型的可解释性,并向监管机构提供决策的解释。
解决这些伦理问题需要一个多学科的方式,涉及技术开发者、政策制定者、伦理学家等。作为从事模型工作专业人士,我们需要牢记这些挑战,尤其是在选择数据集、进行数据预处理或在现实世界中评估模型结果时。
摘要
在本章中,我们深入探讨了人工智能的基本概念,这将为我们在本书第二部分中的旅程奠定基础。我们探讨了包括监督学习、无监督学习和强化学习在内的各种任务类型。通过一个实践示例,我们深入了解了典型的机器学习过程,包括模型选择、训练和评估。
在本章中,我们获得了与机器学习中常见挑战相关的基本知识,如在模型欠拟合和过拟合之间找到正确的平衡,存在不平衡数据集,以及哪些评估指标适用于训练过这些数据集的模型。理解这些概念对于任何成功的机器学习项目至关重要。
此外,我们深入学习了深度学习的基础知识,使用 Keras 探索了神经网络的关键组件。此外,我们实现了一个流程来处理一个监督学习问题,亲自体验了所有概念的应用。
在下一章,我们将讨论一个重要的话题——情感分析。
进一步阅读
想要了解更多本章涵盖的主题,请参考以下资源:
-
定义:
-
Igual, L. 和 Seguí, S. (2017). 数据科学导论:基于 Python 的概念、技术和应用方法。Springer。
-
Ertel, W. (2018). 人工智能导论。Springer。
-
Skansi, S. (2018). 深度学习导论:从逻辑演算到人工智能。Springer。
-
Ian Goodfellow, Yoshua Bengio, 和 Aaron Courville. (2016). 深度学习。可在
www.deeplearningbook.org/
查阅。 -
Chollet, F. (2017). 使用 Python 进行深度学习。Manning 出版公司。
-
Müller, A. C. 和 Guido, S. (2016). 使用 Python 进行机器学习导论:数据科学家指南。O’Reilly Media 出版社。
-
VanderPlas, J. (无日期)。什么是机器学习? Pythonic Perambulations。可在
jakevdp.github.io/PythonDataScienceHandbook/05.01-what-is-machine-learning.xhtml
查阅。 -
什么是深度学习?:
machinelearningmastery.com/what-is-deep-learning/
。 -
从网站挖掘地址:Furneaux, Nick. 研究加密货币, 第九章。理解、提取和分析区块链证据,Wiley,2018 年。第 125 页。
-
James, G., Witten, D., Hastie, T., 和 Tibshirani, R. (2022). 统计学习导论:应用篇。R. Springer 出版社。
-
Gymnasium 文档:
gymnasium.farama.org/
。 -
Introduction – Spinning up 文档。(无日期)。欢迎来到深度强化学习中的 Spinning Up!Spinning Up 文档。可在
spinningup.openai.com/en/latest/user/introduction.xhtml#what-this-is
查阅。 -
Nansen 钱包标签与表情符号:它们是什么意思? (2023 年 3 月 14 日)。Nansen – 加密货币、DeFi 和 NFT 分析。可在
www.nansen.ai/guides/wallet-labels-emojis-what-do-they-mean#alpha-labels
查阅。
-
-
流水线:
-
EliteDataScience. (2022 年 7 月 8 日). 什么是偏差-方差权衡?(信息图表)。可在
elitedatascience.com/bias-variance-tradeoff
查阅。 -
Sklearn.ensemble.RandomForestClassifier。(无日期)。scikit-learn。检索于 2023 年 3 月 14 日,网址
scikit-learn.org/stable/modules/generated/sklearn.ensemble.RandomForestClassifier.xhtml
。 -
SMOTE 过采样。(无日期)。机器学习精通。可在
machinelearningmastery.com/smote-oversampling-for-imbalanced-classification/
查阅。 -
Nyuytiymbiy, K. (2022 年 3 月 28 日). 机器学习与深度学习中的参数与超参数。Medium。可在
towardsdatascience.com/parameters-and-hyperparameters-aa609601a9ac
查阅。 -
Chapter07/ML_warmup
中的热力图:T, D. (2019 年 7 月 25 日). 混淆矩阵可视化。Medium。可访问medium.com/@dtuk81/confusion-matrix-visualization-fc31e3f30fea
。 -
在 Colaboratory 中使用 Kaggle 数据集的教程。跟随
Chapter07/ML_warmup
的内容非常有用:Gupta, K. (2022 年 8 月 24 日). 如何将 Kaggle 数据集加载到 Google Colab 中? Analytics Vidhya。可访问www.analyticsvidhya.com/blog/2021/06/how-to-load-kaggle-datasets-directly-into-google-colab/
。 -
Pramoditha, R. (2022 年 1 月 26 日). 如何选择神经网络的激活函数。Medium。可访问
towardsdatascience.com/how-to-choose-the-right-activation-function-for-neural-networks-3941ff0e6f9c
。 -
Gupta, A. (2022 年 5 月 24 日). 深度学习优化器的全面指南。Analytics Vidhya。可访问
www.analyticsvidhya.com/blog/2021/10/a-comprehensive-guide-on-deep-learning-optimizers/
。 -
PEP 20 – Python 之禅。(2022 年 3 月 15 日). PEP 0 – Python 增强提案(PEPs)索引 | peps.python.org。可访问
peps.python.org/pep-0020/
。 -
Keras 团队。 (2020 年 4 月 17 日). Keras 文档:不平衡分类:信用卡欺诈检测。Keras:深度学习工具。可访问
keras.io/examples/structured_data/imbalanced_classification/
。 -
Ramchandani, P. (2021 年 4 月 10 日). 随机森林与偏差-方差权衡。Medium。可访问
towardsdatascience.com/random-forests-and-the-bias-variance-tradeoff-3b77fee339b4
。 -
使用贝叶斯优化调优:Rendyk. (2023 年 8 月 17 日). 调整神经网络深度学习的超参数和层次结构。Analytics Vidhya。可访问
www.analyticsvidhya.com/blog/2021/05/tuning-the-hyperparameters-and-layers-of-neural-network-deep-learning/
。 -
如何在 Python 中使用 Keras 进行深度学习模型的网格搜索超参数。(2022 年 8 月)。机器学习精通。可访问
machinelearningmastery.com/grid-search-hyperparameters-deep-learning-models-python-keras/
。
-
第八章:情感分析 – 自然语言处理(NLP)与加密新闻
自然语言处理(NLP)属于人工智能领域,致力于计算机对文本的理解。近年来,随着如 ChatGPT 等工具的出现,NLP 已经成为我们日常生活中不可或缺的一部分。然而,金融行业已经在相当长一段时间里利用 NLP,尤其是在基本面分析方面。
基本面分析旨在根据公开可得的信息确定资产的内在价值,如股票、代币或 NFT 艺术作品。在传统金融中,文本数据来源于定期向美国证券交易委员会(SEC)提交的报告(如 10K 表格或 10Q 表格),包括财务报表、专业媒体新闻、社交媒体平台如 X(前身为 Twitter)以及其他渠道。Web3 创造了一个类似的环境,市场活动持续不断,X 和新闻平台成为主要的文本资源。值得注意的是,虽然大多数 Web3 公司目前可能还没有义务提交监管报告,但这些数据源最终有可能会成为大多数公司可以获取的资源。
自然语言处理在金融领域的应用涵盖了多个方面,包括以下内容:
-
情感分析:确定文本的积极性、消极性或中立性,这些文本可能是新闻文章、社交媒体帖子(推文、Reddit 等)等。这些算法还可以提供关于情感极性和主观性的见解,帮助评估对公司、行业、市场、政府决策、加密货币发展等的情感。
-
主题建模:帮助根据文档所涵盖的主题对大量财务文档进行分类和组织。这有助于高效管理和访问相关信息。
-
摘要:在一个内容不断产生的世界里,显然没有足够的时间和/或资源去分析和给每个内容排出层次。NLP 技术正被应用于收集并创建简短的文档摘要,方便分析人员处理。
-
欺诈检测:利用 NLP 技术审查电子邮件、聊天记录、财务文件、转录对话等,发掘潜在的欺诈活动模式。
-
交易:将 NLP 工具纳入交易策略中,发出市场趋势的信号或预测,或增强基本面分析交易员的决策过程。
NLP 技术的数据源是被归类为非结构化的文本。我们周围充斥着这样的文本,且每秒钟都会产生更多。在第三章中我们探讨了其中一些文本来源;本章将继续探讨其他文本来源。
在本章中,我们将分析来自 Crypto Panic 的新闻情感。为此,我们将构建一个神经网络(NN),并解释预训练嵌入的概念和使用方法。我们将使用加密新闻数据集和传统金融新闻数据集来训练我们的模型。此外,我们还将学习如何为神经网络使用预处理文本的基本知识,以及如何评估此类模型的结果。
在撰写本文时,ChatGPT 已经成为现实。公开的信息揭示了它在一个广泛的多语言语料库上进行了训练,并利用强化学习不断提高其性能。我们将学习如何将 ChatGPT 集成到 Crypto Panic 数据集的情感分析中。这可以作为一个现成的工具来使用,同时我们构建一个专门的语料库来训练我们的模型。
在本章中,我们将覆盖以下主要主题:
-
一种用于情感分析的深度学习管道,包括准备、模型构建、训练和评估阶段。
-
集成 ChatGPT 进行情感分析
技术要求
在本章中,我们将使用 第七章 中介绍的库工具——即 scikit-learn 和 Keras。此外,我们还将使用 NLTK,这是一个 Python 库,对处理人类语言数据非常有帮助。NLTK 包含了一系列模块和函数,使我们能够执行诸如分词、词干提取和词性标注等任务。这个库简化了处理大量文本数据集的过程,使它们能够与机器学习或深度学习模型进行集成。
如果你之前没有使用过 NLTK,可以使用以下代码进行安装:
pip install nltk
nltk
的文档可以在 https://www.nltk.org 找到。另一个在处理文本操作和清理时非常重要的库是 re,即正则表达式的缩写。正则表达式是一串字符,用于定义搜索模式。以下是一个示例:
表 8.1 – “re” 模式示例
re
库提供了使用上述模式的函数和方法。例如,re.sub
将所有与模式匹配的字符替换为指定的字符串。有关函数的完整列表,请访问 https://docs.python.org/3/library/re.xhtml#module-re。
在我们的工作中,我们将使用 Google 的 Colaboratory 平台,该平台已包含核心库的导入。然而,对于特定任务,还需要其他的导入。
你可以在本书的 GitHub 仓库中找到本章的所有数据和代码文件,地址为github.com/PacktPublishing/Data-Science-for-Web3/tree/main/Chapter08
。我们建议你浏览Chapter08
文件夹中的代码文件,以便跟随学习。
示例数据集
本章中,我们将合并两个标题数据集;你可以在进一步阅读部分和代码中找到相关来源的链接。数据集如下:
-
金融短语库:该数据集也可在 Kaggle 上获取,包含一个标题,并附带零售投资者角度的情感分析标签。它由多个数据集组成,每个数据集根据短语情感共识的程度对句子进行分类。在本练习中,我们将使用Sentence_AllAgree数据集。
-
CryptoGDELT2022:该数据集来自论文Cryptocurrency Curated News Event Database From GDELT,包含从全球事件、语言与情感数据库(GDELT)提取的新闻事件。它涵盖了 2021 年 3 月 31 日至 2022 年 4 月 30 日之间的新闻事件。该数据集包含多种情感得分和手动标注方法。在本练习中,我们将仅使用手动标注。
让我们开始构建我们的管道。
构建我们的管道
在 NLP 管道中,准备工作通常包括一个预处理步骤,在该步骤中我们清理和规范化数据。接下来,特征表示步骤将语言转换为可以供我们选择的模型使用的输入。完成这些后,我们便可以开始构建、训练和评估模型。这个战略计划将在接下来的章节中实现。
准备
语言在多种形式中表现出来。存在格式化的细微差异,例如大写或标点符号;一些作为语言辅助的词汇,其本身没有真正的语义意义,比如介词;以及包括表情符号在内的特殊字符,进一步丰富了语言的表现形式。为了处理这些数据,我们必须将原始文本转换为数据集,并遵循与数字数据集类似的标准。这个清理过程使我们能够去除异常值、减少噪音、管理词汇大小,并优化数据以便 NLP 模型处理。
数据清理管道的基本流程图如下所示:
https://github.com/OpenDocCN/freelearn-ds-pt4-zh/raw/master/docs/ds-web3/img/B19446_08_01.jpg
图 8.1 – 清理图示
让我们深入了解这些步骤。
规范化
规范化包括一系列任务,如小写化、移除 HTML 痕迹、链接和表情符号。我们的目标是清理数据库,只留下有效的词汇。
此外,这一过程还涉及去除那些对模型缺乏信息量或可能引入偏差的词汇,从而导致不理想的预测。根据任务的不同,我们将选择需要删除的词汇。这个步骤还处理了去除可能遗漏在 停用词 清理过程中的词汇。
我们还可以将 Unidecode 文本转换为 ASCII 文本。Unidecode 支持来自不同语言的字符,将它们转化为最接近的 ASCII 对应字符。例如,西班牙字符“ñ”在 ASCII 中变为“n”。我们在 Database_and_Preprocessing.ipynb
中通过以下代码片段实现了这一转换:
text = unidecode.unidecode(text)
规范化通过将所有文本呈现为一致的格式来促进统一性,指引模型的注意力集中在内容上,而非表面差异。
停用词
我们在这里的目标是排除对模型贡献较小的语义价值或意义的词汇。经常使用的词汇,如冠词(“a”,“the”,“an”)、介词(“on”,“at”,“from”,“to”)、连词(“and”,“so”,“although”)和代词(“she”,“he”,“it”),在语言中起到功能性作用,但缺乏模型可以利用的实质性语义内容。
因此,这些词汇通常在预处理过程中被过滤掉。可以按语言下载停用词集,并通过 NLTK 直接应用于我们的清理过程。在 Database_and_Preprocessing.ipynb
中,我们通过以下代码片段下载了英语停用词:
nltk.download(\'stopwords\')stop_words = set(stopwords.words(\'english\'))
这一过程减少了数据中的噪声,并有助于提高模型的效率。
分词
分词是将数据库中的文本拆分为较小的有意义单位,称为词元。这些单位可以是句子或单词。例如,我们来看一下以下标题:
“SEC 正在调查 Coinbase 的 Earn 产品、钱包服务和 交易活动”*
当分词为单词时,输出结果如下:
[\'SEC\', \'investigating\', \'Coinbase\', \'Earn\', \'product\', \',\', \'wallet\', \'service\', \'``exchange\', \'activity\']
分词产生了模型可以有效处理的结构化输入,促进了数据分析。此类分析指导了词汇大小的选择,用于降维,在 Database_and_Preprocessing.ipynb
中可以找到此类降维的示例。此分析展示了在分析过的数据集中最常出现的词汇。该分析得出以下结果:
https://github.com/OpenDocCN/freelearn-ds-pt4-zh/raw/master/docs/ds-web3/img/B19446_08_02.jpg
图 8.2 – 分析过的标题中最常出现的词
词形还原和词性标注(POS)
这些技术将单词还原为其基本形式或词根。这使我们能够通过选择那些已变化的单词并用其词根替代它们,减少我们需要处理的单词多样性。在我们的示例句子(“SEC 正在调查 Coinbase 的 Earn 产品、钱包服务和交易活动”)中,单词investigating将变为investigate。
词形还原的准确性取决于库对单词在句子中上下文或功能的理解。词性标注为我们的分析提供了这种上下文信息。以下是一个示例:
nltk.pos_tag
词性标注帮助我们根据单词在句子或文档中的位置,程序化地为每个单词分配上下文。以下是一个示例:
word= [\'SEC\', \'investigating\', \'Coinbase\', \'Earn\', \\ \'product\', \',\', \'wallet\', \'service\', \'exchange\',\'activity\'][nltk.pos_tag([w]) for w in word][[(\'SEC\', \'NNP\')], [(\'investigating\', \'VBG\')], [(\'Coinbase\', \'NN\')], [(\'Earn\', \'NN\')], [(\'product\', \'NN\')], [(\',\', \',\')], [(\'wallet\', \'NN\')], [(\'service\', \'NN\')], [(\'exchange\', \'NN\')], [(\'activity\', \'NN\')]]
清理后的句子结果如下所示:
investigate coinbase earn product wallet service exchange activity
让我们来看一些额外的预处理技术:
-
词干提取:这涉及从单词中去除前缀和后缀,以推导出一个共同的基本形式,称为“词干”。得到的词干可能并不总是形成有效的单词,但它旨在捕捉核心含义。
-
命名实体识别(NER):该技术自动识别并分类文本中的命名实体(例如,人名、地名、组织名和日期)。NER 从非结构化文本中提取结构化信息,将实体分类到预定义的类别中。我们在《第三章》中讨论的 X(前身为 Twitter)数据集就是这一方法的一个示例。
-
依存句法分析:该技术分析句子的语法结构,以建立单词之间的关系。它创建了一个层次结构,其中每个单词与其支配单词(“头”)相连,并分配一个语法角色(“依存标签”)。
检查点
该管道的逐步版本已详细列出在Database_and_Preprocessing.ipynb
中。如果你想跳过这一部分,生成的.csv
文件已经上传到本书的 GitHub,并可以通过preprocessed.csv
访问。
特征表示
在预处理阶段之后,下一步是将得到的原始文本数据转换为模型可以利用的特征,用于统计推断。目标是从文本中提取相关信息,并以算法能够理解的方式进行编码。实现这一目标的方法有多种,但通常涉及将单词表示为向量,并衡量单词在文档中的频率。一些常见的技术包括词袋模型、词频-逆文档频率(TF-IDF)和词嵌入。我们简要描述它们。
词袋模型
该技术通过统计单词出现的次数构建一个表示文档中所有单词的向量。它忽略句子的顺序和单词的上下文。可以使用来自 scikit-learn 库的sklearn.feature_extraction.text.CountVectorizer
来实现该方法。这个方法比较基础,丢失了重要的上下文信息,并且可能会创建一个非常稀疏的矩阵,因为词汇表非常庞大:
https://github.com/OpenDocCN/freelearn-ds-pt4-zh/raw/master/docs/ds-web3/img/B19446_08_03.jpg
图 8.3 – 词袋模型。文本摘自 https://rif.technology/content-hub/crypto-credit-card/
此外,通过结合 n-grams(即将具有上下文意义的两个或多个单词连接在一起)可以增强这种方法。例如,“自然语言”,“机器学习”和“新闻稿”在组合时能 encapsulate 特定的概念,但单独来看,它们并不保留这些概念。将 n-grams 融入到词袋模型中,可以进一步扩展词汇表。
TF-IDF
这是一种替代方法,使用sklearn.feature_extraction.text.TfidfVectorizer
。
词嵌入
词嵌入将单词表示为连续空间中的密集向量。通过捕捉单词之间的关系,这种方法保留了上下文和语义信息。Word2Vec 和 GloVe (www.tensorflow.org/tutorials/text/word2vec
) 是生成词嵌入的流行算法。这些嵌入可以在大型文本语料库上进行预训练,或者针对特定任务进行微调。在我们的模型中,我们使用了 GloVe (nlp.stanford.edu/projects/glove
) 向量。
GloVe,特别是,通过一种无监督学习算法开发的预训练向量。这种方法利用文本中普遍存在的线性子结构,通过测量向量之间的距离来评估语义相似性。GloVe 网站提供了一个经典示例,说明了模型所识别的关系:
https://github.com/OpenDocCN/freelearn-ds-pt4-zh/raw/master/docs/ds-web3/img/B19446_08_04.jpg
图 8.4 – GloVe 发现的单词结构示例(来源:nlp.stanford.edu/projects/glove/
)
模型构建
我们正在处理一个监督学习任务,目标是将 Crypto Panic 的头条新闻分类为正面、负面和中立。为此,我们将使用Modeling.ipynb
文件。
LSTM 是一种递归神经网络(RNN),能够学习长期依赖关系,在文本任务中显著优于常规的 RNN。该结构常用于自然语言处理任务,因为它能够很好地建模输入数据的序列并保留句子或文档中单词之间的依赖关系。因此,它不仅可以基于当前输入进行预测,还可以考虑远程信息——即上下文——而不仅仅是特定的单词。需要注意的是,虽然 LSTM 在捕捉长期依赖关系方面可能更有效,但其性能也可能取决于一些因素,如具体任务、数据集的大小以及模型的架构。在某些情况下,基于 Transformer 的高级架构(如 BERT 和 GPT)在某些自然语言处理任务中也表现出了更优的性能。
Christopher Olah 在他的博客中对该模型进行了很好的介绍,他是这样描述的:
“人类在思考时不会每一秒钟都从头开始。当你阅读这篇文章时,你是基于对前一个单词的理解来理解每一个新单词的。你不会把所有东西都抛弃然后重新开始思考。你的思维 具有持续性。”
LSTM 是一种专门的 RNN 变种,旨在检测数据序列中的模式,无论这些模式来源于传感器数据、资产价格还是自然语言。其独特之处在于与传统的 RNN 相比,LSTM 能够在更长的时间内保存信息。RNN 具有短期记忆,只能在当前神经元中保留信息,这导致它在处理更长序列时的预测能力有限。当内存超出时,模型会简单地丢弃最旧的数据,并用新数据替换它,而不考虑被丢弃的数据是否重要。LSTM 通过选择性地将相关信息保存在单元状态中,除了传统的短期记忆存储在隐藏状态外,克服了这种短期记忆问题。
在每个计算步骤的开始,我们有当前的输入 x(t)、长时记忆的前一个状态 c(t-1),以及存储在隐藏状态中的短期记忆的前一个状态 h(t-1)。在过程的结束时,我们获得更新后的单元状态和新的隐藏状态。单元状态携带着信息和数据集的时间戳,使其能够从输入数据的顺序中提取意义。
这三个输入通过三个门进行处理,每个门都有其特定功能:
-
遗忘门:该门决定哪些当前信息和先前信息被保留,哪些被丢弃。它将隐藏状态的先前状态和当前输入进行整合,并通过一个 sigmoid 函数进行传递。sigmoid 函数输出的值在 0 到 1 之间,0 表示先前的信息被认为无关并可被遗忘,1 则表示该信息应被保留。最终的结果将乘以当前的单元状态。
-
输入门:该门决定当前输入在解决任务中的重要性。它量化了由输入 x(t) 传递的新信息的相关性。当前输入与上次运行的隐藏状态相乘。输入门认为重要的所有信息都被加到单元状态中,形成新的单元状态 c(t)。这个新的单元状态成为长期记忆的当前状态,并将在下一次运行中使用。
-
输出门:LSTM 模型的输出在隐藏状态中计算:
https://github.com/OpenDocCN/freelearn-ds-pt4-zh/raw/master/docs/ds-web3/img/B19446_08_05.jpg
图 8.5 – 单元状态
为了与 LSTM 进行交互,我们需要输入具有统一长度的向量。为了满足这一要求,我们必须按照以下方式顺序地对预处理后的输入文本进行编码:
-
tokenizer.texts_to_sequences(X_train)
:此步骤将每个文本转换为一个整数序列,使用 tokenizer 中最常见的词汇。如果 tokenizer 的词汇表中缺少某些词汇,则会使用预定义的(超出词汇表)标记。
-
pad_sequences
:此函数将先前转换的序列转换为形状为(序列数,所需序列长度)的二维数组。maxlen
参数可以由用户定义,或者默认设置为列表中最长期序列的长度。此外,用户可以选择填充发生在序列的开始还是结束。
我们构建的模型以嵌入层作为其核心元素,并设置trainable = False
以保持来自 Glove500 的见解。如果我们选择从头开始训练,则需要将该参数设置为True
:
model = Sequential()model.add(Embedding(input_dim = len(word_index) + 1 ,\\ output_dim = embedding_dim ,\\ weights = [embedding_vectors],\\ input_length = max_length ,\\ trainable = False))
此外,我们的设计包括了一个 LSTM 层、一个全连接层和一个 dropout 层。dropout 层是一种常用的正则化技术,旨在防止过拟合,其通过在每次训练的前向传播中随机停用(即将其置为零)一部分神经元来操作。这有助于防止网络过度依赖特定的神经元,并鼓励网络学习更为鲁棒且具备泛化能力的特征:
model.add(Bidirectional(LSTM(embedding_dim, activation = \'relu\',\\ dropout = 0.0 ,\\ recurrent_dropout = 0.0)))model.add(Dense(embedding_dim, activation=\'relu\'))model.add(Dropout(0.3))
对于最后的全连接层,我们使用\'softmax\'
激活函数,它为每个训练类别分配一个小数概率:
model.add(Dense(label_distinct, activation=\'softmax\',\\ bias_initializer = \'zeros\'))
我们通过利用\'categorical_crossentropy\'
作为损失函数来编译模型,这是多类别分类任务(包括两个以上类别)的标准选择,正如在这里的情况:
model.compile(loss = \'categorical_crossentropy\',\\ optimizer = Adam(1e-3), \\ metrics = [\'accuracy\'])
检查点
该部分管道的逐步版本显示在Modeling.ipynb
中。如果你想跳过这一部分,生成的模型和分词器已经上传到本书的 GitHub 仓库,并可以通过chapter8_model.h5
和text_tokenizer.json
进行访问。
训练与评估
我们可以使用以下代码片段训练模型:
model.fit(X_train_pad, y_train, batch_size = batch_size, \\ epochs = 10, validation_data = (X_test_pad, y_test), \\ verbose = 0, callbacks=[tensorboard_callback])
在完成训练后,我们通过三种不同的方法评估其性能和结果:
小测试:我们查找测试样本,应用模型,并进行评估。我们必须始终记得对样本进行预处理,并将它们以模型准备好的形状传递给模型。
log
文件夹用于存储训练和验证结果:
tensorboard_callback = \\ tf.keras.callbacks.TensorBoard(log_dir=\"./logs\")
这个文件夹在随附的训练说明中提到(callbacks=[tensorboard_callback]
)。TensorBoard 然后访问这个文件夹以显示结果。
ROC AUC 曲线:根据 Jason Brownlee 的博客,“ROC 曲线是通过计算不同阈值下模型预测集的假阳性率和真阳性率来总结模型行为的诊断图。” ROC 曲线是二分类任务的评估指标。为了将其应用于我们的多类问题,我们必须通过 一对一 (OvO) 或 一对多 (OvA)/一对其余 (OvR) 方法将多类问题转化为二类问题。在 OvR 中,我们评估每个类别与其他类别的关系;在 OvO 中,我们评估每对类别之间的关系。选择这些技术取决于特定问题的细节、类别数量、计算资源和数据集特点。某些机器学习库,如 scikit-learn,为多类分类算法提供了 OvA 和 OvO 策略的选择。
在这种情况下,我们使用 OvA 方法,其中我们衡量模型预测每个标签的效果,将一个标签视为真实,其他所有标签视为假。通过这种方式,我们可以绘制 ROC AUC 曲线。曲线越接近 1,模型越好;越接近 0.5,模型的表现越差:
https://github.com/OpenDocCN/freelearn-ds-pt4-zh/raw/master/docs/ds-web3/img/B19446_08_06.jpg
图 8.6 – 应用的 ROC AUC 曲线
在处理不平衡数据集时,准确率和 ROC AUC 曲线可能会过于乐观。
F1 分数:通过 OvA 角度解决多类分类问题时,我们获得一组二值值,从中可以计算精确度、召回率和 F1 分数。F1 分数在目标是最小化假阳性和假阴性时更加适用。这个指标结合了精确度和召回率的信息,是它们的调和平均数。F1 分数的公式如下:
F1 分数 = 2 * 精确度 * 召回率 _____________ 精确度 + 召回率
Joos Korstanje 在他的博客中简洁地总结了这一点:
-
如果模型的精确度和召回率都很高,模型将获得高 F1 分数
-
如果精确度和召回率 都较低,模型将获得较低的 F1 分数
-
如果精确度或召回率较低,而另一个较高,模型将获得中等的 F1 分数。
上述度量可以通过以下代码片段生成:
classification_report(y_test, y_pred_onehot, target_names=target_names
该模型的加权平均 F1 分数为 0.72
。
我们可以使用以下代码片段保存已训练的模型,以备将来使用:
text_tokenizer_json = tokenizer.to_json()with io.open(\'text_tokenizer.json\',\'w\',encoding=\'utf-8\') as f: f.write(json.dumps(text_tokenizer_json, \\ ensure_ascii=False))model.save(\'chapter8_model.h5\')
在本书 GitHub 仓库中的 Chapter08/app.py
文件里,我们开发了一个应用程序,它从 Cryptopanic API 获取标题,应用已训练的情感模型,并在控制台中显示结果。
关于 NLP 挑战的说明
由于人类语言固有的复杂性,NLP 面临着多个挑战,这些挑战可能会显著影响其模型的表现和准确性。然而,存在潜在的缓解策略来应对这些挑战:
歧义性:单词和短语通常具有多重含义,正确的解释依赖于上下文。这种复杂性即使对母语和非母语使用者来说也是一种挑战,尤其是在隐喻的使用中。同样,模型在解释用户意图时也会遇到困难。为了解决这个问题,可以设计模型以纳入更广泛的上下文信息,通过利用周围的单词和短语来进行更准确的意义推断。
语言多样性:语言在语法、句法和语义上展现出广泛的差异。此外,俚语、地区方言和文化差异进一步加剧了语言的多样性。NLP 模型如果只在特定类型的数据上训练,可能难以在多样的语言环境中推广应用。为了解决这一限制,模型可以在更广泛且多样化的数据集上进行训练,以涵盖各种语言模式。
数据稀缺性:NLP 模型在训练过程中严重依赖大量的标注数据。然而,为所有可能的语言变体和应用获取标注数据是一个挑战。迁移学习技术,如在大语料库上进行预训练并对特定任务进行微调,通过减轻对大量标注数据的需求,提供了一个可行的解决方案。
伦理考量与偏差:NLP 模型可能会无意中学习到训练数据中的偏差,从而导致偏向的输出。解决这个问题需要精心策划多样化和具有代表性的训练数据集、定期审查模型的偏差,并实施公平意识的训练技术。
虽然 NLP 面临许多挑战,但机器学习技术的持续研究和进步有助于克服这些障碍。
ChatGPT 集成
当时间紧迫且无法收集必要的数据来训练新模型以构建分类器时,我们可以考虑使用预训练模型,如 TextBlob、spaCy 或 Hugging Face 库提供的模型。此外,我们还可以无缝集成现成的模型,如 ChatGPT。
我让 ChatGPT 自我介绍,以下是它的回答:
“我是 ChatGPT,一个由 OpenAI 开发的大型语言模型,基于 GPT-3 架构。我在大量文本数据上进行训练,能够生成类人回答,回应各种问题和提示。我的主要目的是帮助用户生成文本,无论是写文章、回答问题,还是完成创意任务。我在各种话题上拥有广泛的知识,包括科学、技术、历史和文学等。我旨在理解自然语言,能够以 对话式的方式 回复基于文本的输入。*”
本章特别相关的是最后一句话。该工具精通多样的词汇,能够处理文本输入。
ChatGPT 的架构与 LSTM 不同。它使用transformer架构,使其能够理解和生成自然语言文本。Transformer 使用自注意力机制来捕捉句子中单词之间的关系,从而允许对单词进行并行处理,而不像 LSTM 那样进行顺序处理。Transformer 被用于翻译语言、总结长文章、回答问题、完成句子,甚至创作故事。BERT 和 GPT 是常见的 Transformer 模型。
在Chapter07/chat_gpt integration
文件中,我们复制了与前一部分相同的用例,在该用例中,我们与 Cryptopanic API 进行了交互,提取标题,应用 ChatGPT 模型,并在控制台中显示输出,取得了优异的结果。为了方便操作,需要一个 API 密钥,可以通过以下步骤在 OpenAI 官网生成:
-
访问
platform.openai.com/docs/api-reference
,前往注册部分,然后在其网站上进行注册。 -
在左侧,你会看到一个下拉菜单,写着查看 API 密钥。点击这个菜单,进入生成新 API 密钥的页面:
https://github.com/OpenDocCN/freelearn-ds-pt4-zh/raw/master/docs/ds-web3/img/B19446_08_07.jpg
图 8.7 – ChatGPT – API 密钥登录页面
- 生成并安全存储生成的 API 密钥非常重要,因为一旦生成,它们就无法再被检索:
https://github.com/OpenDocCN/freelearn-ds-pt4-zh/raw/master/docs/ds-web3/img/B19446_08_08.jpg
图 8.8 – Chat GPT – API 密钥生成
本节的目的是要认识到 ChatGPT 的存在,它能够完成出色的工作,并通过连接 API 来解决情感分析问题,这可能是一个临时解决方案,特别是在没有足够数据来训练专用模型的情况下。
可以使用任务特定的数据对 ChatGPT 进行微调,以适应特定任务或领域。此过程使模型能够适应目标应用的细微差别和需求。例如,我们可以将模型定制为生成更简短的回答,减少在提示中所需的上下文量,以提高响应效果,并定义它如何处理边缘情况。假设我们希望将一个专门的机器人集成到公司内部通讯系统中,提供简洁的加密货币新闻摘要,具有特定的语气或格式。这可以通过该训练过程来实现。有关该过程的详细文档,请参阅 platform.openai.com/docs/guides/fine-tuning
,并且可以在 进一步 阅读 部分找到逐步教程。
摘要
自然语言处理(NLP)领域正在迅速发展,为从非结构化数据(如文本)中提取洞察提供了有效的手段。在本章中,我们介绍了该领域,展示了其中的一个典型任务,阐明了工作流程,讨论了相关数据,并使用嵌入进行模型训练。此外,我们还展示了模型评估过程,并展示了如何将其集成到一个程序中,该程序从 CryptoPanic API 获取头条新闻。
值得强调的是,积累大量数据对高模型准确性至关重要。然而,在无法构建此类模型的情况下,也可以采取替代方案。我们探讨了其中一种解决方案,涉及使用 ChatGPT API,它提供了访问经过全面数据集训练的文本机器人。
在接下来的章节中,我们将深入探讨数据团队如何为艺术团体提供支持,帮助他们通过使用 NFT 将艺术作品转化为独特的产品。
进一步阅读
要了解更多关于本章内容的主题,请查阅以下资源:
-
引言:
-
Bird, Steven, Edward Loper 和 Ewan Klein(2009),Python 自然语言处理。O’Reilly Media Inc. 可在
www.nltk.org/book/
查阅。 -
Yordanov, V.(2019 年 8 月 13 日)。文本自然语言处理简介。Medium。可在 https://towardsdatascience.com/introduction-to-natural-language-processing-for-text-df845750fb63 查阅。
-
Gabriel Doyle 和 Charles Elkan。(无日期)。金融主题模型。可在
pages.ucsd.edu/~gdoyle/papers/doyle-elkan-2009-nips-paper.pdf
查阅。 -
Sigmoider.(2018 年 5 月 3 日)。开始使用 NLP(第一部分)。Medium。可在 https://medium.com/@gon.esbuyo/get-started-with-nlp-part-i-d67ca26cc828 查阅。
-
Suhyeon Kim, Haecheong Park, 和 Junghye Lee.(无日期)。基于 Word2vec 的潜在语义分析(W2V-LSA)用于主题建模:区块链技术趋势分析的研究。
www.sciencedirect.com/science/article/pii/S0957417420302256
。 -
数据科学与机器学习的现状(2022)。Kaggle:您的机器学习和数据科学社区。
www.kaggle.com/kaggle-survey-2022
。 -
非常好的 ChatGPT 微调教程:Tech-At-Work。 (2023 年 9 月 11 日)。轻松微调 ChatGPT 3.5,超越 GPT-4![视频]。YouTube。
www.youtube.com/watch?v=8Ieu2v0v4oc
。
-
-
示例数据库:
-
Malo, P., Sinha, A., Korhonen, P., Wallenius, J., 和 Takala, P. (2014 年)。好债务还是坏债务:检测经济文本中的语义取向。信息科学与技术协会期刊,65(4),782-796。
www.kaggle.com/datasets/ankurzing/sentiment-analysis-for-financial-news
。 -
Manoel Fernando Alonso Gadi 和 Miguel Ángel Sicilia.(2022 年 10 月 10 日)。来自 GDELT 的加密货币精选新闻事件数据库 [pdf]。Research Square。
assets.researchsquare.com/files/rs-2145757/v1_covered.pdf?c=1665769708
。
-
-
预处理:
-
Bird, S., Klein, E., 和 Loper, E. (2009 年)。使用 Python 进行自然语言处理。O’Reilly Media。
-
Sklearn.feature_extraction.text.CountVectorizer。(无日期)。scikit-learn。检索于 2023 年 3 月 24 日。
scikit-learn.org/stable/modules/generated/sklearn.feature_extraction.text.CountVectorizer.xhtml
。 -
Sklearn.feature_extraction.text.TfidfVectorizer。(无日期)。scikit-learn。检索于 2023 年 3 月 24 日。
scikit-learn.org/stable/modules/generated/sklearn.feature_extraction.text.TfidfVectorizer.xhtml
。
-
-
模型:
-
Dudeperf3ct。 (2019 年 1 月 28 日)。LSTM 和 GRU 的力量。博客。
dudeperf3ct.github.io/lstm/gru/nlp/2019/01/28/Force-of-LSTM-and-GRU/#bag-of-words-model
。 -
Brandon Rohrer。 (无日期)。循环神经网络(RNN)和长短期记忆(LSTM) [视频]。YouTube。
www.youtube.com/watch?v=WCUNPb-5EYI&list=PLVZqlMpoM6kaJX_2lLKjEhWI0NlqHfqzp
。 -
Pennington, J.(无日期)。GloVe:全球词向量表示。斯坦福自然语言处理组。
nlp.stanford.edu/projects/glove/
。 -
Jason Brownlee. (2020). 深度卷积神经网络在情感分析(文本分类)中的应用。机器学习大师。可在
machinelearningmastery.com/develop-word-embedding-model-predicting-movie-review-sentiment/
获取。
-
-
评估:
-
T., B. (2022 年 12 月 9 日). 多分类分类指标的综合指南。Medium。可在
towardsdatascience.com/comprehensive-guide-on-multiclass-classification-metrics-af94cfb83fbd
获取。 -
Jason Brownlee (2021). 不平衡分类的评估指标概览。机器学习大师。可在 https://machinelearningmastery.com/tour-of-evaluation-metrics-for-imbalanced-classification/获取。
-
Korstanje, J. (2021 年 8 月 31 日). F1 得分。Medium。可在
towardsdatascience.com/the-f1-score-bec2bbc38aa6
获取。
-
第九章:NFT 的生成艺术
“我使用数据作为颜料,借助人工智能的画笔进行绘画。”
——Refik Anadol
在本章中,我们将进行一次艺术休息,尽情发挥创造力。虽然我们之前的重点是分析区块链上由他人生成的内容,但在本章中,我们将创造自己的内容,并将其添加到区块链上。
本章的加入源于认识到,作为数据科学家,我们可能会遇到需要与艺术家团队合作,制作或协助制作 NFT 系列的请求。在第四章中,我们研究了 NFT 的艺术应用,并探索了诸如Bored Ape等知名系列,该系列的总交易量为 978,382 ETH(约合 18 亿美元)。我们不清楚他们是否使用了人工智能来制作所有图像,但它们是艺术可以在区块链上拥有和交易的一个很好的案例。为了能够参与这个市场,我们将学习从制作图像到在 OpenSea 上列出销售的整个过程。
一个名为Artsy Monke的系列使用人工智能通过将 Bored Ape 系列与 20 种精选的绘画风格相结合来创作图像。您可以在opensea.io/collection/artsy-monke
找到他们的 OpenSea 系列网站。书本封面上的图像是 Artsy Monke #9937。
另一个例子是 Refik Anadol 的机器幻觉系列,这是与 NASA 合作的项目,使用了超过两百万张由国际空间站、哈勃望远镜和 MRO 望远镜等空间机构记录的原始图像,经过人工智能数据处理,创作了六幅画作和一件雕塑作为输入。
人工智能所带来的工具范围超出了本章的讨论范围。然而,我们将讨论三种可能对艺术家团队联系以帮助他们建立 NFT 系列时有用的实际工具:上色、风格迁移和提示生成艺术。我们将从不修改内容的编辑开始,逐步过渡到完全创作图像。最后,我们将学习如何在区块链上创建一个系列并将其列出销售。
在本章中,我们将涵盖以下主要主题:
-
创作色彩——上色工具
-
创作风格——风格迁移工作流程
-
创作提示——文本转图像解决方案
-
变现——铸造和销售 NFT
技术要求
在本章中,我们将为每个部分使用不同的工具。对于上色部分,我们将使用一个名为.zip
的程序,该程序需要下载到您的计算机并解压缩。
转到风格迁移部分,我们将使用一个 VGG19 模型,其文档可以在www.tensorflow.org/api_docs/python/tf/keras/applications/vgg19/VGG19
找到。它遵循的是 Keras 示例,详见keras.io/examples/generative/neural_style_transfer/
。
对于文本到图像部分,我们将与 Leonardo AI 平台进行互动,只需要创建一个账户。此外,我们还将与 OpenSea 平台互动,这要求我们拥有一个有效的钱包,以便进行铸造。
你可以在本书的 GitHub 仓库中找到所有数据和代码文件,链接为github.com/PacktPublishing/Data-Science-for-Web3/tree/main/Chapter09
。我们建议你阅读Chapter09
文件夹中的代码文件,以便跟随本书学习。本章节中创建的 NFT 系列可以在opensea.io/collection/mysterious-library
访问。
创作与颜色 – 着色
给图像着色需要艺术团队付出大量工作。作为数据科学家,我们可以借助一种工具来辅助他们,这个工具可以在遵循艺术方向的同时,轻松地进行绘画。我们所提到的工具叫做Style2Paints,它是一种半自动着色方法,在不需要色彩修正时可以生成自动化的结果。它还提供了一个功能,允许为工具提供提示,以便获得更加定制化的结果。
使用 Style2Paints 实操
一旦安装了 Style2Paints,主页面将像图 9.1所示。左侧有一个颜色样式栏,右侧则有一个色板:
https://github.com/OpenDocCN/freelearn-ds-pt4-zh/raw/master/docs/ds-web3/img/B19446_09_01.jpg
图 9.1 – Style2Paints 主视图
这个工具可以与彩色图像和黑白图像一起使用。请按以下步骤操作:
-
要上传图像进行着色,点击符号。https://github.com/OpenDocCN/freelearn-ds-pt4-zh/raw/master/docs/ds-web3/img/Icon_1.jpg
-
选择图像的绘画区域并点击确定。
-
在左侧,我们将看到一个已预先着色的图像列表,可以点击并下载。例如,如果我们上传一个基础草图或“线条艺术”,工具将会在网站的左侧建议一些颜色样式。
请参考以下线条艺术示例:
https://github.com/OpenDocCN/freelearn-ds-pt4-zh/raw/master/docs/ds-web3/img/B19446_09_02.jpg
图 9.2 – 书籍装订机,Joseph William Zaehnsdorf,公共领域,来自 Wikimedia Commons
通过使用这些颜色样式,我们可以仅通过点击一种颜色组合,从一张黑白图像创建出八种不同颜色的书籍装订机图像:
https://github.com/OpenDocCN/freelearn-ds-pt4-zh/raw/master/docs/ds-web3/img/B19446_09_03.jpg
图 9.3 – 书籍装帧的彩色版本
也可以编辑已经有一些颜色的图像。例如,我们考虑艺术猴 #9937:
https://github.com/OpenDocCN/freelearn-ds-pt4-zh/raw/master/docs/ds-web3/img/B19446_09_04.jpg
图 9.4 – 艺术猴 #9937
我们可以通过使用位于工具左侧的颜色样式选项轻松更改图像使用的颜色。点击每种颜色组合,图像会发生变化。可以在图 9.5中看到一些示例:
https://github.com/OpenDocCN/freelearn-ds-pt4-zh/raw/master/docs/ds-web3/img/B19446_09_05.jpg
图 9.5 – 彩色艺术猴 #9937
也可以在没有颜色样式建议的情况下手动上色,并使用文档所称的“提示点”颜色调色板。提示的使用场景是保持某种美学一致性或纠正一些颜色样式建议。按照以下步骤操作:
-
通过点击工具右侧的颜色之一来选择一个颜色。
-
在我们想要用选定颜色着色的图像部分添加一个点。这是一个“提示”。
-
点击图标;图像将重新加载,用我们选择的颜色涂绘所选区域。https://github.com/OpenDocCN/freelearn-ds-pt4-zh/raw/master/docs/ds-web3/img/Icon_2.jpg
关于如何使用这个直观工具的逐步教程可以在进一步 阅读部分找到。
理论
卷积神经网络(CNN)是一种专门用于分析视觉数据的深度神经网络类型。总体而言,CNN 受到人类视觉系统如何处理信息的启发。它们由多个层次组成,这些层次能够自动学习和检测各种特征,如边缘、角落、纹理以及更复杂的模式,从原始像素数据中提取出来。这些学习到的特征随后可用于图像分类、物体检测、人脸识别等任务。
以下是 CNN 的关键组件:
-
卷积层:这是卷积神经网络(CNN)的核心。它将一组可学习的滤波器(也叫卷积核)应用到输入图像上。这个过程被称为特征提取,用于识别图像的不同特征。
-
池化层:此层减少特征图的空间维度,同时保留重要信息。池化有两种类型:最大池化和平均池化。通常在卷积层后应用,以减少在前一层创建的特征图的大小。经过几层卷积和池化层后,特征图被展平成一维向量,作为全连接层的输入。
-
全连接层:这些层类似于传统神经网络中的层,连接不同的层。
我们刚刚详细描述的组件可以按顺序在图 9.6中可视化:
https://github.com/OpenDocCN/freelearn-ds-pt4-zh/raw/master/docs/ds-web3/img/B19446_09_06.jpg
图 9.6 – CNN 的结构。照片由 Alison Wang 提供,来自 Unsplash
CNN 使用标注数据集进行训练。在训练过程中,网络的参数(权重和偏置)通过优化算法(如梯度下降)进行更新,以最小化一个损失函数,该损失函数量化了预测标签和实际标签之间的差异。
Style2Paints 模型基于一个 CNN 框架,并使用 Danbooru 数据库进行训练,模型包含两个部分:草图和细化过程。根据两阶段草图着色论文,“第一个草图阶段会大胆地将颜色涂抹到画布上,创建一个颜色草图,目的是丰富颜色的多样性 (…) 第二个细化阶段纠正颜色错误,细化细节并打磨模糊的纹理,以达到最终的输出效果。”该神经网络已被训练来处理缺乏一些重要信息(如阴影或纹理)的彩色草图。
它使用生成对抗网络(GANs),这是一种用于生成建模的 CNN 类型。这种神经网络由两个子模型组成:生成器和判别器。生成器执行无监督任务,总结训练数据集(通常是图像)的分布,并生成合成副本供判别器分析。判别器接收这些副本,并将其与一些训练数据集的样本结合起来,执行有监督任务,区分真实样本(地面真实样本)和假样本(由生成器生成的)。当判别器无法区分生成图像和地面真实图像时,模型被认为已经训练完成。生成器此时被保留用于生成该问题领域的新样本。
训练过程可以通过以下图示来查看:
https://github.com/OpenDocCN/freelearn-ds-pt4-zh/raw/master/docs/ds-web3/img/B19446_09_07.jpg
图 9.7 – 训练过程的步骤
这可以看作是两个子模型相互竞争并不断提高生成和辨别能力。这就是为什么“对抗性”这个词出现在它的名称中的原因。该结构的概述可以在进一步阅读部分找到。
训练 GAN 需要大量数据集和大量 GPU。如果你有兴趣训练自己的 GAN,圣路易斯华盛顿大学的视频已经包含在进一步阅读部分。
关于训练数据集的说明
如果使用的模型已经使用我们尝试重现的图像风格进行训练,通常会得到更好的结果。例如,如果我们想要用摄影风格进行绘画,我们可能会尽量避免使用经过动漫风格训练的模型。
正如预期的那样,Style2Paints 是使用 Danbooru 数据集训练的,Danbooru 是一个经过标注的动漫数据集,随着时间的推移不断发展和扩展。Style2Paints 是在 2018 年版本上进行训练的,但在撰写时,已有 2021 年版本。该数据集包含带有元数据和标签的图像。动漫艺术有一些共同特征,例如大而富有表现力的眼睛、鲜艳的色彩、夸张的表情,以及变化丰富的色彩调色板,用以反映图像中的氛围。
以下是一些常用的图像数据集:
-
ImageNet:这是一个图像集合,遵循 WordNet 层级结构。WordNet 集合中的每个相关概念都是一个“同义词集”,与其他同义词集形成关系,建立起从一般到抽象和具体的概念层级。ImageNet 项目试图为每个同义词集提供 1,000 张图像。该数据集对于目标分类任务非常有用。欲了解更多信息,请访问
www.image-net.org/
。 -
常见的上下文对象(COCO):这是一个大型数据集,已被注释用于目标检测任务。它包含超过 33,000 张图像,按目录组织,注释以 JSON 格式存储,包含对象和边界框坐标。欲了解更多信息,请访问
cocodataset.org/#home
。 -
MPII 人体姿势数据库:该数据集已为人体姿势估计任务准备。它包含大约 25,000 张图像,反映了超过 410 种日常人类活动。欲了解更多信息,请访问
human-pose.mpi-inf.mpg.de/
。 -
电影中标记的帧:该数据集包含从流行好莱坞电影中提取的图像。这些图像经过多个处理过程(从选择到清理),然后进行了最终的人工审查和身体关节的标注。欲了解更多信息,请访问
bensapp.github.io/flic-dataset.xhtml
。 -
Caltech-UCSD Birds-200-2011:该数据集包含约 12,000 张来自 200 个鸟类类别的图像,并分为测试集和训练集。每张图像都有详细的注释,包括一个子类别标签、15 个部位位置、312 个二进制属性和一个边界框。该数据集可在 TensorFlow 上获取。欲了解更多信息,请访问
www.vision.caltech.edu/datasets/cub_200_2011/
。 -
Laion-5b:这是 Stable Diffusion(我们稍后将回顾的内容)训练所使用的数据集。它包含 58.5 亿对通过 CLIP 筛选的图像-文本对,这些数据通过德国实体 LAION 进行的互联网大规模抓取收集而来。欲了解更多信息,请访问
laion.ai/blog/laion-5b/
。
在这一部分,我们学习了如何使用一个工具,它可以帮助进行着色工作流程,无论是自动还是手动。接下来的部分,我们将深入探讨通过 AI 将一种图像的风格迁移到另一张图像,从而对图像进行广泛的着色影响。
风格创作——风格迁移
我们可以通过风格迁移来帮助艺术团队,这是一种将两张图像结合起来的过程:
-
风格图像或根图像,我们将从中学习风格
-
目标图像,我们将使用新的风格来转换它
结果图像将保留目标图像的核心元素,但看起来像是按照风格图像的风格绘制或印刷的。
风格迁移有多种方法,包括利用 GAN(上一部分中描述)、使用 视觉几何组(VGG),以及使用稳定扩散(我们将在下一部分讨论)。
在 style_transfer.ipynb
中,我们将使用 VGG19,这是一个具有 19 层的特殊 CNN 类型,已使用来自 ImageNet 数据库的超过百万张图像进行训练,以提取毕加索画作的风格并将其迁移到一张照片上。毕加索属于立体主义运动,在这一运动中,艺术家们运用了多种视角,使用几何形状,并且将画面平面进行了简化。关于这一艺术运动的定义特征,可以在 进一步 阅读 部分找到一篇有趣的文章。
让我们逐步了解我们必须遵循的步骤。
准备工作
首先,我们必须获得根图像和目标图像的张量表示。preprocess_image()
函数通过使用 Keras 库和以下代码片段来完成这项工作:
def preprocess_image(image_path): img = keras.preprocessing.image.load_img( image_path, target_size=(img_nrows, img_ncols) ) img = keras.preprocessing.image.img_to_array(img) img = np.expand_dims(img, axis=0) img = vgg19.preprocess_input(img) return tf.convert_to_tensor(img)
模型构建
我们通过设置 ImageNet 数据集的权重来构建 VGG19 模型,这意味着模型将使用已经在 ImageNet 数据集上预训练的权重进行初始化。include_top
参数设置为 False
,这意味着模型中不包括负责分类的顶部层。原因是我们希望将 VGG19 模型用作特征提取器,而非用于分类目的:
model = vgg19.VGG19(weights=\"imagenet\", include_top=False)
代码还提取了由模型每一层生成的信息,以便在后续的损失函数中使用,这些损失函数我们将在此处进行描述。
我们定义了三个损失函数:
-
总变差损失,它通过衡量结果图像中像素之间的空间连续性,来确保最终图像的一致性。
-
content_layer_name
。 -
style_layer_names
。
风格损失使用的是一个 Gram 矩阵(本质上是一个张量与其转置相乘),并在 gram_matrix()
函数中计算。卷积层的 Gram 矩阵的理论基础是将它们之间学到的风格特征结合起来。例如,毕加索的立体主义是一种颜色、形状和纹理的结合。通过这些特征的合成(即 Gram 矩阵)来衡量它们之间的相关性,将能代表毕加索的风格。
compute_loss
函数总结了之前定义的各种损失的组合,而compute_loss_and_grads
执行计算。
训练与推理
训练过程将减少风格损失和内容损失,这两者构成了总变差损失。训练过程使用随机梯度下降(SGD)作为优化器,以迭代方式减少损失。
提议的脚本在每 100 次迭代后保存图像,以便我们监控图像变化。文档建议在训练过程结束时展示最终图像,我们将训练步数设置为 4000 步。
通过使用笔记本中名为deprocess_image()
的util
函数,该函数将张量重建为.png
文件,以便可以保存和显示,我们可以看到将毕加索画作风格转移到照片上的效果:
https://github.com/OpenDocCN/freelearn-ds-pt4-zh/raw/master/docs/ds-web3/img/B19446_09_08.jpg
图 9.8 – 毕加索画风中的瀑布
在第一部分,我们学习了如何通过应用颜色自动修改图像;在这一部分,我们回顾了如何通过将基础图像与特定风格相结合来创建图像。在这两种情况下,我们都提供了想要修改的图像。在接下来的部分,我们将学习如何通过文本输入或提示生成图像。
使用提示生成 – 文本到图像
在本节中,我们将介绍一些能够基于提示生成图像的服务。提示是一组自然语言指令,输入模型后可以生成图像。任何可以用语言描述的内容都可以转化为图像。提示越详细,输出的作品就越独特。指令可以包括一些关键词,这些关键词将增强生成作品的原创性,例如生成图像的风格、长宽比、预期图像的分辨率等。
我们将介绍的所有服务都使用某种形式的扩散模型,结合其他模型以提高图像生成过程的效率,去除干扰性结果(例如,针对次要 18),等等。扩散模型是生成模型,旨在复制训练数据。在训练过程中,模型将噪声添加到训练数据集中,并学习如何反向操作以恢复原始图像。通过从训练噪声中恢复,模型学习图像的基本特征以及如何生成新数据。
让我们简要分析它们逐一。
DALL.E 2
OpenAI,开发了 ChatGPT 的同一个研究团队,开发了 DALL-E 2,它是一个从文本描述生成图像的工具。根据他们的文档,“DALL·E 是一个变换器语言模型。它接收文本和图像作为一个包含最多 1280 个令牌的数据流,并使用最大似然训练来生成所有令牌,依次生成。”该模型是一个 120 亿参数的自回归变换器,经过 2.5 亿对图像-文本对的训练,这些对从互联网上收集而来。
DALL-E 2 不仅根据预定义的提示生成图像,还允许用户修改图像的部分内容或为较小的图像区域添加背景信息。
同样的团队还设计了对比语言图像预训练(CLIP),它使我们能够将文本与图像进行映射,并返回最适合输入图像的标题。更多信息可以在openai.com/research/clip
找到。这使得图像标签和分类的速度提升到了一个新水平。
Stable Diffusion
Stable Diffusion 模型是开源的,包含代码和检查点。为了让 Stable Diffusion 模型能够在低 GPU 上训练,它们并不是直接在图像上训练,而是在数据集的潜在空间中进行训练。模型从数据集的潜在结构中学习,而不是处理每一张图像。使用潜在空间进行训练使得我们能够向模型提供文本和图像,这些内容将在模型用来重新生成图像的同一空间中进行处理。
上一节提到的 CLIP 模型帮助训练了最新版本的 Stable Diffusion V2。仓库链接是github.com/Stability-AI/stablediffusion
。
Midjourney
Midjourney 使用的基础模型没有公开,但它们可能是多种扩散模型的组合,正如 DALL-E 和 Stable Diffusion 的解释所示。Midjourney 目前只能通过其官方 Discord 服务器上的 Discord 机器人访问,或者邀请机器人到第三方服务器。它没有 API。
这项服务迅速变得非常流行。
Leonardo.Ai
他们页面的链接是app.leonardo.ai/
。这个工具提供现成的模型,能够生成专门针对一些最常见主题训练的图像,例如角色扮演游戏(RPGs)或现实照片。它还提供工具来微调模型,使其能够适应我们的训练数据集,并且提供一个慷慨的免费层。最后,它对开发者友好,提供易于互动的 API。每个模型都有一个基于 Stable Diffusion 发布版的“基础模型”描述。
要开始使用,请在他们的应用程序上注册并完成入门调查。与基本服务互动无需付费,但获取 API 密钥时必须付费:
https://github.com/OpenDocCN/freelearn-ds-pt4-zh/raw/master/docs/ds-web3/img/B19446_09_09.jpg
图 9.9 – 第一次登录 Leonardo.Ai
在主页视图中,列出了我们可以互动的模型,具体取决于我们想生成的图像类型。如前所述,每个模型都是针对特定目的进行优化的。例如,有一个模型专门用于复古风格摄影或角色扮演游戏角色肖像。
我们还可以看到两个标签,分别是社区动态和个人动态,它们显示由社区和我们自己生成的图像。
如果我们转到 AI 生成工具,我们将看到视图左侧有多个选项可供选择,其中包括以下内容:
-
图像数量:这使我们可以选择每次运行时生成的图像数量。
-
提示魔力:根据他们的描述,“我们的实验性渲染管道可能具有更好的提示遵循性”。启用此功能后,生成的图像更加艺术化。
-
提示魔力强度:此选项决定了之前渲染的详细程度的权重。
-
公开图像:此选项允许我们选择是否将这些图像与公共动态分享。
-
图像尺寸:此选项让我们可以设置图像的大小。
-
指导尺度:此选项决定了提示在最终图像中的权重。建议将其保持在 7 或 8。
我们还可以上传一张图片作为提示使用。
关于好提示的说明
词汇:避免使用“very”或“super”来表示强调。相反,可以选择表达相同意思的词汇。例如,将“very tired”替换为“exhausted”。
拼写错误:避免发送拼写错误的单词、缩写、收缩词或俚语,因为模型可能难以将它们与其训练时所使用的数据集对齐。
具体性:尽量减少词汇选择中的模糊性和不必要的文本。为了提高效果,可以使用“cheeseless pizza”而不是“pizza with no cheese”。利用负面提示来排除图像中的特定物体或特征。
需要考虑的关键词:包括图像背景、风格词(如动漫、写实、纸艺、立体主义、炭笔画、民间艺术、涂鸦)、光线(柔光、环境光、霓虹灯、工作室灯光)或一天中的时间(早晨、黄金时段、午夜)的提示。
此外,该应用还帮助我们生成提示。在我们刚刚描述的 AI 工具中,我们可以看到提示生成标签,它帮助我们生成提示,以便使用 AI 获取所需的图像。
亲自体验 Leonardo.Ai
让我们通过 API 做一个练习。文档可以在docs.leonardo.ai/reference/getuserself
找到。它是一个易于使用的 API,可以通过我们熟悉的request
库进行访问。
API 可以帮助我们从提示到文件夹的整个管道建设,我们可以将其提交给艺术团队进行审核。Leonardo_AI.ipynb
文件包含我们将要探索的工作流。
尽管 API 仍在开发中,并且并非所有功能和模型都可以通过程序调用,但前面描述的大部分选项都可以作为参数添加到负载中。
让我们查看以下代码片段:
payload = { \"prompt\": prompt, \"modelId\":\"6bef9f1b-29cb-40c7-b9df-32b51c1f67d3\", \"width\": 512, \"height\": 512, \"sd_version\": \"v2\", \"presetStyle\": \"LEONARDO\", \"public\": False, \"promptMagic\": True}
要与 API 互动,我们需要登录并获得一组 API 密钥,这些密钥将作为授权信息传递在请求头中。
重要的是要从网站上阅读参数,因为文档并不完整。例如,有些模型是以特定的图像尺寸进行训练的,因此最好将这些首选尺寸输入到参数负载中。此外,并非所有模型都可以通过 API 调用,也无法访问提示生成器。
尽管有这些限制,这仍然是一个很棒的工具,可以帮助我们快速生成高质量的图像。
铸造一个 NFT 收藏
本节分析所有工具的目的是为了创建或修改我们可以出售的图像,或者艺术团队可以出售的图像。一旦我们生成了图像,我们希望以 Web3 的方式“拥有”它们,正如在 第四章 中解释的那样。为了实现这一目标,我们将在市场平台上创建一个收藏。
铸造是指在区块链上创建一个物品的数字踪迹。正如我们在描述 ERC 721 时看到的,它意味着这个踪迹将指向一个包含存储图像的 URL。所有存储在区块链上的内容都需要支付油费。
懒铸造的概念相对较新。懒铸造意味着授权平台在 NFT 售出时铸造 NFT,而不是提前铸造。这一点很重要,因为铸造需要消耗油费,在高峰期油费可能很高。此外,懒铸造有助于减少创建一个可能不会高价售出的收藏品的风险。截至目前,主要的市场平台,如 OpenSea 和 Rarible,提供这一服务。
该过程包括以下步骤:
-
创作者通过特定的智能合约 懒铸造 NFT。智能合约会代表我们铸造并出售 NFT。我们提供授权。
-
买家在购买我们的 NFT 时支付包括铸造费用和 NFT 本身的费用。
这种方法将铸造过程推迟到 NFT 售出之前,这是对创作者的激励,鼓励他们继续创作和展示艺术作品,而无需支付油费。
让我们在 OpenSea 上创建一个收藏:
-
访问
opensea.io/
。要与平台互动,你需要一个钱包。 -
连接你的钱包并进入个人资料选项:
https://github.com/OpenDocCN/freelearn-ds-pt4-zh/raw/master/docs/ds-web3/img/B19446_09_10.jpg
图 9.10 – 连接到你的钱包
- 点击 我的收藏:
https://github.com/OpenDocCN/freelearn-ds-pt4-zh/raw/master/docs/ds-web3/img/B19446_09_11.jpg
图 9.11 – 我的收藏标签页
- 点击蓝色的 创建一个 收藏 按钮:
https://github.com/OpenDocCN/freelearn-ds-pt4-zh/raw/master/docs/ds-web3/img/B19446_09_12.jpg
图 9.12 – 我的集合页面
- 系统会提供两个选项:传统选项(部署您自己的合约)和懒铸造选项(使用 OpenSea 合约)。点击第二个选项:
https://github.com/OpenDocCN/freelearn-ds-pt4-zh/raw/master/docs/ds-web3/img/B19446_09_13.jpg
图 9.13 – 选择懒铸造选项
-
会打开一个页面,您可以在其中填写集合的详细信息。我们将找到以下几个细节:
-
集合的名称。
-
描述
-
可接受的货币。
-
集合页面的图片。
-
作者收益。如我们在第四章中提到的,每次 NFT 被出售时,可以设定创作者将保留的百分比。
-
填写完所有必需的详细信息后,点击保存。现在我们有了一个集合,接下来需要将艺术品添加到其中:
- 返回您的个人资料并点击创建:
https://github.com/OpenDocCN/freelearn-ds-pt4-zh/raw/master/docs/ds-web3/img/B19446_09_14.jpg
图 9.14 – 创建 NFT
-
您可能需要额外的授权才能访问此面板。如果是这样,您将被带到创建新项目页面:
opensea.io/asset/create
。 -
上传您想要铸造的图片、视频或音频。在这个示例中,我们将铸造一张使用
Leonardo_AI.ipynb
笔记本生成的图片:
https://github.com/OpenDocCN/freelearn-ds-pt4-zh/raw/master/docs/ds-web3/img/B19446_09_15.jpg
图 9.15 – 新项目的详细信息
-
开始填写必填字段:
-
名称
-
描述
-
将其连接到之前在步骤 4中创建的集合
-
确定可以铸造的相同性质的物品数量
-
该物品将所在的网络
点击创建;您将看到以下输出:
-
https://github.com/OpenDocCN/freelearn-ds-pt4-zh/raw/master/docs/ds-web3/img/B19446_09_16.jpg
图 9.16 – 签署创建后的结果信息
- 启用销售。为此,请访问该物品的页面并点击出售按钮:
https://github.com/OpenDocCN/freelearn-ds-pt4-zh/raw/master/docs/ds-web3/img/B19446_09_17.jpg
图 9.17 – 销售详情
新选项将会出现供您选择。可以选择固定价格或限定时间的拍卖。如果我们想以固定价格出售,可以按照以下步骤操作。
- 点击固定价格:
https://github.com/OpenDocCN/freelearn-ds-pt4-zh/raw/master/docs/ds-web3/img/B19446_09_18.jpg
图 9.18 – 固定价格选项
-
设置一个价格,使用我们在创建集合时决定的任何可接受的货币或代币。
-
在此下方,我们将看到收益的总结以及 OpenSea 收取的费用(在写作时,这个费用为 2.5%)。
-
如果我们同意,可以点击完成列表。为了批准这个列表,OpenSea 需要我们的签名。
-
一旦签署完成,我们将收到新的通知,告知我们该物品已列出。现在,它已经在市场上,可以购买了!
https://github.com/OpenDocCN/freelearn-ds-pt4-zh/raw/master/docs/ds-web3/img/B19446_09_19.jpg
图 9.19 – 销售列表已启用
本节中生成的所有插图均可在《神秘图书馆收藏》查看:opensea.io/collection/mysterious-library
。
总结
在本章中,我们探讨了三种不同的使用 AI 工具进行艺术项目的方式。我们研究了使用 GAN 模型为草图上色,探索了 VGG19 模型进行风格转移,并发现了基于提示生成艺术的 Stable Diffusion 模型的最先进应用。
此外,我们还了解了整个工作流程,从完成的艺术作品到将最终图像列出在市场上。通过结合 AI 和区块链技术的力量,我们现在有了探索和变现艺术作品的新机会,以激动人心和创新的方式。
值得注意的是,关于使用 AI 生成的图像的所有权问题已经引发了讨论。这源于这些模型可能在没有艺术家同意的情况下使用了受版权保护的艺术作品进行训练的可能性。回应者认为,模型输出的变革性特征,加上合理使用的论点,可能会驳回此类指控。这个持续的问题尚未被法律当局明确解决,并且可能在不同国家之间存在差异。
在探索了 NFT 领域之后,我们将把注意力转向一个关键方面,这一方面是确保这一创新领域完整性的基础——欺诈检测。在接下来的章节中,我们将分析另一个应用案例,在这个案例中,机器学习可以帮助我们发现异常并提高交易安全性。
进一步阅读
想要了解更多本章所涵盖的主题,请参考以下资源:
-
Crypto Grims:
twitter.com/cryptogrims
-
Artsy Monke 收藏品:
opensea.io/assets/ethereum/0xa4bcd3b7f141ba1f08f36033fdfce691565561bc
。 -
Mishra, M. (2020, September 2). 卷积神经网络解析. Medium. 可在
towardsdatascience.com/convolutional-neural-networks-explained-9cc5188c4939
查看。 -
Fortis, S. (n.d.). Google AI 将所有 10,000 个 BAYC NFT 转化为机器生成艺术. Cointelegraph. 可在
cointelegraph.com/news/google-ai-turns-all-10-000-bayc-nfts-into-machine-made-art
查看。 -
Lllyasviel (n.d.). style2paints.github.io. 可在
style2paints.github.io/
查看。 -
Lllyasviel/style2paints. (n.d.). GitHub. 可在
github.com/lllyasviel/style2paints
查看。 -
Tang, J.(2020 年 10 月 20 日)。尝试理解一个全明星自动上色项目——Style2Paints(第一部分)。Medium。可在
medium.com/ai-innovation/attempt-to-understand-an-all-star-auto-color-project-style2paints-part-1-84d2e3d96da
查看。 -
Lvmin Zhang, Chengze Li, Tien-Tsin Wong, Yi Ji 和 Chunping Liu。(无日期)。CUHK 计算机科学与工程。可在
www.cse.cuhk.edu.hk/~ttwong/papers/colorize/colorize.pdf
查看。 -
Nerdy Rodent。(2020 年 11 月 19 日)。Style2Paints——使用 AI 轻松为任何线条艺术上色 [视频]。YouTube。可在
www.youtube.com/watch?v=cvN9oQfC3w0
查看。 -
GAN 结构概述。(无日期)。Google 开发者平台。可在
developers.google.com/machine-learning/gan/gan_structure
查看。 -
Prof. Jeff Heaton – 圣路易斯华盛顿大学。(2022 年 1 月 19 日)。图像和数据生成的 GAN 入门(7.1) [视频]。YouTube。可在
www.youtube.com/watch?v=hZw-AjbdN5k
查看。 -
Prof. Jeff Heaton – 圣路易斯华盛顿大学。(2021 年 2 月 17 日)。从您自己的图像训练 GAN:StyleGAN2 ADA [视频]。YouTube。可在
www.youtube.com/watch?v=kbDd5lW6rkM
查看。 -
Prof. Jeff Heaton – 圣路易斯华盛顿大学。(2021 年 5 月 12 日)。在 Colab Free 和 Colab Pro 技巧下训练 NVIDIA StyleGAN2 ADA [视频]。YouTube。可在
www.youtube.com/watch?v=L3JLzoe-dJU
查看。 -
T81_558_deep_learning/t81_558_class_07_1_gan_intro.ipynb at master · jeffheaton/t81_558_deep_learning。(无日期)。GitHub。可在
github.com/jeffheaton/t81_558_deep_learning/blob/master/t81_558_class_07_1_gan_intro.ipynb
查看。 -
T81_558_deep_learning/t81_558_class_07_2_train_gan.ipynb at master · jeffheaton/t81_558_deep_learning。(无日期)。GitHub。可在
github.com/jeffheaton/t81_558_deep_learning/blob/master/t81_558_class_07_2_train_gan.ipynb
查看。 -
Jason Brownlee 博士。(2019 年 7 月 19 日)。机器学习精通。机器学习精通。可在
machinelearningmastery.com/what-are-generative-adversarial-networks-gans/
查看。 -
立体主义的 4 个特征及其重要性。(无日期)。Artlex – 艺术词典和百科全书。可在
www.artlex.com/art-movements/cubism/characteristics/
获取。 -
神经风格 迁移:
keras.io/examples/generative/neural_style_transfer/
。 -
DALL·E:从文本创建图像。(无日期)。OpenAI。可在
openai.com/research/dall-e
获取。 -
零-shot 文本到图像生成。(无日期)。arXiv.org。可在
arxiv.org/abs/2102.12092
获取。 -
Aleksa Gordić - The AI Epiphany. (2022 年 9 月 1 日). 稳定扩散:使用潜在扩散模型进行高分辨率图像合成 | ML 编程系列 [视频]。YouTube。可在
www.youtube.com/watch?v=f6PtJKdey8E
获取。 -
Stability-AI/stablediffusion。(无日期)。GitHub。可在
github.com/Stability-AI/stablediffusion
获取。 -
稳定扩散是如何工作的?潜在扩散模型解析。(2022 年 12 月 3 日)。Louis Bouchard。可在
www.louisbouchard.ai/latent-diffusion-models/
获取。 -
Arya, G. (2023 年 1 月 14 日). 潜在扩散模型的力量:革命性的图像创作。Analytics Vidhya。可在
www.analyticsvidhya.com/blog/2023/01/power-of-latent-diffusion-models-revolutionizing-image-creation/
获取。 -
API 文档。(无日期)。Leonardo.Ai。可在
docs.leonardo.ai/reference/getuserself
获取。 -
Ashley, K. (2021). 用人工智能创作艺术:用 AI、区块链和 NFT 创作并销售你的艺术。
第十章:安全与欺诈检测概述
“所有战争都基于欺骗。” —— 孙子
欺诈的历史与人类历史一样悠久。在加密世界中,欺诈并不令人惊讶,随着加密货币的主流化,意识到不同形式的欺诈变得愈加重要,以便能够识别它。
欺诈是企业、政府以及区块链行业尤其面临的重大问题。根据 2022 年普华永道全球欺诈年度报告,46%的受访组织表示在过去 24 个月内遭遇过某种形式的欺诈或经济犯罪。
政府出于税务目的以及打击洗钱和恐怖主义融资的需要,已经意识到这个问题。相关机构有责任执行法律,打击此类非法活动,即使涉及加密货币。对于所有涉及金融活动或货币服务业务的主体,都需要进行尽职调查,这一概念已扩展至包括集中式交易所。因此,主要的集中式交易所(CEXs)仅在验证身份证背后的人身份后才会为新用户开设账户。遵守一定的质量标准至关重要,未能遵守可能导致制裁。
加密行业也有兴趣通过合规的智能合约和无缝交易体验来巩固信任。智能合约漏洞、欺诈计划以及将加密货币作为支付手段来进行黑客攻击的行为并未助力这一目标。数据科学在解决这个问题方面已经有一段时间了,挑战在于如何将数据科学实践应用于区块链数据集,因为它具有较大的差异性且是伪匿名的。一些有趣的公司,如 Chainalysis、Elliptic 和 CipherTrace,处于区块链法医数据科学的前沿,帮助相关部门进行调查并支持用户的普遍信任。
在本章中,我们将研究地址的交易行为,训练一个机器学习模型,以确定我们是否遇到骗子。
特别地,我们将覆盖以下主题:
-
以太坊上的非法活动表现
-
以太坊交易数据的探索性数据分析
-
准备工作、模型训练和评估以标记欺诈交易
技术要求
你可以在本书的 GitHub 仓库中找到本章的所有数据和代码文件,网址为github.com/PacktPublishing/Data-Science-for-Web3/tree/main/Chapter10
。我们建议你浏览Chapter10
文件夹中的代码文件,以便跟随学习。
在本章中,我们将使用以太坊实用程序库(eth-utils
),该库包含用于与以太坊合作的 Python 开发人员常用的实用函数。根据我们的环境,我们可能需要导入其他低级别库,这些库由eth-utils
使用。
如果您尚未安装eth-utils
,可以使用以下代码片段进行安装:
pip install eth-utils
eth-utils
的文档可在eth-utils.readthedocs.io/en/stable/
找到。如果由于缺少支持库而安装失败,您可以在Chapter10/EDA.ipynb
中找到需要预先安装的完整库列表。
以太坊非法活动入门
欺诈和骗局之间存在技术上的差异。骗局是一种行为,我们在不知情的情况下支付虚假物品、转移资金或向犯罪分子提供我们的私钥。相反,欺诈指的是我们的地址上出现的任何未经授权的可疑活动。在本书中,我们将两个术语互换使用。
以太坊安全博客为刚入行加密行业的人提供了三条关键信息:
-
始终 持怀疑态度
-
没有人会免费或 打折 ETH
-
没有人需要访问您的私钥或 个人信息
截至今日,一些最常见的欺诈行为包括以下几种:
-
赠送骗局: 这些骗局基本上通过犯罪分子承诺,如果我们向某个地址发送X数量的加密货币,它将被以加倍的金额返回给我们。这些方案通常是心理上的,只为受害者提供有限的时间参与这个“机会”,产生错失良机 (FOMO) 的效果。此方案通常利用高调的 X(前身为 Twitter)账户、名人视频等。
-
IT 支持骗局: 这些骗子冒充区块链服务(如钱包、交易所、市场等)的 IT 支持或管理员人员。他们可能会向我们索要一些信息或验证我们的身份,并且通常会试图获取提取我们资金所需的最少信息。这类骗子主要出现在 Discord 讨论频道或 Telegram 上。通常可以在真实人名旁边看到短语“永远不要主动私信”。骗子会主动发起对话,试图建立联系和信任。值得记住的是,Web3 是一个去中心化的领域,因此不太可能看到支持团队在互联网上回答我们的问题。如果我们与一个有支持团队的集中式平台进行交互,团队将始终通过官方渠道联系我们。
-
网络钓鱼诈骗:这是一种社交工程攻击,通过电子邮件伪装来诱使受害者提供必要的信息以实施诈骗。邮件通常包含指向假网站的链接或下载恶意软件。正如我们在第三章中所看到的,在详细说明如何访问链外数据时,我们应该尝试通过受信任的链接访问网站——例如,通过 CoinMarketCap 或 CoinGecko。检测网络钓鱼有很多方法,但事实是它们随着时间的推移变得越来越有创意。
-
经纪人诈骗:这些是拥有大量社交媒体粉丝的交易经纪人,声称能够创造出色的利润。经纪人账户背后有一个真实的人物,他会与受害者互动,直到后者将资金转给经纪人“管理”。一旦资金转出,这些资金就会丢失。
每种诈骗都通过实际案例在这个博客中进一步解释:ethereum.org/en/security/
。
无论欺诈方案如何,资金都会通过交易转移并保存在账户中。在接下来的部分,我们将分析账户行为,尝试确定哪些账户可以信任,哪些账户应该被标记为诈骗。
预处理
我们将使用在论文《以太坊区块链上非法账户的检测》中使用的平衡数据集。你可以在进一步阅读部分找到该论文的链接。这个数据集是一个平衡数据集,包含 48 列或特征,结合了合法和非法账户。该数据集通过使用 CryptoScamDB 数据库和 Etherscan 创建,后者是我们已经熟悉的工具。cryptoscamdb.org管理一个开源数据集,跟踪恶意网址及其关联地址。
列及其描述如下:
Avg_min_between_sent_tnx
Avg_min_between_received_tnx
Time_Diff_between_first_and_last(Mins)
Sent_tnx
Received_tnx
Number_of_Created_Contracts
Unique_Received_From_Addresses
Unique_Sent_To_Addresses
Min_Value_Received
Max_Value_Received
Avg_Value_Received
Min_Val_Sent
Max_Val_Sent
Avg_Val_Sent
Min_Value_Sent_To_Contract
Max_Value_Sent_To_Contract
Avg_Value_Sent_To_Contract
Total_Transactions(Including_Tnx_to_Create_Contract)
Total_Ether_Sent
Total_Ether_Received
Total_Ether_Sent_Contracts
Total_Ether_Balance
Total_ERC20_Tnxs
ERC20_Total_Ether_Received
ERC20_Total_Ether_Sent
ERC20_Total_Ether_Sent_Contract
ERC20_Uniq_Sent_Addr
ERC20_Uniq_Rec_Addr
ERC20_Uniq_Rec_Contract_Addr
ERC20_Avg_Time_Between_Sent_Tnx
ERC20_Avg_Time_Between_Rec_Tnx
ERC20_Avg_Time_Between_Contract_Tnx
ERC20_Min_Val_Rec
ERC20_Max_Val_Rec
ERC20_Avg_Val_Rec
ERC20_Min_Val_Sent
ERC20_Max_Val_Sent
ERC20_Avg_Val_Sent
ERC20_Uniq_Sent_Token_Name
ERC20_Uniq_Rec_Token_Name
ERC20_Most_Sent_Token_Type
ERC20_Most_Rec_Token_Type
表 10.1 – 每列数据集的解释(来源 – 《检测以太坊区块链上的非法账户》论文第 10 页)
在Chapter10/EDA.ipynb
中,我们分析了数据集并得出了以下结论:
-
数据中有 4,681 个账户和 48 个特征。在这些地址中,有五个重复地址和五个无效地址。
为了判断一个地址是否有效或无效,我们使用了 EIP-55 的一部分代码,并结合一个名为
address_validation()
的自定义公式。在
address_validation()
函数中,我们添加了一个额外的条件来计算每个地址的字符数,丢弃那些不是 42 个字符的地址。如果满足两个条件,则认为地址有效,并返回带有校验和的版本。否则,返回
not an ethereum address
标志:def checksum_encode(addr): hex_addr = addr.hex() checksummed_buffer = \"\" hashed_address = eth_utils.keccak(text=hex_addr).hex() for nibble_index, character in enumerate(hex_addr): if character in \"0123456789\":checksummed_buffer += character elif character in \"abcdef\": hashed_address_nibble = int(hashed_address[nibble_index], 16) if hashed_address_nibble > 7: checksummed_buffer += character.upper() else: checksummed_buffer += character else: raise eth_utils.ValidationError( f\"Unrecognized hex character {character!r} at position {nibble_index}\") return \"0x\" + checksummed_bufferdef test(addr_str): addr_bytes = eth_utils.to_bytes(hexstr=addr_str) checksum_encoded = checksum_encode(addr_bytes) try: assert checksum_encoded == addr_str, f\"{checksum_encoded} != expected {addr_str}\" except AssertionError: return checksum_encodeddef address_validation(addr_str): if len(addr_str) == 42:result = test(addr_str) else: result = \"not an ethereum address\" return result
-
第 25 到 49 列有一些缺失值,缺失值的百分比为 17.7%。我们识别数据框中的任何缺失值,并计算每列的缺失值百分比。
我们使用以下代码片段:
Chapter10/Rebuilding.ipynb.
-
欺诈交易和缺失值位于数据集的顶部。看起来最具欺诈性的账户似乎有缺失值。请参阅
Chapter10/EDA.ipynb
中的热力图。 -
有 12 列数据方差较小(且只有一个值,即零)。方差较小的列可能对我们的训练没有帮助。这些列如下:
[\'min_value_sent_to_contract\', \'max_val_sent_to_contract\', \'avg_value_sent_to_contract\', \'total_ether_sent_contracts\', \'ERC20_avg_time_between_sent_tnx\', \'ERC20_avg_time_between_rec_tnx\', \'ERC20_avg_time_between_rec_2_tnx\', \'ERC20_avg_time_between_contract_tnx\', \'ERC20_min_val_sent_contract\', \'ERC20_max_val_sent_contract\', \'ERC20_avg_val_sent_contract\']
我们使用以下代码片段来识别这些列:
variance_df= df.nunique()
-
清理重复项和无效项后,有 2,497 个非欺诈账户和 2,179 个欺诈账户。
-
我们运行了相关矩阵,并发现有五列数据高度相关。这些列如下:
[\'ERC20_max_val_rec\', \'ERC20_min_val_sent\', \'ERC20_max_val_sent\', \'ERC20_avg_val_sent\', \'ERC20_uniq_rec_token_name\']
删除具有相似信息的列非常重要,因为冗余信息不会为我们的训练增加价值,反而可能使我们的算法学习变慢,并且如果我们需要解释模型,可能会使模型的可解释性变得更复杂。多重共线性也会影响某些模型,如线性模型。请参阅
Chapter10/EDA.ipynb
中的相关热力图。 -
两列包含分类数据(
ERC20_most_sent_token_type
和ERC20_most_rec_token_type
)非常稀疏,大多数代币只出现一次或为空。当我们按 ERC 代币进行分组时,没有明显的类别可以用来提供帮助。对这些列进行独热编码可能会导致一个稀疏的训练数据集。此外,每天都有新的代币被铸造,将这些信息加入我们的模型将创造一个很快过时的变量。
基于前面分析得出的结论,我们清理了数据以使其适应我们的需求。采取的步骤包括:
-
我们删除了重复的地址。
-
我们尝试从 Etherscan 填充缺失值。
-
我们删除了低方差的列。
-
我们删除了相关性为 0.95 或更高的列。
-
我们删除了
object
类型的列。 -
我们删除了
Address
列。 -
我们用中位数填充了 NaN 值。
让我们扩展一下 步骤 2 的预处理工作,涉及从 Etherscan 填充缺失值。现实中的数据集往往不完整,数据分析师或数据科学家的职责就是填补那些部分完成的列。填补的方式有很多种,我们在 第五章中探讨了传统方法,适用于当没有更多数据可用时。
在 Chapter10_Rebuilding
中,我们尝试了另一种方法论,即直接访问数据源,查找缺失的数据。全书中,我们列出了多个数据源,随着这一领域的不断发展,新的链上数据源将逐步可用,帮助我们完善数据集。此外,Web3 的专业化将使我们能够对数据进行推断,因为我们能理解这些数据。当我们需要在数据集里反映的某个数据点是间接的,或者并非直接来源于链上数据时,这一点尤其重要。
在从论文《检测以太坊区块链上的非法账户》中提取的数据集里,有 17% 的行缺失数据。为了补充这部分数据,我们使用了一个我们已经分析了一段时间的数据源——Etherscan。我们利用了他们免费 API 的免费层,能够补充大部分缺失的行。API 文档链接为 docs.etherscan.io/
。补充这些列的步骤在 Chapter10_Rebuilding
中进行了说明,我们提取了缺失的数据点并将其添加到数据框中。如果 Etherscan 没有记录,我们可以推断该地址并未进行过该交易。
经过这一过程后,仍然留下了一些空值行,我们用列的中位数进行了填充。通过这最后一步,我们获得了一个完整的数据集,准备好进行训练。
.csv
文件已上传至本书的 GitHub,并可通过 final.csv
访问。
关于优秀预处理的一些说明
在该领域,关于数据构建和预处理的一个典型例子是与论文 Exploiting Blockchain Data to Detect Smart Ponzi Schemes on Ethereum 相关的一个数据集(论文链接在 进一步阅读 部分提供)。该论文的目的是训练一个机器学习算法来分类庞氏骗局的智能合约。为了实现这一目标,研究人员构建了一个包含 200 个庞氏骗局智能合约和 3,580 个非庞氏骗局智能合约的数据集。对于每个合约,他们提取了字节码、交易数据和内部交易。由于内部交易没有存储在链上,研究团队重新运行了一个以太坊客户端来重现这些交易。此外,为了将字节码转换为有意义的特征或类别,团队将其转换为操作码并记录了每种操作码在智能合约中的频率。
训练模型
一旦我们完成了数据清洗和预处理,我们将数据集进行洗牌,然后将其分割为训练集和测试集。接着,我们遍历在二分类任务中表现良好的多个模型,包括 KNeighborsClassifier
、DecisionTreeClassifier
、AdaBoostClassifier
、GradientBoostingClassifier
和 RandomForestClassifier
。
然而,仅仅因为一个模型在某个数据集上表现良好,并不意味着它在另一个数据集上也能取得相同效果。这时,调整模型变得非常重要。机器学习模型有一些超参数,需要调整以适应特定数据。定制这些超参数来适应我们的数据集,将提高模型的性能。为了执行这种优化,有一些可用的工具,比如 scikit-learn 中的 GridSearchCV。
GridSearchCV
返回的 best_estimator_
将包含在其中。如果我们不知道选择哪些参数,可以运行 RandomizedSearchCV
,它会定义一个搜索空间并随机测试。两个类的文档可以在 scikit-learn.org/stable/modules/generated/sklearn.model_selection.RandomizedSearchCV.xhtml
和 scikit-learn.org/stable/modules/generated/sklearn.model_selection.GridSearchCV.xhtml
中找到。
GridSearchCV
和 RandomizedSearchCV
都有一个 cv
参数,表示交叉验证。K
个大小相等的区间用于运行 K
次学习实验。然后将结果平均化,以减少模型性能的随机性并提高其稳健性。该类通常包含在其他实现中,例如网格搜索。然而,它也可以独立使用。
有一些变化,例如分层K折叠,它确保每个分割包含每个类别相同比例的观察值,以及重复K折叠,它为每个折叠重复操作,但每次都会打乱每个分区,使其成为一个新的样本。有关这些过程的文档可以在scikit-learn.org/stable/modules/generated/sklearn.model_selection.KFold.xhtml
找到。
我们的训练结果显示GradientBoostingClassifier
模型表现最好。
评估结果
我们将使用混淆矩阵来展示模型的表现,因为它对于二分类问题非常有用。评估指标的选择将取决于所处理问题的类型。在欺诈检测的情况下,我们希望确保最小化假阴性率,因此我们将使用召回率作为评估指标。有关评估指标的详细解释,参见第五章。
结果在整个项目中的得分是 95.6%,这是一个不错的数字。
一个不平衡的数据集
一个类似的数据集也可以在 Kaggle 上找到,最初我们在第六章中进行了分析。这个数据集是一个不平衡的形式,因为只有 20%的行是欺诈性的。欺诈检测任务通常与不平衡数据有关,因为通常合法交易的数量要多于欺诈交易。某些模型可能会忽视少数类,而少数类有时正是我们感兴趣的需要检测的特定类别。为了处理不平衡数据,传统的方法是通过双向重采样数据集,或者通过过采样少数类或随机删除多数类行来进行欠采样。关于这些过程的更多文档可以在进一步阅读部分找到。
展示结果
数据实践者必须具备强大的沟通能力,以确保他们的发现能够让决策同事、客户以及所有使用这些见解的人容易理解。根据观众的不同,定制结果的展示方式至关重要。
我们可以通过仪表盘来展示分析结果,之前在本书中我们学习了如何使用 Dune analytics、Flipside 或 Covalent 来构建仪表盘。值得注意的是,并非所有的可视化分析平台都能灵活查询链上数据;有些平台仅限于传统数据库。像 Tableau 和 Power BI 这样的平台非常灵活,能够连接 API 并处理来自链上数据的复杂 SQL 查询。
我们还可以利用公司幻灯片演示文稿,并且可以通过非正式的X(前身为 Twitter)讨论串来传达数据分析的结果。无论选择何种媒介,目标都是捕获并保持观众的兴趣。以一个引人注目的问题和引言开始,保持句子简洁,只有在观众表现出兴趣时才深入细节,这些都是关键原则。一份关于创作引人入胜故事的宝贵资源可以在这个 X 讨论串中找到:twitter.com/alexgarcia_atx/status/1381066483330117632
.
无论演示平台如何,讲故事的技巧在传递发现时至关重要,要有吸引力的叙事。
摘要
总结来说,我们已经识别并讨论了加密货币领域的一个关键威胁,突出了有效交易监控和识别的必要性。为此,我们在以太坊地址层面开展了机器学习实验,利用 Etherscan 完成了我们的数据集。
我们评估并比较了各种机器学习模型,通过网格搜索超参数调优和交叉验证优化其性能。通过开展这个项目,我们深入探讨了一个法医专业人员活跃的主题,并且这个话题仍然是当前的新闻焦点。
区块链取证是数据科学应用中较为创新的领域之一,因为模型需要扩展并不断发展以适应新的变化,能够发现新类型的欺诈和诈骗。
在下一章中,我们将深入探讨价格预测。
进一步阅读
以下是供您进一步阅读的资源列表:
-
PwC. (2022). PwC 全球经济犯罪与欺诈调查报告 2022.
www.pwc.com/gx/en/forensics/gecsm-2022/PwC-Global-Economic-Crime-and-Fraud-Survey-2022.pdf
-
Furneaux, N. (2018). 研究加密货币:理解、提取和分析区块链证据. John Wiley & Sons. 第 268 页。
-
Sfarrugia15/Ethereum_Fraud_Detection. (无日期). GitHub:
github.com/sfarrugia15/Ethereum_Fraud_Detection
-
Steven Farrugia, Joshua Ellul, George Azzopardi, 检测以太坊区块链上的非法账户,《专家系统与应用》, 第 150 卷, 2020, 113318, ISSN 0957-4174:
doi.org/10.1016/j.eswa.2020.113318
. -
利用区块链数据检测以太坊上的智能合约庞氏骗局。(2019 年 3 月 18 日)。IEEE Xplore:
ieeexplore.ieee.org/stamp/stamp.jsp?arnumber=8668768
-
以太坊安全与防诈骗. (无日期). ethereum.org.
ethereum.org/en/security/
-
Senilov, I.(2021 年 9 月 27 日)。接近事务数据中的异常检测。Medium:
towardsdatascience.com/approaching-anomaly-detection-in-transactional-data-744d132d524e
-
Janiobachmann.(2019 年 7 月 3 日)。信用欺诈 || 处理不平衡数据集。Kaggle:您的机器学习与数据科学社区:
www.kaggle.com/code/janiobachmann/credit-fraud-dealing-with-imbalanced-datasets
-
Jason Brownlee.(2020 年)。用于不平衡分类的随机过采样与欠采样。机器学习精通:
machinelearningmastery.com/random-oversampling-and-undersampling-for-imbalanced-classification/
-
聚类:一旦我们完成了地址的聚类,就可以构建一个异常检测标识符,使用每个地址所属聚类的参数作为正常性标准。
Price, W.(2021 年 5 月 28 日)。聚类以太坊地址。Medium:
towardsdatascience.com/clustering-ethereum-addresses-18aeca61919d
-
Ethereum_clustering/main.ipynb at master · willprice221/ethereum_clustering.(无日期)。GitHub。
github.com/willprice221/ethereum_clustering/blob/master/main.ipynb
-
故事讲述资源:Insider.(2019 年 6 月 21 日)。皮克斯制作完美电影的秘密公式 | 电影艺术 [视频]。YouTube:
www.youtube.com/watch?v=Y34eshkxE5o
第十一章:使用时间序列进行价格预测
金融行业中,分析师和研究人员花费大量时间进行投资机会预测,包括资产价格和资产收益。随着大量数据的可用性和处理技术的进步,机器学习(ML)得到了迅猛发展,应用领域也从资产定价扩展到如保险定价、投资组合管理和风险管理等地方。
除了机器学习在金融行业中的广泛应用外,我们现在还可以考虑 Web3 和开放数据的影响。正如我们在本书中所学到的,Web3 中的数据是任何人都可以访问的。特权信息,如银行余额或重要账户变动,任何知道去哪里查看的人都可以看到,正如在第五章中所解释的那样。
金融行业中的许多资产建模和预测问题都涉及时间因素和连续输出的估计。因此,本章的重点将放在时间序列分析上,理解这些输出是什么,以及如何对其建模。我们的目标是利用包括时间因素在内的历史数据点,来预测未来的结果,特别是在预测价格的背景下。
总结一下,本章将涵盖以下主题:
-
时间序列基础
-
数据库选择和特征工程
-
模型建立、训练和结果评估
我们将同时采用传统统计模型和深度学习(DL)方法来捕捉时间序列数据中的模式和动态。
技术要求
在本章中,我们将使用statsmodels
库,特别是其时间序列分析包(tsa
和statespace
)。statsmodels
是一个全面的 Python 模块,提供了广泛的类和函数,用于估计各种统计模型,执行统计测试,并进行统计数据探索。对于时间序列分析,它提供了基本的模型,如单变量自回归(AR)模型,向量自回归(VAR)模型,以及单变量自回归滑动平均(ARMA)模型。此外,它还提供了时间序列的描述性统计,如自相关和偏自相关函数(ACF和PACF)。
如果你之前没有使用过statsmodels
,可以通过以下命令进行安装:
pip install statsmodels
statsmodels
的文档可以在www.statsmodels.org/stable/index.xhtml
找到。
我们还将使用pmdarima
,它允许我们与pmdarima
进行交互,pmdarima
作为多个统计和机器学习库(包括statsmodels
和scikit-learn
)的 Python 封装。如果你之前没有使用过pmdarima
,可以通过以下命令安装:
pip install pmdarima
pmdarima
的文档可以在 alkaline-ml.com/pmdarima/
找到。
我们还将从 yfinance
中提取我们的工作数据集,yfinance
是一个开源的 Python 库,作为 Yahoo Finance API 的接口,提供便捷的金融数据访问,包括股市价格、历史数据、股息信息等。要安装该库,我们需要运行以下命令:
pip install yfinance
yfinance
的文档可以在 pypi.org/project/yfinance/
找到。
与本章相关的所有数据和代码文件可以在本书的 GitHub 仓库中访问,点击此处查看:
github.com/PacktPublishing/Data-Science-for-Web3/tree/main/Chapter11
我们建议你阅读 Chapter11
文件夹中的代码文件,以便更有效地跟随本章内容。
时间序列基础
时间序列是一组在时间上等间隔观测值的集合。
– 路易斯·阿尔贝里科·吉尔-阿拉尼亚
吉尔-阿拉尼亚教授提到的观测值集合形成了一系列事件,这些事件随着时间的推移按时间顺序展开并发展。
这些观测值代表了随时间变化或波动的各种数据点,例如股价、温度读数、销售数据、网站流量、区块链交易数量等。每个观测值都包含关于过去的宝贵信息,并为未来的趋势提供线索。
一个代表 比特币-美元(BTC-USD)月度收盘价的 10 个月时间序列如下所示:
表 11.1 – BTC-USD 时间序列片段(来源:Yahoo Finance)
在我们分析时间序列数据时,可以识别模式、趋势和波动。这些模式可能揭示反复出现的主题,遵循清晰的轨迹,或者表现出混乱和不可预测的行为。以下是自 2015 年以来 BTC 价格的时间序列可视化:
https://github.com/OpenDocCN/freelearn-ds-pt4-zh/raw/master/docs/ds-web3/img/B19446_11_01.jpg
图 11.1 – 整个系列的图示
时间序列包括以下组成部分:
趋势:这代表系列的整体方向性运动。趋势可以是确定性的,由潜在的理由驱动,或者是随机的,表现出随机行为。
在下一个例子中,我们观察到自 2017 年以来的持续上升趋势,并且在过去 2 年中加速:
https://github.com/OpenDocCN/freelearn-ds-pt4-zh/raw/master/docs/ds-web3/img/B19446_11_02.jpg
图 11.2:趋势图
季节性:这部分指的是系列中在特定时间框架内重复出现的周期或模式。
在给定的数据集中,我们可以观察到每年中期的下降和年末的增长:
https://github.com/OpenDocCN/freelearn-ds-pt4-zh/raw/master/docs/ds-web3/img/B19446_11_03.jpg
图 11.3 – 季节性成分
白噪声:这表示系列中未被趋势或季节性成分捕获的部分。
在给定的数据集中,该成分最初看起来是平坦的,但在特定点呈现出高峰,如 2017-2018 年末和 2021 年:
https://github.com/OpenDocCN/freelearn-ds-pt4-zh/raw/master/docs/ds-web3/img/B19446_11_04.jpg
图 11.4 – 白噪声表示
为了分解时间序列以分析其成分,我们可以使用以下代码:
decompose = seasonal_decompose(df, model= \'additive\').plot(observed=True, seasonal=True, trend=True, resid=True, weights=False)
时间序列分析中还有两个相关概念:自相关和平稳性。
自相关:这指的是序列中连续点之间的依赖关系。它表明给定时间段的值受先前时间段的测量影响。自回归的顺序表示用于预测当前值的先前值数量,称为滞后。例如,如果我们使用前 2 个月的价格来预测比特币的月均价,这对应于滞后为 2 的自相关。
平稳:如果“均值和方差不依赖于时间,并且任何两个观测值之间的协方差仅取决于它们之间的距离,而不取决于具体的时间位置”(Luis Alberiko Gil-Alaña)。对于许多时间序列模型和分析,平稳性是一个重要的假设。我们可以从前述引用中得出结论,具有趋势或季节性的时间序列不能被认为是平稳的。
例如,以下时间序列示例明显呈上升趋势,因此不是平稳的:
https://github.com/OpenDocCN/freelearn-ds-pt4-zh/raw/master/docs/ds-web3/img/B19446_11_05.jpg
图 11.5 – 带有趋势的时间序列
以下时间序列随着时间的推移和趋势具有增加的方差,因此不是平稳的:
https://github.com/OpenDocCN/freelearn-ds-pt4-zh/raw/master/docs/ds-web3/img/B19446_11_06.jpg
图 11.6 – 方差时间序列
以下时间序列没有趋势或季节性,因此可以被视为平稳的:
https://github.com/OpenDocCN/freelearn-ds-pt4-zh/raw/master/docs/ds-web3/img/B19446_11_07.jpg
图 11.7 – 平稳时间序列
现在我们已经了解了理论,让我们介绍数据集。
探索数据集
对于价格预测,我们将利用两个数据集。第一个数据集是从 Yahoo Finance 提取的 BTC 价格时间序列数据,以每日为粒度。
为了提取它,我们使用 Yfinance 库和以下代码:
data=yf.Ticker(\'BTC-USD\')df= data.history (start=\'YEAR-MONTH-DAY\', end=\'YEAR-MONTH-DAY\')
该数据集包含多个列,但我们将重点关注收盘价列和日期列。date
列需要作为索引使用,并指定频率。如果数据源不是 Yfinance(它已经处理了这一点),以下代码片段可能会很有帮助:
df = df.set_index(pd.DatetimeIndex(df[\'Date\'], freq=\'D\'))
作为 Web3 数据集,相较于传统的金融股票价格数据集,它也包括了周末的价格,反映了市场的连续运营特点。在选择时间序列数据集时,必须确保没有缺失值,或者使用适当的技术处理它们。
如果只需要处理工作日,Pandas 库提供了一些额外的函数,比如USFederalHolidayCalendar
,它导入假期日历并提供假期列表:
from pandas.tseries.holiday import USFederalHolidayCalendar
CustomBusinessDay
类提供了一个参数化的 BusinessDay
类,可用于创建自定义的工作日日历,以适应本地假期和本地周末惯例:
from pandas.tseries.offsets import CustomBusinessDay
此外,我们还准备了一个由新闻文章及其对应的情感分析(SA)组成的数据集。对于我们希望建模的比特币(BTC)价格时间序列中的每一天,我们将其与一组新闻文章及其相应的 SA 匹配。我们将验证一个假设,即将来自现实世界的外部信息纳入模型中,将提高预测性能。其他可以考虑的变量包括交易量、包含BTC一词的推文数量、距下次减半事件(即比特币挖矿奖励减半,每约四年发生一次)的剩余天数等。
在探索性数据分析(EDA)过程中,可能会发现数据集中的缺失值、异常值或不规则情况。如在第一章中所讨论,有些时候由于极端波动,市场价格会暂停,例如 UST 脱钩。在处理包含这些问题的数据集时,我们应如何应对?对于平稳序列,非时间序列特定方法,如均值或中位数插补,是有效的。针对时间序列的特定技术包括最近观察值前推(LOCF),它用紧接前一个观察值填充缺失值;以及下一观察值后推(NOCB),它用紧接后一个观察值填充缺失值。另一种方法是插值,根据假定的观察值之间的关系,可以是线性、插值多项式或样条插值。有关解决这一问题的更多方法,参见进一步阅读部分。
在深入研究模型之前,重要的是要解决时间序列数据的训练-测试集拆分概念。与我们迄今为止分析的传统数据集不同,时间序列模型本质上具有内生的时间性,这正是我们希望捕捉的内容。这意味着,值在时间序列中的位置将对未来的点产生影响。为了理解并捕捉这种时间关系,我们必须保持时间序列及任何外生变量的时间顺序。随机拆分数据不适用于时间序列分析。
在这种情况下,测试数据集将由序列中最新的部分组成,而训练数据集将包括从序列开始到所选测试部分的所有行。
Sklearn 提供了一个有用的类来执行这种拆分,叫做TimeSeriesSplit
:
from sklearn.model_selection import TimeSeriesSplit
文档可以在以下链接中找到:
scikitlearn.org/stable/modules/generated/sklearn.model_selection.TimeSeriesSplit.xhtml
我们尝试解决的挑战是预测那些不包含在训练中的日期的 BTC 价格。时间序列问题可以通过使用统计建模来处理,我们将其称为传统方法,也可以通过机器学习来处理,在这种方法中我们将训练一个长短期记忆(LSTM)模型。
讨论传统的数据处理管道
初步的方法涉及统计建模,使用像 ARIMA、带外生变量的 ARIMA(ARIMAX)和自动 ARIMA 等模型。为了使用这些模型,我们需要解决两个额外的挑战:确保时间序列的平稳性和确定合适的模型阶数。
统计模型在应用于平稳时间序列时表现更好。像 ARIMA 这样的传统统计时间序列模型在处理平稳时间序列时更为有效。解决这个问题将是预处理阶段的一部分。
第二个挑战出现在建模阶段,这涉及理解数据集、确定合适的滞后和定义时间窗口。我们将使用 Auto ARIMA 算法手动接近解决方案,它会自动处理超参数。
数据预处理
可以采用多种函数将非平稳时间序列数据转换为适合我们模型的格式。例如,差分、对数变换、移动平均(MAs)、百分比变化、滞后和累积和等。
差分计算连续观测值之间的差异。这个技术通过去除某个水平的变化来帮助稳定时间序列的均值,从而减少或消除趋势和季节性。
在Traditional time series models.ipynb
笔记本中,我们从一个看起来像这样的数据集开始:
https://github.com/OpenDocCN/freelearn-ds-pt4-zh/raw/master/docs/ds-web3/img/B19446_11_08.jpg
图 11.8 – 完整时间序列
为了应用差分,我们可以使用以下代码:
df.diff().dropna()
经过这样的处理,数据集转换如下:
https://github.com/OpenDocCN/freelearn-ds-pt4-zh/raw/master/docs/ds-web3/img/B19446_11_09.jpg
图 11.9 – 差分时间序列
在某些情况下,仅进行一次差分可能无法使序列变为平稳。在这种情况下,可能需要进行第二次差分以实现平稳。
其他函数,如百分比变化、对数差分和 MA,也可以帮助减少趋势和季节性,使序列更像白噪声。对数变换在处理非恒定方差时尤其有用,而 MA 对于波动性较高的序列也有益。
为了帮助判断一个序列是否平稳,我们可以使用统计检验方法,如迪基-富勒检验。该检验是基于根的检验,重点关注与时间序列变量第一阶滞后相关的系数。如果该系数等于 1(表示单位根),则该时间序列表现为非平稳,即原假设。如果检验结果为负且具有统计学显著性,我们拒绝原假设,表明该时间序列是平稳的。还有其他类似的检验方法,如Kwiatkowski-Phillips-Schmidt-Shin(KPSS)检验或 Phillips-Perron 检验。由于解释超出了本书的范围,但它们都可以从我们使用的同一库中获得。一旦我们获得了平稳的数据集,就可以开始建模。
建模 – ARIMA/SARIMAX 和 Auto ARIMA
在用于预测未来值的统计算法中,我们遇到了 ARIMA/SARIMAX 和 Auto ARIMA。ARIMA 考虑过去的值来预测未来的值,而 SARIMAX 则结合了季节性模式和外生变量。Auto ARIMA 则基于训练数据自动化建模过程。
这些模型的名称源自其包含的概念。ARIMA代表自回归(AR)-差分(I)-移动平均(MA)。SARIMAX在此基础上增加了S,表示季节性,以及X,表示外生性,因为它可以输入独立变量。Auto ARIMA则在Auto(自动建模)前缀的基础上进一步简化了建模过程。让我们深入探讨这些概念。
AR确定时间序列自身的回归阶数。它假设最新的数据点值依赖于前一个值,并且该依赖关系具有我们确定的滞后数,即滞后观测数。
我们可以通过使用 PACF 图来确定回归阶数,该图是statsmodels
库的一部分。以下代码可用于绘制该图:
pacf_td = plot_pacf(training_data)
PACF 衡量过去值与当前值之间的直接相关性,并检查每个滞后的尖峰以确定其显著性。如果某个滞后的尖峰超出了显著性限制,则表明该滞后的相关性不为零。显著相关性的数量决定了 AR 项(p)的阶数。
I 表示使序列平稳所需的差分次数。
MA 根据过去的预测误差来建模时间序列的误差,假设当前误差依赖于先前的误差,并且具有我们确定的滞后。这本质上对应于时间序列数据上“窗口”函数的大小,并且对应于模型中的 MA (q) 部分。我们可以通过检查自相关图 (ACF) 来确定 q 的阶数。
ACF 展示了时间序列元素之间是正相关、负相关,还是相互独立的。横轴表示滞后值,尖峰显示了这些滞后值的相关性程度。我们根据远离零的统计显著尖峰,考虑一个阶数为 q 的 ACF。
为了绘制 ACF,我们可以使用以下代码,利用 statsmodels
库:
acf_diff = plot_acf(df_train_diff)
这里是开始测试模型的一个经验法则:
如果 PACF 在滞后 p 处有显著尖峰但之后没有,并且 ACF 图呈现更渐进的衰减,我们将为模型使用以下阶数:ARIMA (p,d,0):
https://github.com/OpenDocCN/freelearn-ds-pt4-zh/raw/master/docs/ds-web3/img/B19446_11_10.jpg
图 11.10 – 假设 1
如果 ACF 图在滞后 q 处有显著尖峰但之后没有,并且 PACF 图呈现出更渐进的衰减,我们将为模型使用以下阶数:ARIMA (0,d,q):
https://github.com/OpenDocCN/freelearn-ds-pt4-zh/raw/master/docs/ds-web3/img/B19446_11_11.jpg
图 11.11 – 假设 2
m
表示时间周期。它将以类似时间序列的方式建模。SARIMA 的季节性组件的具体内容如下:
SARIMA(p,d,q)
(P,D,Q)[m]
组件定义如下:
-
P
:季节性 AR 阶数。 -
D
:季节性差分阶数。 -
Q
:季节性 MA 阶数。 -
m
:单个季节性周期的时间步数。为了得到这个数字,通常需要分解我们希望预测的相似时间段(始终使用训练数据集)以观察季节性。在此分析中,我们看到季节性为 8 天。
为了评估模型,我们采用一种传统的回归指标——均方根误差 (RMSE)。RMSE 是一种统计度量,用于评估模型预测准确性,方法是计算 均方误差 (MSE) 的平方根。MSE 是原始值与预测值之间平方差的平均值。RMSE 产生一个单一、易于解释的值,代表预测模型误差的典型大小。较低的 RMSE 表示预测值与实际值之间的拟合度更好,反映了模型的预测更为准确。另一个相关指标是 平均绝对误差 (MAE),它表示数据集中实际值与预测值之间绝对差值的平均值。
RMSE 被广泛用于比较回归模型的性能,特别是因为它与因变量的单位相同,从而使得结果更容易解释。
在 Jupyter 笔记本中,我们可以观察到模型还可以进一步改进。手动建模的结果是 RMSE 值为 0.073
。
Auto ARIMA
Auto ARIMA 很好地处理了超参数调优任务。它会自动生成参数(p
,d
,q
)的最优值。
被称为赤池信息量准则(AIC)的度量,用于选择回归模型的预测变量,用来确定 ARIMA 模型的阶数。特别地,Auto ARIMA 模型在拟合过程中通过迭代来寻找能最小化 AIC 的最佳参数组合。根据文档,它类似于网格搜索,尝试不同的 p 和 q 参数组合。对于差分项,Auto ARIMA 使用如扩展的迪基-富勒(Augmented Dickey-Fuller)检验等平稳性检验,并考虑季节性。
这种方法显著改善了我们的模型,节省了时间并减少了人为错误。为了实现它,我们可以使用以下代码:
pm.auto_arima(training_data, stepwise=False, seasonal=True, n_jobs=-1, trace=True)
传入的参数如下:
-
training_data
:这是我们希望建模的时间序列数据。 -
stepwise
:一个布尔参数,控制函数是否应执行逐步搜索以找到最佳 ARIMA 模型。如果设置为True
,函数将执行逐步搜索(即,它将迭代考虑添加或删除 AR、MA 或 I 组件)。如果设置为False
,函数将通过对所有可能组合进行穷举搜索来查找最佳 ARIMA 模型,类似于网格搜索。逐步搜索较快,但可能并不总是能找到最佳模型。 -
seasonal
:一个布尔参数,指定模型是否应包括季节性成分(例如 SARIMA)。如果设置为True
,该函数将搜索数据中的季节性模式。如果设置为False
,则仅考虑非季节性的 ARIMA 模型。 -
n_jobs
:该参数控制在执行模型搜索时使用的 CPU 核心数。将其设置为-1
表示使用所有可用的 CPU 核心,这可以加快搜索过程,尤其是在数据集较大的时候。 -
trace
:这是一个调试参数。当设置为True
时,它启用详细输出,包含诊断信息和模型搜索过程中的中间结果。
实现该模型后,RMSE 显著下降;然而,仍有改进空间。现在,让我们看看如何融入特定领域或主题知识。
添加外生变量
外生变量是可以被纳入模型的附加信息。这些变量可以来自相同的时间序列,比如观察 BTC 价格在特定小时或日期的波动,或者它们可以是完全外生的,如新闻情感分析或来自 X(前 Twitter)的数据。
在我们的笔记本中,我们将每天新闻的情感作为外生变量纳入模型。该数据集的预处理包括以下内容:
-
根据
sentiment_mapping
字典将新闻情绪映射到以下标准:sentiment_mapping = { \'Positive\': 1, \'Negative\': -1, \'Neutral\': -1z-score value, which behaves as a threshold against which we will identify outliers. Those considered outliers are multiplied by 2\\. This is done with the following code in the traditional_time_series_models.ipynb file:
outliers = day_sentiment_df[z_scores > threshold]
outliers[‘sentiment_number’] = outliers[‘sentiment_number’] * 2
day_sentiment_df.update(outliers)
步骤 1 和 步骤 2 中的两个决策是数据科学家的任意决定,旨在反映加密市场通常会对新闻产生过度反应,无论是正面、负面还是中性新闻。
通过应用外生变量,ARIMAX 和 Auto ARIMA 模型显示出相较于不使用外生变量的版本,RMSE 下降,这是非常积极的:
-
rmse -
manual: 0.046
-
rmse -
auto: 0.062
我们看到,当加入外生变量时,手动调整模型的表现优于 Auto ARIMA 模型。
为了比较这些模型与 LSTM 的性能,我们可以比较 RMSE 指标,或者使用以下代码反转结果,以便比较 USD 价格。要从对数转换中反转,我们可以使用以下代码片段:
testing_data= np.exp(testing_data)forecast_test=np.exp(forecast_test)rmse_exog = np.sqrt(mean_squared_error(testing_data, forecast_test))
我们已经回顾了统计模型,现在我们继续构建深度学习(DL)模型。
使用神经网络 – LSTM
我们在第八章中详细解释了 LSTM 的工作原理。简而言之,LSTM 是一种专门设计用来检测数据序列中模式的递归神经网络(RNN)。它的独特之处在于,相比于传统的 RNN,LSTM 可以在较长时间内保留信息。LSTM 通过选择性地保留相关信息来克服短期记忆问题。
数据预处理
我们将把这个问题视为监督学习(SL)任务。为此,我们将修改训练集,具体方法如下:
-
使用
MinMaxScaler()
缩放数据集。 -
遍历缩放后的数据集,并提取当前价格(
y_train
)之前的 60 天数据,将其转换为每个价格的特征。结果将是一个训练数据集,其中有 60 个价格列作为每个 BTC 价格(y_train
)的x_train
特征。总之,对于模型学习的每个数据点,它参考的是x_train
中的前 60 天数据:
https://github.com/OpenDocCN/freelearn-ds-pt4-zh/raw/master/docs/ds-web3/img/B19446_11_12.jpg
图 11.12 – 训练数据集结构
我们使用之前的 60 天作为每一天的输入变量,将其视为输出变量。
模型构建
为了构建模型,我们将利用 Keras 库。为此,我们为模型添加了两层 LSTM,每层 50 个神经元,第一层的输入形状为我们的数据集。
我们还添加了两层全连接层,每层分别有 25 和 1 个神经元。模型结构应保持尽可能简单,并且完全可以修改:
model= Sequential ()model.add (LSTM(50, return_sequences=True, input_shape=(x_train.shape[1],1)))model.add (LSTM (50, return_sequences = False))model.add (Dense(25))model.add (Dense(1))
我们稍后会使用 Adam 优化器进行编译,并选择 mean_squared_error
作为损失度量:
model.compile (optimizer=\'Adam\', loss=\'mean_squared_error\')
为了保存回调,以便分析我们训练的结果,我们设置了 TensorBoard 工具,从一个新的文件夹中读取保存的日志:
tensorboard_callback = tf.keras.callbacks.TensorBoard(log_dir=\"./logs\")
训练与评估
我们用批量大小为 10 和 35 个 epoch 来训练我们的模型:
model.fit (x_train, y_train, batch_size=10, epochs=35,callbacks=[tensorboard_callback])
为了评估模型的预测效果,我们将构建一个包含过去 30 天数据的新数据集,这些数据未曾传递给模型。为此,我们需要遵循与数据预处理部分中训练数据集相同的步骤。我们将 60 行数据转化为x_test
中的列,这些列成为第 61 个值的特征,该值即为要预测的y
(或y_test
)。
在预测时,我们只会考虑最后 30 天的数据,并计算预测值与y_test
值之间的 RMSE。为此,我们可以使用以下代码:
np.sqrt(mean_squared_error(y_test, predictions))
如果我们绘制预测值和真实数据的图表,结果还不错。请参阅Chapter11/LSTM.ipynb
笔记本查看彩色版本:
https://github.com/OpenDocCN/freelearn-ds-pt4-zh/raw/master/docs/ds-web3/img/B19446_11_13.jpg
图 11.13 – 预测值和真实数据
对比模型的 RMSE 显示,在价格高波动的环境中,LSTM 方法表现更好,误差为$457,而最好的 ARIMA 模型误差为$1,283。
需要考虑的一些关键差异如下:
-
变量之间的关系:ARIMA 模型假设输入和输出变量之间存在线性关系。它们可以捕捉一些非线性模式,但数据中的复杂非线性依赖关系无法覆盖。LSTM 模型更适合捕捉时间序列数据中的非线性关系和长期依赖性。这使得 LSTM 模型更适合建模具有复杂时间模式的非线性和顺序数据。
-
训练复杂度:ARIMA 模型涉及估计 AR、MA 和差分项等参数。LSTM 模型和所有神经网络(NNs)一样,需要更多的计算资源和训练时间。它们涉及训练多个递归单元层次,且有大量参数。与传统统计模型相比,训练深度学习(DL)模型通常需要更多的数据和计算能力。
在我们分析的库中,可以同时检查这两种方法,比较它们的表现,并评估每个模型的准确性。
总结
在本章中,我们探讨了对 BTC 价格时间序列的分析,适用于一个持续运作、波动性高且可能对新闻事件产生夸张反应的市场。
我们首先熟悉了时间序列分析的基本概念,并介绍了传统模型,如 ARIMA 和 Auto ARIMA。对于我们的用例,我们将价格数据集转换为平稳形式,并学习如何将这些模型应用于数据。最后,我们将外部变量(如新闻)纳入模型中。这个外部信息证明是有价值的,有助于减少我们跟踪的误差指标。
此外,我们深入探讨了 LSTM 模型方法,这要求我们以不同的方式重构数据集。这涉及到对数据集的众多修改和调整,以适应 LSTM 模型的特定要求,最终取得了更好的表现。
通过采用一系列综合性技术并结合外部因素,我们在分析和预测代币价格时间序列方面获得了宝贵的洞察。这些发现为进一步探索和完善我们的模型奠定了基础。
深入阅读
为了补充本章内容,以下链接可能对您有所帮助:
-
R 中的时间序列分析第二部分:时间序列转换。(无日期)。一个展示 R 与 Python 教程的在线社区。DataScience+。
datascienceplus.com/time-series-analysis-in-r-part-2-time-series-transformations/
-
计算机科学。(2019 年,12 月 22 日)。使用 Python 和机器学习进行股票价格预测 [视频]。YouTube。
www.youtube.com/watch?v=QIUxPv5PJOY
-
Luis Alberiko Gil-Alaña。(2021)。时间序列导论 [PDF 文档]。
-
加密货币与股市指数。它们相关吗? LA Gil-Alaña,EJA Abakah,MFR Rojo。国际商业与金融研究,2020。
ddfv.ufv.es/bitstream/handle/10641/2229/cryptocurrencies%20and%20stock%20market%20indices.pdf?sequence=1&isAllowed=y
-
比特币市场中的长记忆波动建模:持久性和结构性断裂的证据。E Bouri,LA Gil-Alaña,R Gupta,D Roubaud。国际金融与经济学杂志,2019。
onlinelibrary.wiley.com/doi/abs/10.1002/ijfe.1670
-
Abulkhair, A. (2023 年,6 月 13 日)。数据插补揭秘 | 时间序列数据。Medium。
medium.com/@aaabulkhair/data-imputation-demystified-time-series-data-69bc9c798cb7
-
Jingjuewang。(2017 年,12 月 11 日)。初学者处理时间序列中的缺失值。Kaggle:你的机器学习与数据科学社区。
www.kaggle.com/code/juejuewang/handle-missing-values-in-time-series-for-beginners
-
Aldean, A. S. (2023 年,6 月 29 日)。时间序列数据插值。Medium。
medium.com/@aseafaldean/time-series-data-interpolation-e4296664b86
-
Holloway, N. (2019, March 16). 季节性和 SARIMAX. Kaggle: 你的机器学习与数据科学 社区.
www.kaggle.com/code/nholloway/seasonality-and-sarimax
-
Brownlee, J. (2020, December). 使用 Python 的预测区间理解时间序列预测不确定性. 机器学习 精通.
machinelearningmastery.com/time-series-forecast-uncertainty-using-confidence-intervals-python/
-
Chugh, A. (2022, March 16). MAE、MSE、RMSE、决定系数、调整后的 R 平方——哪个指标更好? Medium.
medium.com/analytics-vidhya/mae-mse-rmse-coefficient-of-determination-adjusted-r-squared-which-metric-is-better-cd0326a5697e
第十二章:通过图形发现营销机会
数据在营销中发挥了至关重要的作用,推动决策制定,并优化资源配置,以支持有影响力的营销活动。然而,区块链数据固有的伪名性和复杂性为营销团队带来了挑战,其中提取最大价值在很多情况下仍然是一个持续的机会。
营销团队使用的主要应用之一是聚类,它涉及将具有共同兴趣的群体进行组织,以便进行客户细分。这项技术在社交网络中取得了很大成功,促进了产品推荐系统的发展,并推动了新的连接。
类似于社交网络,区块链数据凭借其大量交易,具有从少量互动中推断偏好的巨大潜力。标签分类是另一个有价值的应用场景,它帮助营销团队有效地识别和定位区块链中的社区。通过辨识社区,数据科学家可以帮助营销人员克服伪名性带来的限制,并获得有价值的洞察。
在本章中,我们将深入探讨以下主题:
-
图形入门
-
数据库选择与特征工程
-
建模、训练与评估结果
在本章结束时,我们将全面了解如何利用网络和图形的力量来制定有效的营销策略。
技术要求
在本章中,我们将利用networkx
库,这是一个用于处理网络或图形的 Python 库。它提供了一系列工具和功能,用于创建、操作和分析网络。该库便于创建节点、添加信息,并提供用于分析和探索网络的算法,如寻找最短路径、计算中心性度量和检测社区。
如果你以前没有使用过networkx
,可以通过以下代码片段进行安装:
pip install networkx
networkx
的文档可以在networkx.org/documentation/stable/index.xhtml
找到。
我们还将使用Gephi,一款免费的开源图形绘制工具。Gephi 是一个用户友好的工具,旨在可视化和探索图形和网络。它帮助用户深入洞察并分析图数据中的复杂关系。
使用 Gephi,我们可以从各种格式中导入数据,并选择特定的节点,以了解它们在数据集中的位置。该工具提供了众多统计功能来支持图形分析。它允许我们根据特定标准过滤、排序和操作图形,使我们能够聚焦于相关的节点和边。
如果你之前没有使用过 Gephi,可以从他们的页面下载:gephi.org/
。关于 Gephi 的全面指南可以在《Gephi Cookbook》一书中找到,点击此处查看:www.packtpub.com/product/gephi-cookbook/9781783987405
。
对于我们的机器学习模型,我们将使用 StellarGraph 库。StellarGraph 专为处理图结构数据而设计,特别适用于与机器学习和数据分析相关的任务。它的一个关键特点是与流行的机器学习框架(如 TensorFlow 和 Keras)的集成。StellarGraph 提供了将图转换为这些框架兼容格式的方法,使我们能够将机器学习模型和算法应用于图结构数据。StellarGraph 的文档可以在stellargraph.readthedocs.io/en/stable/
找到。
如果这是你第一次使用这个库,你可以通过pip
安装它:
pip install stellargraph
与本章相关的所有数据和代码文件,以及彩色图像,可以在本书的 GitHub 仓库中找到,网址是:https://github.com/PacktPublishing/Data-Science-for-Web3/tree/main/Chapter12。
我们建议你阅读Chapter12
文件夹中的代码文件,这样你可以更有效地跟随本章的内容。
图论入门
根据伊纳尔·利夫的说法,“网络科学,有时被认为是数据科学的一个子领域,有时被认为是一个独立的学术领域,是研究网络结构模式的一系列技术、方法和工具。” 一个网络的示例是伦敦地铁图的图像:
https://en.wikipedia.org/wiki/File:Beck_Map_1933.jpg,属于合理使用)](https://github.com/OpenDocCN/freelearn-ds-pt4-zh/raw/master/docs/ds-web3/img/B19446_12_01.jpg)
图 12.1 – 贝克设计的伦敦地铁图概述(来源:en.wikipedia.org/wiki/File:Beck_Map_1933.jpg
,属于合理使用)
在我们对网络和图的探索中,我们将交替使用这些术语。
近年来,网络研究因其能够简单地解释实体之间的关系而受到广泛关注。正如马蒂亚斯·阿维拉教授所解释的,“网络,也称为数学文献中的图,是由一些节点组成的集合,其中某些节点通过边连接在一起 *。”
在本教程中,我们将探索图的基本概念,包括它们的定义和特点。
一个网络由节点(也称为顶点或 V)组成,这些节点通过连接(或边或 E)相互链接。图或网络通常表示为 G,表示法为 G=(V,E)。
在图 12.2中,我们可以观察到地址 0xdac17f958d2ee523a2206206994597c13d831ec7
和 0x28C6c06298d514Db089934071355E5743bf21d60
之间网络内图的组成部分:
https://github.com/OpenDocCN/freelearn-ds-pt4-zh/raw/master/docs/ds-web3/img/B19446_12_02.jpg
图 12.2 – 两个地址之间的关系
数据分析师的角色是从数据中提取有意义的见解和可操作的洞察。一旦我们找到了有意义的连接,添加上下文就显得尤为重要。例如,在图 12.3中,我们正在查看 USDT 智能合约与 Binance 地址之间的关系:
https://github.com/OpenDocCN/freelearn-ds-pt4-zh/raw/master/docs/ds-web3/img/B19446_12_03.jpg
图 12.3 – 两个标记地址之间的关系
图的类型
有向图(digraphs),由 Stamile、Marzullo 和 Deusebio 定义,表示为“一个对,G=(V,E),其中 V 是节点集合,E 是表示两个节点之间连接的有序对集合。”E 中的元素是有序的,表示从一个节点(通常称为“源”)到另一个节点(通常称为“目标”)的方向:
https://github.com/OpenDocCN/freelearn-ds-pt4-zh/raw/master/docs/ds-web3/img/B19446_12_04.jpg
图 12.4 – 有向图示例
在 有向图 中,节点可以分为入度(指向某节点的边的数量,表示图中有向边指向该节点的节点)和出度(从某节点出发的边的数量,表示图中该节点有向边指向的节点)。入度和出度提供了关于节点连接性和影响力的见解。理解这个概念对于各种图分析任务非常有价值,比如识别中心节点、研究信息流、检测有影响力的节点、评估有向网络的结构和动态。
自我图,也称为邻居图,专注于一个特定的节点,称为“自我”节点。它显示自我节点及其所有邻居节点,以及连接它们的边。自我图对于分析特定节点周围的局部结构和连接非常有用:
https://github.com/OpenDocCN/freelearn-ds-pt4-zh/raw/master/docs/ds-web3/img/B19446_12_05.jpg
图 12.5 – 自我图示例
加权图是每条边都有一个相关权重或值的图。权重是数值,可以表示连接的节点之间关系的各种特征,如强度、距离、成本、连接频率等。权重提供了额外的信息,可用于分析、训练和推断:
https://github.com/OpenDocCN/freelearn-ds-pt4-zh/raw/master/docs/ds-web3/img/B19446_12_06.jpg
图 12.6 – 加权图示例
还有许多其他具有独特特征和用途的图形模式,它们超出了本介绍的范围。那么,为什么图形模式对我们的数据分析如此重要呢?图形模式有助于揭示区块链中地址之间关系的动态变化。在一篇名为可视化动态比特币交易模式的文章中,作者解析了这些模式并提供了相应的解释:
https://github.com/OpenDocCN/freelearn-ds-pt4-zh/raw/master/docs/ds-web3/img/B19446_12_07.jpg
图 12.7 – 比特币区块中的图形模式示例
归属
可视化动态比特币交易模式,Dan McGinn 等,2016;由 Mary Ann Liebert, Inc.出版。
本开放获取文章根据创作共用许可证(creativecommons.org/licenses/by/4.0
)分发,允许在任何媒介中不受限制地使用、分发和复制,只要正确引用原始作品。
在接下来的部分中,我们将分析属于两个具有不同特征的社区的地址数据集——一个与 OpenSea NFT 市场相关,另一个与名为 Binance 的集中式交易所相关。每个地址与其社区之间的关系特征可以通过图中形成的模式观察到:
https://github.com/OpenDocCN/freelearn-ds-pt4-zh/raw/master/docs/ds-web3/img/B19446_12_08.jpg
图 12.8 – 目标社区之间的关系
图形属性
根据 Stamile、Marzullo 和 Deusebio 提出的分类方法,我们发现分析整合度量和隔离度量是很有帮助的。
整合度量显示了节点之间相互连接的趋势。在这些度量中,我们有距离和最短路径。
距离定义为“从给定的源节点到达目标节点所需经过的边的数量”。最短路径是与两个节点之间所有可能路径相比,边数最少的路径。如果图是加权的,它是具有最小边权和的路径。我们对这一概念感兴趣,因为它将帮助我们识别重要的节点。
另一个与最短路径相关的度量是特征路径长度。它被定义为所有可能的节点对之间最短路径长度的平均值。
另一类度量是隔离度量,顾名思义,它们寻找节点之间更可能存在的相似关系模式。它们识别出互联节点的群体,这些群体被称为社区。在这些度量中,我们有聚类系数和模块度。
聚类系数是衡量节点之间倾向于聚集(或“聚类”)的程度。其原理是节点与相似节点之间的聚集程度要高于与随机节点之间的聚集。聚类系数基于三角形或三重组的划分,它由三个节点和三条边组成。它研究节点的邻居之间也是否是邻居的比例。这里存在局部和全局聚类系数。
模块化衡量一个网络的强度,以便它可以被划分成模块或社区。如果一个网络的模块化高,意味着在一个社区内部的节点之间连接密集,而不同模块之间的节点连接稀疏。Gephi 工具和 Networkx 库都可以帮助我们计算模块化并识别社区。
图 12.9 显示了将在下一部分介绍的数据集,数据集以两种颜色呈现,每种颜色对应一个已检测到的社区:
https://github.com/OpenDocCN/freelearn-ds-pt4-zh/raw/master/docs/ds-web3/img/B19446_12_09.jpg
图 12.9 – 应用 Gephi 筛选条件的数据集社区
该图是使用 Gephi 创建的,并应用了以下筛选条件:
-
拓扑筛选器:巨型组件
-
度数范围:大于 3
-
节点大小:介数中心性
-
节点颜色:模块化 2.0
让我们深入了解这个数据集!
数据集
数据集包含一系列目标地址为 Binance 或 OpenSea 的交易。这些实体由多个地址提供服务,为了简化,我们选择了其中一个与它们相关联的地址。
Binance 14 地址(0x28c6c06298d514db089934071355e5743bf21d60
)代表一个 Binance 热钱包,用于促进中心化交易所与以太坊之间的连接。这个钱包中的资金用于 Binance 之外的存取款。
另一方面,OpenSea 的地址,特别是 Wyvern Exchange v2(0x7f268357a8c2552623316e2562d90e642bb538e5
),对应 OpenSea 的市场合约。
要使用 Flipside 复制此数据集,我们可以使用以下查询:
sql =SELECT from_address, to_address, tx_hashFROM ethereum.core.fact_transactionsWHERE block_timestamp >= \'2023-01-01T00:00:00.000Z\' and block_timestamp <= \'2023-06-01T00:00:00.000Z\' and to_address in (\'0x28c6c06298d514db089934071355e5743bf21d60\', \'0x7f268357a8c2552623316e2562d90e642bb538e5\') limit [800]
对于可视化,我们可以使用 Graph Machine Learning 中提出的 draw_metric
函数,该函数突出显示在讨论的指标下具有较高值的节点。我们将进行的分析可以在 Chapter12/features.ipynb
中找到,结果 DataFrame 名为 influencer_nodes.csv
。
介数中心性是一个衡量指标,表示一个节点作为最短路径中桥梁的次数。经过该节点的最短路径数量越多,介数中心性就越大。
有趣的是,在influencer_nodes.csv
中,我们可以观察到 USDT 和Wrapped Ethereum(WETH)稳定币节点具有较高的介数中心性,分别与 Binance 和 OpenSea 连接。下图展示了具有较高介数中心性的节点:
https://github.com/OpenDocCN/freelearn-ds-pt4-zh/raw/master/docs/ds-web3/img/B19446_12_10.jpg
图 12.10 – 数据集中的介数中心性
以下信息来自 CSV 文件,经过Betweenness
Centrality
列筛选:
0x28c6c06298d514db089934071355e5743bf21d60
0.494010213
0x7f268357a8c2552623316e2562d90e642bb538e5
0.323956896
0xdac17f958d2ee523a2206206994597c13d831ec7
0.173128355
0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2
0.16215128
表 12.1 – 经过介数中心性列筛选的数据
度数是指与特定节点直接相连的连接或节点的数量。连接较多的节点通常具有更强的影响力和中心性。
在influencer_nodes.csv
中,我们可以看到,与 Binance 连接的有 USDT 和 USD Coin,与 OpenSea 连接的有 WETH 和 Seaport 1.1 地址(是 OpenSea 基础设施的一部分):
https://github.com/OpenDocCN/freelearn-ds-pt4-zh/raw/master/docs/ds-web3/img/B19446_12_11.jpg
图 12.11 – 数据集中的度数
以下信息来自 CSV 文件,经过Degree
列筛选:
0x28c6c06298d514db089934071355e5743bf21d60
0.370160529
0x7f268357a8c2552623316e2562d90e642bb538e5
0.101038716
0xdac17f958d2ee523a2206206994597c13d831ec7
0.094428706
0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48
0.046270066
0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2
0.16215128
0x00000000006c3852cbef3e08e8df289169ede581
0.029272899
表 12.2 – 经过度数列筛选的数据
在influencer_nodes.csv
中,我们可以看到,具有较接近中心性的地址是连接在两个介数中心性较高的地址之间的节点(Binance 14 和 OpenSea: Wyvern Exchange v2)。它们作为两个社区之间的桥梁:
https://github.com/OpenDocCN/freelearn-ds-pt4-zh/raw/master/docs/ds-web3/img/B19446_12_12.jpg
图 12.12 – 数据集中的接近中心性
以下信息来自 CSV 文件,经过Closeness
Centrality
列筛选:
0x411c104dcec01380ee86ea2d090ed3450850f1d6
0.33197098
0x28c6c06298d514db089934071355e5743bf21d60
0.33030801
0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2
0.32937989
0x6e785f2fdbdc899f8f08cc1517f82a585b44f9c5
0.32602094
表 12.3 – 通过接近中心性列筛选的数据
特征值中心性显示了一个节点在网络中的影响力,考虑到它与之连接的节点的得分。如果它与得分较高的节点连接,则中心性将更高。对于本次分析,我们需要尊重社区,因为节点在某个特定社区中会变得很重要。
如果我们计算 Binance 社区内的特征值中心性,我们会看到 USDT 稳定币智能合约和美元稳定币 USD Coin 具有最高的特征值中心性。随后地址值的下降表明,通常这些地址通过稳定币地址连接以到达 Binance:
https://github.com/OpenDocCN/freelearn-ds-pt4-zh/raw/master/docs/ds-web3/img/B19446_12_13.jpg
图 12.13 – Binance 社区的特征值中心性
以下信息来自 CSV 文件,通过Class1_ecentrality
列进行筛选:
0x28c6c06298d514db089934071355e5743bf21d60
0.669654742
0xdac17f958d2ee523a2206206994597c13d831ec7
0.198603275
0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48
0.080423932
表 12.4 – 通过 Class1_ecentrality 列筛选的数据
对于 OpenSea 社区,第一个两个地址和其余地址之间的差距较小。作为去中心化结构,得分较为分散。我们可以在主要节点中看到 Wrapped Eth、Uniswap 和一个名为renethecat.eth
的收藏家的地址(opensea.io/ReneTheCat
):
https://github.com/OpenDocCN/freelearn-ds-pt4-zh/raw/master/docs/ds-web3/img/B19446_12_14.jpg
图 12.14 – OpenSea 社区的特征值中心性
以下信息来自 CSV 文件,通过Class0_ecentrality
列进行筛选:
0x7f268357a8c2552623316e2562d90e642bb538e5
0.553669353
0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2
0.227218243
0x00000000006c3852cbef3e08e8df289169ede581
0.208338034
0xef1c6e67703c7bd7107eed8303fbe6ec2554bf6b
0.17412939
0x6e785f2fdbdc899f8f08cc1517f82a585b44f9c5
0.133520629441651
表 12.5 – 通过 Class0_ecentrality 列筛选的数据
执行这种类型的分析有助于我们确定特定社区中的影响力节点。影响力的概念取决于上下文。例如,如果我们正在分析一个中心化交易所,我们可以了解他们使用哪些地址作为储备,他们的客户主要使用哪些稳定币,等等。而对于一个去中心化的 NFT 市场,其中个人通过自己的地址进行交易,我们可以识别出收藏家、收藏智能合约等。
根据之前的分析,我们发现一个标记为“rene the cat”的地址具有影响力。如果我们结合 OpenSea 和 X(前 Twitter)的链下信息(这两个 API 在本书的第三章和第四章中有详细介绍),我们可以检索到以下来自区块链数据的可操作数据:
-
0x6e785f2fDbdc899F8F08cc1517F82A585b44F9c5
-
OpenSea 收藏:
opensea.io/ReneTheCat
-
Twitter 账号:
twitter.com/mmendiguchiia
关于展示的说明
有时候,将图形分析结果展示给没有数据背景的观众可能会具有挑战性。通常建议以表格形式展示关键节点,提供一种用户友好的格式,根据所选标准(如最高的接近度、介数中心性等)概览列出的个体。这种方法使我们能够突出在多个排行榜上出现的个体,如本节所示。这样,观众可以轻松识别并理解这些节点的重要性。
通过这一分析,我们已识别出影响力节点。在接下来的部分中,我们将关注被影响的节点,即属于某个社区的节点。
节点分类
正如本章介绍所提到的,在处理大型图时,例如不断增长的区块链交易数据,我们可能只有部分节点带有标签。这些标签指示特定的协议、用户兴趣以及市场细分群体。挑战在于扩展标签,使得随着所有节点被添加到网络中,它们可以归属到一个特定的群体或社区。此练习在Chapter12/Graphsage_node_classification.ipynb
中进行。
在这个特定案例中,我们计划构建一个营销解决方案,但图分析也可以用于发现潜在的欺诈检测或洗钱行为。
在本次练习中,我们将使用 GraphSAGE,它是建立在图卷积网络基础上的模型。GraphSAGE 是一个用于图的归纳式深度学习模型,可以处理新增节点而无需重新训练。这一特性对于不断增长的交易数据特别有利,因为随着新的地址和交易的不断加入,我们不需要生成新的训练数据来为整个网络创建新的模型。GraphSAGE 已在 StellarGraph 库中实现。
GraphSAGE 能够预测新节点的嵌入。为了实现这一点,模型学习聚合器函数,这些函数能够基于节点的特征和其邻域的特性生成新节点的嵌入。
图 12.15 显示了我们数据集的简化版本,其中可以观察到两个社区。GraphSAGE 通过对节点的局部邻域进行采样和聚合信息来生成节点嵌入,从而捕捉图中的结构属性和关系。该算法通过考虑邻居节点的嵌入并聚合其信息来迭代更新嵌入。这使得 GraphSAGE 能够在利用局部邻域信息的同时捕捉图的全局结构:
https://github.com/OpenDocCN/freelearn-ds-pt4-zh/raw/master/docs/ds-web3/img/B19446_12_15.jpg
图 12.15 – GraphSAGE 学习步骤
这个过程被称为 归纳 学习,因为模型可以推断出一般原则是从一系列观察中得出的,类似于我们大脑的功能。有关该过程的更多技术解释,请参阅本章的 进一步阅读 部分。
准备工作
对于这个模型,我们需要提供一个 edges 数据集和一个 features 数据集。
edges 数据集与我们在前一部分分析的相同,由与 Binance 14 和 OpenSea 地址交互的交易组成。
influencers.csv
文件是 Chapter12/features.ipynb
笔记本的输出。从这个数据集中,我们将只使用基于特征标准(如介数中心性、节点度数等)的 30 个最重要节点。对于 edges 数据集中的每个节点,我们将分析它们是否与这 30 个顶级影响力节点有任何交易。
此外,我们将向 Louvain 社区检测算法(包含在 Networkx 库中)提供一个模块化字典,以确定每个节点在 edges 数据集中的社区分配。我们将使用 best_partition
函数,它通过 Louvain 启发式方法计算图节点的划分,并最大化模块化。此过程的代码片段如下:
partition = community.best_partition(G)
这个过程的结果是一个平衡良好的数据集,其中每个节点有 30 个特征,包括名为 community
的目标列,其值为 0
和 1
。这是一个二分类任务,针对两个社区,但也可以用更多类别重新创建这个练习。
建模
使用模型的第一步是从数据集创建一个 StellarGraph 对象。可以通过以下代码片段使用这两个数据集创建图形来实现:
from stellargraph import StellarGraphG = StellarGraph({\"features\": addresses_no_community}, {\"transactions\": edges})
此外,我们有两个标签:{\'community 0\'
和 \'community 1\'}
。这些标签需要进行编码。我们将使用来自 scikit-learn 库的 binarize
标签来执行该任务。
与所有机器学习任务一样,我们必须使用传统的model_selection.train_test_split
函数将数据分割为训练集和测试集,这个函数来自 scikit-learn。
我们将构建一个GraphSAGENodeGenerator
对象,将采样子图中的节点特征输入到 Keras 中:
graphsage_model = GraphSAGE( layer_sizes=[32, 32], generator=generator, bias=True, dropout=0.5,)
偏差、dropout 和层的概念在第六章中介绍。
预测层将采用 sigmoid 激活函数,因为这是一个二分类问题。如果需要预测更多类别,可以将激活函数改为 softmax:
prediction = layers.Dense(units=train_targets.shape[1], activation=\"sigmoid\")(x_out)
训练与评估
我们将使用 20 个 epochs 来训练模型。在这里,我们关注的是使用accuracy
作为评估指标。损失指标是binary_crossentropy
,这与我们正在处理的二分类任务一致。我们将使用shuffle
来确保在每个 epoch 前对数据进行洗牌:
history = model.fit( train_gen, epochs=20, verbose=2, shuffle=True)
由于结果已被编码,要解读它们,我们必须将其转回原始格式。为此,我们可以使用以下代码片段:
target_encoding.inverse_transform(all_predictions)
测试集上的准确率为 99%。要查看结果,我们需要创建一个新的 DataFrame,包含两列——一列包含预测的社区,另一列包含实际的标签。该 DataFrame 和混淆矩阵在笔记本中展示。
最后,可以在进一步阅读部分找到 GraphSAGE 演示的列表。
总结
总结来说,本章深入探讨了图网络的基本原理,探索了节点特征、图的类型及其在数据分析中的重要性。通过理解这些基础概念,我们为进一步探索和分析复杂网络奠定了基础。
在此基础上,我们进一步探索了在由两个不同社区——一个集中化的,如 Binance,另一个去中心化的,如 OpenSea——之间互动形成的图中,有影响力节点的特征。
营销解决方案在 Web3 经济的这一阶段至关重要。像 Spindl 这样的公司正在积极构建工具,旨在弥合 Web2 和 Web3 世界之间的信息与粒度差距。为了实现这一目标,它们集中精力研究归因机制,衡量广告对协议的实际影响。一旦归因完成,就需要识别目标社区以进行营销活动。为了实现这一目标,我们采用了 GraphSAGE 算法进行节点分类任务。这种方法使得有限的标签可以扩展到日益增长的 Web3 交易数据。
这是本书第二部分的最后一章。在第三部分中,我们将分析一些实际的建议,以便你能够在理解领先公司专业人士观点的同时,开始 Web3 数据科学的职业生涯。
进一步阅读
要了解本章中涉及的主题,可以查看以下资源:
-
Stamile, C., Marzullo, A., 和 Deusebio, E.(2021 年)。图机器学习:通过应用机器学习技术和算法将图数据提升到新高度。Packt Publishing。
-
Liiv, I.(2021 年)。加密货币 区块链的数据科学技术。Springer。
-
Spindl。(无日期)。介绍:
docs.spindl.xyz/spindl/overview/introduction
。 -
关于 GraphSAGE:
-
Ruberts, A.(2021 年 5 月 4 日)。GraphSAGE 在 Python 中的分类应用。Well Enough:
antonsruberts.github.io/graph/graphsage/
. -
Özçelik, R.(2019 年 10 月 25 日)。GraphSAGE 的直观解释。Medium:
towardsdatascience.com/an-intuitive-explanation-of-graphsage-6df9437ee64f
.
-
-
演示:
-
StellarGraph 基础知识 – StellarGraph 1.2.1 文档。(无日期)。欢迎访问 StellarGraph 文档!– StellarGraph 1.2.1 文档:
stellargraph.readthedocs.io/en/stable/demos/basics/index.xhtml
. -
攻击者可追溯性通过图分析在以太坊上的应用。(2022 年 1 月 27 日)。开放获取研究期刊与论文出版 | Hindawi:
www.hindawi.com/journals/scn/2022/3448950/
. -
使用网络图可视化以太坊区块链上的潜在欺诈。(2022 年 9 月 29 日)。NVIDIA 技术博客:
developer.nvidia.com/blog/using-network-graphs-to-visualize-potential-fraud-on-ethereum-blockchain/
.
-
-
NFT 数据集:
- Blog_scripts/nft_network_analysis_blog_06042022/nft_analytics/nft_analytics_notebook.ipynb 在主分支 · onthemarkdata/blog_scripts。(无日期)。GitHub:
github.com/onthemarkdata/blog_scripts/blob/main/nft_network_analysis_blog_06042022/nft_analytics/nft_analytics_notebook.ipynb?nvid=nv-int-txtad-930904-vt46#cid=an01_nv-int-txtad_en-us
.
- Blog_scripts/nft_network_analysis_blog_06042022/nft_analytics/nft_analytics_notebook.ipynb 在主分支 · onthemarkdata/blog_scripts。(无日期)。GitHub:
-
NNs(图神经网络):
-
Prodramp。(无日期)。觉得图神经网络(GNN)难以理解吗?试试这个两部分系列。[视频]。YouTube:
www.youtube.com/watch?v=YdGN-J322y4
. -
Avkash Chauhan。(无日期)。你想了解 Python 中的图神经网络(GNN)实现吗? [视频]。YouTube:
www.youtube.com/watch?v=VDzrvhgyxsU
. -
DeepWorks/GraphNeuralNetworks/Part2_Example2NodeClassification.ipynb 位于主分支 · prodramp/DeepWorks。 (无日期)。GitHub:
github.com/prodramp/DeepWorks/blob/main/GraphNeuralNetworks/Part2_Example2NodeClassification.ipynb
。
-
第三部分 附录
本书的这一部分,我们将探索如何使用我们已获得的知识。我们将深入研究潜在的职业路径,并从 Web3 数据领域的领袖们那里了解他们的经历——他们如何到达现在的职位、他们对未来的愿景,以及他们看重的专业人士素质。
本部分包含以下章节:
-
第十三章,构建加密数据经验 – BUIDL
-
第十四章,与 Web3 数据领域领袖的访谈
-
附录 1
-
附录 2
-
附录 3