Material de apoio ao CDEC

Ementas para referência

Materiais interessantes

Estudando RMarkdown e Markdown

O entendimento sobre o RMarkdown e o Markdown será muito importante para desenvolvermos os nossos materiais. Segue uma apresentação preliminar:

Como usar o GitHub

Para entender como usar o GitHub e nossos projetos R/Python/RStudio, assista a série rapidinahs do R (0005 - 00011).

Linguagens de programação

Iremos iniciar a falar sobre as duas principais linguagens que iremos trabalhar, o ambiente R e o Python.

Ambiente R

Família de pacotes a serem estudados

Estudando o R

Temos um curso em desenvolvimento que vale a pena estudar, seguido por vídeo-aulas, materiais escritos e exercícios. Acesse: http://bendeivide.github.io/cursor.

Linguagem Python

Introdução ao Python

Por volta dos anos 1980, o holandês Guido Van Rossum, que até então trabalhava no time de desenvolvimento da linguagem ABC no CWI (Centrum Wiskunde & Informatica), o instituto nacional de pesquisa em matemática e ciência da computação da Holanda, se tornaria a principal figura responsável pela criação do Python, uma linguagem de programação com ampla aplicabilidade que atingiu alta popularidade entre desenvolvedores, acadêmicos e empresas (incluindo gigantes como Google, YouTube e Dropbox).

Sucintamente, podemos descrever o Python como uma linguagem de programação open source de alto nível, interpretada, interativa e orientada a objetos. Sua aplicação é bastante versátil e inclui desenvolvimento de aplicativos, páginas da web, análise de dados, automatização de rotinas e até mesmo desenvolvimento de jogos.

O Python está disponível para muitos sistemas operacionais, incluindo os populares Linux, Mac OS e Windows. A versão mais recente para seu processador e sistema operacional (SO) pode ser encontrada para download na página oficial do Python.

Após a instalação, você poderá utilizar a linguagem por meio do seu terminal ou prompt de comando, além do IDLE, o ambiente de desenvolvimento integrado (do inglês, Integrated Development Environment, ou IDE) padrão do Python, criado pelo já citado fundador da linguagem, Guido Van Rossum. A utilização de outros IDE’s, além do próprio IDLE, podem tornar a experiência com a linguagem mais didática e/ou dinâmica, porém trata-se uma escolha que fica a critério do estudante/programador. Algumas alternativas de IDE’s para programação Python são o Spyder, o Pycharm e o RStudio.

Primeiros comandos no Python

Com o Python já disponível na sua máquina, é o momento de inaugurar a experiência com a linguagem. Tipicamente, o código mais básico para iniciar os estudos é retornar “Olá, Mundo!” na tela.

Código

Print('Ola, Mundo!')

Output

Ola, Mundo!

Finalmente, temos nosso primeiro programa no Python! É válido citar que as aspas utilizadas podem ser simples ou duplas.

Para a construção de um código bem estruturado, é importantíssimo adicionar comentários conforme o trabalho avança, garantindo que a leitura do programa fique o mais dinâmica possível, permitindo melhor compreensão e facilitando o ajuste de possíveis erros.

Por padrão, os comentários no Python são inseridos utilizando o símbolo # + 1 espaço + comentário. É recomendável utilizar ao menos 2 espaços entre a última linha de código e um comentário, conforme o exemplo a seguir.

Código

var = 'Ola, Mundo!'  # Exemplo de comentário 1

Print(var)  # Exemplo de comentário 2

Output

Ola, Mundo!

Cada código trará suas informações no formato que mais se adeque ao seu objetivo, sendo assim, o Python apresenta diferentes tipos de dados possíveis. Para os primeiros passos, os tipos de dados mais utilizados serão os demonstrados abaixo:

Exemplos de strings: “Olá, Mundo!”, “CDEC”, “Python”…

Exemplos de números de tipo integer: 1, -2, -5, 15…

Exemplos de números de tipo float: 1.20, -13.444, 15.89…

Os únicos valores possíveis para uma variável booleana são “True” e “False”

A função type( ) pode nos mostrar o tipo de uma variável, enquanto as funções str( ), int( ), float( ) e bool( ) permite fazer os valores transitarem entre diferentes tipos, como pode ser observado nos exemplos abaixo:

Código

a = True

x = 1

