graph TD %% Define styles before nodes classDef startEnd fill:#f9f,stroke:#333,stroke-width:2px classDef process fill:#e6f3ff,stroke:#007bff classDef data fill:#ffecb3,stroke:#ffc107 classDef decision fill:#d4edda,stroke:#28a745 classDef endNode fill:#afa,stroke:#333,stroke-width:2px %% Define nodes A[Início] --> B(Coleta de Dados Brutos); B --> C(Limpeza de Dados: Tratar Ausentes, Erros, Duplicados); C --> D(Análise Univariada: Distribuição de Cada Variável); D --> E(Análise Bivariada/Multivariada: Relações entre Variáveis); E --> F{Padrões/Anomalias Encontrados?}; F -- Sim --> G(Geração de Insights / Novas Hipóteses); F -- Não --> H(Revisar / Refinar Análise); G --> I(Preparação para Modelagem / Inferência); H --> C; I --> J[Fim]; %% Apply styles class A startEnd class J endNode class C,D,E process class B,H data class F,G,I decision
Análise Exploratória de Dados (AED)
Visualizar e Interpretar Dados para Identificar Padrões e Anomalias
Introdução e Objetivos
Nas aulas anteriores, construímos uma base sólida em análise combinatória e probabilidade, e aprendemos a descrever dados através de medidas de tendência central e dispersão. Agora, vamos mergulhar na Análise Exploratória de Dados (AED), uma filosofia e um conjunto de técnicas para investigar conjuntos de dados, resumir suas características principais, e identificar padrões, anomalias e relações. A AED é um passo crítico no pipeline de ciência de dados, frequentemente o primeiro após a coleta e limpeza de dados.
A AED vai além dos números brutos, utilizando visualizações para contar a história dos dados. Ela nos permite formular hipóteses, validar suposições sobre os dados e preparar o terreno para modelagem estatística e aprendizado de máquina. Através de gráficos e tabelas, podemos descobrir insights que seriam difíceis de perceber apenas com medidas numéricas.
Objetivos de Aprendizagem
Ao final desta aula, você será capaz de:
- Compreender o propósito e a importância da Análise Exploratória de Dados.
- Utilizar diferentes tipos de gráficos para visualizar variáveis univariadas (quantitativas e qualitativas).
- Utilizar diferentes tipos de gráficos para explorar relações bivariadas (entre dois tipos de variáveis).
- Identificar visualmente padrões, tendências, distribuições e outliers nos dados.
- Interpretar as informações extraídas das visualizações para gerar insights.
- Aplicar ferramentas de visualização de dados em Python (
matplotlib
,seaborn
) e R (ggplot2
).
O que é Análise Exploratória de Dados (AED)?
A Análise Exploratória de Dados (AED), popularizada por John Tukey, é uma abordagem para analisar conjuntos de dados para resumir suas características principais, muitas vezes com métodos visuais. Um modelo estatístico pode ser usado ou não, mas a AED é primariamente para ver o que os dados podem nos dizer além do formalismo. (Bussab; Morettin, 2017, p. 95–96)
A AED é um processo iterativo e investigativo que envolve:
- Entendimento do Contexto: Compreender o que os dados representam e de onde vieram.
- Limpeza e Preparação: Lidar com valores ausentes, formatar dados e corrigir erros.
- Visualização: Criar gráficos para revelar distribuições, relações e anomalias.
- Resumo Numérico: Calcular medidas descritivas (média, mediana, desvio padrão, etc.) para complementar as visualizações.
- Formulação de Hipóteses: Gerar perguntas sobre os dados que podem ser testadas posteriormente.
A AED é crucial porque:
- Revela Insights: Ajuda a descobrir padrões e relações que não seriam evidentes de outra forma.
- Identifica Problemas: Permite detectar erros nos dados, outliers, e problemas de qualidade.
- Guia a Modelagem: Informa a escolha de modelos estatísticos e técnicas de aprendizado de máquina.
- Valida Suposições: Permite verificar as suposições subjacentes aos métodos estatísticos.
Fluxo de Trabalho Típico da AED
Visualização de Dados para Variáveis Únicas (Análise Univariada)
A análise univariada foca na distribuição de cada variável individualmente.
Variáveis Qualitativas (Nominais e Ordinais)
Para variáveis categóricas, os gráficos nos ajudam a visualizar as frequências de cada categoria.
Gráfico de Barras (Bar Plot)
Mostra a frequência ou contagem de cada categoria. É ideal para comparar a magnitude das categorias.
Exemplo: Contagem de diferentes cores de carros em um estacionamento.
import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns
# Criando um dataset de exemplo
data_qual = {'Cor_Carro': ['Vermelho', 'Azul', 'Verde', 'Vermelho', 'Azul', 'Azul', 'Branco', 'Vermelho', 'Verde']}
df_qual = pd.DataFrame(data_qual)
plt.figure(figsize=(8, 5))
sns.countplot(x='Cor_Carro', data=df_qual, palette='viridis')
plt.title('Frequência de Cores de Carros')
plt.xlabel('Cor do Carro')
plt.ylabel('Contagem')
plt.grid(axis='y', linestyle='--', alpha=0.7)
plt.show()
library(ggplot2)
library(dplyr)
# Criando um dataset de exemplo
df_qual <- data.frame(
Cor_Carro = c('Vermelho', 'Azul', 'Verde', 'Vermelho', 'Azul', 'Azul', 'Branco', 'Vermelho', 'Verde')
)
ggplot(df_qual, aes(x = Cor_Carro, fill = Cor_Carro)) +
geom_bar() +
labs(title = 'Frequência de Cores de Carros', x = 'Cor do Carro', y = 'Contagem') +
theme_minimal() +
theme(legend.position = "none") + # Oculta a legenda se a cor já estiver no eixo x
scale_fill_viridis_d() # Usando uma paleta de cores discreta

