Quer fazer um curso de pandas? Dê uma olhada no nosso curso Data Manipulation with pandas !
Importando os dados Para começar a explorar, você precisa carregar os dados. Graças ao pandas, isso vira uma tarefa simples: importe o pacote como pd, seguindo a convenção, e use a função read_csv(), passando a URL onde os dados estão e o argumento header. Esse último argumento ajuda a garantir que a leitura ocorra corretamente: a primeira linha dos dados não será interpretada como nomes de colunas do seu DataFrame.
Além disso, há outros argumentos que você pode especificar para garantir a leitura correta: o delimitador com sep ou delimiter, os nomes das colunas com names ou a coluna a usar como índice das linhas do DataFrame resultante com index_col.
Mas esses estão longe de ser os únicos argumentos de read_csv(). Confira a função e seus parâmetros na documentação .
# Import the `pandas` library as `pd`
import pandas as pd
# Load in the data with `read_csv()`
digits = pd.read_csv("http://archive.ics.uci.edu/ml/machine-learning-databases/optdigits/optdigits.tra",
header=None)
# Print out `digits`
print(digits)
Note que, neste caso, usamos read_csv() porque os dados estão em formato separado por vírgulas. Se seus arquivos tiverem outro separador, também há funções para carregar os dados, como read_table(), read_excel(), read_fwf() e read_clipboard, para ler arquivos delimitados em geral, arquivos do Excel, dados de largura fixa e dados copiados para a área de transferência, respectivamente.
Você também encontra read_sql() para ler uma consulta SQL ou uma tabela de banco de dados em um DataFrame. Para mais funções de entrada, consulte esta seção da documentação do pandas.
O que é análise exploratória de dados (EDA)? A Análise Exploratória de Dados (EDA) serve, por um lado, para responder perguntas, testar suposições de negócio e gerar hipóteses para análises futuras. Por outro lado, você também pode usá-la para preparar os dados para a modelagem. O ponto em comum entre os dois usos é ter um bom conhecimento dos seus dados — seja para obter as respostas que você precisa, seja para desenvolver intuição ao interpretar resultados de modelos no futuro.
Há muitas formas de atingir esses objetivos: obter uma descrição básica dos dados, visualizá-los, identificar padrões, reconhecer desafios no uso dos dados, etc.
Um conceito que você vai encontrar com frequência quando ler sobre EDA é o data profiling. O data profiling resume seu conjunto de dados por meio de estatísticas descritivas. Você usa várias medidas para entender melhor o dataset. A ideia é ter uma compreensão sólida para, depois, começar a fazer consultas e visualizações de diferentes maneiras. Isso não significa que não haja iteração: justamente por resumir o dataset, o data profiling é frequentemente usado para avaliar a qualidade dos dados. Dependendo dos resultados, você pode decidir corrigir, descartar ou tratar os dados de outra forma.
Você aprenderá mais sobre data profiling em um próximo post.
EDA e mineração de dados (DM) EDA se distingue da mineração de dados, embora sejam áreas próximas, já que muitas técnicas de EDA foram incorporadas à mineração. Os objetivos também são parecidos: a EDA garante que você explore os dados de modo que features interessantes e relações entre elas fiquem mais claras. Em EDA, você normalmente explora e compara muitas variáveis com várias técnicas para buscar e encontrar padrões sistemáticos. Já a mineração de dados se preocupa em extrair padrões dos dados. Esses padrões oferecem insights sobre relações entre variáveis que podem melhorar decisões de negócio. Em ambos os casos, você não tem expectativas a priori (ou elas são incompletas) sobre as relações entre variáveis.
De forma geral, pode-se dizer que a mineração de dados é mais orientada à aplicação, enquanto a EDA se volta à natureza básica dos fenômenos subjacentes. Em outras palavras, a mineração de dados se preocupa relativamente menos em identificar relações específicas entre as variáveis envolvidas. Como resultado, adota uma abordagem de “caixa-preta” para explorar dados e usa não só técnicas de EDA, mas também métodos como redes neurais para gerar previsões válidas, sem necessariamente identificar a natureza específica das relações entre as variáveis nas quais as previsões se baseiam.
Descrição básica dos dados Como você leu acima, EDA é sobre conhecer seus dados. Um passo elementar é obter uma descrição básica. “Descrição básica” é um termo amplo: pode ser um jeito rápido e prático de extrair informações simples e fáceis de entender, para ter uma noção inicial do dataset.
Esta seção não vai distinguir entre interpretações: ela apresenta algumas formas de reunir rapidamente informações fáceis de entender sobre seu DataFrame.
Descrevendo os dados Por exemplo, você pode usar a função describe() para obter várias estatísticas-resumo que excluem valores NaN. Veja este exemplo em que descrevemos o famoso conjunto de dados Iris . Os dados já foram carregados para você no bloco do DataCamp Light:
Você vê que a função retorna contagem, média, desvio padrão, valores mínimo e máximo e os quantis. Claro, há muitos pacotes em Python que podem fornecer essas estatísticas, inclusive o próprio pandas. Usar essa função é apenas uma das formas de obter a informação.
Também vale reservar um tempo para se aprofundar em estatística descritiva, caso ainda não tenha feito isso. Você pode usar essas estatísticas para começar a avaliar a qualidade dos dados. Assim, decide se precisa corrigir, descartar ou tratar os dados de outra forma. Normalmente, isso é a etapa de data profiling. Ela serve para entender melhor os elementos dos dados e suas anomalias e verificar como os dados se alinham, por um lado, com a documentação e, por outro, com as necessidades do negócio.
Observação : você vai voltar ao data profiling ao longo da EDA, porque a qualidade dos dados pode ser impactada pelos passos que você executar.
Primeiras e últimas linhas do DataFrame Agora que você tem uma visão geral, também é uma boa ideia olhar mais de perto para os dados em si. Com as funções head() e tail() do pandas, você vê rapidamente as primeiras e as últimas linhas do seu DataFrame, respectivamente.
Inspecione as cinco primeiras e cinco últimas linhas dos dados de dígitos manuscritos com head() e tail() no bloco abaixo do DataCamp Light. Os dados já foram carregados para você:
# Inspect the first 5 rows of `digits`
first = digits._____(5)
# Inspect the last 5 rows
last = digits.____(5)
Você vai notar que o resultado de head() e tail() não diz muita coisa se você não estiver familiarizado com esse tipo de dado.
Você pode ver apenas um monte de linhas e colunas com valores numéricos. Considere ler a descrição do conjunto de dados se ainda não fez isso — ela traz informações relevantes sobre como os dados foram coletados e informa o número de atributos e linhas, o que ajuda a checar se a importação deu certo.
Além disso, volte ao achado inicial: os valores numéricos nas linhas. À primeira vista, pode parecer que está tudo certo, pois os inteiros parecem adequados e não levantam bandeiras vermelhas.
Mas, se você estivesse analisando outro dataset com, por exemplo, dados de data e hora, um olhar rápido poderia levantar questões como: “Meus dados foram lidos como DateTime?”, “Como verificar isso?” e “Como mudar o tipo de dado?”.
Essas questões mais profundas você normalmente aborda na etapa de data profiling, que será tratada em um próximo post.
Amostrando os dados Se você tem um dataset grande, talvez valha a pena pegar uma amostra como um jeito rápido de sentir os dados. Para começar de forma simples, use a função sample() do pandas, assim:
# Take a sample of 5
digits.sample(5)
Outra forma — talvez mais trabalhosa — é criar um índice aleatório e então recuperar linhas aleatórias do DataFrame. O código abaixo usa o módulo random (função sample) em combinação com range() e len(). Note que também usamos ix para selecionar as linhas exatas do DataFrame que queremos na amostra.
Se você não tem certeza por que usar ix nesse contexto, o tutorial mais específico da DataCamp pode ajudar! Ele cobre esses tópicos gerais em detalhe. Clique no link acima e confira!
Por agora, vamos praticar Python! Comece o exercício abaixo:
# import `sample` from `random`
from random import ______
# Create a random index
randomIndex = np.array(sample(range(len(______)), 5))
# Get 5 random rows
digitsSample = digits.ix[___________]
# Print the sample
print(____________)
Os desafios dos seus dados Agora que você reuniu informações básicas, vale a pena aprofundar nos desafios que os dados podem trazer. Se você já passou pelo data profiling, estará ciente de valores ausentes, terá ideia de possíveis outliers, etc.
Esta seção descreve formas básicas de identificar essas questões e como tratar os dados caso encontre irregularidades. Vale reforçar: você vai (ou já foi) mais fundo na identificação dessas irregularidades no data profiling, e é normal voltar a essa etapa depois de lidar com alguns desafios.
Valores ausentes Algo que você também deve verificar durante a exploração é se existem valores ausentes no conjunto de dados.
Analisar isso é importante porque, quando parte dos dados está ausente, o dataset perde poder de expressão, o que pode levar a análises fracas ou enviesadas. Na prática, quando há lacunas em determinadas features, aumentam as chances de sua classificação ou previsão sair errada.
É claro que a causa para faltas pode estar em uma extração ou importação com problemas, ou no próprio processo de coleta. Os sistemas que geram os dados podem falhar, ou o questionário enviado pode ter sido deixado em branco pelos respondentes. É fundamental verificar se há padrão nos dados ausentes — e o data profiling ajuda muito aqui. Lembre que ele serve para avaliar melhor a qualidade dos dados. Um post de continuidade vai mostrar como descobrir padrões de ausência.
Em resumo, as causas variam e dependem do contexto, mas também podem depender de você. Por isso, você inspecionou os dados logo após a importação nas etapas anteriores!
Para identificar as linhas que contêm valores ausentes, use isnull(). No resultado, cada célula terá True ou False: True indica que o valor daquela célula está ausente; False significa que a célula contém um valor “normal”.
# Identifiy missing values
pd.isnull(______)
Neste caso, você vê que os dados estão bem completos: não há valores ausentes.
Observação : você também poderia ter lido isso na descrição do dataset no UCI Machine Learning Repository, linkada acima, onde consta que não há valores ausentes.
Contudo, isso não acontece em todo conjunto de dados. Por isso, é bom saber o que fazer quando você se depara com dados faltantes.
Excluir os dados ausentes: você pode deletar o registro inteiro ou manter apenas os registros em que as features de interesse estão presentes. Tenha cuidado, pois excluir dados pode enviesar a análise. Pergunte-se se a probabilidade de ausência para aquele registro é a mesma dos demais. Se a probabilidade não varia de registro para registro, excluir pode ser uma opção válida. Além de excluir, você pode preencher as lacunas com “métodos de imputação”. Se você já tem experiência com estatística, sabe que imputação é substituir valores faltantes por valores estimados. Você pode preencher com média, moda ou mediana. Pense se vai usar, por exemplo, a média geral da variável ou se vai substituir com base em outra variável. Em dados com categorias como “masculino” e “feminino”, pode ser interessante considerar essas diferenças antes de imputar, pois as observações podem variar entre grupos. Nesse caso, calcule a média para “feminino” e preencha os ausentes desse grupo com essa média. Estimar o valor com regressão, ANOVA, regressão logística ou outra técnica de modelagem. É a abordagem mais complexa. Preencher com valores de registros mais semelhantes ao que tem lacunas. Você pode usar KNN (K-Nearest Neighbors) em casos assim. Note que cada abordagem tem prós e contras. Considere tempo, custo, natureza dos dados, etc., antes de decidir.
Depois de decidir o que fazer com os dados ausentes, siga lendo para ver como implementar as mudanças.
Preenchendo valores ausentes Se você optar por imputação, ainda pode escolher como fazer!
Use fillna() do pandas em combinação com funções do NumPy. Considere o trecho abaixo, em que você teria um DataFrame com resultados de uma pesquisa sobre salário. Supondo um contexto em que o público é do mesmo estrato social e a probabilidade de resposta é igual para todos, você pode calcular a média das pessoas que responderam e usar essa média para preencher quem não respondeu.
# Import NumPyimport numpy as np# Calculate the meanmean = np. mean ( df. Salary) # Replace missing values with the meandf. = df. Salary. fillna ( mean) Tecnologia Claro que você não precisa, necessariamente, passar um valor para fillna(). Também dá para propagar valores não nulos para frente ou para trás adicionando o argumento method à função. Passe ffill ou bfill para indicar se quer preencher para frente ou para trás.
Para excluir colunas ou linhas com valores ausentes, use dropna() do pandas:
# Drop rows with missing valuesdf. dropna ( axis= 0 ) # Drop columns with missing values df. dropna ( axis= 1 ) Tecnologia Interpolação Alternativamente, você pode interpolar valores ausentes: a função interpolate() realiza interpolação linear nos pontos faltantes para “estimar” o valor mais provável.
df. interpolate ( ) Tecnologia Você também pode incluir o argumento method para acessar métodos mais avançados, como interpolação polinomial ou cúbica. Para esses tipos, é necessário ter SciPy instalado.
Existem limites para a interpolação, especialmente se os NaNs estiverem muito distantes da última observação válida. Nesses casos, adicione o argumento limit. Passe um inteiro positivo e esse número determinará quantos valores após um não-NaN serão preenchidos. A direção padrão é para frente, mas isso também pode ser alterado com limit_direction.
Outliers Assim como valores ausentes, seu dataset pode conter pontos que divergem muito da maioria: os “outliers”. Para encontrá-los, verifique a distribuição de variáveis individuais com boxplots ou faça um scatter plot para identificar pontos fora da área “esperada”.
As causas variam — desde erros de sistema até interferências no registro ou processamento. É importante considerar o efeito deles na análise: podem mudar o resultado de testes estatísticos como desvio padrão, média e mediana, reduzir a normalidade e impactar modelos estatísticos, como regressão ou ANOVA.
Para lidar com outliers, você pode excluir, transformar ou imputar — a decisão depende do contexto. Por isso, é essencial entender seus dados e identificar a causa:
Se o valor extremo for causado por erro de entrada ou processamento, considere removê-lo. Você pode transformar os outliers atribuindo pesos às observações ou usando log natural para reduzir a variação que eles causam. Assim como com valores ausentes, você pode usar métodos de imputação para substituir valores extremos por mediana, média ou moda. Você pode reutilizar as funções descritas acima para lidar com outliers.
As features dos seus dados Observação : esta etapa acontece de forma iterativa com outras tarefas de ciência de dados: você constrói e valida modelos, depois pode ajustar as features e repetir o ciclo de modelagem, e assim por diante.
Seleção de atributos Na seleção de atributos, você escolhe um subconjunto-chave das features originais para reduzir a dimensionalidade do problema de treinamento. Parece parecido com outras técnicas de redução de dimensionalidade, como PCA, mas há diferença: PCA combina atributos similares (correlacionados) e cria novos, considerados superiores aos originais. A seleção de atributos não combina: ela avalia qualidade e poder preditivo e seleciona o melhor conjunto.
Para encontrar atributos importantes, você pode usar o algoritmo RandomForest: ele gera milhares de árvores de decisão aleatórias e, em rodízio, deixa cada variável de fora ao ajustar o modelo. Assim, dá para calcular o quanto o modelo melhora ou piora quando uma variável é excluída. Use a biblioteca Scikit-Learn para implementar:
# Import `RandomForestClassifier`
from sklearn.ensemble import RandomForestClassifier
# Isolate Data, class labels and column values
X = iris.iloc[:,0:4]
Y = iris.iloc[:,-1]
names = iris.columns.values
# Build the model
rfc = RandomForestClassifier()
# Fit the model
rfc.fit(X, Y)
# Print the results
print("Features sorted by their score:")
print(sorted(zip(map(lambda x: round(x, 4), rfc.feature_importances_), names), reverse=True))
Você verá que o melhor conjunto inclui os dados de comprimento e largura da pétala.
Observação : você também pode visualizar os resultados da seleção de atributos com Matplotlib:
# Import ` pyplot ` and ` numpy ` import matplotlib. pyplot as pltimport numpy as np# Isolate feature importances importance = rfc. feature_importances_# Sort the feature importances sorted_importances = np. argsort ( importance) # Insert paddingpadding = np. arange ( len ( names) - 1 ) + 0.5 # Plot the dataplt. barh ( padding, importance[ sorted_importances] , align= 'center' ) # Customize the plotplt. yticks ( padding, names[ sorted_importances] ) plt. xlabel ( "Relative Importance" ) plt. title ( "Variable Importance" ) # Show the plotplt. show ( ) Tecnologia
Padrões nos seus dados Um próximo passo na exploração é identificar padrões, como correlação entre atributos ou entre dados ausentes. A visualização ajuda muito nisso; e não precisa ser estática: experimente criar visualizações interativas com as bibliotecas Bokeh ou Plotly.
Depois de olhar os números e analisar quantitativamente, também é útil considerar seus dados de forma visual. É hora de explorar visualmente.
Para fazer isso de maneira rápida, use o Matplotlib. O único “obstáculo” pode ser, ironicamente, seu dataset: como você sabe, ele tem 64 colunas (features). Com tantas features, dizemos que os dados são de alta dimensionalidade.
Você vai aprender exatamente o que isso significa no nosso tutorial de machine learning, mas, por ora, saiba que, para visualizar em 2D ou 3D, você precisa ter duas ou três dimensões. Isso significa reduzir a dimensionalidade.
Ou seja, usar técnicas de redução de dimensionalidade, como Análise de Componentes Principais (PCA):
# Import `PCA` from `sklearn.decomposition`
from sklearn.decomposition import ___
# Build the model
pca = PCA(n_components=2)
# Reduce the data, output is ndarray
reduced_data = pca.fit_transform(_______)
# Inspect the shape of `reduced_data`
reduced_data.______
# print out the reduced data
print(_______________)
Ao inspecionar os dados reduzidos, você verá que agora as colunas (features) foram reduzidas para duas. O número de linhas (observações) permanece o mesmo: 3823. Com os dados no formato certo, vamos ao gráfico!
Escolher o tipo de gráfico certo já é um excelente começo — qual escolher?
Neste caso, estamos explorando os dados e queremos descobrir possíveis correlações entre atributos. Um scatter plot é uma boa opção: ele permite identificar relações entre as duas features obtidas após a redução de dimensionalidade.
import matplotlib. pyplot as pltplt. scatter ( reduced_data[ : , 0 ] , reduced_data[ : , 1 ] , c= labels, cmap = 'viridis' ) plt. show ( ) Tecnologia
Outra opção é usar Bokeh para construir um gráfico interativo e descobrir correlações entre atributos. Bokeh é uma biblioteca de visualização interativa em Python voltada a navegadores modernos. É ideal para conjuntos grandes ou em streaming, mas, como você verá no exemplo, também serve para dados “comuns”.
O código é simples: importe os módulos necessários, construa o scatter plot, configure a saída padrão para gerar um arquivo quando show() for chamado e, por fim, chame show() para ver o gráfico!
# Import the necessary modulesfrom bokeh. charts import Scatter, output_file, show# Construct the scatter plotp = Scatter ( iris, x= 'Petal_length' , y= 'Petal_width' , color= "Class" , title= "Petal Length vs Petal Width" , xlabel= "Sepal Length" , ylabel= "Sepal Width" ) # Output the file output_file ( 'scatter.html' ) # Show the scatter plotshow ( p) Tecnologia O resultado fica elegante:
Note que esta é uma imagem estática salva, mas o gráfico resultante no seu notebook ou terminal será interativo! Claro, este é apenas um exemplo simples de como usar Bokeh para visualizações interativas. Confira a Bokeh Gallery para mais inspirações ou faça o curso da DataCamp Interactive Data Visualization with Bokeh .
Os gráficos anteriores são uma forma visual de explorar correlação entre atributos. Mas você também pode explorar essa medida quantitativamente! Quando optar por isso, use a função corr() do pandas. Lembre que valores NaN ou nulos são excluídos do cálculo.
# Pearson correlation
iris.corr()
# Kendall Tau correlation
iris.corr('kendall')
# Spearman Rank correlation
iris.corr('spearman')
Observação : as duas últimas medidas de correlação exigem classificar os dados antes de calcular os coeficientes. Você faz isso facilmente com rank(): para o exercício acima, os dados de iris foram ranqueados com iris.rank().
Além disso, há pressupostos: a correlação de Pearson supõe variáveis normalmente distribuídas, relação linear entre as variáveis e dados normalmente distribuídos em torno da linha de regressão. Já a correlação de Spearman supõe duas variáveis ordinais ou relacionadas de alguma forma, mas não linearmente.
A correlação Kendall Tau representa o grau de concordância entre duas colunas de dados ranqueados. A de Spearman mede o grau de associação entre duas variáveis. Elas parecem similares, não é?
Embora Kendall e Spearman pareçam semelhantes, diferem no cálculo. Kendall Tau é (pares concordantes menos pares discordantes) dividido pelo total de pares. Spearman é a soma dos desvios ao quadrado dividida por n vezes n menos 1.
O coeficiente de Spearman geralmente é maior que o de Kendall Tau, mas não sempre: você obterá um Spearman menor quando os desvios entre observações forem muito grandes. A correlação de Spearman é sensível a isso — o que pode ser útil em alguns casos.
Então, quando usar qual? Eles testam coisas diferentes: Kendall Tau representa a proporção de pares concordantes em relação aos discordantes; Spearman não. Você também pode argumentar que Kendall Tau é mais intuitiva, mais fácil de calcular, dá melhor estimativa do parâmetro populacional correspondente e que os p-values são mais precisos em amostras pequenas.
Dica : adicione print() para ver os resultados das correlações par a par de colunas específicas.
Como você já deve saber, a biblioteca de manipulação de dados do Python, pandas, é usada para manipular dados. Para quem está começando, isso pode dar a entender que o pacote só é útil no pré-processamento, mas não é bem assim: o pandas também é ótimo para explorar seus dados e para armazená-los depois que você terminar o pré-processamento.
Além disso, para quem vem acompanhando os tutoriais de Python da DataCamp ou já foi apresentado aos fundamentos de SciPy, NumPy, Matplotlib e pandas, vale a pena recapitular alguns conhecimentos que você já construiu.
O tutorial de hoje vai apresentar formas de explorar seus dados com eficiência usando todos os pacotes acima, para que você possa começar a modelar seus dados: