LR-POR / tools

Tools for checking the compatibility between a lexical resource and a treebank
BSD 3-Clause "New" or "Revised" License
2 stars 0 forks source link

como extrair as preposições e complementadores? #18

Open leoalenc opened 2 years ago

leoalenc commented 2 years ago

@lucasrct, parabéns pelo programa extrator de valências. Com as modificações necessárias, será de extrema valia para a construção do léxico da PorGram e de outras gramáticas, inclusive de outras línguas. Infelizmente, receio que eu não vou poder fazer muita coisa com o extrator no estado atual para povoar o léxico da PorGram. De fato, como expliquei nos meus comentários em https://github.com/LR-POR/PorGram/issues/19#issuecomment-946028428, saber que um verbo ocorre com a moldura '<nsubj,VERB,obj>' não é suficiente para atribuí-lo a um dos tipos da gramática, uma vez que eu preciso saber se o objeto é direto ou se é introduzido por meio de uma preposição e qual exatamente é essa preposição. Do mesmo modo, preciso, para xcomp e ccomp, das propriedades listadas nos meus comentários da mencionada issue.
@arademaker, alguma ideia de como fazer isso no estágio atual do programa? @lucasrct, você teria como integrar essas informações?

https://github.com/LR-POR/ud-matrix/blob/master/examples.conllu#L186-L199

Eu preciso da seguinte moldura para codificar esse verbo na gramática:

<nsubj,VERB:act,obj:de>

Observe que incluí act para caracterizar o verbo como forma na voz ativa, ou podemos convencionar que apenas VERB é voz ativa e VERB:pass é voz passiva. Como @arademaker e eu temos comentado em diversos lugares, são vários os indicativos de voz passiva, mas bastaria nsubj:pass ou Voice=Pass ou VerbForm=Part E aux:pass para atribuir a voz passiva.

lucasrct commented 2 years ago

Entendi o ponto @leoalenc! Eu acredito que tenhamos uma funcionalidade parecida atualmente na ferramenta, mas isso ocorre a nível do verbo. Você pode dar um .print() em um objeto do tipo verbo para ver todas as ocorrências dele no bosque, com as informações que discutimos no issue 19. O seu ponto seria então de enriquecer esse objeto <nsubj,VERB,obj> com os valores específicos, como por exemplo adicionando a informação do 'de' no objeto. Isso é possível, mas aumentaria bastante o conjunto de classes no final! Eu escrevi o script para considerar os casos nsubj:pass e aux:pass como um caso diferente também, então pode existir a seguinte construção <nsubj:pass, VERB>, por exemplo.

lucasrct commented 2 years ago

No exemplo do README

situar+Mood:Sub+Number:Sing+Person:3+Tense:Pres+VerbForm:Fin nsubj PRON+se+Acc+Fem+Sing+3+Prs
situar+VerbForm:Inf PRON+se+Acc+Fem+Sing+3+Prs
situar+VerbForm:Ger PRON+se+Acc+Fem+Sing+3+Prs
situar+Mood:Ind+Number:Sing+Person:3+Tense:Pres+VerbForm:Fin nsubj PRON+se+Acc+Fem+Sing+3+Prs
situar+Mood:Ind+Number:Sing+Person:3+Tense:Pres+VerbForm:Fin obj nsubj 
situar+VerbForm:Inf PRON+se+Acc+Masc+Sing+3+Prs
situar+VerbForm:Inf PRON+se+Acc+Masc+Plur+3+Prs
situar+VerbForm:Ger obj 
situar+VerbForm:Inf nsubj PRON+se+Acc+Fem+Sing+3+Prs

É possível gerar essa lista para cada verbo. Essa lista contem, em particular, as informações que você considerou nesse issue.

leoalenc commented 2 years ago

No exemplo do README

