From 97545ad781f35a445a57fea1f53d4bb8d8996312 Mon Sep 17 00:00:00 2001 From: Filipe Caixeta Date: Wed, 12 Sep 2018 18:12:56 -0300 Subject: [PATCH 1/4] Add words to portuguese language _num_words --- spacy/lang/pt/lex_attrs.py | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/spacy/lang/pt/lex_attrs.py b/spacy/lang/pt/lex_attrs.py index 1a350776bf0..d26ec52370a 100644 --- a/spacy/lang/pt/lex_attrs.py +++ b/spacy/lang/pt/lex_attrs.py @@ -4,12 +4,14 @@ from ...attrs import LIKE_NUM -_num_words = ['zero', 'um', 'dois', 'três', 'quatro', 'cinco', 'seis', 'sete', - 'oito', 'nove', 'dez', 'onze', 'doze', 'treze', 'catorze', - 'quinze', 'dezesseis', 'dezasseis', 'dezessete', 'dezassete', 'dezoito', 'dezenove', 'dezanove', 'vinte', - 'trinta', 'quarenta', 'cinquenta', 'sessenta', 'setenta', - 'oitenta', 'noventa', 'cem', 'mil', 'milhão', 'bilhão', 'bilião', 'trilhão', 'trilião', - 'quatrilhão'] +_num_words = ['zero', 'um', 'dois', 'três', 'tres', 'quatro', 'cinco', 'seis', 'sete', 'oito', 'nove', 'dez', + 'onze', 'doze', 'dúzia', 'dúzias', 'duzia', 'duzias', 'treze', 'catorze', 'quinze', 'dezasseis', + 'dezassete', 'dezoito', 'dezanove', 'vinte', 'trinta', 'quarenta', 'cinquenta', 'sessenta', + 'setenta', 'oitenta', 'noventa', 'cem', 'cento', 'duzentos', 'trezentos', 'quatrocentos', + 'quinhentos', 'seicentos', 'setecentos', 'oitocentos', 'novecentos', 'mil', 'milhão', 'milhao', + 'milhões', 'milhoes', 'bilhão', 'bilhao', 'bilhões', 'bilhoes', 'trilhão', 'trilhao', 'trilhões', + 'trilhoes', 'quadrilhão', 'quadrilhao', 'quadrilhões', 'quadrilhoes'] + _ordinal_words = ['primeiro', 'segundo', 'terceiro', 'quarto', 'quinto', 'sexto', 'sétimo', 'oitavo', 'nono', 'décimo', 'vigésimo', 'trigésimo', From efc0f0e01c497a7bccc65570b111af5f96ae38a2 Mon Sep 17 00:00:00 2001 From: Filipe Caixeta Date: Wed, 12 Sep 2018 19:51:45 -0300 Subject: [PATCH 2/4] Add words to portuguese language _num_words --- .github/contributors/filipecaixeta.md | 106 ++++++++++++++++++++++++++ 1 file changed, 106 insertions(+) create mode 100644 .github/contributors/filipecaixeta.md diff --git a/.github/contributors/filipecaixeta.md b/.github/contributors/filipecaixeta.md new file mode 100644 index 00000000000..526583ce10d --- /dev/null +++ b/.github/contributors/filipecaixeta.md @@ -0,0 +1,106 @@ +# spaCy contributor agreement + +This spaCy Contributor Agreement (**"SCA"**) is based on the +[Oracle Contributor Agreement](http://www.oracle.com/technetwork/oca-405177.pdf). +The SCA applies to any contribution that you make to any product or project +managed by us (the **"project"**), and sets out the intellectual property rights +you grant to us in the contributed materials. The term **"us"** shall mean +[ExplosionAI UG (haftungsbeschränkt)](https://explosion.ai/legal). The term +**"you"** shall mean the person or entity identified below. + +If you agree to be bound by these terms, fill in the information requested +below and include the filled-in version with your first pull request, under the +folder [`.github/contributors/`](/.github/contributors/). The name of the file +should be your GitHub username, with the extension `.md`. For example, the user +example_user would create the file `.github/contributors/example_user.md`. + +Read this agreement carefully before signing. These terms and conditions +constitute a binding legal agreement. + +## Contributor Agreement + +1. The term "contribution" or "contributed materials" means any source code, +object code, patch, tool, sample, graphic, specification, manual, +documentation, or any other material posted or submitted by you to the project. + +2. With respect to any worldwide copyrights, or copyright applications and +registrations, in your contribution: + + * you hereby assign to us joint ownership, and to the extent that such + assignment is or becomes invalid, ineffective or unenforceable, you hereby + grant to us a perpetual, irrevocable, non-exclusive, worldwide, no-charge, + royalty-free, unrestricted license to exercise all rights under those + copyrights. This includes, at our option, the right to sublicense these same + rights to third parties through multiple levels of sublicensees or other + licensing arrangements; + + * you agree that each of us can do all things in relation to your + contribution as if each of us were the sole owners, and if one of us makes + a derivative work of your contribution, the one who makes the derivative + work (or has it made will be the sole owner of that derivative work; + + * you agree that you will not assert any moral rights in your contribution + against us, our licensees or transferees; + + * you agree that we may register a copyright in your contribution and + exercise all ownership rights associated with it; and + + * you agree that neither of us has any duty to consult with, obtain the + consent of, pay or render an accounting to the other for any use or + distribution of your contribution. + +3. With respect to any patents you own, or that you can license without payment +to any third party, you hereby grant to us a perpetual, irrevocable, +non-exclusive, worldwide, no-charge, royalty-free license to: + + * make, have made, use, sell, offer to sell, import, and otherwise transfer + your contribution in whole or in part, alone or in combination with or + included in any product, work or materials arising out of the project to + which your contribution was submitted, and + + * at our option, to sublicense these same rights to third parties through + multiple levels of sublicensees or other licensing arrangements. + +4. Except as set out above, you keep all right, title, and interest in your +contribution. The rights that you grant to us under these terms are effective +on the date you first submitted a contribution to us, even if your submission +took place before the date you sign these terms. + +5. You covenant, represent, warrant and agree that: + + * Each contribution that you submit is and shall be an original work of + authorship and you can legally grant the rights set out in this SCA; + + * to the best of your knowledge, each contribution will not violate any + third party's copyrights, trademarks, patents, or other intellectual + property rights; and + + * each contribution shall be in compliance with U.S. export control laws and + other applicable export and import laws. You agree to notify us if you + become aware of any circumstance which would make any of the foregoing + representations inaccurate in any respect. We may publicly disclose your + participation in the project, including the fact that you have signed the SCA. + +6. This SCA is governed by the laws of the State of California and applicable +U.S. Federal law. Any choice of law rules will not apply. + +7. Please place an “x” on one of the applicable statement below. Please do NOT +mark both statements: + + * [x] I am signing on behalf of myself as an individual and no other person + or entity, including my employer, has or will have rights with respect to my + contributions. + + * [ ] I am signing on behalf of my employer or a legal entity and I have the + actual authority to contractually bind that entity. + +## Contributor Details + +| Field | Entry | +|------------------------------- | -------------------- | +| Name | Filipe Caixeta | +| Company name (if applicable) | | +| Title or role (if applicable) | | +| Date | 09.12.2018 | +| GitHub username | filipecaixeta | +| Website (optional) | filipecaixeta.com.br | From 29757d35181c1dd6d1d363858f20deb999d94cde Mon Sep 17 00:00:00 2001 From: Filipe Caixeta Date: Fri, 21 Sep 2018 22:31:03 -0300 Subject: [PATCH 3/4] Portuguese - Add/remove stopwords, fix tokenizer, add currency symbols --- spacy/lang/pt/__init__.py | 9 +++- spacy/lang/pt/lex_attrs.py | 2 +- spacy/lang/pt/stop_words.py | 67 +++++++++++++-------------- spacy/lang/pt/tokenizer_exceptions.py | 2 +- 4 files changed, 43 insertions(+), 37 deletions(-) diff --git a/spacy/lang/pt/__init__.py b/spacy/lang/pt/__init__.py index 8270bcbe0ea..6670095e653 100644 --- a/spacy/lang/pt/__init__.py +++ b/spacy/lang/pt/__init__.py @@ -8,6 +8,7 @@ from .tag_map import TAG_MAP from ..tokenizer_exceptions import BASE_EXCEPTIONS +from ..punctuation import TOKENIZER_INFIXES, TOKENIZER_PREFIXES from ..norm_exceptions import BASE_NORMS from ...language import Language from ...attrs import LANG, NORM @@ -17,13 +18,19 @@ class PortugueseDefaults(Language.Defaults): lex_attr_getters = dict(Language.Defaults.lex_attr_getters) lex_attr_getters[LANG] = lambda text: 'pt' + BASE_NORMS.update({ + "R$": "$", + "Cz$": "$", + "NCz$": "$", + }) lex_attr_getters[NORM] = add_lookups(Language.Defaults.lex_attr_getters[NORM], BASE_NORMS) lex_attr_getters.update(LEX_ATTRS) tokenizer_exceptions = update_exc(BASE_EXCEPTIONS, TOKENIZER_EXCEPTIONS) stop_words = STOP_WORDS lemma_lookup = LOOKUP tag_map = TAG_MAP - + infixes = tuple(TOKENIZER_INFIXES + [r'(\w+-\w+)']) + prefixes = tuple(TOKENIZER_PREFIXES + [r'\w{1,3}\$']) class Portuguese(Language): lang = 'pt' diff --git a/spacy/lang/pt/lex_attrs.py b/spacy/lang/pt/lex_attrs.py index d26ec52370a..87372a8a74f 100644 --- a/spacy/lang/pt/lex_attrs.py +++ b/spacy/lang/pt/lex_attrs.py @@ -23,7 +23,7 @@ def like_num(text): - text = text.replace(',', '').replace('.', '') + text = text.replace(',', '').replace('.', '').replace('º','').replace('ª','') if text.isdigit(): return True if text.count('/') == 1: diff --git a/spacy/lang/pt/stop_words.py b/spacy/lang/pt/stop_words.py index a18e8ded3e1..ebd450eb5d0 100644 --- a/spacy/lang/pt/stop_words.py +++ b/spacy/lang/pt/stop_words.py @@ -3,67 +3,66 @@ STOP_WORDS = set(""" -à às acerca adeus agora ainda algo algumas alguns ali além ambas ambos ano -anos antes ao aos apenas apoio apoia apontar após aquela aquelas aquele aqueles -aqui aquilo área as assim através atrás até aí +à às área acerca ademais adeus agora ainda algo algumas alguns ali além ambas ambos antes +ao aos apenas apoia apoio apontar após aquela aquelas aquele aqueles aqui aquilo +as assim através atrás até aí baixo bastante bem boa bom breve cada caminho catorze cedo cento certamente certeza cima cinco coisa com como -comprido comprida conhecida conhecido conselho contra corrente custa cá +comprida comprido conhecida conhecido conselho contra contudo corrente cuja +cujo custa cá -da daquela daquele dar das de debaixo demais dentro depois desde desligada -desligado dessa desse desta deste deve devem deverá dez dezanove dezasseis -dezassete dezoito dia diante direita diz dizem dizer do dois dos doze duas dá -dão dúvida +da daquela daquele dar das de debaixo demais dentro depois des desde dessa desse +desta deste deve devem deverá dez dezanove dezasseis dezassete dezoito diante +direita disso diz dizem dizer do dois dos doze duas dá dão -é ela elas ele eles em embora enquanto entre então era és essa essas esse esses -esta estado estar estará estas estava este estes esteve estive estivemos -estiveram estiveste estivestes estou está estás estão eu exemplo +é és ela elas ele eles em embora enquanto entre então era essa essas esse esses esta +estado estar estará estas estava este estes esteve estive estivemos estiveram +estiveste estivestes estou está estás estão eu eventual exemplo falta fará favor faz fazeis fazem fazemos fazer fazes fazia faço fez fim final foi fomos for fora foram forma foste fostes fui geral grande grandes grupo -hoje horas há +inclusive iniciar inicio ir irá isso isto -iniciar inicio ir irá isso isto já +já -lado ligado local logo longe lugar lá +lado lhe ligado local logo longe lugar lá -maior maioria maiorias mais mal mas me meio menor menos meses mesmo meu meus -mil minha minhas momento muito muitos máximo mês +maior maioria maiorias mais mal mas me meio menor menos meses mesmo meu meus mil +minha minhas momento muito muitos máximo mês -na nada naquela naquele nas nem nenhuma nessa nesse nesta neste no noite nome -nos nossa nossas nosso nossos nova novas nove novo novos num numa nunca nuns -não nível nós número números +na nada naquela naquele nas nem nenhuma nessa nesse nesta neste no nos nossa +nossas nosso nossos nova novas nove novo novos num numa nunca nuns não nível nós +número números -obra obrigada obrigado oitava oitavo oito onde ontem onze os ou outra outras -outro outros +obrigada obrigado oitava oitavo oito onde ontem onze ora os ou outra outras outros -para parece parte partir pegar pela pelas pelo pelos perto pessoas pode podem -poder poderá podia ponto pontos por porque porquê posição possivelmente posso -possível pouca pouco povo primeira primeiro próprio próxima próximo puderam pôde -põe põem +para parece parte partir pegar pela pelas pelo pelos perto pode podem poder poderá +podia pois ponto pontos por porquanto porque porquê portanto porém posição +possivelmente posso possível pouca pouco povo primeira primeiro próprio próxima +próximo puderam pôde põe põem -qual qualquer quando quanto quarta quarto quatro que quem quer querem quero +quais qual qualquer quando quanto quarta quarto quatro que quem quer querem quero questão quieta quieto quinta quinto quinze quê relação sabe saber se segunda segundo sei seis sem sempre ser seria sete seu seus sexta -sexto sim sistema sob sobre sois somente somos sou sua suas são sétima sétimo +sexto sim sistema sob sobre sois somente somos sou sua suas são sétima sétimo só -tal talvez também tanta tanto tarde te tem temos tempo tendes tenho tens tentar -tentaram tente tentei ter terceira terceiro teu teus teve tipo tive tivemos -tiveram tiveste tivestes toda todas todo todos trabalhar trabalho treze três tu -tua tuas tudo tão têm +tais tal talvez também tanta tanto tarde te tem temos tempo tendes tenho tens +tentar tentaram tente tentei ter terceira terceiro teu teus teve tipo tive +tivemos tiveram tiveste tivestes toda todas todo todos treze três tu tua tuas +tudo tão têm -último um uma umas uns usa usar +um uma umas uns usa usar último -vai vais valor veja vem vens ver verdade verdadeira verdadeiro vez vezes viagem -vinda vindo vinte você vocês vos vossa vossas vosso vossos vários vão vêm vós +vai vais valor veja vem vens ver vez vezes vinda vindo vinte você vocês vos vossa +vossas vosso vossos vários vão vêm vós zero """.split()) diff --git a/spacy/lang/pt/tokenizer_exceptions.py b/spacy/lang/pt/tokenizer_exceptions.py index 69578655c28..16b0f7f9b63 100644 --- a/spacy/lang/pt/tokenizer_exceptions.py +++ b/spacy/lang/pt/tokenizer_exceptions.py @@ -67,7 +67,7 @@ for orth in [ "Adm.", "Dr.", "e.g.", "E.g.", "E.G.", "Gen.", "Gov.", "i.e.", "I.e.", "I.E.", "Jr.", "Ltd.", "p.m.", "Ph.D.", "Rep.", "Rev.", "Sen.", "Sr.", - "Sra.", "vs."]: + "Sra.", "vs.", "tel.", "pág.", "pag."]: _exc[orth] = [{ORTH: orth}] From 0b92f4a9888190e6bba2ae7df53a3a2c1d7d833f Mon Sep 17 00:00:00 2001 From: Filipe Caixeta Date: Fri, 28 Sep 2018 23:51:26 -0300 Subject: [PATCH 4/4] Extended punctuation and norm_exceptions in the Portuguese language --- spacy/lang/pt/__init__.py | 14 +++++--------- spacy/lang/pt/norm_exceptions.py | 23 +++++++++++++++++++++++ spacy/lang/pt/punctuation.py | 18 ++++++++++++++++++ 3 files changed, 46 insertions(+), 9 deletions(-) create mode 100644 spacy/lang/pt/norm_exceptions.py create mode 100644 spacy/lang/pt/punctuation.py diff --git a/spacy/lang/pt/__init__.py b/spacy/lang/pt/__init__.py index 6670095e653..8fa0601eeca 100644 --- a/spacy/lang/pt/__init__.py +++ b/spacy/lang/pt/__init__.py @@ -6,9 +6,10 @@ from .lex_attrs import LEX_ATTRS from .lemmatizer import LOOKUP from .tag_map import TAG_MAP +from .norm_exceptions import NORM_EXCEPTIONS from ..tokenizer_exceptions import BASE_EXCEPTIONS -from ..punctuation import TOKENIZER_INFIXES, TOKENIZER_PREFIXES +from .punctuation import TOKENIZER_INFIXES, TOKENIZER_PREFIXES from ..norm_exceptions import BASE_NORMS from ...language import Language from ...attrs import LANG, NORM @@ -18,19 +19,14 @@ class PortugueseDefaults(Language.Defaults): lex_attr_getters = dict(Language.Defaults.lex_attr_getters) lex_attr_getters[LANG] = lambda text: 'pt' - BASE_NORMS.update({ - "R$": "$", - "Cz$": "$", - "NCz$": "$", - }) - lex_attr_getters[NORM] = add_lookups(Language.Defaults.lex_attr_getters[NORM], BASE_NORMS) + lex_attr_getters[NORM] = add_lookups(Language.Defaults.lex_attr_getters[NORM], BASE_NORMS, NORM_EXCEPTIONS) lex_attr_getters.update(LEX_ATTRS) tokenizer_exceptions = update_exc(BASE_EXCEPTIONS, TOKENIZER_EXCEPTIONS) stop_words = STOP_WORDS lemma_lookup = LOOKUP tag_map = TAG_MAP - infixes = tuple(TOKENIZER_INFIXES + [r'(\w+-\w+)']) - prefixes = tuple(TOKENIZER_PREFIXES + [r'\w{1,3}\$']) + infixes = TOKENIZER_INFIXES + prefixes = TOKENIZER_PREFIXES class Portuguese(Language): lang = 'pt' diff --git a/spacy/lang/pt/norm_exceptions.py b/spacy/lang/pt/norm_exceptions.py new file mode 100644 index 00000000000..1f09221ebb0 --- /dev/null +++ b/spacy/lang/pt/norm_exceptions.py @@ -0,0 +1,23 @@ +# coding: utf8 +from __future__ import unicode_literals + +# These exceptions are used to add NORM values based on a token's ORTH value. +# Individual languages can also add their own exceptions and overwrite them - +# for example, British vs. American spelling in English. + +# Norms are only set if no alternative is provided in the tokenizer exceptions. +# Note that this does not change any other token attributes. Its main purpose +# is to normalise the word representations so that equivalent tokens receive +# similar representations. For example: $ and € are very different, but they're +# both currency symbols. By normalising currency symbols to $, all symbols are +# seen as similar, no matter how common they are in the training data. + + +NORM_EXCEPTIONS = { + "R$": "$", # Real + "r$": "$", # Real + "Cz$": "$", # Cruzado + "cz$": "$", # Cruzado + "NCz$": "$", # Cruzado Novo + "ncz$": "$" # Cruzado Novo +} diff --git a/spacy/lang/pt/punctuation.py b/spacy/lang/pt/punctuation.py new file mode 100644 index 00000000000..957af8e9cbc --- /dev/null +++ b/spacy/lang/pt/punctuation.py @@ -0,0 +1,18 @@ +# coding: utf8 +from __future__ import unicode_literals + +from ..punctuation import TOKENIZER_PREFIXES as BASE_TOKENIZER_PREFIXES +from ..punctuation import TOKENIZER_SUFFIXES as BASE_TOKENIZER_SUFFIXES +from ..punctuation import TOKENIZER_INFIXES as BASE_TOKENIZER_INFIXES + +_prefixes = ([r'\w{1,3}\$'] + BASE_TOKENIZER_PREFIXES) + +_suffixes = (BASE_TOKENIZER_SUFFIXES) + +_infixes = ([r'(\w+-\w+(-\w+)*)'] + + BASE_TOKENIZER_INFIXES + ) + +TOKENIZER_PREFIXES = _prefixes +TOKENIZER_SUFFIXES = _suffixes +TOKENIZER_INFIXES = _infixes