COVID-19 Open Research Dataset

Jeu de données de texte intégral et de métadonnées d’articles de recherche liés au COVID-19 et aux coronavirus, optimisé pour la lisibilité par une machine et mis à disposition par la communauté mondiale de chercheurs.

Pour répondre à la pandémie du COVID-19, l’institut Allen Institute for AI s’est associé à des groupes de recherche dans le but de préparer et de distribuer le jeu de données COVID-19 Open Research Dataset (CORD-19). Ce jeu de données est constitué de plus de 47 000 articles universitaires (dont 36 000 peuvent être lus dans leur intégralité) ayant pour sujet le COVID-19 et la famille des coronavirus. Il s’agit d’une ressource gratuite destinée aux chercheurs du monde entier.

Ce jeu de données mobilise les chercheurs pour qu’ils appliquent les avancées récentes du traitement du langage naturel afin de générer de nouvelles connaissances dans la lutte contre cette maladie infectieuse.

Le corpus fera l’objet de mises à jour lorsque de nouvelles recherches seront publiées dans des documents évalués par des pairs et des services d’archivage tels que bioRxiv, medRxiv et d’autres.

Notes

Microsoft fournit Azure Open Datasets « en l’état ». Microsoft n’offre aucune garantie, expresse ou implicite, ni de conditions relatives à votre utilisation des jeux de données. Dans la mesure autorisée par votre droit local, Microsoft décline toute responsabilité pour les dommages ou pertes, y compris directs, consécutifs, spéciaux, indirects ou punitifs, résultant de votre utilisation des jeux de données.

Ce jeu de données est fourni selon les conditions initiales par lesquelles Microsoft a reçu les données sources. Le jeu de données peut inclure des données provenant de Microsoft.

Termes du contrat de licence

Ce jeu de données est mis à disposition par l’institut Allen Institute of AI par le biais du projet Semantic Scholar. En parcourant, en téléchargeant ou en utilisant de quelque manière que ce soit le contenu fourni dans le jeu de données CORD-19, vous acceptez la licence associée au jeu de données et à son utilisation. Des informations de licence propres à chaque article du jeu de données sont disponibles dans le fichier de métadonnées. Pour plus d’informations sur les licences, consultez les sites web PMC, medRxiv et bioRxiv.

Volume et conservation

Ce jeu de données est stocké au format JSON et la dernière version contient plus de 36 000 articles en texte intégral. Chaque article est représenté comme un seul objet JSON. Afficher le schéma.

Emplacement de stockage

Ce jeu de données est stocké dans la région Azure USA Est. Il est recommandé de placer les ressources de calcul dans la région USA Est pour des raisons d’affinité.

Citation

Lorsque vous incluez des données CORD-19 dans une publication ou une redistribution, vous devez citer le jeu de données de la façon suivante :

Dans la bibliographie :

COVID-19 Open Research Dataset (CORD-19). 2020. Version YYYY-MM-DD. Récupéré à partir de COVID-19 Open Research Dataset (CORD-19). Accès AAA-MM-JJ. doi:10.5281/zenodo.3715505

Dans le texte : (CORD-19, 2020)

Contact

Pour toute question sur ce jeu de données, contactez partnerships@allenai.org.

Accès aux données

Azure Notebooks

Jeu de données CORD-19

CORD-19 est un ensemble de plus de 50 000 articles universitaires (dont plus de 40 000 en texte intégral) portant sur le COVID-19, le SARS-CoV-2 et autres coronavirus. Ce jeu de données est disponible gratuitement dans le but d’aider les communautés chercheurs à combattre la pandémie du COVID-19.

L’objectif de ce notebook est double :

  1. Montrer comment accéder au jeu de données CORD-19 dans Azure - Nous nous connectons au compte de stockage Blob Azure qui héberge le jeu de données CORD-19.
  2. Parcourir la structure du jeu de données - Les articles du jeu de données sont stockés sous forme de fichiers JSON. Nous fournissons des exemples qui montrent comment :
  • Trouver les articles (en parcourant le conteneur)
  • Lire les articles (en parcourant le schéma JSON)

Dépendances - Ce notebook nécessite les bibliothèques suivantes :

  • Stockage Azure (par exemple, pip install azure-storage)
  • NLTK (docs)
  • Pandas (par exemple, pip install pandas)

Obtention des données CORD-19 à partir d’Azure

Les données CORD-19 ont été chargées en tant que jeu de données ouvert Azure disponible ici. Nous créons un service blob lié au jeu de données ouvert 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,
)

Nous pouvons utiliser ce service blob comme handle pour ces données. Nous pouvons accéder au jeu de données à l’aide des API BlockBlobService. Pour plus d’informations, consultez ce qui suit :

Les données CORD-19 sont stockées dans le conteneur covid19temp. Voici la structure de fichiers située dans le conteneur, avec un exemple de fichier.

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
        ...

Chaque fichier .json correspond à un article du jeu de données. C’est ici que sont stockés le titre, les auteurs, le résumé et le texte intégral (le cas échéant).

Utilisation de metadata.csv

Le jeu de données CORD-19 est fourni avec metadata.csv. Ce fichier contient les informations de base sur tous les articles disponibles dans le jeu de données CORD-19. C’est un bon point de départ pour l’exploration !

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

Il y a beaucoup de choses à intégrer à première vue, il faut donc être le plus clair possible.

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

Exemple : Lire le texte intégral

metadata.csv ne contient pas le texte intégral. Voyons un exemple pour comprendre comment le lire. Accédez au code JSON qui comprend le texte intégral, décompressez-le puis convertissez-le en une liste de phrases.

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

Nous pouvons maintenant lire le contenu JSON associé à cet objet Blob en procédant de la façon suivante :

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

Dans cet exemple, nous nous intéresserons à body_text, qui stocke les données texte de la façon suivante :

"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"
    },
    ...
]

Le schéma json complet est disponible ici.

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

Analyse XML PDF et PMC

Dans l’exemple ci-dessus, nous avons vu un scénario qui utilisait has_pdf_parse == True. Le chemin du fichier Blob se présentait ainsi :

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

Pour les scénarios utilisant has_pmc_xml_parse == True, vous pouvez également utiliser le format suivant :

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

Par exemple :

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

Effectuer une itération directement dans les objets blob

Dans les exemples ci-dessus, nous avons utilisé le fichier metadata.csv pour parcourir les données, construire le chemin du fichier d’objet blob et lire les données de l’objet blob. Une autre possibilité consiste à effectuer une itération dans les objets blob.

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

À présent, nous pouvons effectuer une itération directement dans les objets blob. Par exemple, nous allons compter le nombre de fichiers JSON disponibles.

# 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

Annexe

Problèmes de qualité des données

Il s’agit d’un jeu de données volumineux qui, pour des raisons évidentes, a été créé dans la précipitation ! Voici quelques problèmes de qualité des données que nous avons détectés.

SHA multiples

Nous observons que dans certains cas, il existe plusieurs SHA pour une même entrée.

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

Disposition du conteneur

Ici, nous utilisons une expression régulière simple pour explorer la structure des fichiers du conteneur au cas où celle-ci serait mise à jour.

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

Étapes suivantes

Consultez les autres jeux de données du catalogue Open Datasets.