Gráfico de Setores (Pie Chart)
Representa a proporção de cada categoria em relação ao total. Útil para poucas categorias, mas pode ser enganoso com muitas.
Exemplo: Distribuição percentual do voto em uma eleição.
import pandas as pd
import matplotlib.pyplot as plt
# Contando as frequências do exemplo anterior
contagem_cores = df_qual['Cor_Carro'].value_counts()
plt.figure(figsize=(8, 8))
plt.pie(contagem_cores, labels=contagem_cores.index, autopct='%1.1f%%', startangle=140, colors=sns.color_palette('viridis', len(contagem_cores)))
plt.title('Distribuição Percentual de Cores de Carros')
plt.axis('equal') # Garante que o círculo seja desenhado como um círculo
plt.show()
# Contando as frequências do exemplo anterior
contagem_cores <- as.data.frame(table(df_qual$Cor_Carro))
colnames(contagem_cores) <- c("Cor", "Frequencia")
ggplot(contagem_cores, aes(x = "", y = Frequencia, fill = Cor)) +
geom_bar(stat = "identity", width = 1) +
coord_polar("y", start = 0) +
labs(title = 'Distribuição Percentual de Cores de Carros') +
theme_void() + # Tema vazio para gráficos de pizza
geom_text(aes(label = paste0(round(Frequencia/sum(Frequencia)*100, 1), "%")),
position = position_stack(vjust = 0.5), size = 4) +
scale_fill_viridis_d()

Variáveis Quantitativas (Discretas e Contínuas)
Para variáveis numéricas, buscamos entender a forma da distribuição, a dispersão e a presença de valores atípicos.
Histograma
Mostra a distribuição de uma variável quantitativa, agrupando os valores em “bins” (intervalos) e exibindo a frequência de cada bin.
Exemplo: Distribuição de idades de clientes.
import numpy as np
import matplotlib.pyplot as plt
import seaborn as sns
# Criando um dataset de exemplo
np.random.seed(42)
idades = np.random.normal(loc=30, scale=8, size=100) # Média 30, desvio padrão 8
idades = idades[(idades > 18) & (idades < 60)] # Filtrando para idades mais realistas
idades = np.round(idades).astype(int) # Arredondando para inteiros
plt.figure(figsize=(10, 6))
sns.histplot(idades, bins=10, kde=True, color='skyblue', edgecolor='black')
plt.title('Distribuição de Idades de Clientes')
plt.xlabel('Idade')
plt.ylabel('Frequência')
plt.grid(axis='y', linestyle='--', alpha=0.7)
plt.show()
library(ggplot2)
# Criando um dataset de exemplo
set.seed(42)
idades <- rnorm(100, mean = 30, sd = 8)
idades <- idades[idades > 18 & idades < 60]
idades <- round(idades)
df_idades <- data.frame(Idade = idades)
ggplot(df_idades, aes(x = Idade)) +
geom_histogram(binwidth = 3, fill = "skyblue", color = "black", alpha = 0.7) +
geom_density(aes(y = after_stat(count * 3)), color = "blue", size = 1) + # Multiplica por binwidth para escalar
labs(title = 'Distribuição de Idades de Clientes', x = 'Idade', y = 'Frequência') +
theme_minimal()

