Conjunto de Dados de Pesquisa Aberta sobre a COVID-19

Conjunto de dados de texto completo e metadados de artigos acadêmicos relacionados à COVID-19 e ao coronavírus otimizados para facilitar a leitura pelo computador e disponibilizados para uso pela comunidade global de pesquisa.

Em resposta à pandemia da COVID-19, o Allen Institute for AI fez uma parceria com os principais grupos de pesquisa do mundo para preparar e distribuir o CORD-19 (Conjunto de Dados de Pesquisa Aberta sobre a COVID-19). Esse conjunto de dados é um recurso gratuito de mais de 47 mil artigos acadêmicos, incluindo mais de 36 mil com texto completo, sobre a COVID-19 e a família de vírus coronavírus para uso pela comunidade de pesquisa global.

Ele mobiliza os pesquisadores a aplicar os avanços recentes em processamento de idioma natural para gerar novos insights em auxílio ao combate dessa doença infecciosa.

O corpus pode ser atualizado à medida que novas pesquisas são publicadas em publicações revisadas por pares e em serviços de arquivo como bioRxiv, medRxiv e outros.

Observação

A Microsoft fornece o Azure Open Datasets no estado em que se encontra. A Microsoft não oferece garantias nem coberturas, expressas ou implícitas, em relação ao uso dos conjuntos de dados. Até o limite permitido pela legislação local, a Microsoft se exime de toda a obrigação por danos ou perdas, inclusive diretos, consequentes, especiais, indiretos, acidentais ou punitivos, resultantes do uso dos conjuntos de dados.

Esse conjunto de dados é fornecido de acordo com os termos originais com que a Microsoft recebeu os dados de origem. O conjunto de dados pode incluir dados originados da Microsoft.

Termos de Licença

Esse conjunto de dados é disponibilizado pelo Allen Institute of AI e pelo Semantic Scholar. Ao acessar, baixar ou usar qualquer conteúdo fornecido no Conjunto de Dados CORD-19, você concorda com a Licença do Conjunto de Dados relacionada ao uso desse conjunto de dados. As informações de licenciamento específicas para artigos individuais no conjunto de dados estão disponíveis no arquivo de metadados. Mais informações sobre o licenciamento estão disponíveis no site da PMC, no site da medRxiv e no site da bioRxiv.

Volume e retenção

Esse conjunto de dados é armazenado no formato JSON, e a última versão contém mais de 36 mil artigos de texto completo. Cada artigo é representado como um único objeto JSON. Veja o esquema.

Local de armazenamento

Este conjunto de dados está armazenado na região Leste dos EUA do Azure. Recomendamos alocar recursos de computação no Leste dos EUA para permitir a afinidade.

Citação

Ao incluir dados do CORD-19 em uma publicação ou uma redistribuição, cite o conjunto de dados da seguinte forma:

Na bibliografia:

CORD-19 (Conjunto de Dados de Pesquisa Aberta sobre a COVID-19). 2020. Versão AAAA-MM-DD. Recuperado de CORD-19 (Conjunto de Dados de Pesquisa Aberta sobre a COVID-19). Acessado em AAAA-MM-DD. doi:10.5281/zenodo.3715505

No texto: (CORD-19, 2020)

Contact

Para perguntas sobre este conjunto de dados, entre em contato com partnerships@allenai.org.

Acesso de dados

Azure Notebooks

O conjunto de dados CORD-19

O CORD-19 é uma coleção de mais de 50 mil artigos, incluindo mais de 40 mil com texto completo, sobre a COVID-19, a SARS-CoV-2 e os coronavírus relacionados. Esse conjunto de dados foi disponibilizado gratuitamente com a meta de ajudar as comunidades de pesquisa a combater a pandemia da COVID-19.

São duas as metas deste notebook:

  1. Demonstrar como acessar o conjunto de dados CORD-19 no Azure: nós nos conectamos à conta de Armazenamento de Blobs do Azure que hospeda o conjunto de dados CORD-19.
  2. Apresentar a estrutura do conjunto de dados passo a passo: os artigos do conjunto de dados são armazenados como arquivos JSON. Fornecemos exemplos mostrando:
  • Como encontrar os artigos (navegando pelo contêiner)
  • Como ler os artigos (navegando pelo esquema JSON)

Dependências: este notebook exige as seguintes bibliotecas:

  • Armazenamento do Azure (por exemplo, pip install azure-storage)
  • NLTK (documentação)
  • Pandas (por exemplo, pip install pandas)

Como obter os dados do CORD-19 do Azure

Vários dados do CORD-19 foram carregados como um conjunto de dados em aberto do Azure aqui. Criamos um serviço Blob vinculado a esse conjunto de dados em aberto CORD-19.

from azure.storage.blob import BlockBlobService

