PDF多表格结构识别与跨表语义对齐:基于对抗迁移的鲁棒相似度度量模型

文章目录

    • 一. 项目结构
    • 二.流程分析
      • 2.1 批处理器核心代码解析
    • 三. 跨页表格相似度匹配原理
      • 3.1 表头内容相似度-特征向量归一化
      • 3.2 表头内容相似度-余弦相似度
      • 3.3 定时缓存清理


ocr扫描有其局限性。对于pdf文本类型这种pdfbox,aspose-pdf,spire直接提取文本的精准性更高。经过综合对比我们觉得aspose和spire在读取pdf文本方面较为优秀。基于此我们可能需要提取pdf中所有表格数据,完成数据录入。但是表格数据不同,还存在跨页表格问题。但是按照以下方案即可解决。本文的表格处理思想来源于mybatis的底层设计。

特征余弦相似度编辑距离
原理衡量向量方向的夹角(语义相似性)计算字符串转换所需的最小操作次数(字符级差异)
输入类型向量(如文本的TF-IDF或词嵌入向量)字符串或序列
关注点语义层面的相似性(如主题、用词)结构层面的差异(如拼写错误、字符顺序)
输出范围[-1, 1](通常取绝对值或归一化为0-1)非负整数(0表示完全匹配)
计算复杂度O(n)(向量化后快速计算)O(n*m)(对长文本较慢)
典型应用文档相似度、推荐系统、语义搜索拼写纠错、DNA序列比对、短文本模糊匹配

开源地址

一. 项目结构

本设计基于aspose-pdf实现

|-- SpringContextUtil.java
`-- pdf|-- AbstractTextMappingTemplate.java #抽象模板映射器 解析内容映射到结构化对象|-- PDFboxTable.java # 暂留扩展|-- PdfTableParsingEngine.java # 表格解析引擎 提供从PDF文档中提取并处理表格数据的功能|-- StringEscapeUtil.java # 字符串转义工具类 防止注入攻击|-- TableBatchProcessor.java # 具体表格执行处理器 表格批处理器|-- annotation # 映射注解包|-- aspect # 注解处理器包|-- converter # 抽象模板映射器具体实现 包`-- entity # 想要映射的结构化对象包

二.流程分析

  1. 表格解析器提取pdf表格文本
  2. 表格批处理器负责具体执行表格解析
  3. 字符串转义避免恶意攻击
  4. 抽象映射器允许用户具体实现映射实体

2.1 批处理器核心代码解析