Box Plot (Diagrama de Caixa)
Fornece um resumo de cinco números: mínimo, primeiro quartil (Q1), mediana (Q2), terceiro quartil (Q3) e máximo. É excelente para identificar outliers e comparar distribuições.
Exemplo: Distribuição do tempo de resposta de servidores.
import numpy as np
import matplotlib.pyplot as plt
import seaborn as sns
# Criando um dataset de exemplo com outliers
np.random.seed(42)
tempos_resposta = np.random.normal(loc=150, scale=20, size=50)
tempos_resposta = np.append(tempos_resposta, [30, 40, 500, 550]) # Adicionando outliers
plt.figure(figsize=(8, 6))
sns.boxplot(y=tempos_resposta, color='lightgreen')
plt.title('Distribuição do Tempo de Resposta de Servidores')
plt.ylabel('Tempo de Resposta (ms)')
plt.grid(axis='y', linestyle='--', alpha=0.7)
plt.show()
library(ggplot2)
# Criando um dataset de exemplo com outliers
set.seed(42)
tempos_resposta <- rnorm(50, mean = 150, sd = 20)
tempos_resposta <- c(tempos_resposta, 30, 40, 500, 550)
df_tempos <- data.frame(Tempo = tempos_resposta)
ggplot(df_tempos, aes(y = Tempo)) +
geom_boxplot(fill = "lightgreen") +
labs(title = 'Distribuição do Tempo de Resposta de Servidores', y = 'Tempo de Resposta (ms)') +
theme_minimal()

Gráfico de Densidade (KDE Plot)
Uma versão suavizada do histograma, que mostra a estimativa da função de densidade de probabilidade. É útil para visualizar a forma da distribuição sem a dependência da escolha dos bins.
Exemplo: Distribuição de pesos de amostras.
import numpy as np
import matplotlib.pyplot as plt
import seaborn as sns
# Reutilizando o dataset de idades
# idades = np.random.normal(loc=30, scale=8, size=100)
# idades = idades[(idades > 18) & (idades < 60)]
plt.figure(figsize=(10, 6))
sns.kdeplot(idades, fill=True, color='purple')
plt.title('Densidade da Distribuição de Idades de Clientes')
plt.xlabel('Idade')
plt.ylabel('Densidade')
plt.grid(axis='y', linestyle='--', alpha=0.7)
plt.show()
library(ggplot2)
# Reutilizando o dataset de idades
# idades <- rnorm(100, mean = 30, sd = 8)
# idades <- idades[idades > 18 & idades < 60]
# df_idades <- data.frame(Idade = idades)
ggplot(df_idades, aes(x = Idade)) +
geom_density(fill = "purple", alpha = 0.7) +
labs(title = 'Densidade da Distribuição de Idades de Clientes', x = 'Idade', y = 'Densidade') +
theme_minimal()

Visualização de Dados para Relações entre Variáveis (Análise Bivariada)
A análise bivariada explora a relação entre duas variáveis.
Quantitativa vs. Quantitativa
Gráfico de Dispersão (Scatter Plot)
Mostra a relação entre duas variáveis quantitativas. Cada ponto representa uma observação. É excelente para identificar padrões, correlações e clusters.
Exemplo: Relação entre horas de estudo e nota em um exame.
import numpy as np
import matplotlib.pyplot as plt
import seaborn as sns
import pandas as pd
# Criando um dataset de exemplo
np.random.seed(42)
horas_estudo = np.random.uniform(2, 10, 50)
notas = 50 + horas_estudo * 5 + np.random.normal(0, 7, 50)
notas = np.clip(notas, 0, 100) # Limita as notas entre 0 e 100
df_estudo = pd.DataFrame({'Horas_Estudo': horas_estudo, 'Notas': notas})
plt.figure(figsize=(10, 6))
sns.scatterplot(x='Horas_Estudo', y='Notas', data=df_estudo, hue='Horas_Estudo', size='Notas', sizes=(20, 400), palette='viridis', legend='full')
plt.title('Relação entre Horas de Estudo e Notas em Exame')
plt.xlabel('Horas de Estudo')
plt.ylabel('Nota no Exame')
plt.grid(linestyle='--', alpha=0.7)
plt.show()
library(ggplot2)
# Criando um dataset de exemplo
set.seed(42)
horas_estudo <- runif(50, 2, 10)
notas <- 50 + horas_estudo * 5 + rnorm(50, 0, 7)
notas <- pmin(pmax(notas, 0), 100) # Limita as notas entre 0 e 100
df_estudo <- data.frame(Horas_Estudo = horas_estudo, Notas = notas)
ggplot(df_estudo, aes(x = Horas_Estudo, y = Notas, color = Horas_Estudo, size = Notas)) +
geom_point(alpha = 0.7) +
labs(title = 'Relação entre Horas de Estudo e Notas em Exame', x = 'Horas de Estudo', y = 'Nota no Exame') +
theme_minimal() +
scale_color_viridis_c()