# storage account details
azure_storage_account_name = "azureopendatastorage"
azure_storage_sas_token = "sv=2019-02-02&ss=bfqt&srt=sco&sp=rlcup&se=2025-04-14T00:21:16Z&st=2020-04-13T16:21:16Z&spr=https&sig=JgwLYbdGruHxRYTpr5dxfJqobKbhGap8WUtKFadcivQ%3D"

# create a blob service
blob_service = BlockBlobService(
    account_name=azure_storage_account_name,
    sas_token=azure_storage_sas_token,
)

Podemos usar esse serviço Blob como um identificador nos dados. Podemos navegar pelo conjunto de dados usando as APIs BlockBlobService. Acesse aqui para obter mais detalhes:

Os dados do CORD-19 são armazenados no contêiner covid19temp. Esta é a estrutura de arquivos dentro do contêiner junto com um arquivo de exemplo.

metadata.csv
custom_license/
    pdf_json/
        0001418189999fea7f7cbe3e82703d71c85a6fe5.json        # filename is sha-hash
        ...
    pmc_json/
        PMC1065028.xml.json                                  # filename is the PMC ID
        ...
noncomm_use_subset/
    pdf_json/
        0036b28fddf7e93da0970303672934ea2f9944e7.json
        ...
    pmc_json/
        PMC1616946.xml.json
        ...
comm_use_subset/
    pdf_json/
        000b7d1517ceebb34e1e3e817695b6de03e2fa78.json
        ...
    pmc_json/
        PMC1054884.xml.json
        ...
biorxiv_medrxiv/                                             # note: there is no pmc_json subdir
    pdf_json/
        0015023cc06b5362d332b3baf348d11567ca2fbb.json
        ...

Cada arquivo .json corresponde a um artigo individual no conjunto de dados. É nele que o título, os autores, o resumo e (quando disponíveis) os dados de texto completo são armazenados.

Como usar o metadata.csv

O conjunto de dados CORD-19 vem com o metadata.csv, um arquivo individual que registra informações básicas sobre todos os artigos disponíveis no conjunto de dados CORD-19. Esse é um bom lugar para começar a explorá-lo!

# container housing CORD-19 data
container_name = "covid19temp"

# download metadata.csv
metadata_filename = 'metadata.csv'
blob_service.get_blob_to_path(
    container_name=container_name,
    blob_name=metadata_filename,
    file_path=metadata_filename
)
import pandas as pd

# read metadata.csv into a dataframe
metadata_filename = 'metadata.csv'
metadata = pd.read_csv(metadata_filename)
metadata.head(3)

À primeira vista, esse é um volume muito grande para usarmos. Portanto, vamos refiná-lo um pouco.

simple_schema = ['cord_uid', 'source_x', 'title', 'abstract', 'authors', 'full_text_file', 'url']

def make_clickable(address):
    '''Make the url clickable'''
    return '<a href="{0}">{0}</a>'.format(address)

def preview(text):
    '''Show only a preview of the text data.'''
    return text[:30] + '...'

format_ = {'title': preview, 'abstract': preview, 'authors': preview, 'url': make_clickable}

metadata[simple_schema].head().style.format(format_)
# let's take a quick look around
num_entries = len(metadata)
print("There are {} many entries in this dataset:".format(num_entries))

metadata_with_text = metadata[metadata['full_text_file'].isna() == False]
with_full_text = len(metadata_with_text)
print("-- {} have full text entries".format(with_full_text))

with_doi = metadata['doi'].count()
print("-- {} have DOIs".format(with_doi))

with_pmcid = metadata['pmcid'].count()
print("-- {} have PubMed Central (PMC) ids".format(with_pmcid))

with_microsoft_id = metadata['Microsoft Academic Paper ID'].count()
print("-- {} have Microsoft Academic paper ids".format(with_microsoft_id))
There are 51078 many entries in this dataset:
-- 42511 have full text entries
-- 47741 have DOIs
-- 41082 have PubMed Central (PMC) ids
-- 964 have Microsoft Academic paper ids

Exemplo: ler o texto completo

O metadata.csv não contém o texto completo propriamente dito. Vamos ver um exemplo de como ler isso. Localize e desempacote o JSON de texto completo e converta-o em uma lista de frases.

# choose a random example with pdf parse available
metadata_with_pdf_parse = metadata[metadata['has_pdf_parse']]
example_entry = metadata_with_pdf_parse.iloc[42]

# construct path to blob containing full text
blob_name = '{0}/pdf_json/{1}.json'.format(example_entry['full_text_file'], example_entry['sha'])  # note the repetition in the path
print("Full text blob for this entry:")
print(blob_name)

Agora podemos ler o conteúdo JSON associado a esse blob, conforme mostrado a seguir.