situar+Mood:Sub+Number:Sing+Person:3+Tense:Pres+VerbForm:Fin nsubj PRON+se+Acc+Fem+Sing+3+Prs
situar+VerbForm:Inf PRON+se+Acc+Fem+Sing+3+Prs
situar+VerbForm:Ger PRON+se+Acc+Fem+Sing+3+Prs
situar+Mood:Ind+Number:Sing+Person:3+Tense:Pres+VerbForm:Fin nsubj PRON+se+Acc+Fem+Sing+3+Prs
situar+Mood:Ind+Number:Sing+Person:3+Tense:Pres+VerbForm:Fin obj nsubj 
situar+VerbForm:Inf PRON+se+Acc+Masc+Sing+3+Prs
situar+VerbForm:Inf PRON+se+Acc+Masc+Plur+3+Prs
situar+VerbForm:Ger obj 
situar+VerbForm:Inf nsubj PRON+se+Acc+Fem+Sing+3+Prs

É possível gerar essa lista para cada verbo. Essa lista contem, em particular, as informações que você considerou nesse issue.

@lucasrct , obrigado. Mas como temos em vista o artigo, conceitualmente não é adequado como está, pois obj não é igual a obj. O mesmo vale para cccomp e xcomp. O objetivo do algoritmo é exatamente facilitar a extração das valências e isso, no momento, não ocorre. Temo como agregar em obj, cccomp e xcomp as informações que eu listei?

arademaker commented 2 years ago

Eu tenho a impressão de que @leoalenc precisa mesmo de outra agregação, pelas chaves que ele descreveu. Afinal serão estas classes que ele irá tentar manualmente mapear para os tipos definidos na gramática.

Sobre a passiva, não acho que queremos classes distintas como <nsubj:pass, VERB> e <nsubj, VERB:Pass>. Queremos que quando o verbo for identificado como na voz passiva, sempre receba <...VERB:Pass...>.

Sugiro fixarmos a identificação via o AUX ligado por aux:pass:

  1. http://match.grew.fr/?corpus=UD_Portuguese-Bosque@dev&custom=617035bb7c1be me retorna >1000 resultados
  2. http://match.grew.fr/?corpus=UD_Portuguese-Bosque@dev&custom=617035fdd7b89 me retorna 982 resultados
  3. http://match.grew.fr/?corpus=UD_Portuguese-Bosque@dev&custom=617036691e4c0 me retorna >1000 resultados

Ou seja, mesmo que tenhamos erros, temos provavelmente casos de voz passiva sem sujeito. Tanto [1] quanto [2] podem ser usados. Se quiser pode mesmo usar ambos os critérios e saberemos que eventualmente alguns casos serão perdidos, mas ok. Isso é outro issue.

lucasrct commented 2 years ago

Entendi o ponto, mas ainda não está claro exatamente o melhor formato. @leoalenc ou @arademaker, poderiam dar mais um exemplo de uma frase / verbo e o output desejado?

Sobre o caso da voz passiva, os critérios então seriam a existência de nsubj:pass ou ( aux:pass E VerbForm = Part), ou Voice = Pass, é isso?

arademaker commented 2 years ago

Em https://github.com/LR-POR/ud-matrix/blob/master/examples.conllu#L7-L15

Devemos extrair:

<nsubj,perguntar,ccomp>
<obj:que,nsubj,perseguir>

não, o critério é: se tem filho aux:pass e Voice=Pass é passiva!

lucasrct commented 2 years ago

Em https://github.com/LR-POR/ud-matrix/blob/master/examples.conllu#L7-L15

Devemos extrair:

<nsubj,perguntar,ccomp>
<obj:que,nsubj,perseguir>

Obrigado, está mais claro agora, vou trabalhar na mudança, não me parece algo muito complicado de alterar no código. A ideia então é trocar também o VERB pelo verbo específico? Ou criaremos clusteres de todos os verbos que satisfazem <obj:que,nsubj,VERB>, por exemplo

arademaker commented 2 years ago

@leoalenc vc pode ajudar a completar outros casos e/ou corrigir a entrada que espera. Veja https://github.com/LR-POR/ud-matrix/blob/master/examples.conllu#L4

acho que assim vai ficar super concreto para o @lucasrct

leoalenc commented 2 years ago

Entendi o ponto, mas ainda não está claro exatamente o melhor formato. @leoalenc ou @arademaker, poderiam dar mais um exemplo de uma frase / verbo e o output desejado?

Sobre o caso da voz passiva, os critérios então seriam a existência de nsubj:pass ou ( aux:pass E VerbForm = Part), ou Voice = Pass, é isso?