y = -3.50

z = "Olá, Mundo!"

print(type(a))

print(type(x))

print(type(y))

print(type(z))

print(str(x))

print(int(y))

Output

<class 'bool'>

<class 'int'>

<class 'float'>

<class'str'>

1

-3

Módulos Python para Data Science

Python é hoje em dia considerado a linguagem para cientistas de dados, isso se dá pelo fato de ela possuir vários módulos que facilitam a construção do algoritmo além de permitir em alguns casos a utilização de computação em GPU, tornando o processo muito mais rápido. Hoje os principais módulos usados são os seguintes: * Numpy: NumPy é um projeto open source que permite executar computação numérica com Python de forma rápida e fácil, quase todas as ferramentas seguintes, se não todas, usam do poder de computação de arrays e matrizes de Numpy. * Scipy: SciPy é um pacote de módulos Python open source voltados para ciência, matemática e engenharia. Dentro deste pacote são incluídos módulos como NumPy, Matplotlib (usado principalmente para plotagem de gráficos) e Pandas. * Theano: Theano é um módulo Python que te permite definir, otimizar, e avaliar expressões matemáticas envolvendo arrays multi-dimensionais eficientemente. Ele é construído em cima de NumPy. Theano também te permite fazer computações de dados usando a GPU, aumentando a performance em até 140x. * TensorFlow: TensorFlow é um módulo Python open source para machine learning. Ele tem um ecossistema abrangente e flexível de ferramentas, bibliotecas e recursos da comunidade que permite aos pesquisadores levar adiante ML de última geração e aos desenvolvedores criar e implantar aplicativos com tecnologia de ML. * Keras: Keras é uma API desenvolvida para facilitar o desenvolvimento de modelos de machine learning diminuindo o número de ações que o usuário necessita fazer para casos comuns, além de mostrar mensagens de erro claras e que permitem encontrar a causa de forma mais fácil. Keras também possui uma documentação extensa e guias para o desenvolvedor. Hoje em dia é considerado uma das 5 melhores para deep learning. * PyTorch: Assim como TensorFlow, PyTorch é um módulo Python open source para machine learning. Ele é baseado na biblioteca Torch que também está disponível para C++. * Pandas: Pandas é uma ferramenta open source essencial para análise de dados em Python. Ele é rápido, flexível e fácil de usar. Com ele é possível fazer a criação e manipulação de Data Frames, além de poder fazer um resumo estatístico do Data Frame com um único comando. ### Introdução ao Numpy Primeiramente, antes de usar o módulo numpy, é necessário que ele esteja instalado no computador ou virtual environment de desenvolvimento. Para isso, assim como quase todos os módulos para Python, podemos fazer essa instalação utilizando o pip ou conda.

pip install numpy ou conda install numpy

Agora com o módulo instalado podemos utilizá-lo em código. Para isso precisamos primeiro importar esse módulo da seguinte forma:

import numpy as np

Essa é a forma que o módulo numpy é normalmente importado. Esse código nos permite escrever apenas np quando formos utilizar alguma função Numpy, esse mesmo formato será visto posteriormente.

Numpy contem arrays multidimensionais e matrizes como estrutura de dados. Ele disponibiliza um tipo de dado chamado ndarray que como o nome sugere, é um array multidimensional. Esse tipo de dado contém vários métodos para fazer operações sobre ele de forma eficiente e facilmente, a maioria das vezes mais rápido que listas nativas do Python. ndarray juntamente com Numpy, adicionam estruturas de dados cálculos eficientes com arrays e matrizes e ainda disponibilizam uma grande gama de funções matemáticas de alto nível que operam nesses arrays e matrizes.

Para criar um ndarray inicializado com todos os indices como 0 ou 1 basta seguir o código abaixo:

>>> import numpy as np
>>> # Inicializa um ndarray com 10 elementos todos com o valor 0
>>> a = np.zeros(10)
>>> # Inicializa um ndarray com 10 elementos todos com o valor 1
>>> b = np.ones(10)

Para criar um ndarray usando uma lista Python é necessário fazer o seguinte:

>>> c = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
>>> d = np.array(c)  # Também é possível utilizar a lista diretamente como parâmetro

Os cálculos básicos como soma, subtração, multiplicação e divisão são tão simples quanto as operações de variáveis numéricas:

>>> e = b + d
>>> e
array([ 2.,  3.,  4.,  5.,  6.,  7.,  8.,  9., 10., 11.])
>>> e = b - d
>>> e
array([ 0., -1., -2., -3., -4., -5., -6., -7., -8., -9.])
>>> f = e * d
>>> f
array([  0.,  -2.,  -6., -12., -20., -30., -42., -56., -72., -90.])
>>> f = e / d
>>> f
array([ 0.        , -0.5       , -0.66666667, -0.75      , -0.8       ,
       -0.83333333, -0.85714286, -0.875     , -0.88888889, -0.9       ])

Para criar ndarrays multidimensionais existem algumas formas, como usar uma lista Python multidemensional ou simplesmente iniciar um ndarray com valores aleatórios. Esses não são os únicos métodos para realizar essa tarefa, mas já é um bom começo para se habituar ao Numpy.

>>> # Utilizando Python list
>>> g = [[1, 2, 3], [4, 5, 6]]
>>> h = np.array(g)
>>> h
array([[1, 2, 3],
       [4, 5, 6]])
>>> # Inicializando com método empty.
>>> h = np.empty((2, 2))
>>> h
array([[1.5711153e-316, 0.0000000e+000],
       [0.0000000e+000, 0.0000000e+000]])

As mesmas regras de operações entre matrizes também são aplicadas aos ndarrays, ou seja, se tivermos uma matriz 2x2 e tentarmos multiplicar por um vetor de tamanho 3 teremos um erro no código e o programa irá levantar uma exceção.

>>> h = np.empty((2, 2))
>>> a = np.random.rand(2)  # Inicializa um vetor de tamanho 2 com números aleatórios
>>> a
array([0.22500409, 0.32657332])
>>> a * h  # Operação com sucesso
array([[3.535074e-317, 0.000000e+000],
       [0.000000e+000, 0.000000e+000]])
>>> a = np.random.rand(3)  # Vetor agora com 3 números aleatórios
>>> a * h  # Essa operação gera erro
Traceback (most recent call last):
  File "/usr/lib/python3.8/code.py", line 90, in runcode
    exec(code, self.locals)
  File "<input>", line 1, in <module>
ValueError: operands could not be broadcast together with shapes (3,) (2,2) 

Como podemos ver pelo erro, a operação não foi sucedida pelo fato de não terem formatos compatíveis.

Agora que sabemos como inicializar ndarrays e fazer operações com eles, ainda precisamos saber como acessar os valores dentro destes ndarrays. Para isso, utilizamos uma sintaxe muito parecida com a nativa do Python.

import numpy as np

>>> a = np.arange(10)  # Inicia um ndarray de 0 a 9
>>> a
array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])
>>> # Acessando um único valor
>>> a[2]
2
>>> # Acessando o último valor
>>> a[-1]
9
>>> # Criando um slice, ou corte, do ndarray de 0 a 2
>>> a[:3]
array([0, 1, 2])
>>> # Criando um slice, ou corte, do ndarray de 3 a 9
>>> a[3:]
array([3, 4, 5, 6, 7, 8, 9])
>>> # Criando um slice, ou corte de 3 a 6
>>> a[3:7]
array([3, 4, 5, 6])
>>> # Acessando um único valor em uma matriz
>>> b = np.array([[1, 2, 3], [4, 5, 6]])
>>> b[1][0]
4

O mesmo que foi feito com o vetor pode ser feito para conseguir slices das matrizes, com a diferença que é possível utilizar a notação de slice em todos os campos de índice.

Para obter mais informações, visite o site da documentação do Numpy.

Introdução ao Pandas

Assim como Numpy, Pandas também necessita ser instalado antes de ser usado. Para isso, podemos usar tanto pip quanto conda:

pip install pandas ou conda install pandas

Após instalado, Pandas agora pode ser importado para ser utilizado no seu script assim como vimos anteriormente com o Numpy

import pandas as pd

Assim quando formos usar as funções, classes e métodos do Pandas nós precisamos escrever apenas pd.

Existem várias formas de criar um DataFrame usando Pandas. Aqui veremos dois métodos básicos, um criado a partir de um dicionário Python e outro importando de um CSV.

