O Spaczz fornece correspondência difusa e funcionalidade adicional de correspondência regex para spacy. Os componentes do Spaczz têm APIs semelhantes aos seus colegas de spacy e componentes do pipeline do SPACZZ podem se integrar aos pipelines Spacy, onde eles podem ser salvos/carregados como modelos.
Atualmente, a combinação difusa é realizada com Matchers do módulo Fuzz de Rapidfuzz e a correspondência Regex atualmente depende da Biblioteca Regex. O Spaczz certamente tem influência adicional de outras bibliotecas e recursos. Para detalhes adicionais, consulte a seção Referências.
Suporta Spacy> = 3.0
O Spaczz foi testado no Ubuntu, MacOS e Windows Server.
V0.6.0 Notas de lançamento:
python<=3.11,>=3.7 , juntamente com rapidfuzz>=1.0.0 ."spaczz_" SpaczzRuler . Além disso, lamento fazer isso sem um ciclo de depreciação.Matcher.pipe , que foram preteridos, agora são removidos.spaczz_span , que foi descontinuado, agora é removido.Consulte o Changelog para obter notas de lançamento anteriores. Isso acabará sendo movido para a página de leitura da leitura.
O Spaczz pode ser instalado usando PIP.
pip install spaczz Os principais recursos do Spaczz são o FuzzyMatcher , RegexMatcher e "Fuzzy" TokenMatcher que funcionam de maneira semelhante ao Matcher and PhraseMatcher de Spacy, e ao SpaczzRuler , que integra os Matcas Spaczz em um componente de pipeline espacial semelhante ao EntityRuler de espacos.
O uso básico do Matcher Fuzzy é semelhante ao PhraseMatcher de Spacy, exceto que retorna a proporção difusa e o padrão correspondente, juntamente com o ID da correspondência, as informações de partida e final; portanto, inclua variáveis para a proporção e padrão ao descompactar os resultados.
import spacy
from spaczz . matcher import FuzzyMatcher
nlp = spacy . blank ( "en" )
text = """Grint M Anderson created spaczz in his home at 555 Fake St,
Apt 5 in Nashv1le, TN 55555-1234 in the US.""" # Spelling errors intentional.
doc = nlp ( text )
matcher = FuzzyMatcher ( nlp . vocab )
matcher . add ( "NAME" , [ nlp ( "Grant Andersen" )])
matcher . add ( "GPE" , [ nlp ( "Nashville" )])
matches = matcher ( doc )
for match_id , start , end , ratio , pattern in matches :
print ( match_id , doc [ start : end ], ratio , pattern ) NAME Grint M Anderson 80 Grant Andersen
GPE Nashv1le 82 Nashville
Ao contrário de Matcheers Spacy, os Matchers Spaczz são escritos em Python Pure. Embora sejam obrigados a ter um vocabulário espacial transmitido a eles durante a inicialização, isso é puramente para consistência, pois os Matchers Spaczz não usam atualmente o vocabulário espacial. É por isso que o match_id acima é simplesmente uma string em vez de um valor inteiro, como nos Matcheers Spacy.
Os fósforos do SPACZZ também podem usar regras de partida por meio de funções de retorno de chamada. Esses retornos de chamada de partida precisam aceitar o próprio Matcher, o Doc que o Matcher foi chamado, o índice da Match e as correspondências produzidas pelo Matcher.
import spacy
from spacy . tokens import Span
from spaczz . matcher import FuzzyMatcher
nlp = spacy . blank ( "en" )
text = """Grint M Anderson created spaczz in his home at 555 Fake St,
Apt 5 in Nashv1le, TN 55555-1234 in the US.""" # Spelling errors intentional.
doc = nlp ( text )
def add_name_ent ( matcher , doc , i , matches ):
"""Callback on match function. Adds "NAME" entities to doc."""
# Get the current match and create tuple of entity label, start and end.
# Append entity to the doc's entity. (Don't overwrite doc.ents!)
_match_id , start , end , _ratio , _pattern = matches [ i ]
entity = Span ( doc , start , end , label = "NAME" )
doc . ents += ( entity ,)
matcher = FuzzyMatcher ( nlp . vocab )
matcher . add ( "NAME" , [ nlp ( "Grant Andersen" )], on_match = add_name_ent )
matches = matcher ( doc )
for ent in doc . ents :
print (( ent . text , ent . start , ent . end , ent . label_ )) ('Grint M Anderson', 0, 3, 'NAME')
Como EntityRuler de Spacy, uma lógica de atualização de entidades muito semelhante foi implementada no SpaczzRuler . O SpaczzRuler também cuida do manuseio de correspondências sobrepostas. É discutido em uma seção posterior.
Ao contrário dos Matchers de Spacy, as regras adicionadas aos Matcores Spaczz têm argumentos opcionais de palavras -chave que podem modificar o comportamento correspondente. Pegue os exemplos de correspondência confusa abaixo:
import spacy
from spaczz . matcher import FuzzyMatcher
nlp = spacy . blank ( "en" )
# Let's modify the order of the name in the text.
text = """Anderson, Grint created spaczz in his home at 555 Fake St,
Apt 5 in Nashv1le, TN 55555-1234 in the US.""" # Spelling errors intentional.
doc = nlp ( text )
matcher = FuzzyMatcher ( nlp . vocab )
matcher . add ( "NAME" , [ nlp ( "Grant Andersen" )])
matches = matcher ( doc )
# The default fuzzy matching settings will not find a match.
for match_id , start , end , ratio , pattern in matches :
print ( match_id , doc [ start : end ], ratio , pattern )Em seguida, alteramos o comportamento de correspondência difuso para o padrão na regra do "nome".
import spacy
from spaczz . matcher import FuzzyMatcher
nlp = spacy . blank ( "en" )
# Let's modify the order of the name in the text.
text = """Anderson, Grint created spaczz in his home at 555 Fake St,
Apt 5 in Nashv1le, TN 55555-1234 in the US.""" # Spelling errors intentional.
doc = nlp ( text )
matcher = FuzzyMatcher ( nlp . vocab )
matcher . add ( "NAME" , [ nlp ( "Grant Andersen" )], kwargs = [{ "fuzzy_func" : "token_sort" }])
matches = matcher ( doc )
# The default fuzzy matching settings will not find a match.
for match_id , start , end , ratio , pattern in matches :
print ( match_id , doc [ start : end ], ratio , pattern ) NAME Anderson, Grint 83 Grant Andersen
A lista completa de argumentos de palavras -chave disponíveis para configurações combinadas difusas inclui:
ignore_case (bool): seja para o texto de baixo caso antes de corresponder. O padrão é True .min_r (int): taxa de correspondência mínima necessária.thresh (int): Se essa proporção for excedida na varredura inicial e flex > 0 , nenhuma otimização será tentada. Se flex == 0 , thresh não tem efeito. O padrão é 100 .fuzzy_func (str): nome da função de correspondência difusa a ser usada. Todas as funções de correspondência RapidFuzz com configurações padrão estão disponíveis. Funções de correspondência difusa adicionais podem ser registradas pelos usuários. O padrão é "simple" :"simple" = ratio"partial" = partial_ratio"token" = token_ratio"token_set" = token_set_ratio"token_sort" = token_sort_ratio"partial_token" = partial_token_ratio"partial_token_set" = partial_token_set_ratio"partial_token_sort" = partial_token_sort_ratio"weighted" = WRatio"quick" = QRatio"partial_alignment" = partial_ratio_alignment (requer rapidfuzz>=2.0.3 )flex (int | literal ['padrão', 'min', 'max']): número de tokens para mover os limites da correspondência para a esquerda e direita durante a otimização. Pode ser um int com um máximo de len(pattern) e um min de 0 (avisará e mudará se mais alto ou menor). "max" , "min" ou "default" também são válidos. O padrão é "default" : len(pattern) // 2 .min_r1 (int | nenhum): controle granular opcional sobre a taxa de correspondência mínima necessária para a seleção durante a varredura inicial. Se flex == 0 , min_r1 será substituído por min_r2 . Se flex > 0 , min_r1 deverá ser menor que min_r2 e "baixo" em geral porque os limites da correspondência não são flexionados inicialmente. O padrão é None , o que resultará na definição min_r1 para round(min_r / 1.5) . O uso básico do Matcher REGEX também é bastante semelhante ao PhraseMatcher de Spacy. Ele aceita padrões Regex como strings para que as bandeiras devem estar embutidas. As regexes são compiladas com o pacote regex, de modo que a correspondência "difusa" aproximada é suportada. Para fornecer acesso a esses resultados de correspondência "difuso", o Matchaer retorna uma proporção difusa calculada e padrão correspondente, juntamente com o ID da correspondência, as informações de partida e final, portanto, inclua variáveis para a proporção e padrão ao descompactar os resultados.
import spacy
from spaczz . matcher import RegexMatcher
nlp = spacy . blank ( "en" )
text = """Anderson, Grint created spaczz in his home at 555 Fake St,
Apt 5 in Nashv1le, TN 55555-1234 in the US.""" # Spelling errors intentional.
doc = nlp ( text )
matcher = RegexMatcher ( nlp . vocab )
# Use inline flags for regex strings as needed
matcher . add (
"ZIP" ,
[ r"bd{5}(?:[-s]d{4})?b" ],
)
matcher . add ( "GPE" , [ r"(usa){d<=1}" ]) # Fuzzy regex.
matches = matcher ( doc )
for match_id , start , end , ratio , pattern in matches :
print ( match_id , doc [ start : end ], ratio , pattern ) ZIP 55555-1234 100 bd{5}(?:[-s]d{4})?b
GPE US 80 (usa){d<=1}
Os fósforos do SPACZZ também podem usar regras de partida por meio de funções de retorno de chamada. Esses retornos de chamada de partida precisam aceitar o próprio Matcher, o Doc que o Matcher foi chamado, o índice da Match e as correspondências produzidas pelo Matcher. Veja o exemplo de uso do Matcher Fuzzy acima para obter detalhes.
Como o Fuzzy Matcher, o REGEX Matcher possui argumentos de palavras -chave opcionais que podem modificar o comportamento correspondente. Pegue o exemplo de correspondência de regex abaixo.
import spacy
from spaczz . matcher import RegexMatcher
nlp = spacy . blank ( "en" )
text = """Anderson, Grint created spaczz in his home at 555 Fake St,
Apt 5 in Nashv1le, TN 55555-1234 in the USA.""" # Spelling errors intentional. Notice 'USA' here.
doc = nlp ( text )
matcher = RegexMatcher ( nlp . vocab )
# Use inline flags for regex strings as needed
matcher . add (
"STREET" , [ "street_addresses" ], kwargs = [{ "predef" : True }]
) # Use predefined regex by key name.
# Below will not expand partial matches to span boundaries.
matcher . add ( "GPE" , [ r"(?i)[U](nited|.?) ?[S](tates|.?)" ], kwargs = [{ "partial" : False }])
matches = matcher ( doc )
for match_id , start , end , ratio , pattern in matches :
print (
match_id , doc [ start : end ], ratio , pattern
) # comma in result isn't ideal - see "Roadmap" STREET 555 Fake St, 100 street_addresses
A lista completa de argumentos de palavras -chave disponíveis para configurações de correspondência de regex inclui:
ignore_case (bool): seja para o texto de baixo caso antes de corresponder. O padrão é True .min_r (int): taxa de correspondência mínima necessária.fuzzy_weights (STR): Nome do método de ponderação para inserção, exclusão e substituição de regex. Métodos de ponderação adicionais podem ser registrados pelos usuários. O padrão é "indel" ."indel" = (1, 1, 2)"lev" = (1, 1, 1)partial : (Bool): se as correspondências parciais devem ser estendidas aos limites Token ou Span no doc ou não. Por exemplo, o regex corresponde apenas a parte de um Token ou Span no doc . O padrão é True .predef (string): se a string regex deve ser interpretada como uma chave para um padrão regex predefinido ou não. Padrões Regex predefinidos adicionais podem ser registrados pelos usuários. O padrão é False."dates""times""phones""phones_with_exts""links""emails""ips""ipv6s""prices""hex_colors""credit_cards""btc_addresses""street_addresses""zip_codes""po_boxes""ssn_numbers" O uso básico do correspondente de similaridade é semelhante ao PhraseMatcher da Spacy, exceto que retorna a taxa de similaridade vetorial e o padrão correspondente, juntamente com o ID da correspondência, as informações de partida e final, portanto, inclua variáveis para a proporção e padrão ao descompactar os resultados.
Para produzir resultados significativos do Matcário de similaridade, um modelo de spacy com vetores de palavras (por exemplo, modelos médios ou grandes em inglês) deve ser usado para inicializar o correspondente, processar o documento de destino e processar quaisquer padrões adicionados.
import spacy
from spaczz . matcher import SimilarityMatcher
nlp = spacy . load ( "en_core_web_md" )
text = "I like apples, grapes and bananas."
doc = nlp ( text )
# lowering min_r2 from default of 75 to produce matches in this example
matcher = SimilarityMatcher ( nlp . vocab , min_r2 = 65 )
matcher . add ( "FRUIT" , [ nlp ( "fruit" )])
matches = matcher ( doc )
for match_id , start , end , ratio , pattern in matches :
print ( match_id , doc [ start : end ], ratio , pattern ) FRUIT apples 70 fruit
FRUIT grapes 73 fruit
FRUIT bananas 70 fruit
Observe que, mesmo para o espaço de pítone principalmente puro, esse processo é extremamente lento, portanto, esteja atento ao escopo em que é aplicado. A ativação do suporte à GPU no Spacy (veja aqui) deve melhorar um pouco a velocidade, mas acredito que o processo ainda será gargalos no algoritmo de pesquisa python puro até desenvolver um algoritmo de pesquisa melhor e/ou soltar a pesquisa no código de nível inferior (ex c).
Além disso, como uma característica um tanto experimental, o Matcário de similaridade não faz parte do SpaczzRuler nem possui um governante separado. Se você precisar adicionar correspondências de similaridade às entidades de um Doc , precisará usar um retorno de chamada para correspondência por enquanto. Consulte o exemplo de retorno de chamada de correspondência confuso acima para idéias. Se houver interesse suficiente em integrar/criar uma régua para o combinador de similaridade, isso pode ser feito.
A lista completa de argumentos de palavras -chave disponíveis para configurações de correspondência de similaridade inclui:
ignore_case (bool): seja para o texto em caso mais baixo antes da correspondência difusa. O padrão é True .min_r (int): taxa de correspondência mínima necessária.thresh (int): Se essa proporção for excedida na varredura inicial e flex > 0 , nenhuma otimização será tentada. Se flex == 0 , thresh não tem efeito. O padrão é 100 .flex (int | literal ['padrão', 'min', 'max']): número de tokens para mover os limites da correspondência para a esquerda e direita durante a otimização. Pode ser um int com um máximo de len(pattern) e um min de 0 (avisará e mudará se mais alto ou menor). "max" , "min" ou "default" também são válidos. O padrão é "default" : len(pattern) // 2 .min_r1 (int | nenhum): controle granular opcional sobre a taxa de correspondência mínima necessária para a seleção durante a varredura inicial. Se flex == 0 , min_r1 será substituído por min_r2 . Se flex > 0 , min_r1 deverá ser menor que min_r2 e "baixo" em geral porque os limites da correspondência não são flexionados inicialmente. O padrão é None , o que resultará na definição min_r1 para round(min_r / 1.5) .min_r2 (int | nenhum): controle granular opcional sobre a taxa de correspondência mínima necessária para a seleção durante a otimização de correspondências. Precisa ser maior que min_r1 e o "alto" em geral para garantir que apenas correspondências de qualidade sejam retornadas. O padrão é None , o que resultará na definição min_r2 como min_r . NOTA: Matcher da Spacy agora suporta correspondência difusa; portanto, a menos que você precise de um recurso específico do TokenMatcher do Spaczz, é altamente recomendável usar Matcher muito mais rápido de Spacy.
O uso básico do Matcher Token é semelhante ao Matcher de Spacy. Ele aceita padrões marcados na forma de listas de dicionários em que cada lista descreve um padrão individual e cada dicionário descreve um token individual.
O Matcher de token aceita os mesmos atributos de token e a sintaxe do padrão, pois é a contraparte do Spacy, mas adiciona suporte difuso e difuso-regex.
"FUZZY" e "FREGEX" são as duas opções adicionais de padrões de token espacial.
Por exemplo:
[
{ "TEXT" : { "FREGEX" : "(database){e<=1}" }},
{ "LOWER" : { "FUZZY" : "access" , "MIN_R" : 85 , "FUZZY_FUNC" : "quick_lev" }},
]Certifique -se de usar teclas de dicionário em maiúsculas em padrões.
A lista completa de argumentos de palavras -chave disponíveis para configurações de correspondência de token inclui:
ignore_case (bool): seja para o texto de baixo caso antes de corresponder. Só pode ser definido no nível do padrão. Para padrões "Fuzzy" e "Fregex". O padrão é True .min_r (int): taxa de correspondência mínima necessária. Para padrões "Fuzzy" e "Fregex".fuzzy_func (str): nome da função de correspondência difusa a ser usada. Só pode ser definido no nível do padrão. Apenas para padrões "difusos". Todas as funções de correspondência RapidFuzz com configurações padrão estão disponíveis, no entanto, quaisquer funções baseadas em token não fornecem utilidade no nível individual de token. Funções de correspondência difusa adicionais podem ser registradas pelos usuários. As funções incluídas e úteis são (o padrão é simple ):"simple" = ratio"partial" = partial_ratio"quick" = QRatio"partial_alignment" = partial_ratio_alignment (requer rapidfuzz>=2.0.3 )fuzzy_weights (STR): Nome do método de ponderação para inserção, exclusão e substituição de regex. Métodos de ponderação adicionais podem ser registrados pelos usuários. O padrão é "indel" ."indel" = (1, 1, 2)"lev" = (1, 1, 1)predef : se Regex deve ser interpretado como uma chave para um padrão Regex predefinido ou não. Só pode ser definido no nível do padrão. Apenas para padrões "Fregex". O padrão é False . import spacy
from spaczz . matcher import TokenMatcher
# Using model results like POS tagging in token patterns requires model that provides these.
nlp = spacy . load ( "en_core_web_md" )
text = """The manager gave me SQL databesE acess so now I can acces the Sequal DB.
My manager's name is Grfield"""
doc = nlp ( text )
matcher = TokenMatcher ( vocab = nlp . vocab )
matcher . add (
"DATA" ,
[
[
{ "TEXT" : "SQL" },
{ "LOWER" : { "FREGEX" : "(database){s<=1}" }},
{ "LOWER" : { "FUZZY" : "access" }},
],
[{ "TEXT" : { "FUZZY" : "Sequel" }, "POS" : "PROPN" }, { "LOWER" : "db" }],
],
)
matcher . add ( "NAME" , [[{ "TEXT" : { "FUZZY" : "Garfield" }}]])
matches = matcher ( doc )
for match_id , start , end , ratio , pattern in matches :
print ( match_id , doc [ start : end ], ratio , pattern ) DATA SQL databesE acess 91 [{"TEXT":"SQL"},{"LOWER":{"FREGEX":"(database){s<=1}"}},{"LOWER":{"FUZZY":"access"}}]
DATA Sequal DB 87 [{"TEXT":{"FUZZY":"Sequel"},"POS":"PROPN"},{"LOWER":"db"}]
NAME Grfield 93 [{"TEXT":{"FUZZY":"Garfield"}}]
Mesmo que o Matcher Token possa substituir o Matcher de Spacy, ainda é recomendável usar Matcher de Spacy se você não precisar dos recursos difusos do Matcioner do Spaczz Token - isso diminuirá desnecessariamente o processamento desnecessariamente.
Lembrete: Matcher do Spacy agora suporta combinações difusas; portanto, a menos que você precise de um recurso específico do TokenMatcher do Spaczz, é altamente recomendável usar Matcher muito mais rápido de Spacy.
O governante Spaczz combina os fósforos de frase difusa e regex e o fósforo "difuso", em um componente de pipeline que pode atualizar um Doc.ents semelhante ao EntityRuler de Spacy.
Os padrões devem ser adicionados como um iterável dos dicionários no formato de {etique (str), padrão (str ou list), tipo (str), kwargs opcionais (dict) e id (str)} .
Por exemplo, um padrão de frase difusa:
{'label': 'ORG', 'pattern': 'Apple' 'kwargs': {'min_r2': 90}, 'type': 'fuzzy'}
Ou, um padrão simbólico:
{'label': 'ORG', 'pattern': [{'TEXT': {'FUZZY': 'Apple'}}], 'type': 'token'}
import spacy
from spaczz . pipeline import SpaczzRuler
nlp = spacy . blank ( "en" )
text = """Anderson, Grint created spaczz in his home at 555 Fake St,
Apt 5 in Nashv1le, TN 55555-1234 in the USA.
Some of his favorite bands are Converg and Protet the Zero.""" # Spelling errors intentional.
doc = nlp ( text )
patterns = [
{
"label" : "NAME" ,
"pattern" : "Grant Andersen" ,
"type" : "fuzzy" ,
"kwargs" : { "fuzzy_func" : "token_sort" },
},
{
"label" : "STREET" ,
"pattern" : "street_addresses" ,
"type" : "regex" ,
"kwargs" : { "predef" : True },
},
{ "label" : "GPE" , "pattern" : "Nashville" , "type" : "fuzzy" },
{
"label" : "ZIP" ,
"pattern" : r"b(?:55554){s<=1}(?:(?:[-s])?d{4}b)" ,
"type" : "regex" ,
}, # fuzzy regex
{ "label" : "GPE" , "pattern" : "(?i)[U](nited|.?) ?[S](tates|.?)" , "type" : "regex" },
{
"label" : "BAND" ,
"pattern" : [{ "LOWER" : { "FREGEX" : "(converge){e<=1}" }}],
"type" : "token" ,
},
{
"label" : "BAND" ,
"pattern" : [
{ "TEXT" : { "FUZZY" : "Protest" }},
{ "IS_STOP" : True },
{ "TEXT" : { "FUZZY" : "Hero" }},
],
"type" : "token" ,
},
]
ruler = SpaczzRuler ( nlp )
ruler . add_patterns ( patterns )
doc = ruler ( doc )
for ent in doc . ents :
print (
(
ent . text ,
ent . start ,
ent . end ,
ent . label_ ,
ent . _ . spaczz_ratio ,
ent . _ . spaczz_type ,
ent . _ . spaczz_pattern ,
)
) ('Anderson, Grint', 0, 3, 'NAME', 83, 'fuzzy', 'Grant Andersen')
('555 Fake St,', 9, 13, 'STREET', 100, 'regex', 'street_addresses')
('Nashv1le', 17, 18, 'GPE', 82, 'fuzzy', 'Nashville')
('55555-1234', 20, 23, 'ZIP', 90, 'regex', '\b(?:55554){s<=1}(?:(?:[-\s])?\d{4}\b)')
('USA', 25, 26, 'GPE', 100, 'regex', '(?i)[U](nited|\.?) ?[S](tates|\.?)')
('Converg', 34, 35, 'BAND', 93, 'token', '[{"LOWER":{"FREGEX":"(converge){e<=1}"}}]')
('Protet the Zero', 36, 39, 'BAND', 89, 'token', '[{"TEXT":{"FUZZY":"Protest"}},{"IS_STOP":true},{"TEXT":{"FUZZY":"Hero"}}]')
Vemos no exemplo acima que estamos referenciando alguns atributos personalizados, que são explicados abaixo.
Para mais exemplos SpaczzRuler , consulte aqui. Em particular, isso fornece detalhes sobre o processo de classificação do governante e os parâmetros de correspondência difusa.
O Spaczz inicializa alguns atributos personalizados ao importar. Estes estão sob o spacy ._. atributo e são ainda mais anteriores ao spaczz_ , portanto, não deve haver conflitos com seus próprios atributos personalizados. Se houver spacz, forçará substituí -los.
Esses atributos personalizados são definidos apenas através do Ruler Spaczz no nível do token. As versões Span e Doc desses atributos são getters que fazem referência aos atributos de nível de token.
Os seguintes atributos Token estão disponíveis. Todos são mutáveis:
spaczz_token : padrão = False . Booleano que denota se o token faz parte de uma entidade estabelecida pelo governante do Spaczz.spaczz_type : padrão = None . String que mostra qual Matcher produziu uma entidade usando o token.spaczz_ratio : padrão = None . Se o token fizer parte de uma entidade correspondente, ele retornará a proporção difusa.spaczz_pattern : padrão = None . Se o token fizer parte de uma entidade correspondente, ele retornará o padrão como uma string (JSON Formatted for Token Patterns) que produziu a partida. Os atributos Span a seguir referenciam os atributos de token incluídos no período. Todos são imutáveis:
spaczz_ent : padrão = False . Booleano que denota se todos os tokens no período fazem parte de uma entidade estabelecida pelo governante do Spaczz.spaczz_type : padrão = None . String que denota que Matcher produziu uma entidade usando os tokens incluídos.spaczz_types : padrão = set() . Definir que mostra quais Matchers produziram entidades usando os tokens incluídos. Um período de entidade deve ter apenas um tipo, mas isso permite que você veja os tipos incluídos em qualquer extensão arbitrário.spaczz_ratio : padrão = None . Se todos os tokens em Span fizerem parte de uma entidade correspondente, ele retornará a relação nebulosa.spaczz_pattern : padrão = None . Se todos os tokens em um período fizer parte de uma entidade correspondente, ele retornará o padrão como uma string (JSON Formatted for Token Patterns) que produziu a partida. Os atributos Doc a seguir referenciam os atributos do token incluídos no doc. Todos são imutáveis:
spaczz_doc : padrão = False . Booleano que denota se houver algum tokens no médico fazem parte de uma entidade estabelecida pelo governante do Spaczz.spaczz_types : padrão = set() . Conjunto que mostra quais matcheres produziam entidades no documento. O SpaczzRuler possui os métodos de disco/bytes e aceitará parâmetros config passados para spacy.load() . Ele também tem seu próprio ponto de entrada de fábrica de Spacy, para que Spacy esteja ciente do SpaczzRuler . Abaixo está um exemplo de salvar e carregar um pipeline de spacy com o pequeno modelo em inglês, o EntityRuler e o SpaczzRuler .
import spacy
from spaczz . pipeline import SpaczzRuler
nlp = spacy . load ( "en_core_web_md" )
text = """Anderson, Grint created spaczz in his home at 555 Fake St,
Apt 5 in Nashv1le, TN 55555-1234 in the USA.
Some of his favorite bands are Converg and Protet the Zero.""" # Spelling errors intentional.
doc = nlp ( text )
for ent in doc . ents :
print (( ent . text , ent . start , ent . end , ent . label_ )) ('Anderson, Grint', 0, 3, 'ORG')
('555', 9, 10, 'CARDINAL')
('Apt 5', 14, 16, 'PRODUCT')
('Nashv1le', 17, 18, 'GPE')
('TN 55555-1234', 19, 23, 'ORG')
('USA', 25, 26, 'GPE')
('Converg', 34, 35, 'PERSON')
('Zero', 38, 39, 'CARDINAL')
Embora Spacy faça um trabalho decente ao identificar que as entidades nomeadas estão presentes neste exemplo, podemos definitivamente melhorar as correspondências - particularmente com os tipos de rótulos aplicados.
Vamos adicionar um governante de entidade para algumas partidas baseadas em regras.
from spacy . pipeline import EntityRuler
entity_ruler = nlp . add_pipe ( "entity_ruler" , before = "ner" ) #spaCy v3 syntax
entity_ruler . add_patterns (
[{ "label" : "GPE" , "pattern" : "Nashville" }, { "label" : "GPE" , "pattern" : "TN" }]
)
doc = nlp ( text )
for ent in doc . ents :
print (( ent . text , ent . start , ent . end , ent . label_ )) ('Anderson, Grint', 0, 3, 'ORG')
('555', 9, 10, 'CARDINAL')
('Apt 5', 14, 16, 'PRODUCT')
('Nashv1le', 17, 18, 'GPE')
('TN', 19, 20, 'GPE')
('USA', 25, 26, 'GPE')
('Converg', 34, 35, 'PERSON')
('Zero', 38, 39, 'CARDINAL')
Estamos progredindo, mas Nashville está escrito errado no texto para que o governante da entidade não o encontre, e ainda temos outras entidades para consertar/encontrar.
Vamos adicionar uma régua de espaço para arredondar este oleoduto. Também incluiremos o atributo personalizado spaczz_span nos resultados para denotar quais entidades foram definidas via Spaczz.
spaczz_ruler = nlp . add_pipe ( "spaczz_ruler" , before = "ner" ) #spaCy v3 syntax
spaczz_ruler . add_patterns (
[
{
"label" : "NAME" ,
"pattern" : "Grant Andersen" ,
"type" : "fuzzy" ,
"kwargs" : { "fuzzy_func" : "token_sort" },
},
{
"label" : "STREET" ,
"pattern" : "street_addresses" ,
"type" : "regex" ,
"kwargs" : { "predef" : True },
},
{ "label" : "GPE" , "pattern" : "Nashville" , "type" : "fuzzy" },
{
"label" : "ZIP" ,
"pattern" : r"b(?:55554){s<=1}(?:[-s]d{4})?b" ,
"type" : "regex" ,
}, # fuzzy regex
{
"label" : "BAND" ,
"pattern" : [{ "LOWER" : { "FREGEX" : "(converge){e<=1}" }}],
"type" : "token" ,
},
{
"label" : "BAND" ,
"pattern" : [
{ "TEXT" : { "FUZZY" : "Protest" }},
{ "IS_STOP" : True },
{ "TEXT" : { "FUZZY" : "Hero" }},
],
"type" : "token" ,
},
]
)
doc = nlp ( text )
for ent in doc . ents :
print (( ent . text , ent . start , ent . end , ent . label_ , ent . _ . spaczz_ent )) ('Anderson, Grint', 0, 3, 'NAME', True)
('555 Fake St,', 9, 13, 'STREET', True)
('Apt 5', 14, 16, 'PRODUCT', False)
('Nashv1le', 17, 18, 'GPE', True)
('TN', 19, 20, 'GPE', False)
('55555-1234', 20, 23, 'ZIP', True)
('USA', 25, 26, 'GPE', False)
('Converg', 34, 35, 'BAND', True)
('Protet the Zero', 36, 39, 'BAND', True)
Incrível! O pequeno modelo em inglês ainda comete um erro de reconhecimento de entidade nomeado ("5" em "Apt 5" como CARDINAL ), mas estamos satisfeitos no geral.
Vamos salvar este pipeline no disco e verifique se podemos carregá -lo corretamente.
import tempfile
with tempfile . TemporaryDirectory () as tmp_dir :
nlp . to_disk ( f" { tmp_dir } /example_pipeline" )
nlp = spacy . load ( f" { tmp_dir } /example_pipeline" )
nlp . pipe_names ['tok2vec',
'tagger',
'parser',
'attribute_ruler',
'lemmatizer',
'entity_ruler',
'spaczz_ruler',
'ner']
Podemos até garantir que todos os padrões do governante do Spaczz ainda estejam presentes.
spaczz_ruler = nlp . get_pipe ( "spaczz_ruler" )
spaczz_ruler . patterns [{'label': 'NAME',
'pattern': 'Grant Andersen',
'type': 'fuzzy',
'kwargs': {'fuzzy_func': 'token_sort'}},
{'label': 'GPE', 'pattern': 'Nashville', 'type': 'fuzzy'},
{'label': 'STREET',
'pattern': 'street_addresses',
'type': 'regex',
'kwargs': {'predef': True}},
{'label': 'ZIP',
'pattern': '\b(?:55554){s<=1}(?:[-\s]\d{4})?\b',
'type': 'regex'},
{'label': 'BAND',
'pattern': [{'LOWER': {'FREGEX': '(converge){e<=1}'}}],
'type': 'token'},
{'label': 'BAND',
'pattern': [{'TEXT': {'FUZZY': 'Protest'}},
{'IS_STOP': True},
{'TEXT': {'FUZZY': 'Hero'}}],
'type': 'token'}]
A principal razão para a velocidade mais lenta do Spaczz é que o C em seu nome não está capitalizado como está no spa c y. O Spaczz está escrito em python puro e seus fósforos atualmente não utilizam vocabulários de idiomas Spacy, o que significa que seguir sua lógica deve ser fácil para quem está familiarizado com o Python. No entanto, isso significa que os componentes do SPACZZ funcionarão mais lentos e provavelmente consumirão mais memória do que seus colegas de spacy, especialmente à medida que mais padrões são adicionados e os documentos ficam mais longos. Portanto, é recomendável usar componentes espaciais como o EntityRuler para entidades com pouca incerteza, como erros de ortografia consistentes. Use componentes do SPACZZ quando não houver alternativas viáveis de espacial.
No momento, não estou trabalhando em otimizações de desempenho para o Spacz, mas as sugestões algorítmicas e de otimização são bem -vindas.
Os métodos primários para acelerar o FuzzyMatcher e SimilarityMatcher estão diminuindo o parâmetro flex em relação 0 , ou se flex > 0 , aumentando o parâmetro min_r1 em direção ao valor de min_r2 e/ou diminuindo o parâmetro thresh em direção min_r2 . Esteja ciente de que todas essas "acelerações" têm o custo de oportunidade de partidas potencialmente aprimoradas.
Conforme mencionado na descrição SimilarityMatcher , a utilização de uma GPU também pode ajudar a acelerar seu processo de correspondência.
Estou sempre aberto e receptivo a solicitações de recursos, mas esteja ciente, como um solo-Dev com muito para aprender, o desenvolvimento pode se mover muito devagar. A seguir, é apresentado o meu roteiro para o Spaczz, para que você possa ver onde os problemas levantados podem se encaixar nas minhas prioridades atuais.
Nota: Embora eu queira manter spaczz funcional, não o estou desenvolvendo ativamente. Eu tento responder a problemas e solicitações, mas este projeto não é um foco meu.
Alta prioridade
Aprimoramentos
Solicitações e colaboradores de tração são bem -vindos.
O Spaczz é flake8, formatado com preto, verificado com MyPy (embora isso possa se beneficiar da especificidade aprimorada), testada com pytest, automatizada com NOx e construída/embalada com poesia. Existem algumas outras ferramentas de desenvolvimento detalhadas no Noxfile.py, juntamente com ganchos de pré-compromisso do Git.
Para contribuir para o desenvolvimento do Spaczz, bifurque o repositório e instale o Spaczz e suas dependências de desenvolvimento com poesia. Se você estiver interessado em ser um colaborador regular, entre em contato comigo diretamente.
poetry install # Within spaczz's root directory.Eu mantenho o NOX e o pré-compromisso fora do meu ambiente de poesia como parte dos meus ambientes de cadeia de ferramentas Python. Com o pré-compromisso instalado, você também pode precisar executar o abaixo para cometer alterações.
pre - commit install O único outro pacote que não será instalado via poesia, mas é usado para testes e exemplos de documentação é o modelo em inglês médio SPacy ( en-core-web-md ). Isso precisará ser instalado separadamente. O comando abaixo deve fazer o truque:
poetry run python - m spacy download "en_core_web_md"