表格解析器每检测一页的所有表格,就提交到批处理器进行具体数据清洗,归一化。以下是进行数据批处理的核心逻辑

    /*** 添加表格到批处理队列** @param pageIndex 页码索引* @param tables    页面中的表格列表*/public void addPageTables(int pageIndex, List<AbsorbedTable> tables) {// 资源限制检查 一页10个表格if (tables.size() > MAX_TABLES_PER_PAGE) {log.warn("页面{}表格数量超过限制: {}", pageIndex, tables.size());// 截取前MAX_TABLES_PER_PAGE个表格tables = tables.subList(0, MAX_TABLES_PER_PAGE);}// 处理当前页的表格List<StringBuilder> processedTables = new ArrayList<>();for (AbsorbedTable table : tables) {// 处理单个表格StringBuilder tableContent = processSingleTable(table);if (tableContent == null) continue;// 数据清洗PdfTableParsingEngine.cleanData(tableContent);// 生成表格指纹String tableFingerprint = generateTableFingerprint(tableContent);// 将表格指纹和内容存储到跨页表格缓存中crossPageTableCache.putIfAbsent(tableFingerprint, new CacheEntry(new StringBuilder(tableContent)));// 更新缓存条目的最后访问时间crossPageTableCache.get(tableFingerprint).updateLastAccessTime();// 检查是否为跨页表格if (isCrossPageTable(tableFingerprint)) {// 合并跨页表格tableContent = mergeCrossPageTable(tableContent, tableFingerprint);} else {// 异常检测(连续重复表格)if (isDuplicateTable(tableFingerprint)) {log.warn("检测到连续重复表格类型: {}", tableFingerprint);continue;}}// 添加到处理队列processedTables.add(tableContent);}// 将处理后的表格添加到缓冲队列if (!processedTables.isEmpty()) {try {// 尝试添加到队列,如果队列已满则提交当前队列中的所有表格if (!tableBufferQueue.offer(processedTables, 100, TimeUnit.MILLISECONDS)) {log.info("缓冲队列已满,提交批处理任务");submitBatchTask();// 重新尝试添加tableBufferQueue.put(processedTables);}} catch (InterruptedException e) {log.error("添加表格到缓冲队列失败: {}", e.getMessage());Thread.currentThread().interrupt();}}}

如上述代码,

  • processSingleTable(AbsorbedTable table)用于具体解析表格内容并拼接成特定字符串。
  • cleanData(StringBuilder builder) 移除所有空白字符和换行符
  • generateTableFingerprint(StringBuilder tableContent) 用于识别跨页表格相似度合并
  • crossPageTableCache 缓存跨页表格,因为是以页为单位检测表格的。下一页需要保留上一页表格
  • mergeCrossPageTable(tableContent, tableFingerprint) 设定相似度大于85%且不为100%。为同一表格。进行合并。
  • submitBatchTask() 提交批处理任务
  • processBatchTables(List<List> batchTables) 获取抽象映射器的具体实现。根据具体规则进行映射匹配

三. 跨页表格相似度匹配原理

  • 1.根据特定表头内容相似度
  • 2.根据表格样式特征

3.1 表头内容相似度-特征向量归一化

字符串长度建议不要超过特征矩阵维度长度
使用余弦相似矩阵,比较两个表头字符串相似度.一般认为表头字串很短,因此初始化16特征向量即可
表示我们可以把字符ascii映射到特征向量上,并通过单位向量归一化结果。获取第一块内容字串的标准化特征向量。同理对第二块内容字串做标准化计算。

    /*** 计算内容相似度(基于矢量相似度)** @param str1 字符串1* @param str2 字符串2* @return 内容相似度*/private double calculateContentSimilarity(String str1, String str2) {if (str1 == null || str2 == null) {throw new IllegalArgumentException("输入字符串不能为空");}// 将字符串转换为特征向量double[] vector1 = stringToVector(str1);double[] vector2 = stringToVector(str2);// 计算余弦相似度return cosineSimilarity(vector1, vector2);}/*** 将字符串转换为特征向量** @param str 输入字符串* @return 特征向量*/private double[] stringToVector(String str) {// 初始化特征向量double[] vector = new double[VECTOR_DIMENSION];// 创建字符频率映射Map<Character, Integer> charFrequency = new HashMap<>();// 统计字符频率for (char c : str.toCharArray()) {charFrequency.put(c, charFrequency.getOrDefault(c, 0) + 1);}// 将字符频率映射到特征向量for (char c : charFrequency.keySet()) {int index = Math.abs(c) % VECTOR_DIMENSION;vector[index] += charFrequency.get(c);}// 归一化向量normalizeVector(vector);return vector;}/*** 归一化向量** @param vector 输入向量*/private void normalizeVector(double[] vector) {double magnitude = 0.0;// 计算向量模长for (double value : vector) {magnitude += value * value;}magnitude = Math.sqrt(magnitude);// 归一化向量if (magnitude > 0) {for (int i = 0; i < vector.length; i++) {vector[i] /= magnitude;}}}

3.2 表头内容相似度-余弦相似度

  • 我们将原始特征向量进行标准化(归一化)处理,使其转化为单位向量(模长为1),从而消除向量尺度差异对相似性度量的影响。(注:此步骤确保所有向量处于同一量纲空间,使得后续计算具有可比性)
  • 对于两个单位向量 u u u v v v,其点积在数值上等于它们的余弦相似度(即 c o s θ cosθ cosθ)。
    几何意义:余弦相似度反映向量方向的接近程度,与向量维度无关。
    数学表达
    c o s θ = u ⋅ v ∣ u ∣ ⋅ ∣ v ∣ cosθ=\frac{u·v}{|u|·|v|} cosθ=uvuv
    结果解释
    cos ⁡ θ ≈ 1 c o s θ ≈ 1 \cos\theta \approx 1cosθ≈1 cosθ1cosθ1:向量方向高度一致,对应字符串内容几乎相同。
    cos ⁡ θ ≈ 0 c o s θ ≈ 0 \cos\theta \approx 0cosθ≈0 cosθ0cosθ0:向量正交,字符串内容无相关性。
    应用示例:在文本匹配任务中,可通过该值量化两段文本的语义相似性。

点积与哈达玛积的区别:
点积输出标量,用于衡量整体相似性;
哈达玛积为元素级乘法,输出同维向量,常用于局部特征交互。

    private double cosineSimilarity(double[] vector1, double[] vector2) {if (vector1.length != vector2.length) {throw new IllegalArgumentException("向量维度不匹配");}double dotProduct = 0.0;double magnitude1 = 0.0;double magnitude2 = 0.0;for (int i = 0; i < vector1.length; i++) {dotProduct += vector1[i] * vector2[i];magnitude1 += vector1[i] * vector1[i];magnitude2 += vector2[i] * vector2[i];}magnitude1 = Math.sqrt(magnitude1);magnitude2 = Math.sqrt(magnitude2);if (magnitude1 == 0.0 || magnitude2 == 0.0) {return 0.0;} else {return dotProduct / (magnitude1 * magnitude2);}}

3.3 定时缓存清理

由于我们为了保证跨页表格的关联关系。我们使用map集合保存上一页表格内容。

    /*** 构造函数*/public TableBatchProcessor() {// 使用虚拟线程池处理批量映射任务this.executorService = Executors.newVirtualThreadPerTaskExecutor();// 初始化表格缓冲队列this.tableBufferQueue = new LinkedBlockingQueue<>(BUFFER_CAPACITY);// 初始化表格类型计数器this.tableTypeCounter = new ConcurrentHashMap<>();// 初始化跨页表格缓存this.crossPageTableCache = new ConcurrentHashMap<>();// 初始化缓存清理调度器this.cacheCleanupScheduler = Executors.newScheduledThreadPool(1);// 启动定时清理任务this.cacheCleanupScheduler.scheduleAtFixedRate(this::cleanupCrossPageTableCache, 1, 1, TimeUnit.MINUTES);}

我设计了最早时间淘汰机制,同时为了进一步防止内存溢出。设计了map最大值。超出阈值清理所有。但显然这是有问题的,可能导致跨表关联关系断开。因此先以抛出异常解决

    /*** 清理跨页表格缓存(增强版)*/private void cleanupCrossPageTableCache() {long currentTime = System.currentTimeMillis();List<String> expiredKeys = new ArrayList<>();for (Map.Entry<String, CacheEntry> entry : crossPageTableCache.entrySet()) {if (currentTime - entry.getValue().lastAccessTime > CACHE_ENTRY_TTL) {expiredKeys.add(entry.getKey());}}// 限制缓存条目数量if (crossPageTableCache.size() > MAX_CACHE_ENTRIES) {crossPageTableCache.clear();throw new IllegalStateException("缓存条目数量超过限制");}for (String key : expiredKeys) {crossPageTableCache.remove(key);log.info("清理过期缓存条目: {}", key);}}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/899297.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

es 3期 第27节-运用Script脚本实现复杂需求

#### 1.Elasticsearch是数据库&#xff0c;不是普通的Java应用程序&#xff0c;传统数据库需要的硬件资源同样需要&#xff0c;提升性能最有效的就是升级硬件。 #### 2.Elasticsearch是文档型数据库&#xff0c;不是关系型数据库&#xff0c;不具备严格的ACID事务特性&#xff…

23、web前端开发之html5(四)

十二. HTML5实践示例 前面我们详细讲解了HTML5的特点&#xff0c;包括语义化标签、增强的表单功能、多媒体元素&#xff08;如<video>和<audio>&#xff09;、Canvas绘图、SVG集成以及离线存储等。以下是一些详细的HTML5实践示例&#xff0c;展示如何使用HTML5的新…

海思烧录工具HITool电视盒子刷机详解

HiTool是华为开发的一款用于海思芯片设备的刷机和调试工具&#xff0c;可对搭载海思芯片的机顶盒、智能电视等设备进行固件烧录、参数配置等操作。以下为你详细介绍&#xff1a; 功能用途 固件烧录&#xff1a;这是HiTool最主要的功能之一。它能够将下载好的适配固件文件烧录到…

软考中级-软件设计师 23种设计模式(内含详细解析)

23种设计模式 &#x1f3af; 创建型设计模式&#x1f4cc; 抽象工厂&#xff08;Abstract Factory&#xff09; 设计模式&#x1f4cc; 工厂方法&#xff08;Factory Method&#xff09;设计模式&#x1f4cc; 单例&#xff08;Singleton&#xff09;设计模式&#x1f4cc; 生成…

thinkphp8.0\swoole的websocket应用

环境&#xff1a;centOS7.9、php8.3、thinkphp8.0\think-swoole4.1 我用的官方think-swoole插件 第一步&#xff1a;根据官方文档&#xff0c;需要安装此扩展插件 composer require topthink/think-swoole 第二步&#xff1a;在根目录下config文件夹下编辑swoole.php配置文…

Ubuntu服务器挂载时遇到文件系统错误怎么办

在Ubuntu服务器上挂载分区时&#xff0c;如果遇到文件系统错误&#xff0c;通常可能是由于磁盘损坏、文件系统损坏、不正确的卸载等原因造成的。以下是详细的排查与修复步骤&#xff1a; 一、查看错误信息 首先&#xff0c;尝试手动挂载并观察具体错误&#xff1a; sudo mount …

【设计模式】策略模式(Strategy Pattern)详解

策略模式&#xff08;Strategy Pattern&#xff09;详解 一、策略模式的定义 策略模式&#xff08;Strategy Pattern&#xff09;是一种行为型设计模式&#xff0c;它定义了一组算法&#xff0c;将每个算法封装起来&#xff0c;并使它们可以相互替换&#xff0c;从而让算法的…

软考笔记5——软件工程基础知识

第五章节——软件工程基础知识 软件工程基础知识 第五章节——软件工程基础知识一、软件工程概述1. 计算机软件2. 软件工程基本原理3. 软件生命周期4. 软件过程 二、软件过程模型1. 瀑布模型2. 增量模型3. 演化模型&#xff08;原型模型、螺旋模型)4. 喷泉模型5. 基于构建的开发…

Vim 实用指南

导航 简介Vim 的来历Vim 语言 Vim 的三种模式Normal&#xff08;普通模式&#xff09;Insert&#xff08;插入模式&#xff09;Visual&#xff08;可视模式&#xff09;三种模式转换 普通模式实用技巧说明复制当前行并粘贴使用上一个命令撤销上一个操作最常用的跳转命令查找对应…

Git入门——常用指令汇总

以下是一份精心整理的 Git常用指令速查表&#xff0c;基本覆盖日常开发使用场景&#xff0c;建议收藏备用&#x1f447; &#x1f527; 环境配置 指令作用git config --global user.name "你的名字"设置全局用户名git config --global user.email "你的邮箱&qu…

常见中间件漏洞攻略-Jboss篇

一、CVE-2015-7501-Jboss JMXInvokerServlet 反序列化漏洞 第一步&#xff1a;开启靶场 第二步&#xff1a;访问该接口&#xff0c;发现直接下载&#xff0c;说明接⼝开放&#xff0c;此接⼝存在反序列化漏洞 http://47.103.81.25:8080/invoker/JMXInvokerServlet 第三步&…

播放本地视频-实现视频画廊功能

实现一个视频画廊&#xff0c;播放本地视频 可以切换不同视频的功能 文章目录 需求&#xff1a;场景实现方案遇到的坑播放器选择界面显示不全视频友好显示问题缓存 总结 需求&#xff1a; 实现一个视频画廊&#xff0c;播放本地视频 可以切换不同视频的功能 场景 图片画廊的…

从零构建大语言模型全栈开发指南:第二部分:模型架构设计与实现-2.2.2文本生成逻辑:Top-k采样与温度控制

👉 点击关注不迷路 👉 点击关注不迷路 👉 点击关注不迷路 文章大纲 2.2.2 文本生成逻辑:Top-k采样与温度控制1. 文本生成的核心挑战与数学框架1.1 自回归生成的基本流程2. `Top-k`采样原理与工程实现2.1 数学定义与算法流程2.2 PyTorch实现优化3. 温度控制的数学本质与参…

为什么后端接口返回数字类型1.00前端会取到1?

这得从axios中得默认值说起&#xff1a; Axios 的 transformResponse axios 在接收到服务器的响应后&#xff0c;会通过一系列的转换函数&#xff08;transformResponse&#xff09;来处理响应数据&#xff0c;使其适合在应用程序中使用。默认情况下&#xff0c;axios 的 tran…

【C++游戏引擎开发】《线性代数》(2):矩阵加减法与SIMD集成

一、矩阵加减法数学原理 1.1 定义 ​逐元素操作:运算仅针对相同位置的元素,不涉及矩阵乘法或行列变换。​交换律与结合律: 加法满足交换律(A + B = B + A)和结合律( ( A + B ) + C = A + ( B + C ) )。 ​减法不满足交换律(A − B ≠ B − A)。1.2 公式 ​ C i j = …

openGauss关联列数据类型不一致引起谓词传递失败

今天分享一个比较有意思的案例 注意&#xff1a;因为原始SQL很长&#xff0c;为了方便排版&#xff0c;简化了SQL 下面SQL跑60秒才出结果&#xff0c;客户请求优化 select dtcs.owner, dtcs.table_name, dtcs.column_name, dct.commentsfrom dba_tab_columns dtcsleft outer j…

01 相机标定与相机模型介绍

学完本文,您将了解不同相机模型分类、内参意义,及对应的应用代码模型 标定的意义 建模三维世界点投影到二维图像平面的过程。标定输出的是相机模型。 相机模型 相机模型可以解理解为投影模型 +

Hyperlane:Rust Web开发的未来,释放极致性能与简洁之美

Hyperlane&#xff1a;Rust Web开发的未来&#xff0c;释放极致性能与简洁之美 你是否厌倦了复杂的Web框架&#xff0c;想要一个既高效又易用的工具来构建现代Web应用&#xff1f;Hyperlane正是你需要的答案&#xff01;作为专为Rust打造的轻量级、高性能HTTP服务器库&#xf…

STM32学习笔记之振荡器(原理篇)

&#x1f4e2;&#xff1a;如果你也对机器人、人工智能感兴趣&#xff0c;看来我们志同道合✨ &#x1f4e2;&#xff1a;不妨浏览一下我的博客主页【https://blog.csdn.net/weixin_51244852】 &#x1f4e2;&#xff1a;文章若有幸对你有帮助&#xff0c;可点赞 &#x1f44d;…

Stereolabs ZED Box Mini:机器人与自动化领域的人工智能视觉新选择

在人工智能视觉技术快速发展的今天&#xff0c;其应用场景正在持续拓宽&#xff0c;从智能安防到工业自动化&#xff0c;从机器人技术到智能交通&#xff0c;各领域都在积极探索如何利用这一先进技术。而 Stereolabs 推出的ZED Box Mini&#xff0c;正是一款专为满足这些多样化…