Python机器学习

GCN常用数据集- SciTSR介绍

2020-12-08  本文已影响0人  blade_he

简介

SciTSR是一个多种格式PDF表格的数据集。
TSR对应英文单词为:Table Structure Recognition,即表格结构识别。
共有15000个样例,其中12000训练数据 (2885张复杂表格),3000(716张复杂表格)测试数据。
Github链接为:https://github.com/Academic-Hammer/SciTSR

文件夹结构如下:

SciTSR
├── SciTSR-COMP.list
├── test
│   ├── chunk
│   ├── img
│   ├── pdf
│   └── structure
└── train
    ├── chunk
    ├── img
    ├── pdf
    ├── rel
    └── structure

所有文件夹的对应数据的文件名相同,扩展名不同而已。
比如文件:0704.2596v1.2在各个文件夹均有同名文件。

训练集相比测试集多了rel文件夹,因为rel文件夹中的数据就是需要预测的表格中各个单元格的同行或同列的关系。

pdf文件夹

顾名思义,即原始表格对应的PDF文件,如:


2020-12-08 17_15_42-Start.png

chunk文件夹

存储表格各个单元格的位置以及文本信息
数据格式:json
数据对应表格顺序:从左往右,从上往下,如:

{
    "pos": [
        41.35900115966797,
        61.00923538208008,
        574.2490234375,
        579.2303466796875
    ],
    "text": "code"
},
{
    "pos": [
        90.00299835205078,
        149.44332885742188,
        572.7540283203125,
        581.053466796875
    ],
    "text": "computing S d"
},
{
    "pos": [
        170.58999633789062,
        186.80360412597656,
        572.7540283203125,
        581.053466796875
    ],
    "text": "|S d |"
},
{
    "pos": [
        198.75900268554688,
        253.30320739746094,
        574.2490234375,
        579.2303466796875
    ],
    "text": "fulliteration"
}

img文件夹

即对pdf文件内容截图

structure文件夹

与chunk数据的索引一一对应的结果数据,即y
其中id的值即为chunk数据中的索引
start_row, end_row, start_col, end_col都是给定的结果
示例:

{
    "id": 0,
    "tex": "code",
    "content": [
        "code"
    ],
    "start_row": 0,
    "end_row": 0,
    "start_col": 0,
    "end_col": 0
},
{
    "id": 1,
    "tex": "computing ${\\cal S}_d$",
    "content": [
        "computing",
        "Sd"
    ],
    "start_row": 0,
    "end_row": 0,
    "start_col": 1,
    "end_col": 1
},
{
    "id": 2,
    "tex": "$|{\\cal S}_d|$",
    "content": [
        "|Sd|"
    ],
    "start_row": 0,
    "end_row": 0,
    "start_col": 2,
    "end_col": 2
},
{
    "id": 10,
    "tex": "$[105,7,77]_5$",
    "content": [
        "[105,",
        "7,",
        "77]5"
    ],
    "start_row": 1,
    "end_row": 1,
    "start_col": 0,
    "end_col": 0
},

rel文件夹

经过structure的行列索引,计算出来的单元格之间的行列关系,同一行为1:0,同一列为2:0,严格来说这个是输入图卷积网络真正的y,示例为:

0   1   1:0
0   10  2:0
1   2   1:0
1   11  2:0
2   3   1:0
2   12  2:0
3   4   1:0
3   13  2:0
4   5   1:0
4   14  2:0
5   15  2:0
7   17  2:0
9   19  2:0
10  11  1:0
10  20  2:0
11  12  1:0
11  21  2:0
12  13  1:0
12  22  2:0
13  14  1:0
13  23  2:0
14  15  1:0
14  24  2:0
15  16  1:0
15  25  2:0
16  17  1:0
16  26  2:0
17  18  1:0
17  27  2:0
18  19  1:0
18  28  2:0
19  29  2:0
20  21  1:0
20  30  2:0
21  22  1:0
21  31  2:0
22  23  1:0

应用该训练集的GCN实例:GFTE