Precisamos incluir mais informações nas chaves:

So, for instance, the key '<nsubj,VERB,obj>' means every VERB that has only nsubj and obj as sons and the order in the sentence is nsubj -- verb -- obj.

Typing

val['<nsubj,VERB,obj>'][:20] The output is [situar, continuar, manter ...]

https://github.com/LR-POR/tools/blob/main/etc/valence_script/README.md

@lucasrct , veja agora, novamente, este exemplo de comentário anterior:

http://match.grew.fr/data/616adee240cc5/42.svg

Foi retirado desta query elaborada pelo @wellington36:

http://match.grew.fr/?corpus=UD_Portuguese-Bosque@dev&custom=6168622521909

Para obter o verbo pedir na moldura do exemplo, a chave do dicionário acima deve ser: '<nsubj,VERB:act, iobj:a, ccomp:que+Sub, xcomp:Inf>'. Agreguei o lema da preposição ao iobj e as informações de complementador (SCONJ ligada via mark) e modo verbal do ccomp e forma verbal do xcomp. Buscando pelo chave '<nsubj,VERB:act, iobj:a, ccomp:que+Sub, xcomp:Inf>', vou obter todos os verbos com essa valência. É claro que a anotação do exemplo no corpus está errada, mas isso não vem ao caso no presente contexto, que é correção do algoritmo de extração. Mas note-se que é exatamente o fato de que essa moldura foi extraída que vai alertar para erros no corpus. @arademaker, veja que, como essa moldura parece espúria em si mesma, pois um mesmo verbo não pode reger ccomp e xcomp ao mesmo tempo, vou poder extrair todos os verbos anotados de forma igualmente errada.
O verbo empenhar do referido exemplo deve estar na lista que é obtida como valor de '<expl,VERB:act,obj:em>'.
O verbo transformar do referido exemplo deve estar na lista que é obtida como valor de '<VERB:act,obj:em>'. O verbo surgir do referido exemplo deve estar na lista que é obtida como valor de '<nsubj,VERB:act>'.
Talvez fosse interessante modelar a chave como set, pois a ordem dos elementos não é relevante para a valência (mas talvez haja elementos repetidos?) ou ordenar os elementos de modo a consolidar molduras como

'<nsubj,VERB:act, iobj:a, ccomp:que+Sub>'

'< iobj:a, nsubj,VERB:act,ccomp:que+Sub>'

'<VERB:act, nsubj, iobj:a, ccomp:que+Sub>'

numa única moldura

'<nsubj,VERB:act, iobj:a, ccomp:que+Sub>'

Pode-se convencionar colocar nsubj e VERB no início, os demais em ordem alfabética.

leoalenc commented 2 years ago

@leoalenc vc pode ajudar a completar outros casos e/ou corrigir a entrada que espera. Veja https://github.com/LR-POR/ud-matrix/blob/master/examples.conllu#L4

acho que assim vai ficar super concreto para o @lucasrct

@arademaker , eu acho que fui bastante explícito no meu último comentário sobre as informações que precisam ser agregadas. Prefiro não incluir essas informações lá no outro repositório para não gerar confusão.

leoalenc commented 2 years ago

Em https://github.com/LR-POR/ud-matrix/blob/master/examples.conllu#L7-L15 Devemos extrair:

<nsubj,perguntar,ccomp>
<obj:que,nsubj,perseguir>

Obrigado, está mais claro agora, vou trabalhar na mudança, não me parece algo muito complicado de alterar no código. A ideia então é trocar também o VERB pelo verbo específico? Ou criaremos clusteres de todos os verbos que satisfazem obj:que,nsubj,VERB, por exemplo

@lucasrct e @arademaker , como estava no readme era o formato adequado para mim, busco, por exemplo:

val['<nsubj,VERB,obj>'][:20]

e obtenho os 20 primeiros verbos com a moldura. Como disse, só falta agregar as informações sobre o obj, xcomp, ccomp eiobj e voz do verbo (VERB:act ou VERB:pass). Eu esperaria diversas variantes de '<nsubj,VERB,obj>'. Por exemplo:

val['<nsubj,VERB:act,obj:de>']

retornaria lista com gostar, depender, precisar etc., motivada por exemplos do corpus como

