Skip to content

Latest commit

 

History

History
434 lines (277 loc) · 13.7 KB

chapter2.md

File metadata and controls

434 lines (277 loc) · 13.7 KB
title description prev next type id
Chapter 2: Análise de dados em larga escala usando a biblioteca spaCy
Neste capítulo você desenvolverá novas habilidades ao extrair informações específicas de um grande volume de texto. Você vai aprender a otimizar o uso das estruturas de dados da spaCy e como criar estratégias combinadas de estatística e baseadas em regras para efetuar análises de textos de maneira eficiente.
/chapter1
/chapter3
chapter
2

Parte 1

  • Consulte a string "gato" em nlp.vocab.strings para obter seu código indexador (hash).
  • Consulte o código indexador (hash) para obter a string novamente.
  • Você pode acessar nlp.vocab.strings de maneira semelhante a dicionários em Python. Por exemplo, nlp.vocab.strings["unicorn"] retornará o código hash e ao fazer a consulta do hash irá retornar a string "unicorn".

Parte 2

  • Consulte a marcador "PERSON" em nlp.vocab.strings para obter o código hash.
  • Consulte o código hash para obter a string de volta.
  • Você pode acessar nlp.vocab.strings de maneira semelhante a dicionários em Python. Por exemplo, nlp.vocab.strings["unicorn"] retornará o código hash e ao fazer a consulta do hash irá retornar a string "unicorn".

Por que o código abaixo dá erro?

import spacy

# Criar um objeto do idioma inglês e um objeto do idioma alemão
nlp = English()
nlp_de = German()

# Consultar o código hash da palavra 'Bowie'
bowie_id = nlp.vocab.strings["Bowie"]
print(bowie_id)

# Consultar o código hash de "Bowie" no vocabulário
print(nlp_de.vocab.strings[bowie_id])

Códigos hash não podem ser revertidos. Para prevenir este problema, adicione a palavra ao vocabulário processando um texto ou consultando a palavra, ou use o mesmo vocabulário para mapear o código hash de volta para a palavra.

Qualquer palavra pode ser mapeada para um código hash.

O nome da variável nlp é apenas uma convenção. Se no código fosse feita a atribuição da variável nlp ao invés de nlp_de, ele teria sobrescrito a variável nlp existente e o seu vocabulário.

Vamos criar objetos Doc a partir do zero!

Parte 1

  • Importe a classe Doc de spacy.tokens.
  • Crie um Doc a partir das palavras words e espaçamento spaces. Não se esqueça de passar o vocabulário como argumento!

A classe Doc tem 3 argumentos: o vocabulário compartilhado, geralmente nlp.vocab, a lista de palavras words e espaçamento spaces formado por valores booleanos que indicam se a palavra é ou não seguida de um espaço em branco.

Parte 2

  • Importe a classe Doc de spacy.tokens.
  • Crie um Doc a partir das palavras words e espaçamento spaces. Não se esqueça de passar o vocabulário como argumento!

Observe cada palavra no texto desejado e verifique se ela é seguida de um espaço. Se sim, o valor em spaces deve ser True. Se não, deve ser False.

Parte 3

  • Importe a classe Doc de spacy.tokens.
  • Complete os valores de words e spaces para que o resultado seja o texto desejado. Em seguida crie o doc.

Preste atenção nos tokens. Para entender como a spaCy toqueniza uma string, você pode tentar imprimir os tokens de nlp("Oh, really?!").

Neste exercício você criará os objetos Doc e Span manualmente e atualizará as Entidades Nomeadas (named entities), da mesma maneira que a spaCy faz nos bastidores. Um objeto nlp deve ser previamente criado.

  • Importe as classes Doc e Span de spacy.tokens.
  • Use a classe Doc para criar diretamente um doc a partir das palavras e espaçamento.
  • Crie uma partição Span para "David Bowie" a partir do doc e atribua a ela o marcador "PERSON".
  • Sobrescreva o doc.ents com uma lista contendo uma entidade: a partição span com "David Bowie"
  • O Doc é inicializado com três parâmetros: o vocabulário compartilhado, por exemplo: nlp.vocab, uma lista de palavras e uma lista de valores booleanos que indicam se uma palavra é seguida de um espaço em branco.
  • A classe Span tem dois parâmetros: a referência ao doc, os índices do token inicial e do token final e opcionalmente um marcador.
  • A propriedade doc.ents é sobrescrevível, e por isso você pode atribuir a ela qualquer objeto iterável do tipo Span.

No exemplo abaixo, o texto será analizado e todos os substantivos próprios serão selecionados.

import spacy

nlp = spacy.load("en_core_web_sm")
doc = nlp("Berlin looks like a nice city")

# Iterar nos tokens
token_texts = [token.text for token in doc]
pos_tags = [token.pos_ for token in doc]

for index, pos in enumerate(pos_tags):
    # Verifica se o token atual é um substantivo próprio.
    if pos == "PROPN":
        # Verifica se o próximo token é um verbo
        if pos_tags[index + 1] == "VERB":
            result = token_texts[index]
            print("Found proper noun before a verb:", result)

Parte 1

Por que esse código não é eficiente?