>>> # Criando DataFrame com dicionários Python.
>>> import pandas as pd
>>>
>>> # Cria um dicionário com as chaves iguais ao nome das colunas e com os valores
>>> # iguais a listas de valores.
>>> dict_data = {"a": [1, 2, 3],
...              "b": [4, 5, 6],
...              "c": [7, 8, 9]}
>>> # (Opcional) Cria uma lista de nomes para os índices.
>>> index = ["experimento 1", "experimento 2", "experimento 3"]
>>> # Cria o DataFrame passando o dicionário como primeiro parâmetro e a lista
>>> # de índices como segundo parâmetro
>>> dict_data_frame = pd.DataFrame(dict_data, index=index)
>>> dict_data_frame
               a  b  c
experimento 1  1  4  7
experimento 2  2  5  8
experimento 3  3  6  9

Aqui criamos um DataFrame usando dicionários Python. O parâmetro de índice é opcional, caso ele não seja colocado, no lugar dos nomes escolhidos serão adicionados valores incrementais, ou seja, 1, 2, 3, … n, em que n é o número de linhas no seu DataFrame.

Agora veremos como importar um CSV como DataFrame usando Pandas

>>> # Criando um DataFrame importando um CSV.
>>> import pandas as pd
>>>
>>> # Utilizamos a função read_csv(local do arquivo, separador, index_col=índice ou nome da coluna)
>>> csv_data_frame = pd.read_csv('./recursos/introducao pandas/csvData.csv', ";", index_col=0)
>>> csv_data_frame
               a  b  c
Experimento 1  1  4  7
Experimento 2  2  5  8
Experimento 3  3  6  9

Aqui podemos ver como é simples importar um CSV como DataFrame usando o Pandas. O arquivo utilizado para este teste pode ser encontrado no nosso GIT na pasta recursos, introducao pandas.

Introdução a Ciência de Dados

Tratado como um termo novo, o Data Science (ou Ciência de dados), como ciência analítica estatística, teve seu primeiro passo em 1980. Em uma palestra na Universidade de Michigan, EUA, C.F Jeff Wu já sugeria os rótulos Statistical Data Science ou Data Science com o objetivo de dar mais foco e visibilidade para os projetos e estudos estatísticos.

Hoje, a maioria desses centros de pesquisas envolvidos na ciência dos dados se encontram em escolas de Engenharia, Bioestatísticas, Ciência da computação, entre outros. Dessa forma, surge a necessidade de destacarmos a importância da Estatística nessa ampla área da ciência. Afinal, a fundamentação de toda análise formada em volta dos dados tem como carater inicial, a análise estatística.

Podemos então, nos perguntar: qual o impacto desse subgênero estatístico em nossas vidas?

Blei e Smyth (2017) nos ajudam a pensar sobre quando discutem sobre Estatística e Ciência de dados sob três perspectivas: estatística, computacional e humana. A estatística oferece um guia para coleta e análise de dados complexos. A computacional com seu poder desenvolveria algoritmos que, ao distribuir a massiva quantidade de dados em mais de um processador, permitiria mais possibilidade e capacidade de análise. E a humana, utilizaria a Ciência de dados como ferramenta para resolução de problema interdisciplinares, seus domínios, suas peculiaridades, modos de uso e afins.

Dessa maneira, ainda no âmbito humano, os dados e sua análise surgem como partes fundamentais na industria de consumo tão avassaladora atualmente. A obtenção de dados por ferramentas diversas em um estado de pico na segunda década do século geram a quantidade e a necessidade de profissionalização das análises corporativas, a fomentação de Inteligências artificiais e estudos financeiros complexos e mais abrangentes.

Por isso, a partir dessa essa introdução, pretende-se fomentar um estudo inicial da Ciência de dados e suas área correlatas, Machine Learning (Aprendizado de máquina), Redes neurais e, especificamente para esse estudo, Lógica Fuzzy.

Introdução a Machine Learning

A partir dessa etapa do estudo, abordaremos dois termos muito recorrentes no estudo de dados: Aprendizado com Estatística (Statical Learning) e o Aprendizado de Máquina (Machine Learning). Ambos consistem na fomentação e utiliação de modelos estatísticos junto ao algoritmos computacionais que, em sua maioria, usados na extração de informações de conjuntos de dados, sejam eles Mega Data (grande amontoado de dados) ou Small Data (pequenos dados).