Ele gosta da cidade. Ele depende do emprego. Ele precisa do emprego.

val['<nsubj,VERB:act,obj:a>']

retornaria lista com obedecer, ajudar, avisar etc., motivada por exemplos do corpus como

Ele obedece à mãe. Ele ajuda aos pobres. Ele avisou ao povo.

val['<nsubj,VERB:pass>']

retornaria lista com devorar, destruir, consertar etc., motivada por exemplos do corpus como

A carne foi devorada pelos cães. A cidade foi destruída. O carro foi consertado.

arademaker commented 2 years ago

Entendo, mas o ponto é que fizemos os exemplos simples exatamente para facilitar a compreensão sobre UD e a tradução para a PorGram e usar exemplos das. sentenças complexas do corpus confunde... O fato é que embora esteja claro para você e para mim, não está (ou estava) claro para o @lucasrct

lucasrct commented 2 years ago

@leoalenc e @arademaker

Só para conferir se estamos na mesma página:

As alterações que estou fazendo são:

  1. Remoção da ordem relativa na exibiçao das deprels no objeto de Valência, colocando sempre o VERB e o nsubj na frente (caso haja o nsubj).
  2. Enriquecimento das informações:
  1. o verbo será classificado como pass (voz passiva) caso possua um aux:pass ligado a ele E Voice=Pass nas features. Caso contrário, será act (voz ativa)

Como lidar com os tokens nsubj:pass? Coloco no mesmo bolo que os nsubj?

Como lidar com os casos nsubj:pass? Junto no mesmo bolo dos nsubj?

leoalenc commented 2 years ago

@leoalenc e @arademaker

Só para conferir se estamos na mesma página:

As alterações que estou fazendo são:

  1. Remoção da ordem relativa na exibiçao das deprels no objeto de Valência, colocando sempre o VERB e o nsubj na frente (caso haja o nsubj).
  2. Enriquecimento das informações:
  • iobj e obj -- token ligado via ADP ao token iobj/obj
  • ccomp - info do SCONJ ligado a ele e modo verbal do token
  • xcomp - igual ao ccomp com a exibiçao da forma verbal
  1. o verbo será classificado como pass (voz passiva) caso possua um aux:pass ligado a ele E Voice=Pass nas features. Caso contrário, será act (voz ativa)

@lucasrct, proponho esta alteração:

  1. o verbo será classificado como pass (voz passiva) caso possua um aux:pass OU nsubj:pass ligado a ele OU Voice=Pass nas features. Caso contrário, será act (voz ativa).

Como lidar com os casos nsubj:pass? Junto no mesmo bolo dos nsubj?

@lucasrct , se tivermos nsubj:pass, então podemos transferir essa informação pro VERB.

val['<nsubj,VERB:pass>']

Vou entender que se trata do sujeito de uma forma na voz passiva. @arademaker , que acha?

lucasrct commented 2 years ago

@leoalenc

O verbo ter na seguinte frase, teria qual configuraçao?

CP4-3 «Não estou a ver que, para emitir uma opinião, nós tivéssemos de informar previamente o ministro, afirmou.

─┮  
 │ ╭─╼ « PUNCT punct 1 21  
 │ │ ╭─╼ Não ADV advmod 2 3  
 │ ├─┾ estou VERB ccomp 3 21  
 │ │ │ ╭─╼ a SCONJ mark 4 5  
 │ │ ╰─┾ ver VERB xcomp 5 3  
 │ │   │                               ╭─╼ que SCONJ mark 6 16  
 │ │   │                               │ ╭─╼ , PUNCT punct 7 9  
 │ │   │                               │ ├─╼ para SCONJ mark 8 9  
 │ │   │                               ├─┾ emitir VERB advcl 9 16  
 │ │   │                               │ │ ╭─╼ uma DET det 10 11  
 │ │   │                               │ ├─┶ opinião NOUN obj 11 9  
 │ │   │                               │ ╰─╼ , PUNCT punct 12 9  
 │ │   │ ╭─╼ nós PRON nsubj 13 14      │ 
 │ │   ╰─┾ tivéssemos VERB ccomp 14 5  │ 
 │ │     │                             ├─╼ de SCONJ mark 15 16  
 │ │     ╰─────────────────────────────┾ informar VERB xcomp 16 14  
 │ │                                   ├─╼ previamente ADV advmod 17 16  
 │ │                                   │ ╭─╼ o DET det 18 19  
 │ │                                   ├─┶ ministro NOUN obj 19 16  
 │ │                                   ╰─╼ , PUNCT punct 20 16  
 ╰─┾ afirmou VERB root 21 0  
   ╰─╼ . PUNCT punct 22 21  