Github地址为:https://github.com/Irene323/GFTE
作者期望通过:

  1. 仅仅position信息
  2. position + 文本信息
  3. position + 文本信息 + 图像特征
    分别训练GCN
    这是一个很好的用例,且有使用SciTSR的示范代码
    不过在GFTE-pos/GFTE-pos/dataset0.py的代码中,标签获取的计算方程,仅仅是获取是否同一行的标签,并没有是否同列的信息。
    原代码如下:
    def cal_label(self,data,tbpos): # 根据构造的图,计算边的标注。
        edges = data.edge_index  # [2, 边的个数] 无向图的边是对称的,即有2条。
        y = []
        for i in range(edges.size()[1]):
            y.append(self.if_same_row(edges[0,i], edges[1,i],tbpos))
        return y
            
    def if_same_row(self,si,ti,tbpos):
        ss,se = tbpos[si][0], tbpos[si][1]
        ts,te = tbpos[ti][0], tbpos[ti][1]
        if (ss>=ts and se<=te):
            return 1
        if (ts>=ss and te<=se):
            return 1
        return 0

我们加入相应的修改,使得其不仅能获取是否同一行信息,也能获取是否同一列的信息:

    def cal_label(self,data,tbpos): # 根据构造的图,计算边的标注。
        edges = data.edge_index  # [2, 边的个数] 无向图的边是对称的,即有2条。
        y = []
        for i in range(edges.size()[1]):
            # 相同列的y值为2,相同行的y值为1,否则为0
            if self.if_same_col(edges[0,i], edges[1,i],tbpos):
                y.append(2)
            elif self.if_same_row(edges[0,i], edges[1,i],tbpos):
                y.append(1)
            else:
                y.append(0)
#           y.append(self.if_same_row(edges[0,i], edges[1,i],tbpos))
        return y
            
    def if_same_row(self,si,ti,tbpos):
        ss,se = tbpos[si][0], tbpos[si][1]
        ts,te = tbpos[ti][0], tbpos[ti][1]
        if (ss>=ts and se<=te):
            return 1
        if (ts>=ss and te<=se):
            return 1
        return 0
    
    def if_same_col(self,si,ti,tbpos):
        ss,se = tbpos[si][2], tbpos[si][3]
        ts,te = tbpos[ti][2], tbpos[ti][3]
        if (ss>=ts and se<=te):
            return 1
        if (ts>=ss and te<=se):
            return 1
        return 0

根据SciTSR给出的label信息,我们或许可以得出如下结论:仅仅相邻的行,才判断是否位于同一列,亦即:相邻边的两个点:
点1结束行索引-点2开始行索引的绝对值为1,或者点2结束行索引-点1开始行索引的绝对值为1,才进入判断是否是同一列的判断
是否是同一行的索引可以进行类推。
代码示例如下:

    def cal_label(self,data,tbpos): # 根据构造的图,计算边的标注。
        edges = data.edge_index  # [2, 边的个数] 无向图的边是对称的,即有2条。
        y = []
        for i in range(edges.size()[1]):
            # 相同列的y值为2,相同行的y值为1,否则为0
            if self.if_same_col(edges[0,i], edges[1,i],tbpos):
                y.append(2)
            elif self.if_same_row(edges[0,i], edges[1,i],tbpos):
                y.append(1)
            else:
                y.append(0)
#           y.append(self.if_same_row(edges[0,i], edges[1,i],tbpos))
        return y
            
    def if_same_row(self,si,ti,tbpos):
        # 是否需要考虑两个单元格是邻近列的关系
        # 0:开始行,1:结束行,2:开始列,3:结束列
        if abs(tbpos[si][3] - tbpos[ti][2]) == 1 or \
                abs(tbpos[ti][3] - tbpos[si][2]) == 1:
            ss,se = tbpos[si][0], tbpos[si][1]
            ts,te = tbpos[ti][0], tbpos[ti][1]
            if (ss>=ts and se<=te):
                return 1
            if (ts>=ss and te<=se):
                return 1
        return 0
    
    def if_same_col(self,si,ti,tbpos):
        # 是否需要考虑两个单元格是邻近行的关系
        # 0:开始行,1:结束行,2:开始列,3:结束列
        if abs(tbpos[si][1] - tbpos[ti][0]) == 1 or \
                abs(tbpos[ti][1] - tbpos[si][0]) == 1:
            ss,se = tbpos[si][2], tbpos[si][3]
            ts,te = tbpos[ti][2], tbpos[ti][3]
            if (ss>=ts and se<=te):
                return 1
            if (ts>=ss and te<=se):
                return 1
        return 0
上一篇 下一篇

猜你喜欢

热点阅读