Matriz de Correlação (Heatmap)
Quando há múltiplas variáveis quantitativas, um heatmap da matriz de correlação visualiza as forças e direções das relações lineares entre todos os pares de variáveis.
Exemplo: Correlação entre diferentes características de um dataset (e.g., Iris).
import seaborn as sns
import matplotlib.pyplot as plt
import pandas as pd
# Usando o dataset Iris para exemplo
iris = sns.load_dataset('iris')
numeric_iris = iris.select_dtypes(include=np.number) # Seleciona apenas colunas numéricas
plt.figure(figsize=(8, 6))
sns.heatmap(numeric_iris.corr(), annot=True, cmap='coolwarm', fmt=".2f", linewidths=.5)
plt.title('Matriz de Correlação do Dataset Iris')
plt.show()
library(ggplot2)
library(reshape2) # Para a função melt
# Usando o dataset Iris para exemplo
data(iris)
numeric_iris <- iris %>% select_if(is.numeric)
# Calcular a matriz de correlação
cor_matrix <- cor(numeric_iris)
# Converter a matriz de correlação para um formato longo para ggplot2
melted_cor_matrix <- melt(cor_matrix)
ggplot(melted_cor_matrix, aes(Var1, Var2, fill = value)) +
geom_tile(color = "white") +
scale_fill_gradient2(low = "blue", high = "red", mid = "white",
midpoint = 0, limit = c(-1,1), space = "Lab",
name="Correlação") +
theme_minimal() +
theme(axis.text.x = element_text(angle = 45, vjust = 1,
size = 10, hjust = 1)) +
coord_fixed() +
geom_text(aes(Var1, Var2, label = round(value, 2)), color = "black", size = 4) +
labs(title = "Matriz de Correlação do Dataset Iris")

Qualitativa vs. Quantitativa
Box Plot (por Categoria)
Permite comparar a distribuição de uma variável quantitativa entre diferentes grupos (categorias de uma variável qualitativa).
Exemplo: Comparar salários por nível de escolaridade.
import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns
# Criando um dataset de exemplo
data_mix = {
'Escolaridade': ['Fundamental', 'Médio', 'Superior', 'Médio', 'Fundamental', 'Superior', 'Superior', 'Médio'],
'Salario': [2500, 3500, 6000, 3000, 2800, 7500, 5500, 3200]
}
df_mix = pd.DataFrame(data_mix)
plt.figure(figsize=(10, 6))
sns.boxplot(x='Escolaridade', y='Salario', data=df_mix, order=['Fundamental', 'Médio', 'Superior'], palette='coolwarm')
plt.title('Salário por Nível de Escolaridade')
plt.xlabel('Nível de Escolaridade')
plt.ylabel('Salário (R$)')
plt.grid(axis='y', linestyle='--', alpha=0.7)
plt.show()
library(ggplot2)
# Criando um dataset de exemplo
df_mix <- data.frame(
Escolaridade = factor(c('Fundamental', 'Médio', 'Superior', 'Médio', 'Fundamental', 'Superior', 'Superior', 'Médio'),
levels = c('Fundamental', 'Médio', 'Superior')),
Salario = c(2500, 3500, 6000, 3000, 2800, 7500, 5500, 3200)
)
ggplot(df_mix, aes(x = Escolaridade, y = Salario, fill = Escolaridade)) +
geom_boxplot() +
labs(title = 'Salário por Nível de Escolaridade', x = 'Nível de Escolaridade', y = 'Salário (R$)') +
theme_minimal() +
scale_fill_brewer(palette = "Set2") # Usando uma paleta de cores