Não é necessário converter string para objetos Token. Evite converter tokens para strings se você ainda precisar acessar seus atributos e relações.

Sempre converta um resultado para string o mais tarde possível, e tente sempre usar atributos nativos para manter a consistência da informação.

O atributo .pos_ retorna a classe gramatical genérica enquanto "PROPN" é a forma correta de verificar se trata-se de um substantivo próprio.

Parte 2

  • Rescreva o código utilizando diretamente os atributos nativos dos tokens ao invés de criar uma lista de token_texts e pos_tags.
  • Crie um loop (laço) e para cada token no doc verifique o atributo token.pos_.
  • Use doc[token.i + 1] para referenciar o próximo token e verifique seu atributo .pos_.
  • Não é necessário gerar uma lista de strings antecipadamente: remova token_texts e pos_tags.
  • Ao invés de iterar em pos_tags, crie um loop (laço) e para cada token em doc, verifique o atributo token.pos_.
  • Para verificar se o próximo token é um verbo, use: doc[token.i + 1].pos_.

Neste exercício vamos usar um fluxo de processamento do Português médio que inclui cerca de 20.000 vetores das palavras. Esse pacote do fluxo (pipeline) de processamento já está instalado.

  • Carregue o fluxo (pipeline) de processamento médio "pt_core_news_md"com seus vetores das palavras.
  • Imprima o vetor para "bananas" usando o atributo token.vector.
  • Para carregar um fluxo (pipeline) de processamento, use spacy.load passando uma string com o nome do modelo.
  • Para acessar um token no doc, você pode indexá-lo. Por exemplo: doc[4].

Neste exercício, você utilizará o método similarity para comparar objetos do tipo Doc, Token and Span e obter o sua pontuação (score).

Parte 1

  • Use o método doc.similarity para comparar doc1 e doc2 e imprima o resultado.
  • O método doc.similarity tem um argumento: o outro objeto para ser comparado ao objeto atual.

Parte 2

  • Use o método token.similarity para comparar token1 e token2 e imprima o resultado.
  • O método token.similarity tem um argumento: o outro objeto para ser comparado ao objeto atual.

Parte 3

  • Crie partições para "excelente restaurante" e "ótimo bar".
  • Use span.similarity para comparar e imprima o resultado.

Por que essa expressão não corresponde aos tokens "Silicon Valley" no doc?

pattern = [{"LOWER": "silicon"}, {"TEXT": " "}, {"LOWER": "valley"}]
doc = nlp("Can Silicon Valley workers rein in big tech from within?")

O atributo "LOWER" na expressão refere-se a tokens na forma minúscula que corresponderão a um valor. Então a expressão {"LOWER": "valley"} corresponderá aos tokens "Valley", "VALLEY", "valley" etc.

O toquenizador automaticamente retira os espaços em branco entre as palavras, e cada dicionário na expressão deve ser um token.

Por padrão (default) os tokens em uma expressão irão corresponder somente uma vez. Operadores são necessários para alterar esse comportamento padrão, como por exemplo, corresponder uma ou mais vezes.

As expressões neste exercício contêm erros e não haverá correspondência com o texto. Você consegue corrigí-las? Se tiver dificuldade, tente imprimir os tokens do doc para entender como o texto será quebrado e ajuste a expressão de forma que cada dicionário represente um token.

  • Edite pattern1 de forma que ele faça a correspondência de todas as combinações de maiúscula e minúsculas de "Amazon" seguido de um substantivo próprio iniciado com letra maiúscula.

  • Edite pattern2 de forma que ele faça a correspondência de todas as combinações maiúsculas e minúsculas de "sem anúncios", precedido de um substantivo.

  • Tente processar os textos que devem fazer a correspondência utilizando o objeto nlp da seguinte forma: [token.text for token in nlp("visualização sem anúncios")].
  • Inspecione os tokens e certique-se que cada dicionário na expressão descreva corretamtente o token desejado.

Muitas vezes é mais eficiente fazer a correspondência exata dos textos ao invés de escrever expressões descrevendo os tokens individualmente. Esso é o caso de categorias finitas, como por exemplo, lista dos países do mundo. Nós já temos uma lista de países, então vamos usá-la como base para o nosso roteiro. A lista com os nomes está disponível na variável COUNTRIES.

  • Importe o PhraseMatcher, inicializando-o com o vocabulário compartilhado vocab com a variável matcher.
  • Adicione a expressão e chame o comparador matcher no doc.

O vocabulário compartilhado vocab está disponível em nlp.vocab.

No exercício anterior, você escreveu um roteiro usando o PhraseMatcher para localizar nomes de países no texto. Vamos usar esse comparador em um texto maior, fazer a análise sintática e atualizar as entidades do documento com os países encontrados.

  • Itere nos resultados do comparador e crie uma partição Span com o marcador "GPE" (entidade geopolítica).
  • Sobrescreva doc.ents com as entidades encontradas.
  • Identifique o token inicial da partição dos resultados encontrados.
  • Imprima o texto da partição a partir do token inicial.
  • Lembre-se que o texto está disponível na variável text.
  • A referência ao token está no atributo span.root. O início do token está no atributo token.head.