O Aprendizado com Estatística (AE) pode ser dividido em dois: supervisionado e não-supervisionado. O supervisionado tem como objetivos prever o valor de uma saída (output) a partir de uma entrada (input), sendo que os output podem ser qualitativos e quantitativos. No primeiro grupo, um dos modelos mais usados é o de regressão, já no segunto, a regressão logística para análise é mais utilizado.

No caso dos não-supervisionado, há apenas um conjunto de inputs e o objetivo é descrever associações e padrões entre essas variáveis pré-definidas. Não há conjuntos de saída e as principais técnicas são análises de componentes principais e análise de componentes independentes, ou seja, uma visão mais restrita com peso entre os dados.

Os métodos de AE, antes não usualmente considerados em programas de graduação e pós-graduação em Estatística, surgiram recentemente como objeto de estudo, prncipalmente englobados no conceito de Ciência de dados, alguns exemplos são: Support Vector Machines, Decision Trees, Random Forest, Bagging, Boosting, etc.

Cada vez mais faladas, as Inteligências Artificiais (IA) são derivadas de aprendizado automático. Como Chollet (2018) pontuou a IA é apenas um esforço para automatizar tarefas intelectuais usualmente realizada por seres humanos.

A ideia principal de treinar um sistema computacional vem de uma lógica associativa de ajustar modelos, através de algoritmos, ao utilizar repetidas análises de conjunto de dados, conhecidos como dados de treinamento. Progressivamente, um outro conjunto de dados é submetido aos modelos, os dados de teste têm como função instigar os modelos já treinados, e no final, o de melhor acurácia, termo muito comum nesse meio, se mostra o melhor e mais adequado para aquele conjunto de amostras.

Contudo, a ideia pode ser simples, mas a execução exige a divisão dos dados em dois grupos e suscetivas tentativas, sempre submetendo novas divisões desses grupos, para que assim, consiga-se as melhores médias de acurácia entre os modelos testados. Em seguida, uma comparação é feita entre os modelos e aquele com menor média de erro é definido como o mais adequado, esse processo é conhecido como validação cruzada.

Tipos de dados

Considerando um tópico importante em toda essa análise, vale separar uma etapa do desenvolvimento em prol da definição dos tipos de dados analisados. Nesse sentido, começamos a denotar uma matriz com dimensão N x P. Sendo que N indica o número de unidades amostras e P o número de variáveis.

Dessa forma, tem-se as seguintes estruturas de dados: a) Grande número de unidades amostrais e pequeno número de variáveis, N >> P; b) Pequeno número de unidades amostrais e grande número de variáveis, P >> N; c) Grande número de unidades amostrais e grande número de variáveis, N e P grandes.

Tudo isso se encaixa no conceito de megadados (big data). Quando N << P, os dados tem alta dimensão. Ademais, a análise dos megadados passam por dois conceitos muito importantes no mundo da Ciência de dados e na etapa corporativa de toda essa ciência.

  1. Dados estruturados: em que a informação se ajusta às estruturas usuais de bases de dados, relativamente fáceis de armazenar e analisar. Exemplos usuais de dados numéricos ou não que podem ser dispostos em matrizes de dados.
  2. Dados não-estruturados: tudo o que não se encaixa nos dados estruturados, como arquivos de texto, páginas web, e-mails, mídias sociais, etc.

Outro ponto considerável entre o conceito de Big Data é que sua definição pode ser descrito por 4 V’s: Veracidade, Velocidade, Volume e Variedade. A partir desses quatro conceitos, usamos os chamados megamodelos para análise de efiência e acurácia codizentes.

Introdução a Redes Neurais

Introdução a Lógica Fuzzy

Uma técnica muito presente em avaliações educacionais é a lógica Fuzzy, pois ela consegue lidar com diferentes entradas nebulosas ou difusas (Bom, Ruim, Correto, Errado, etc.). A ideia de seccionar elementos em conjuntos difusos a partir de um raciocínio com expressões lógicas, ao considerar coeficientes de pertencimento, agrega em nossa análise e relaciona diretamente com o aprendizado automático.

O sistema lógico consiste em três etapas: fuzzificação, inferência e defuzzificação. Nosso objetivo em analisar Fuzzy ao lado de Machine Learning e Redes Neurais é identificar se com a criação de regras importantes para a fase da inferência, especificamente, na automatização da extração das regras Fuzzy, podemos comparar os resultados de divisão de grupos entre essas técnicas.