Violin Plot
Combina um box plot com um gráfico de densidade, mostrando a distribuição completa dos dados em cada categoria. É útil para ver a forma da distribuição, além dos quartis.
Exemplo: Comparar a distribuição do tempo de atendimento por tipo de serviço.
import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns
import numpy as np
# Criando um dataset de exemplo
np.random.seed(42)
data_violin = {
'Tipo_Servico': np.random.choice(['Básico', 'Premium', 'Standard'], size=100),
'Tempo_Atendimento': np.concatenate([
np.random.normal(5, 1, 40), # Básico
np.random.normal(8, 2, 30), # Premium
np.random.normal(6.5, 1.5, 30) # Standard
])
}
df_violin = pd.DataFrame(data_violin)
plt.figure(figsize=(10, 6))
sns.violinplot(x='Tipo_Servico', y='Tempo_Atendimento', data=df_violin, palette='pastel')
plt.title('Distribuição do Tempo de Atendimento por Tipo de Serviço')
plt.xlabel('Tipo de Serviço')
plt.ylabel('Tempo de Atendimento (minutos)')
plt.grid(axis='y', linestyle='--', alpha=0.7)
plt.show()
library(ggplot2)
# Criando um dataset de exemplo
set.seed(42)
df_violin <- data.frame(
Tipo_Servico = factor(sample(c('Básico', 'Premium', 'Standard'), size = 100, replace = TRUE,
prob = c(0.4, 0.3, 0.3))),
Tempo_Atendimento = c(
rnorm(40, mean = 5, sd = 1),
rnorm(30, mean = 8, sd = 2),
rnorm(30, mean = 6.5, sd = 1.5)
)
)
ggplot(df_violin, aes(x = Tipo_Servico, y = Tempo_Atendimento, fill = Tipo_Servico)) +
geom_violin(trim = FALSE) + # trim=FALSE mostra os "rabos" completos
labs(title = 'Distribuição do Tempo de Atendimento por Tipo de Serviço', x = 'Tipo de Serviço', y = 'Tempo de Atendimento (minutos)') +
theme_minimal() +
scale_fill_brewer(palette = "Pastel1")

Qualitativa vs. Qualitativa
Gráfico de Barras Agrupadas/Empilhadas
Compara as frequências ou proporções de uma categoria em relação a outra.
Exemplo: Gênero de clientes por tipo de produto adquirido.
import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns
import numpy as np
# Criando um dataset de exemplo
np.random.seed(42)
data_cat = {
'Genero': np.random.choice(['Masculino', 'Feminino'], size=100),
'Produto': np.random.choice(['Eletrônico', 'Vestuário', 'Alimentos'], size=100)
}
df_cat = pd.DataFrame(data_cat)
# Usando crosstab para criar a tabela de contingência
contingency_table = pd.crosstab(df_cat['Genero'], df_cat['Produto'])
# Gráfico de barras agrupadas
contingency_table.plot(kind='bar', figsize=(10, 6), colormap='tab10')
plt.title('Distribuição de Gênero por Tipo de Produto Adquirido')
plt.xlabel('Gênero')
plt.ylabel('Contagem')
plt.xticks(rotation=0)
plt.grid(axis='y', linestyle='--', alpha=0.7)
plt.show()
# Gráfico de barras empilhadas (proporções)
contingency_table_percent = contingency_table.apply(lambda r: r/r.sum(), axis=1)
contingency_table_percent.plot(kind='bar', stacked=True, figsize=(10, 6), colormap='tab10')
plt.title('Proporção de Gênero por Tipo de Produto Adquirido')
plt.xlabel('Gênero')
plt.ylabel('Proporção')
plt.xticks(rotation=0)
plt.grid(axis='y', linestyle='--', alpha=0.7)
plt.show()
library(ggplot2)
library(dplyr)
# Criando um dataset de exemplo
set.seed(42)
df_cat <- data.frame(
Genero = factor(sample(c('Masculino', 'Feminino'), size = 100, replace = TRUE)),
Produto = factor(sample(c('Eletrônico', 'Vestuário', 'Alimentos'), size = 100, replace = TRUE))
)
# Gráfico de barras agrupadas
ggplot(df_cat, aes(x = Genero, fill = Produto)) +
geom_bar(position = "dodge") +
labs(title = 'Distribuição de Gênero por Tipo de Produto Adquirido', x = 'Gênero', y = 'Contagem') +
theme_minimal() +
scale_fill_brewer(palette = "Paired")
# Gráfico de barras empilhadas (proporções)
ggplot(df_cat, aes(x = Genero, fill = Produto)) +
geom_bar(position = "fill") + # "fill" para proporções empilhadas
labs(title = 'Proporção de Gênero por Tipo de Produto Adquirido', x = 'Gênero', y = 'Proporção') +
theme_minimal() +
scale_fill_brewer(palette = "Paired")