import json
blob_as_json_string = blob_service.get_blob_to_text(container_name=container_name, blob_name=blob_name)
data = json.loads(blob_as_json_string.content)

# in addition to the body text, the metadata is also stored within the individual json files
print("Keys within data:", ', '.join(data.keys()))

Para os fins deste exemplo, estamos interessados em body_text, que armazena os dados de texto da seguinte forma:

"body_text": [                      # list of paragraphs in full body
    {
        "text": <str>,
        "cite_spans": [             # list of character indices of inline citations
                                    # e.g. citation "[7]" occurs at positions 151-154 in "text"
                                    #      linked to bibliography entry BIBREF3
            {
                "start": 151,
                "end": 154,
                "text": "[7]",
                "ref_id": "BIBREF3"
            },
            ...
        ],
        "ref_spans": <list of dicts similar to cite_spans>,     # e.g. inline reference to "Table 1"
        "section": "Abstract"
    },
    ...
]

O esquema JSON completo está disponível aqui.

from nltk.tokenize import sent_tokenize

# the text itself lives under 'body_text'
text = data['body_text']

# many NLP tasks play nicely with a list of sentences
sentences = []
for paragraph in text:
    sentences.extend(sent_tokenize(paragraph['text']))

print("An example sentence:", sentences[0])

Comparação entre a análise XML PMC e PDF

No exemplo acima, vimos um caso com has_pdf_parse == True. Nesse caso, o caminho do arquivo de blob estava no formato:

'<full_text_file>/pdf_json/<sha>.json'

Como alternativa, para os casos com has_pmc_xml_parse == True, use o seguinte formato:

'<full_text_file>/pmc_json/<pmcid>.xml.json'

Por exemplo:

# choose a random example with pmc parse available
metadata_with_pmc_parse = metadata[metadata['has_pmc_xml_parse']]
example_entry = metadata_with_pmc_parse.iloc[42]

# construct path to blob containing full text
blob_name = '{0}/pmc_json/{1}.xml.json'.format(example_entry['full_text_file'], example_entry['pmcid'])  # note the repetition in the path
print("Full text blob for this entry:")
print(blob_name)

blob_as_json_string = blob_service.get_blob_to_text(container_name=container_name, blob_name=blob_name)
data = json.loads(blob_as_json_string.content)

# the text itself lives under 'body_text'
text = data['body_text']

# many NLP tasks play nicely with a list of sentences
sentences = []
for paragraph in text:
    sentences.extend(sent_tokenize(paragraph['text']))

print("An example sentence:", sentences[0])
Full text blob for this entry:
custom_license/pmc_json/PMC546170.xml.json
An example sentence: Double-stranded small interfering RNA (siRNA) molecules have drawn much attention since it was unambiguously shown that they mediate potent gene knock-down in a variety of mammalian cells (1).

Iterar pelos blobs diretamente

Nos exemplos acima, usamos o arquivo metadata.csv para navegar pelos dados, construir o caminho do arquivo de blob e ler os dados do blob. Uma alternativa é a iteração pelos próprios blobs.

# get and sort list of available blobs
blobs = blob_service.list_blobs(container_name)
sorted_blobs = sorted(list(blobs), key=lambda e: e.name, reverse=True)

Agora podemos iterar pelos blobs diretamente. Por exemplo, vamos contar o número de arquivos JSON disponíveis.

# we can now iterate directly though the blobs
count = 0
for blob in sorted_blobs:
    if blob.name[-5:] == ".json":
        count += 1
print("There are {} many json files".format(count))
There are 59784 many json files

Anexo

Problemas de qualidade dos dados

Esse é um conjunto de dados grande que, por motivos óbvios, foi compilado às pressas. Estes são alguns problemas de qualidade dos dados que observamos.

Vários SHAs

Observamos que, em alguns casos, há vários SHAs para determinada entrada.

metadata_multiple_shas = metadata[metadata['sha'].str.len() > 40]

print("There are {} many entries with multiple shas".format(len(metadata_multiple_shas)))

metadata_multiple_shas.head(3)
There are 1999 many entries with multiple shas

Layout do contêiner

Aqui, usamos um regex simples para explorar a estrutura de arquivos do contêiner caso isso seja atualizado no futuro.

container_name = "covid19temp"
blobs = blob_service.list_blobs(container_name)
sorted_blobs = sorted(list(blobs), key=lambda e: e.name, reverse=True)
import re
dirs = {}

pattern = '([\w]+)\/([\w]+)\/([\w.]+).json'
for blob in sorted_blobs:
    
    m = re.match(pattern, blob.name)
    
    if m:
        dir_ = m[1] + '/' + m[2]
        
        if dir_ in dirs:
            dirs[dir_] += 1
        else:
            dirs[dir_] = 1
        
dirs

Próximas etapas

Exiba o restante dos conjuntos de dados no catálogo do Open Datasets.