使用什么算法从银行对账单中提取信息

数据挖掘 机器学习 nlp 命名实体识别
2022-02-15 17:42:33

我试图找到从银行对账单中提取信息的最佳方法。银行交易不是自然文本,但仍然是人类可读的。

如果存在,我想提取一堆数据,例如付款方式、日期、金额、供应商/客户名称,甚至是订单/发票 ID 或原因等信息。我有一组可用于培训的数据,例如(100k+ 供应商、支付方式词等)。此外,该解决方案必须适用于多语言。银行交易可以使用不同的语言(不仅是英语)。

命名实体识别是最好的方法吗?

这是我可以输入的一些示例数据:

  • 股利
  • POS 购买非 PIN:RCI*RINGCENTRAL, INC.
  • IMP.DEB.LEY 83652 - 阿里科塔属
  • 直接借记股权商业商品费用 158713 62000329526385 CCD
  • ADVANCE AUTO PARTS 杰克逊维尔

谢谢你的帮助

2个回答

我目前正在研究这个领域的一些东西。

我目前正在遵循的粗略过程是 -

  1. 从 PDF(如今普遍存在的银行对帐单版本)中提取数据为更可用的格式。目前,首先将它们转换为 TXT 文件作为中间步骤。
  2. 通常,银行对账单(来自特定银行)往往采用相同的格式。因此,在将 TXT 转换为 CSV 时,您可以根据对 TXT 文件的粗略分析来构建算法,使其知道要拾取什么。

    • 使用 2 个不同的数据框来存储报表内容 - 一个 df 跟踪交易数据(存储 3 个值 - 日期、描述和金额),另一个跟踪元数据(存储 2 个值 - 键和值)
    • 您可以通过浏览几个 TXT 来确定 TXT 文件的粗略结构。例如,交易通常在每个银行对账单中出现特定元素之后开始。忽略在多页事务的情况下重复出现的页脚/页眉。此外,另一个观察结果是交易的特定列中的所有数据(交易被我的程序作为表读入[下面给出的链接])一起出现。
    • 执行上述操作使事务和元数据具有相对结构化和可处理的格式
  3. 对 Description 列或由此生成的整个事务 df 执行分析。

您可以使用以下代码将给定的 PDF 转换为 txt 文件 -

from __future__ import unicode_literals
import os
import sys  
reload(sys)  
sys.setdefaultencoding('utf8')
from pdfminer.pdfinterp import PDFResourceManager, PDFPageInterpreter
from pdfminer.pdfpage import PDFPage
from pdfminer.converter import XMLConverter, HTMLConverter, TextConverter
from pdfminer.layout import LAParams
from cStringIO import StringIO

def pdfparser(data):
    dest = data[:-3]+"txt"    
    print "\n\n\n\n\n",dest    
    fp = file(data, 'rb')
    rsrcmgr = PDFResourceManager()
    retstr = StringIO()
    codec = 'utf-8'
    laparams = LAParams()
    device = TextConverter(rsrcmgr, retstr, codec=codec, laparams=laparams)
    # Create a PDF interpreter object.
    interpreter = PDFPageInterpreter(rsrcmgr, device)
    # Process each page contained in the document.
    for page in PDFPage.get_pages(fp):
        interpreter.process_page(page)
        data =  retstr.getvalue()
        data = unicode(data,'utf-8', errors='ignore')
    #print data
    # write data to a file
    print data
    with open(dest, "w") as f:
        f.write(data)

# set the working directory
path = "F:/banking/payments/"
os.chdir(path)
fls=os.listdir(path)

for x in fls:
    if x[-3:]=="pdf":
        pdfparser(path+x)

通过使用嵌入(用于词嵌入的 Glove 50)和双向 LSTM 将此问题视为分类问题,我得到了很好的结果。我知道这个问题看起来更像是一个实体识别问题,但在我的用例中,我只需要对一个已知的商家子集进行分类,所以效果很好。由于训练数据非常不平衡,我还使用数据合成来提高准确性。

我的 Keras 模型:

__________________________________________________________________________________________________ 
Layer (type)                    Output Shape         Param #     Connected to                     
================================================================================================== 
words_input (InputLayer)        (None, None)         0          
__________________________________________________________________________________________________ 
casing_input (InputLayer)       (None, None)         0          
__________________________________________________________________________________________________ 
embedding_1 (Embedding)         (None, None, 50)     20000000    words_input[0][0]                
__________________________________________________________________________________________________ 
embedding_2 (Embedding)         (None, None, 9)      81          casing_input[0][0]               
__________________________________________________________________________________________________ 
concatenate_1 (Concatenate)     (None, None, 59)     0           embedding_1[0][0]                
                                                                 embedding_2[0][0]                
__________________________________________________________________________________________________ 
bidirectional_1 (Bidirectional) [(None, 400), (None, 416000      concatenate_1[0][0]              
__________________________________________________________________________________________________ 
dense_1 (Dense)                 (None, 1591)         637991      bidirectional_1[0][0]            
================================================================================================== 
Total params: 21,054,072 Trainable params: 1,053,991 Non-trainable params: 20,000,081
__________________________________________________________________________________________________