Identificando Padrões e Anomalias
Durante a AED, a interpretação visual é fundamental.
-
Distribuições:
- Simétricas (normal): Histograma/densidade com forma de sino. Média \(\approx\) Mediana \(\approx\) Moda.
- Assimétricas à direita (positiva): Cauda longa à direita. Moda \(<\) Mediana \(<\) Média.
- Assimétricas à esquerda (negativa): Cauda longa à esquerda. Média \(<\) Mediana \(<\) Moda.
- Multimodais: Múltiplos picos, indicando subgrupos.
Outliers (Valores Atípicos): Pontos de dados que se desviam significativamente da maioria das observações. Visíveis como pontos isolados em Box Plots, Scatter Plots, ou em caudas muito longas em Histograms.
Tendências: Direção geral em Scatter Plots (positiva, negativa, sem relação).
Agrupamentos (Clusters): Aglomerados de pontos em Scatter Plots, sugerindo subgrupos naturais.
Variações e Dispersão: A largura de Histogramas, Box Plots e Violin Plots indica o quão espalhados os dados estão.
Relação com Outros Conceitos
A AED atua como uma ponte entre a estatística descritiva (medidas de tendência central e dispersão) e a estatística inferencial. As medidas descritivas fornecem os números que a AED visualiza e interpreta. Os padrões e anomalias descobertos na AED frequentemente levam à formulação de hipóteses que serão testadas usando inferência estatística (próximas aulas).
graph TD A[Dados Brutos] --> B(Estatística Descritiva: Medidas); B --> C(Análise Exploratória de Dados - AED); C --> D(Visualização de Dados); C --> E(Identificação de Padrões/Anomalias); D & E --> F(Geração de Insights/Hipóteses); F --> G(Modelagem Estatística / Inferência); G --> H[Tomada de Decisão / Previsão]; style A fill:#f9f,stroke:#333,stroke-width:2px; style B fill:#ffe0b3,stroke:#ffc107; style C fill:#a7e9ff,stroke:#007bff; style D fill:#c8e6c9,stroke:#4caf50; style E fill:#f8bbd0,stroke:#e91e63; style F fill:#d4edda,stroke:#28a745; style G fill:#bbdefb,stroke:#2196f3; style H fill:#afa,stroke:#333,stroke-width:2px;
Verificação de Aprendizagem
Para esta atividade, utilizaremos o famoso dataset Iris
. Este dataset contém medidas de sépalas e pétalas (comprimento e largura) de três espécies de flores Iris: setosa
, versicolor
e virginica
.
Carregue o dataset Iris em Python/R e execute as seguintes análises:
-
Visão Geral do Dataset:
- Carregue o dataset Iris.
- Exiba as primeiras 5 linhas.
- Verifique os tipos de dados e informações básicas (número de linhas, colunas, valores ausentes).
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import seaborn as sns
# Carregando o dataset Iris
iris = sns.load_dataset('iris')
print("Dataset Iris carregado com sucesso.")
# Exibindo as primeiras 5 linhas do dataset
print("\nPrimeiras 5 linhas do dataset:")
print(iris.head())
# Verificando os tipos de dados e informações básicas
print("\nInformações do dataset:")
print(iris.info())
print("\nVerificação de valores ausentes:")
print(iris.isnull().sum())
library(ggplot2)
library(dplyr)
library(reshape2) # Para melt
# Carregando o dataset Iris
data(iris)
print("Dataset Iris carregado com sucesso.")
# Exibindo as primeiras 5 linhas do dataset
print("\nPrimeiras 5 linhas do dataset:")
print(head(iris, 5))
# Verificando os tipos de dados e informações básicas
print("\nInformações do dataset:")
print(str(iris))
print("\nVerificação de valores ausentes:")
print(colSums(is.na(iris)))
Interpretação: O dataset Iris tem 150 entradas e 5 colunas. Quatro são numéricas (sepal_length
, sepal_width
, petal_length
, petal_width
) e uma é categórica (species
). Não há valores ausentes.
-
Análise Univariada (Comprimento da Sépala):
- Crie um histograma para a variável
sepal_length
. - Crie um box plot para a variável
sepal_length
. - Interprete a forma da distribuição (simétrica, assimétrica), o centro e a dispersão do
sepal_length
com base nos gráficos. Há outliers aparentes?
- Crie um histograma para a variável
import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns
iris = sns.load_dataset('iris')
# a) Histograma para sepal_length
plt.figure(figsize=(8, 5))
sns.histplot(iris['sepal_length'], bins=10, kde=True, color='purple', edgecolor='black')
plt.title('Distribuição do Comprimento da Sépala')
plt.xlabel('Comprimento da Sépala (cm)')
plt.ylabel('Frequência')
plt.grid(axis='y', linestyle='--', alpha=0.7)
plt.show()
# b) Box plot para sepal_length
plt.figure(figsize=(8, 5))
sns.boxplot(x='sepal_length', data=iris)
plt.title('Box Plot do Comprimento da Sépala')
plt.xlabel('Comprimento da Sépala (cm)')
plt.show()
library(ggplot2)
data(iris)
# a) Histograma para sepal_length
ggplot(iris, aes(x = Sepal.Length)) +
geom_histogram(binwidth = 0.5, fill = "purple", color = "black", alpha = 0.7) +
geom_density(aes(y = after_stat(count * 0.5)), color = "blue", size = 1) +
labs(title = 'Distribuição do Comprimento da Sépala', x = 'Comprimento da Sépala (cm)', y = 'Frequência') +
theme_minimal()
# b) Box plot para sepal_length
ggplot(iris, aes(x = Sepal.Length)) +
geom_boxplot(fill = "orange") +
labs(title = 'Box Plot do Comprimento da Sépala', x = 'Comprimento da Sépala (cm)') +
theme_minimal()
- c) Interpretação da distribuição. Interpretação: O histograma mostra uma distribuição bimodal ou talvez uma mistura de distribuições, com picos em torno de 5 cm e 6.5 cm, sugerindo a presença de subgrupos (que sabemos serem as espécies). A distribuição não é perfeitamente simétrica. O box plot indica que a mediana do comprimento da sépala está em torno de 5.8 cm, com a maioria dos dados entre aproximadamente 5.1 cm (Q1) e 6.4 cm (Q3). Não há outliers aparentes para o comprimento da sépala no conjunto de dados total.
-
Análise Bivariada (Comprimento da Sépala vs. Comprimento da Pétala por Espécie):
- Crie um gráfico de dispersão que mostre a relação entre
sepal_length
(eixo X) epetal_length
(eixo Y). - Colora os pontos por
species
(espécie) para distinguir as três espécies. - Interprete o gráfico: Há uma correlação entre o comprimento da sépala e da pétala? Como as diferentes espécies se agrupam ou se separam neste gráfico?
- Crie um box plot do
sepal_length
para cadaspecies
. Interprete as diferenças de comprimento da sépala entre as espécies.
- Crie um gráfico de dispersão que mostre a relação entre
import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns
iris = sns.load_dataset('iris')
# a) Gráfico de dispersão com coloração por espécie
plt.figure(figsize=(10, 7))
sns.scatterplot(x='sepal_length', y='petal_length', hue='species', data=iris, s=100, alpha=0.8)
plt.title('Comprimento da Sépala vs. Comprimento da Pétala por Espécie')
plt.xlabel('Comprimento da Sépala (cm)')
plt.ylabel('Comprimento da Pétala (cm)')
plt.grid(linestyle='--', alpha=0.7)
plt.legend(title='Espécie')
plt.show()
# b) Box plot de sepal_length para cada species
plt.figure(figsize=(10, 7))
sns.boxplot(x='species', y='sepal_length', data=iris, palette='Set3')
plt.title('Comprimento da Sépala por Espécie')
plt.xlabel('Espécie')
plt.ylabel('Comprimento da Sépala (cm)')
plt.grid(axis='y', linestyle='--', alpha=0.7)
plt.show()
# d) Box plot de sepal_length para cada species
plt.figure(figsize=(10, 7))
sns.boxplot(x='species', y='sepal_length', data=iris, palette='Set3')
plt.title('Comprimento da Sépala por Espécie')
plt.xlabel('Espécie')
plt.ylabel('Comprimento da Sépala (cm)')
plt.grid(axis='y', linestyle='--', alpha=0.7)
plt.show()
library(ggplot2)
data(iris)
# a) Gráfico de dispersão com coloração por espécie
ggplot(iris, aes(x = Sepal.Length, y = Petal.Length, color = Species)) +
geom_point(size = 3, alpha = 0.8) +
labs(title = 'Comprimento da Sépala vs. Comprimento da Pétala por Espécie', x = 'Comprimento da Sépala (cm)', y = 'Comprimento da Pétala (cm)', color = 'Espécie') +
theme_minimal() +
scale_color_brewer(palette = "Set1")
# b) Box plot de sepal_length para cada species
ggplot(iris, aes(x = Species, y = Sepal.Length, fill = Species)) +
geom_boxplot() +
labs(title = 'Comprimento da Sépala por Espécie', x = 'Espécie', y = 'Comprimento da Sépala (cm)') +
theme_minimal() +
scale_fill_brewer(palette = "Set3")
# d) Box plot de sepal_length para cada species
ggplot(iris, aes(x = Species, y = Sepal.Length, fill = Species)) +
geom_boxplot() +
labs(title = 'Comprimento da Sépala por Espécie', x = 'Espécie', y = 'Comprimento da Sépala (cm)') +
theme_minimal() +
scale_fill_brewer(palette = "Set3")
Interpretação: O gráfico de dispersão revela uma forte correlação positiva entre sepal_length
e petal_length
para o conjunto de dados como um todo. As espécies são claramente separadas:
-
setosa
(roxo/vermelho): Apresenta comprimentos de pétala menores e comprimentos de sépala menores em comparação com as outras. Forma um cluster bem distinto. -
versicolor
(verde): Tem valores intermediários para ambos os comprimentos. -
virginica
(azul): Possui os maiores comprimentos de sépala e pétala. Há uma clara separação entre asetosa
e as outras duas espécies, enquantoversicolor
evirginica
se sobrepõem um pouco, mas ainda mostram tendências separadas.
-
Matriz de Correlação:
- Calcule e visualize a matriz de correlação entre todas as variáveis numéricas do dataset Iris usando um heatmap.
- Identifique os pares de variáveis com a correlação linear mais forte (positiva e negativa, se houver).
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import seaborn as sns
iris = sns.load_dataset('iris')
# a) Matriz de correlação
numeric_iris = iris.select_dtypes(include=np.number)
plt.figure(figsize=(8, 6))
sns.heatmap(numeric_iris.corr(), annot=True, cmap='coolwarm', fmt=".2f", linewidths=.5)
plt.title('Matriz de Correlação do Dataset Iris')
plt.show()
# b) Identificar os pares de variáveis com a correlação linear mais forte
print(numeric_iris.corr().abs().unstack().sort_values(kind="quicksort").tail(10))
library(ggplot2)
library(reshape2)
data(iris)
# a) Matriz de correlação
numeric_iris <- iris %>% select_if(is.numeric)
cor_matrix <- cor(numeric_iris)
melted_cor_matrix <- melt(cor_matrix)
ggplot(melted_cor_matrix, aes(Var1, Var2, fill = value)) +
geom_tile(color = "white") +
scale_fill_gradient2(low = "blue", high = "red", mid = "white",
midpoint = 0, limit = c(-1,1), space = "Lab",
name="Correlação") +
theme_minimal() +
theme(axis.text.x = element_text(angle = 45, vjust = 1,
size = 10, hjust = 1)) +
coord_fixed() +
geom_text(aes(Var1, Var2, label = round(value, 2)), color = "black", size = 4) +
labs(title = "Matriz de Correlação do Dataset Iris")
# b) Identificar os pares de variáveis com a correlação linear mais forte
print(cor_matrix)
Interpretação:
-
Correlação positiva mais forte:
petal_length
epetal_width
(0.96). Isso significa que, à medida que o comprimento da pétala aumenta, a largura da pétala também tende a aumentar significativamente. - Outras correlações positivas fortes:
sepal_length
competal_length
(0.87) epetal_width
(0.82). -
Correlação negativa mais forte: Não há correlações negativas fortes neste dataset. A correlação mais próxima de um valor negativo é entre
sepal_width
epetal_length
(-0.43), indicando uma fraca relação inversa. O heatmap claramente mostra que as medidas das pétalas são altamente correlacionadas entre si, e também têm forte correlação com o comprimento da sépala. A largura da sépala (sepal_width
) parece ter relações mais fracas com as outras variáveis.