要迁移的数据库可以具有广泛的数据表示形式和内容。从简单的数字数据字段到具有复杂结构和内容的字段,其中可能包含文件、图像、表格甚至复杂的自定义对象(例如,XML、CLOB、BLOB 等格式)。
使用具有一些基本知识和值集的传统方法可以轻松且非常有效地发现更简单的数据。然而,随着数据变得更加复杂,这种效率会降低,直到传统方法不再足够。
例如,此类更复杂的数据可以是非结构化文本或二进制文件,其类型和内容无法清楚地识别和解释。为了便于讨论,我们忽略这样一个事实:在数据库中使用此类数据类型仅在少数特定情况下才合理,因为在迁移复杂系统时经常会出现此问题。这些复杂的数据格式通常是非结构化的,在结构上只是给定字段中的一组字节,由于文档不完整,用户通常没有可靠的信息。如果没有元信息,就很难得出有关内容类型及其解释的结论。因此,我们的首要任务是确定这些字段包含哪些类型的数据。
识别文件类型的最明显方法是检查其扩展名,但是当存储在数据库中时,此信息通常不可用,或者即使可用,也无法以最大的可信度使用。假设只有二进制版本的数据可用,即二进制大对象(BLOB),第一步是加载它。根据文件的格式,所有元数据都编码在此 BLOB 中。
根据文件的格式或数据类型,文件中的元数据可能出现在文件中的多个位置,或者在文件头中,或者在文件末尾。除了标识文件格式之外,文件头还可能包含有关文件及其内容的元数据。基于字符的(文本)文件通常具有基于字符的标头,而二进制格式通常具有二进制标头,尽管这不是标准,只是行业惯例。
不同文件类型中字节值的分布显示每种类型的不同模式。早期的尝试侧重于整个文件的字节分布,但最近的方法执行不同的采样,例如仅分析文件开头、结尾和中间的样本。这些样本可以提供良好的基础 机器学习,它可以使用基于不同分布构建的模型来确定(以一定概率)未知文件的类型。在一个基于的过程中 BFD (字节频率分布),不需要读取整个文件,节省了时间。对从文件中多个位置提取的值进行统计分析,以获得特定于该文件的指纹。根据此指纹,机器学习能够在模型中找到最适合它的文件类型(我们用已知文件教它的文件类型)。
下图展示了一些文件类型的字节分布:
请注意,本文中的所有代码和输入/输出数据示例均来自 Clarity Consulting 米格农 工具。该数据迁移辅助软件是一个多年研发项目的成果,部分由欧盟资助。
将机器学习应用于文件格式识别
机器学习可以成为文件格式识别的有效方法,尤其是在处理大型数据集时。文件格式检测可以考虑以下模型:
- 朴素贝叶斯:适用于基于字节或序列的分析,其中考虑了每种文件格式的典型特征,例如字节分布或特征模式。
- 支持向量机 (SVM):当需要根据字节频率定义文件格式之间的边界(即决策面)时,这是一个不错的选择。
- 随机森林:在集成学习方法中,经常使用随机森林,因为它可以处理许多不同的文件格式,并且可以应对噪声数据。
- 卷积神经网络 (CNN):CNN 能够识别字节分布模式,并且可以将文件视为图像,其中字节频率被解释为“像素”,从而识别不同的文件格式。
- 自动编码器:可用于无监督学习,特别是在尝试检测字节模式与给定文件格式的通常字节模式不同的文件时用于异常检测。
- K 最近邻 (KNN):对于小型数据集,这可能是一种简单但有效的方法,可以根据最近邻居的相似性来识别文件格式。
- 循环神经网络 (RNN):由于 RNN 可以有效地处理顺序数据,因此它们对于文件中的字节序列很重要的任务非常有用。
对于自动文件格式识别, 光GBM (光梯度增强机)模型可能是一个不错的选择,原因有几个。首先,它在大型且多样化的数据集上非常高效,针对快速学习和预测进行了优化,因此在具有大字节分布或许多样本的文件格式分析中表现良好。它需要很少的内存,这在检测和分类系统中的多种文件格式时是一个重要的考虑因素。它是梯度增强模型系列的成员,可以有效地对复杂的决策面进行建模,并且这种准确性在字节频率可能具有离散分布的文件格式检测中至关重要。
LightGBM 解决方案是数据驱动的,由于我们需要大量数据来构建适当质量的模型,因此我们在示例中为此创建了一个准自动下载系统。为了实现我们的自动下载系统,我们在 Python 中使用 Selenium 来通过 Firefox 驱动程序控制浏览器。这使我们能够搜索链接和 HTML 元素,然后对它们执行操作,例如单击或输入数据。在自动下载过程中,我们处理了 CSV、DOC、DOCX、XML、JPG、JSON、PDF、PNG、XLS 和 XLSX 等文件类型,但某些文件(例如 MP3 或 AVI)必须手动收集和处理。文件是从各种来源收集的,例如 kaggle.com 收集 CSV 和 JSON 文件,而 PNG 和 JPG 图像则从 imgur.com 下载。 YouTube 视频从 btclod.com 以 MP4 格式下载,并使用 WinFF 转换为 AVI。对于 ZIP 文件,压缩和下载由单独的 Python 脚本处理。自动下载被仔细组织成适当的目录结构。下载量和数据质量由程序内的参数控制。我们的一些测试数据是手动收集的,以确保存在不同的文件,但我们无法收集足够数量的每种文件类型,因此在许多情况下,自动下载仍然是生成输入的主要方法。
获得的输入数据量如下:


认识到引言中提到的字节频率分布模式的细节是在收集的数据上构建 LightGBM 模型的基础。处理完整的字节列表的成本很高,因此为了确定文件扩展名,需要通过 BFD 过滤数据,这可以看作是一种“部分指纹识别”。使用它作为输入数据,我们能够确定模型的某些文件的类型。这是通过从字节数组创建频率哈希映射来完成的,其中键是字节,值是出现的次数。由于键是正数(0 到 255),因此该 HASH-MAP 可以轻松转换为数组,从而加快规范化过程。在这种情况下,归一化意味着根据频率值构建概率分布。结果,归一化频率的总和将为 1。该归一化形式将是 BFD。
测试和调整模型
定义文件扩展名的主要问题是使用 256 字节的初始模型无法区分相似的格式,例如 XML、JSON、ZIP、DOCX 和 XLSX。其中,ZIP 格式尤其令人困惑,因为 DOCX 和 XLSX 都包含包装在 ZIP 文件中的 XML。 XML 和 JSON 之间的混淆也很常见,因为它们在结构上非常相似。由于这些因素,这些文件类型的模型准确性仍然很低,因此有必要改进模型并引入新功能。
为了提高准确性,添加了以下功能
- 字节率为 60、62
- 字节率为 123、125
- SharedStrings 字节系列
为了完善模型,我们引入了几个特定于字节的特征来识别不同的文件类型。例如,字节 60 和 62 对应于“<”和“>”符号,在准确识别 XML 文件方面发挥了关键作用。同样,代表“{”和“}”字符的字节 123 和 125 在识别 JSON 文件时很有用。为了识别 DOCX 文件,我们使用了“ 对于 XLSX 文件检测,“sharedStrings”字节序列效果非常好,因为所有 XLSX 文件都包含 shareStrings.xml 文件,该文件不会被 ZIP 格式解析。然而,这个功能最终被丢弃,因为它的长度使得它对即使是最小的变化也过于敏感。虽然这些功能提高了模型的效率,但 ZIP 文件的准确识别仍然存在问题,我们不得不使用另一种方法来识别它们。 由于我们并不确切知道需要哪些特征来可靠地识别 ZIP 文件,因此我们决定在模型中包含所有可能的 2 字节组合以提高准确性。然而,这种方法对内存、时间和处理器的要求极高,因为学习过程必须处理大量数据。为了优化这一点,我们计划仅使用 500 个最重要的 2 字节特征,从而在不影响模型效率的情况下显着减少计算资源的负载。 根据我们的初步分析,我们对所有类单独实现了 90% 以上的准确率,但 XML 文件除外,我们在该文件中仅实现了 49%。这表明该模型可能存在过拟合问题。当模型使用太多特征时,可能会发生过度拟合,导致模型更快地做出决策,例如在决策树的端点处。这可能会导致训练集的准确性很高,但实际数据的泛化能力较差。处理过度拟合最有效的方法之一是减少使用的特征数量。 最终模型包含三个特征的组合。首先,256 个单字节特征检查每个字节出现的频率。接下来是一个附加功能,用于测量“<”和“>”符号(字节 60 和 62)的比例,这对于识别 XML 文件特别有用。最后,该模型包含 42 个选定的两字节特征,根据之前的分析,这些特征与文件类型识别最相关。这些组合功能有助于提高模型识别不同文件类型的准确性。 模型最终确定后,在测试堆栈上发现了以下准确度(按文件类型细分)。 由于表中一列的元素具有相同的类型,因此可以通过在一组中同时对这些二进制数据点进行分类来提高准确性,因为即使该组中存在一个错误分类的数据点,其他数据点也会推动该组的分类。平均到正确的分类。 针对模型的不同集大小的 API 运行时测量得出以下结果(平均文件大小为 5 MB,测试是在配备 Intel Core i7-2600 3.4 GHz 处理器和 1333 MHz RAM 的计算机上完成的)。 根据内存使用情况测量了以下运行时间: – 89.428 秒,最大 RAM 使用量为 7.28 GB – 56.451 秒,最大 RAM 使用量为 4.55 GB – 30.186 秒,最大 RAM 使用量为 2.58 GB Docker 镜像由以下文件组成: dockerfile的结构如下: 文件格式识别是数据迁移中的一个挑战,特别是对于未记录的遗留系统。文件(例如 BLOB)的编码结构使得格式识别变得困难,需要更先进的方法。我们的经验表明,将机器学习与字节频率分布 (BFD) 相结合可以根据字节分布模式有效地识别文件。通过添加特定的字节序列和特征来可靠区分不同格式,可以提高模型的准确性。在 Docker 化环境中运行的最终模型可以实现为灵活高效的服务,可用于数据迁移项目。
上图显示了不同集合大小的 3 个最低准确度类别(XLSX、XLS、XML)的准确度进展。选择三个最低精度等级是因为它们需要最大的集合大小才能实现 100% 的整体精度。该方法使我们能够确定最坏情况下所需的最小集合大小。可以看到,即使在最坏的情况下,一次对 7 个文件进行分类时,模型的平均准确率也提高到接近 100%。
基于微服务的文件识别实现
该服务使用 Docker 进行容器化,基于 Python fastAPI 和 uvicorn 模块构建。在API调用过程中,系统首先接收请求,然后将接收到的数据转换为二进制(Base64)格式。然后,二进制数据用于生成数据点的字节频率分布 (BFD) 值。一旦生成 BFD,与数据点关联的 BFD 和 lightGBM 类型模型将用于文件类型检测的分类。系统记录事件并处理任何错误。最后,在该过程结束时,系统向用户发送响应。
在服务调用中,Body 结构仅包含两个字段“data”(该属性是 JSON 对象列表)和“id”。这些 JSON 对象有一个“位”字段(它是包含文件的 base64 编码版本的字符串)。
来自 /predict 端点的响应是一个包含状态代码的 JSON 对象。 JSON 对象的结构与请求正文类似。响应将包含一个“数据”字段,其值为列表。此列表包含其他 JSON 对象,其中包含“id”和“pred”字段。 “id”字段的值可以是分配给提交项目的标识符,也可以是生成的标识符(如果最初没有为“bit”字段指定)。预测(“pred”)字段还包含一个 JSON 对象,其中包含扩展名和概率键值对。
结束语





