在Spacy中保存和加载NLP结果。

3

我想使用SpaCy分析许多小文本,并希望存储nlp结果以节省处理时间。 我在Storing and Loading spaCy Documents Containing Word Vectors找到了代码,但我遇到了错误,无法找到如何修复它。 我对python相当陌生。

在以下代码中,我将nlp结果存储到文件中并尝试再次读取它。 我可以写入第一个文件,但是我找不到第二个文件(vocab)。 我还得到两个错误:未定义Doc和Vocab。

有没有什么想法来解决这个问题或实现相同结果的另一种方法都非常受欢迎。

谢谢!

import spacy
nlp = spacy.load('en_core_web_md')
doc = nlp("He eats a green apple")
for token in doc:
    print(token.text, token.lemma_, token.pos_, token.tag_, token.dep_,
            token.shape_, token.is_alpha, token.is_stop)

NLP_FName = "E:\\SaveTest.nlp"
doc.to_disk(NLP_FName)
Vocab_FName = "E:\\SaveTest.voc"
doc.vocab.to_disk(Vocab_FName)

#To read the data again:
idoc = Doc(Vocab()).from_disk(NLP_FName)
idoc.vocab.from_disk(Vocab_FName)

for token in idoc:
    print(token.text, token.lemma_, token.pos_, token.tag_, token.dep_,
            token.shape_, token.is_alpha, token.is_stop)
3个回答

3
我尝试了你的代码,发现几个小问题并在下面的代码中进行了修复。
请注意,SaveTest.nlp是一个包含文档信息的二进制文件,SaveTest.voc是一个包含所有spacy模型词汇信息(矢量、字符串等)的文件夹。
我所做的更改如下:
  1. spacy.tokens导入Doc
  2. spacy.vocab导入Vocab
  3. 使用以下命令下载en_core_web_md模型:
python -m spacy download en_core_web_md

请注意,spacy针对每种语言有多个模型,通常您需要先下载它(通常是smmdlg模型)。在此处了解更多信息。
import spacy
from spacy.tokens import Doc
from spacy.vocab import Vocab

nlp = spacy.load('en_core_web_md')
doc = nlp("He eats a green apple")
for token in doc:
    print(token.text, token.lemma_, token.pos_, token.tag_, token.dep_,
          token.shape_, token.is_alpha, token.is_stop)

NLP_FName = "E:\\SaveTest.nlp"
doc.to_disk(NLP_FName)
Vocab_FName = "E:\\SaveTest.voc"
doc.vocab.to_disk(Vocab_FName)

#To read the data again:
idoc = Doc(Vocab()).from_disk(NLP_FName)
idoc.vocab.from_disk(Vocab_FName)

for token in idoc:
    print(token.text, token.lemma_, token.pos_, token.tag_, token.dep_,
          token.shape_, token.is_alpha, token.is_stop)

如果这对你有帮助,请让我知道,如果没有,请将错误消息添加到原始问题中,以便我可以提供帮助。


非常感谢!它运行得非常好 :))。 - MJ_Nadeau

3

这样做的高效方式是使用DocBinhttps://spacy.io/usage/saving-loading#docs

示例取自文档(您可以使用doc_bin.to/from_disk代替to/from_bytes):

import spacy
from spacy.tokens import DocBin

doc_bin = DocBin()
texts = ["Some text", "Lots of texts...", "..."]
nlp = spacy.load("en_core_web_sm")
for doc in nlp.pipe(texts):
    doc_bin.add(doc)

bytes_data = doc_bin.to_bytes()

# Deserialize later, e.g. in a new process
nlp = spacy.blank("en")
doc_bin = DocBin().from_bytes(bytes_data)
docs = list(doc_bin.get_docs(nlp.vocab))

谢谢,这个很好用。在涉足新领域时,一个严重的问题是词汇量;)。对我来说,序列化意味着另外一件事情。 - MJ_Nadeau

0
有点难以得到答案,但我尝试了你的代码,对于 DocBins 无效。下面是我粘贴的导入部分的代码。
import spacy
from spacy.tokens import DocBin
from LanguageIdentifier import predict

import fitz
import glob
import os

from datetime import datetime

import logging

#English-Accuracy: en_core_web_trf
#French-Accuracy: fr_dep_news_trf
#German-Accuracy: de_dep_news_trf
#Multi Language-Accuracy: xx_sent_ud_sm

#DocBins
FRdoc_bin = DocBin (store_user_data=True,attrs=['ENT_TYPE','LEMMA','LIKE_EMAIL','LIKE_URL','LIKE_NUM','ORTH','POS'])
ENdoc_bin = DocBin (store_user_data=True,attrs=['ENT_TYPE','LEMMA','LIKE_EMAIL','LIKE_URL','LIKE_NUM','ORTH','POS'])
DEdoc_bin = DocBin (store_user_data=True,attrs=['ENT_TYPE','LEMMA','LIKE_EMAIL','LIKE_URL','LIKE_NUM','ORTH','POS'])
MULTIdoc_bin = DocBin (store_user_data=True,attrs=['ENT_TYPE','LEMMA','LIKE_EMAIL','LIKE_URL','LIKE_NUM','ORTH','POS'])


#NLP modules
frNLP = spacy.load('fr_dep_news_trf')
enNLP = spacy.load('en_core_web_trf') 
deNLP = spacy.load('de_dep_news_trf')
multiNLP = spacy.load('xx_sent_ud_sm')

ErroredFiles =[]

def processNLP(text):
    
    lang = predict(text) 
    if 'fr' in lang:
        doc = frNLP(text)
        FRdoc_bin.add(doc)
        return
    elif 'de' in lang:
        DEdoc_bin.add(deNLP(text))
        return
    elif 'en' in lang:        
        ENdoc_bin.add(enNLP(text))
        return
    else:
        MULTIdoc_bin.add(multiNLP(text))
        return


def get_text_from_pdf(Path):
    text = ''
    content = fitz.open(Path)
    for page in content:
        if page.number == 1:
            text = page.get_text()[212:]
        else:
            text = text + page.get_text()
    return text


FolderPath = r'C:\[Redacted]\DataSource\*\*.pdf'
PDFfiles = glob.glob(FolderPath)
counter = 0

for file in PDFfiles:    
    counter = counter +1
    try:
        textPDF = get_text_from_pdf(file)
        processNLP(textPDF)
        
    except Exception as e:        
        ErroredFiles.append(file)
        logging.error('Error with file '+ file)
        logging.error('Error message: '+ str(e))
        MULTIdoc_bin.add(multiNLP(textPDF))
    
    if(counter == 10):  #For testing purposes only
        break


CreatedModelPath = r'C:\[Redacted]\Results' + datetime.strftime(datetime.now(),"%Y%m%d%H%M%S") 
os.mkdir(CreatedModelPath)

FRdoc_bin.to_disk(CreatedModelPath+r'\FRdocBin'+'.nlp')
FRdoc_bin.vocab.to_disk(CreatedModelPath+r'\FRdocBin'+'.voc')


ENdoc_bin.to_disk(CreatedModelPath+r'\ENdocBin'+'.nlp')
DEdoc_bin.to_disk(CreatedModelPath+r'\DEdocBin'+'.nlp')
MULTIdoc_bin.to_disk(CreatedModelPath+'\MULTIdocBin'+'.nlp')

我收到的错误信息:

Traceback (most recent call last):

  File "C:\[Redacted]\ProcessingEngine.py", line 117, in <module>
    FRdoc_bin.vocab.to_disk(CreatedModelPath+r'\FRdocBin'+'.voc')

AttributeError: 'DocBin' object has no attribute 'vocab'

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接