PhraseMatcher возвращает пустой список при попытке пометить более одного элемента внутри документа - PullRequest
0 голосов
/ 12 февраля 2019

PhraseMatcher возвращает пустой список при попытке пометить более одного элемента внутри документа.Я передаю значения из столбца в csv, чтобы пометить названия продуктов внутри документа, но PhraseMatcher помечает только строки с одной строкой.Если для тегирования имеется более одного элемента, возвращается пустой список.Какое решение для этого

import spacy
import re
import csv
from spacy.matcher import PhraseMatcher

#Function to convert PhraseMatcher return value to string indexes 
def str_index_conversion(lbl, doc, matchitem):
    o_one = len(str(doc[0:matchitem[1]]))
    subdoc = doc[matchitem[1]:matchitem[2]]
    o_two = o_one + len(str(subdoc))
    return (o_one, o_two, lbl)

#nlp = spacy.blank('en')
nlp = spacy.load('en')

if 'ner' not in nlp.pipe_names:
    ner = nlp.create_pipe('ner')
    nlp.add_pipe(ner)
else:
    ner = nlp.get_pipe('ner')

ner.add_label('PRODUCT')     

DIR = 'C:\\Users\\Lenovo\\.spyder-py3\\smoke\\'
matcher = PhraseMatcher(nlp.vocab)


list_str_index = []
to_train_ents = []
with open('qq1.csv', newline='') as myFile:

    reader = csv.reader(myFile)
    for row in reader:
        try:
            product = row[0].lower()
            filename = row[1]
            #print(product)
            file = open(DIR+filename, "r", encoding ='utf-8')
            filecontents = file.read()
            #print(product)
            for s in filecontents:
                filecontents = re.sub(r'\[[0-9]*\]', ' ', filecontents)
                filecontents = re.sub(r'\s+', ' ', filecontents)
                #filecontents = filecontents.encode().decode('unicode-escape')
                filecontents = ''.join([line.lower() for line in filecontents])                
                print(product.split())
                matcher.add('PRODUCT', None, nlp(product))
                doc = nlp(filecontents)
                matches = matcher(doc)
                        #print(matches)
                list_str_index = [str_index_conversion('PRODUCT', doc, x) for x in matches]
                to_train_ents.append((filecontents, dict(entities=list_str_index)))
                break

        except Exception as e:
            #print(e)
            pass`

Список «to_train_ents» возвращает пустой список, когда внутри документа есть несколько элементов для тега.Элементы для тега предоставляются в виде csv, как прикреплено ниже: `SAMPLE CSV:

PRODUCT          FILES
ABC              XXXX
ABC2, ABC3, BCA3 XXXX
BC2              XXXX

Так, в случае 2-й строки, он возвращает пустой список в списке to_train_ents.Как можно пометить такие случаи в doc

ПОСЛЕ УДАЛЕНИЯ ИСПЫТАНИЯ И ИСКЛЮЧЕНИЯ БЛОКА: На этот раз я сохранил в моем csv только названия продуктов и имена файлов, которые есть в каталоге, содержащем файлы для пометки,Но все же, когда я отправил название продукта для тегирования, в котором есть два имени для тега в документе, он возвращает пустой список.ОБРАЗЕЦ КОДА СЕЙЧАС:

import spacy
import re
import csv
from spacy.matcher import PhraseMatcher

#Function to convert PhraseMatcher return value to string indexes 
def str_index_conversion(lbl, doc, matchitem):
    o_one = len(str(doc[0:matchitem[1]]))
    subdoc = doc[matchitem[1]:matchitem[2]]
    o_two = o_one + len(str(subdoc))
    return (o_one, o_two, lbl)

#nlp = spacy.blank('en')
nlp = spacy.load('en')

if 'ner' not in nlp.pipe_names:
    ner = nlp.create_pipe('ner')
    nlp.add_pipe(ner)
else:
    ner = nlp.get_pipe('ner')

ner.add_label('PRODUCT')     

DIR = 'C:\\Users\\Lenovo\\.spyder-py3\\sanity\\'
matcher = PhraseMatcher(nlp.vocab)



list_str_index = []
to_train_ents = []
with open('qq2.csv', newline='') as myFile:

    reader = csv.reader(myFile)
    for row in reader:
        product = row[0].lower()
        filename = row[1]
                #print(product)
        file = open(DIR+filename, "r", encoding ='utf-8')
        filecontents = file.read()
                #print(product)
        for s in filecontents:
            filecontents = re.sub(r'\[[0-9]*\]', ' ', filecontents)
            filecontents = re.sub(r'\s+', ' ', filecontents)
                    #filecontents = filecontents.encode().decode('unicode-escape')
            filecontents = ''.join([line.lower() for line in filecontents])                
                    #print(product.split())
                    #product_patterns = [nlp(text) for text in product.split()]
            matcher.add('PRODUCT', None, nlp(product))
            doc = nlp(filecontents)
            matches = matcher(doc)
                            #print(matches)
            list_str_index = [str_index_conversion('PRODUCT', doc, x) for x in matches]
            to_train_ents.append((filecontents, dict(entities=list_str_index)))
            break
...