Tanto o token sconj que (token 6) quanto o token sconj de (token 16) são filhos do verbo informar que é filho de ter via xcomp. Nesse caso, deveríamos captar o 'de' e nao o 'que', correto? Como decidir automaticamente, nesses casos? O token mais próximo do verbo?

lucasrct commented 2 years ago

@arademaker e @leoalenc

Subi o script atualizado, a única questao é que existem casos onde o verbo de xcomp está ligado a mais de 1 token sconj, e isso não foi tratado ainda, portanto aparecerá dois tokens na visualizaçao.

arademaker commented 2 years ago

para verbos com mais de um SCONJ, devemos simplesmente listar na valencia esta existencia. Note que isto permitirá identificarmos erros nos dados, como no caso de dois xcomp já identificado pelo @leoalenc, não cabe ao script contornar erros dos dados, mas apenas reportar os padrões que encontrar.

Em tempo, eu acho que não devemos

ccomp - info do SCONJ ligado a ele e modo verbal do token xcomp - igual ao ccomp com a exibiçao da forma verbal

Me parece (posso ter entendido errado) que queremos qualquer filho case/mark dos nós VERB ligados a outro verbo via xcomp ou ccomp. E tanto para ccomp quanto xcomp queremos a forma do verbo secundário.

% awk '$0 ~ /^[0-9]/ && $8 ~ /case/ {print $4}' *.conllu | sort | uniq -c | sort -nr
32675 ADP
   88 ADV <- http://match.grew.fr/?corpus=UD_Portuguese-Bosque@dev&custom=6170cd3adde6e
    3 DET 
    2 SCONJ <- http://match.grew.fr/?corpus=UD_Portuguese-Bosque@dev&custom=6170c9fce1534

% awk '$0 ~ /^[0-9]/ && $8 ~ /mark/ {print $4}' *.conllu | sort | uniq -c | sort -nr
5161 SCONJ
 169 ADV
  68 ADP  <- http://match.grew.fr/?corpus=UD_Portuguese-Bosque@dev&custom=6170c9959ff7a
  10 DET  <- 'uma vez que' http://match.grew.fr/?corpus=UD_Portuguese-Bosque@dev&custom=6170cc76e7eb1
   3 VERB  <- http://match.grew.fr/?corpus=UD_Portuguese-Bosque@dev&custom=6170ca763c7a3
arademaker commented 2 years ago

O verbo ter na seguinte frase, teria qual configuraçao?

Eu editei seu comentário para apresentar a sentença de forma mais visual. O ter (token 14) tem

  1. nsubj
  2. xcomp+VERB:informar+Inf++mark:de+mark:que

Certo @leoalenc ? ou seja, realmente não acho que o que deveria estar ligado ao token 16, mas sim ao token 14. No entanto, o script deve refletir o dado, e isto nos ajudará a ver este erro. Minha correção parcial abaixo, mas ainda acho que emitir não deveria modificar o tivéssemos ao invés do informar:

─┮  
 │ ╭─╼ « PUNCT punct 1 21  
 │ │ ╭─╼ Não ADV advmod 2 3  
 │ ├─┾ estou VERB ccomp 3 21  
 │ │ │ ╭─╼ a SCONJ mark 4 5  
 │ │ ╰─┾ ver VERB xcomp 5 3  
 │ │   │ ╭─╼ que SCONJ mark 6 14  
 │ │   │ │                               ╭─╼ , PUNCT punct 7 9  
 │ │   │ │                               ├─╼ para SCONJ mark 8 9  
 │ │   │ │                             ╭─┾ emitir VERB advcl 9 16  
 │ │   │ │                             │ │ ╭─╼ uma DET det 10 11  
 │ │   │ │                             │ ├─┶ opinião NOUN obj 11 9  
 │ │   │ │                             │ ╰─╼ , PUNCT punct 12 9  
 │ │   │ ├─╼ nós PRON nsubj 13 14      │ 
 │ │   ╰─┾ tivéssemos VERB ccomp 14 5  │ 
 │ │     │                             ├─╼ de SCONJ mark 15 16  
 │ │     ╰─────────────────────────────┾ informar VERB xcomp 16 14  
 │ │                                   ├─╼ previamente ADV advmod 17 16  
 │ │                                   │ ╭─╼ o DET det 18 19  
 │ │                                   ├─┶ ministro NOUN obj 19 16  
 │ │                                   ╰─╼ , PUNCT punct 20 16  
 ╰─┾ afirmou VERB root 21 0  
   ╰─╼ . PUNCT punct 22 21  