Por detalhar as etapas da lógica, inicia-se com a fuzzificação. A análise do problema e os dados de entrada transformados em variáveis linguísticas. Logo após, são determinadas as funções de pertinência para cada uma das entradas definidas na arquitetura Fuzzy. No segundo momento, a etapa de interferência se inicia com a criação de regras ou proposições. Nesse momento, há a necessidade de análise do “operador”, já que há a necessidade de associar as variáveis em conjuntos de dominínios semelhantes. Em seguida, a defuzzificação converte os valores fuzzy em números reais para que haja uma saída matemática dessa clusterização feita anteriormente.

Introduzido o sistema lógica Fuzzy, o objetivo desse texto fomentar algumas discussões sobre esse método. Menos conhecido e comentado que Machine Learning e IA nos últimos anos, a ideia é entender seu funcionamento e a viabilidade de colocá-lo lado a lado dos anteriores como método relacionado a Ciência de dados. Para isso, dividiremos algumas sessões do texto, sendo que finaliza-se aqui a introdução.

Regras do Fuzzy

Um ponto de destaque dentro da lógica Fuzzy e que concreta as bases do estudo, é a definição de quais regras serão usadas. A análise de agrupamento dos dados e métricas é para a lógica Fuzzy o essencial. Visto isso, essa noção fomenta muito a construção automática de grupos vindos de conjuntos de dados.

Nesse sentido, uma importante possibilidade é o uso do Aprendizado automático de máquina como gerador de regras adequadas, afinal reconhecimento de padrões e agrupamento de conjuntos é concomitante às duas técnicas citadas. Nos campos de Aprendizado de máquina e a lógica Fuzzy, existem abordagem diversas e complexas. Deixarei alguns estudo e referência: “Por exemplo, a combinação de Algoritmos Genéticos e Agrupamentos pode ser encontradas em Saez et al. (2008)”. Em Lee et al. (2008) é apresentado um novo algoritmo de agrupamento fuzzy iterativo que incorpora um esquema de supervisão em uma abordagem de agrupamento fuzzy não supervisionado. O processo de aprendizado começa de modo não supervisionado e contrói partições significativas no espaço de entrada. As regras fuzzy são geradas por meio de uma seleção de grupos com supervisao baseado nas noções de pureza e separabilidade dos grupos[Stanovov et al. 2025].

Outra estratégia é a utilização de mapas de auto-organização (Self Organizing Maps - SOM) para extrair parâmetros de regras fuzzy automaticamente sem intervenção humana. Contudo, essa abordagem funcionaria melhor em conjunto de escala menor, dezenas ou pequenas centenas de amostras.

Árvores de decisão

A ideia de árvores de decisão já foi abordado no texto como um método usado na Ciência de dados. Dentro da lógica Fuzzy, ela pode ter um papel importante, exige-se assim uma introdução a esse conceito.

Uma árvore de decisão pode ser entendido como estruturas formadas por um conjunto de nós de decisão, perguntas, que permitem a classificação de cada caso. Como definido em Nilsson [2014], um nó folha que correponde a uma classe ou um nós de decisão que contém um teste sobre algum atributio.

A facilidade de compressão dos resultados de uma árvores de decisão seria outro fator que contribui para seu uso. A ideia de divisão de conjuntos sempre conectados possibilita ao desenvolver entender pontos de contato entre os conjuntos, gerando novas percepções e mais entendimento dos dados. Ademais, o seu tempo de geração é menor e, na maioria dos casos, suficiente, sem necessidade de parâmetros ou termos exógenos.

Por fim, o entendimento das árvores de decisão como modelo estatístico que são, podem ser usados para classificar objetos, sendo até capaz de classificar novas instância após a fase de treinamento do modelo. Torna-se assim, uma grande aliada na classificação e automatização do processo de geração de regras fuzzy.

Como destaque final, a técnica/algoritmo ID3, cua criação se baseou em sistemas de inferência e em conceitos de sistemas de aprendizagem, sendo assim um dos primeiros de árvore de decisão.

BLEI, D. M.; SMYTH, P. Science and data science. Proceedings of the National Academy of Sciences, v. 114, n. 33, p. 8689–8692, 2017.

References