Conjunto de dados de pesquisa aberta COVID-19

Conjunto de dados de texto completo e metadados de artigos académicos sobre a COVID-19 e relacionados com o coronavírus otimizados para legibilidade automática e disponibilizados para utilização pela comunidade de investigação global.

Em resposta à pandemia de COVID-19, o Allen Institute for AI fez parceria com os principais grupos de pesquisa para preparar e distribuir o COVID-19 Open Research Dataset (CORD-19). Este conjunto de dados é um recurso gratuito de mais de 47.000 artigos acadêmicos, incluindo mais de 36.000 com texto completo, sobre COVID-19 e a família de vírus coronavírus para uso pela comunidade de pesquisa global.

Este conjunto de dados mobiliza os investigadores a aplicar os recentes avanços no processamento da linguagem natural para gerar novas ideias em apoio à luta contra esta doença infeciosa.

O corpus poderá ser atualizado à medida que a nova investigação é publicada em publicações revistas por colegas e serviços de arquivo como o bioRxiv, medRxiv, entre outros.

Nota

A Microsoft fornece os Conjuntos de Dados Abertos do Azure "no estado em que se encontram". A Microsoft não oferece garantias, expressas ou implícitas, garantias ou condições em relação ao seu uso dos conjuntos de dados. Na medida permitida pela legislação local, a Microsoft se isenta de qualquer responsabilidade por quaisquer danos ou perdas, incluindo diretos, consequenciais, especiais, indiretos, incidentais ou punitivos, resultantes do uso dos conjuntos de dados por parte do cliente.

Este conjunto de dados é disponibilizado de acordo com os termos originais em que a Microsoft recebeu os dados de origem. O conjunto de dados pode incluir dados obtidos junto da Microsoft.

Termos de Licenciamento

Este conjunto de dados é disponibilizado pelo Allen Institute of AI and Semantic Scholar. Ao aceder, transferir ou utilizar algum conteúdo fornecido no Conjunto de Dados CORD-19, concorda com a Licença de Conjunto de Dados referente à utilização deste conjunto de dados. As informações de licenciamento específicas de artigos individuais no conjunto de dados estão disponíveis no ficheiro de metadados. Mais informações sobre licenciamento estão disponíveis no site da PMC, no site do medRxiv e no site do bioRxiv.

Volume e retenção

Este conjunto de dados é armazenado em formato JSON e a versão mais recente contém mais de 36.000 artigos de texto completo. Cada documento é representado por um único objeto JSON. Exiba o esquema.

Localização de Armazenamento

Este conjunto de dados é armazenado na região do Azure E.U.A. Leste. A localização de recursos de computação no leste dos EUA é recomendada por afinidade.

Citação

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

Na bibliografia:

COVID-19 Open Research Dataset (CORD-19). 2020. Versão AAAA-MM-DD. Retirado do COVID-19 Open Research Dataset (CORD-19). Acedido em AAAA-MM-DD. doi:10.5281/zenodo.3715505

No texto: (CORD-19, 2020)

Contacto

Para colocar questões sobre este conjunto de dados, contacte partnerships@allenai.org.

Acesso a dados

Azure Notebooks

O conjunto de dados CORD-19

CORD-19 é uma coleção de mais de 50.000 artigos acadêmicos - incluindo mais de 40.000 com texto completo - sobre COVID-19, SARS-CoV-2 e coronavírus relacionados. Este conjunto de dados foi disponibilizado gratuitamente com o objetivo de ajudar as comunidades de pesquisa a combater a pandemia de COVID-19.

O objetivo deste notebook é duplo:

  1. Demonstre como acessar o conjunto de dados CORD-19 no Azure: nos conectamos à conta de armazenamento de blob do Azure que hospeda o conjunto de dados CORD-19.
  2. Percorra a estrutura do conjunto de dados: Os artigos no conjunto de dados são armazenados como arquivos json. Apresentamos exemplos que mostram:
  • Como encontrar os artigos (navegar no contentor)
  • Como ler os artigos (navegando no esquema json)

Dependências: Este bloco de notas requer as seguintes bibliotecas:

  • Armazenamento do Azure (por exemplo, pip install azure-storage)
  • NLTK (documentos)
  • Pandas (por exemplo, pip install pandas)

Obtendo os dados CORD-19 do Azure

Os dados CORD-19 foram carregados como um conjunto de dados aberto do Azure aqui. Criamos um serviço de blob vinculado a este conjunto de dados 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 este serviço de blob como um identificador dos dados. Podemos navegar no conjunto de dados fazendo uso das BlockBlobService APIs. Veja aqui mais detalhes:

Os dados CORD-19 são armazenados no covid19temp contêiner. Esta é a estrutura do arquivo dentro do contêiner juntamente 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. É aqui que o título, os autores, o resumo e (quando disponíveis) os dados de texto completo são armazenados.

Usando metadados.csv

O conjunto de dados CORD-19 vem com metadata.csv - um único arquivo que registra informações básicas sobre todos os papéis disponíveis no conjunto de dados CORD-19. Este é um bom lugar para começar a explorar!

# 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)

Isso é muito para absorver à primeira vista, então vamos aplicar um pouco de polimento.

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 texto completo

metadata.csv não contém o texto completo em si. Vamos ver um exemplo de como ler isso. Localize e descompacte 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 este blob da seguinte forma.

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 no , que armazena body_textos dados de texto da seguinte maneira:

"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])

Análise XML PDF vs PMC

No exemplo acima, analisamos um caso com has_pdf_parse == True. Nesse caso, o caminho do arquivo blob era do formato:

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

Alternativamente, para casos com has_pmc_xml_parse == True o uso do 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 através de blobs diretamente

Nos exemplos acima, usamos o arquivo para navegar pelos dados, construir o metadata.csv caminho do arquivo de blob e ler dados do blob. Uma alternativa é a iteração através das próprias bolhas.

# 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 através das bolhas 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

Trata-se de um grande conjunto de dados que, por razões óbvias, foi elaborado de forma bastante apressada! Aqui estão alguns problemas de qualidade de dados que observamos.

Lâminas múltiplas

Observamos que, em alguns casos, existem vários shas para uma 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

Disposição do contentor

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óximos passos

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