leoalenc commented 2 years ago

@lucasrct, de fato, @arademaker tem razão, a sentença tem erros de anotação, mas o script deve ser cego pra isso, refletindo o que está no corpus. O que for extraído de dados errados vai normalmente parecer estranho linguisticamente e isso servirá para corrigir posteriormente o corpus. Temos, nesse exemplo, um encadeamento de construções, numa espécie de matrioska, i.e., a estrutura 1 contém 2 que contém 3 que contém 4 que contém 5 etc.:

  1. afirmou rege ccomp no indicativo sem conjunção
  2. estou rege xcomp introduzido pela SCONJ a
  3. ver rege ccomp no subjuntivo introduzido pela SCONJ que (como ressaltou @arademaker, isso não foi anotado corretamente)
  4. tivéssemos rege nsubj e xcomp:de+Inf (erroneamente anotado como xcomp:de+que+Inf)
  5. informar rege obj sem preposição
  6. emitir, ligado a informar via advcl, rege obj sem preposição (como sugere @arademaker, deveria vincular-se como advcl a tivéssemos, mas isso não vem ao caso no presente contexto)

Ver http://match.grew.fr/?corpus=UD_Portuguese-Bosque@2.8&custom=6170d0589dc63

http://match.grew.fr/data/6170d0589dc63/1055_1.svg

Considerando o dado de entrada errado, vamos ter realmente duas conjunções filhas de informar, gerando uma moldura espúria:

val['<nsubj,VERB:act, xcomp:de+que+Inf>']

que retorna o verbo ter (e talvez outros). Apesar de errado, como notou @arademaker, esse resultado será excelente para corrigir o corpus, pois se observe que xcomp:de+que+Inf é algo muito anômalo linguisticamente. De fato, quando se trata de xcomp, os complementadores de e que se excluem:

Tenho de fazer isso. Tenho que fazer isso. *Tenho de que fazer isso.

arademaker commented 2 years ago

@lucasrct

  1. coloquei o team developers com acesso neste repo, logo vc não precisa mais usar fork , pode trabalhar direto em branches.
  2. movi seus arquivos para o etc ao invés de criar um subdir
  3. por favor, no readme README-Valence.md acrescente alguma info sobre como 'coletar' os dados do corpus. Seria bom, por exemplo, conseguirmos coletar valencias do https://github.com/LR-POR/ud-matrix/blob/master/examples.conllu como teste do seu código.
lucasrct commented 2 years ago

Pronto @arademaker, criei a função e já a documentei. Acabei de fazer o PR. Vou também documentar melhor o código e pretendo te-lo documentado até o fim do dia.

leoalenc commented 2 years ago

@lucasrct

  1. por favor, no readme README-Valence.md acrescente alguma info sobre como 'coletar' os dados do corpus. Seria bom, por exemplo, conseguirmos coletar valencias do https://github.com/LR-POR/ud-matrix/blob/master/examples.conllu como teste do seu código.

@arademaker, concordo, isso seria extremamente útil para testar a ferramenta. @lucasrct, poderia criar dicionário de Python a partir desses exemplos e colocar na pasta da ferramenta?

lucasrct commented 2 years ago

@leoalenc A função foi criada, ela se chama _extractvalences, e, inicialmente possui como entrada o path de um .conllu, mas irei modificá-la para ser um pouco mais agrangente, como sugerido pelo @arademaker, podendo ter um padrão ou um diretório como input!