0Pricing
Machine Learning Academy · Aula

Tratamento de dados e análise exploratória de dados

Carregue um conjunto de dados bruto, analise distribuições e correlações, identifique problemas de qualidade dos dados e documente as descobertas em um notebook Jupyter reproduzível.

Tratamento de dados e análise exploratória de dados é uma aula grátis de Machine Learning Academy no CoddyKit. Esta é a aula 2 de 4. Você pode ler a aula completa abaixo gratuitamente — depois pratica ao vivo no navegador com um editor de código integrado e um tutor de IA 24/7. Faz parte do caminho de aprendizado de Machine Learning Academy, e seu progresso é sincronizado entre a web e o app CoddyKit. O curso de Machine Learning Academy inclui 4 aulas no total.

Partes desta aula ainda não foram traduzidas e aparecem em inglês.

What Is Exploratory Data Analysis?

Exploratory Data Analysis (EDA) is the practice of profiling a dataset before modelling to understand its structure, distributions, relationships, and quality issues. Coined by John Tukey, EDA follows a simple principle: let the data speak. Rushing past EDA and jumping straight to modelling is the second most common reason ML projects fail, after poor problem scoping. EDA prevents you from building models on faulty foundations.

Loading and First Inspection

Always start with a structural inspection: how many rows, columns, and what data types? Use df.shape, df.dtypes, df.head(), and df.info(). Look for columns that appear numeric but are stored as object (strings), and columns that appear categorical but are encoded as integers. Mismatched dtypes cause silent bugs downstream when scikit-learn treats an integer-encoded category as a continuous variable.

import pandas as pd
import numpy as np

# Load dataset
df = pd.read_csv('customer_churn.csv')

print('Shape:', df.shape)
print('\nData types:')
print(df.dtypes)
print('\nFirst 5 rows:')
print(df.head())
print('\nSummary info:')
df.info()

Univariate Analysis: Distributions

Univariate analysis examines one variable at a time. For numeric features, plot histograms and compute summary statistics (mean, median, std, skewness). Highly skewed distributions (skewness > 2) often benefit from a log transform before modelling. For categorical features, plot bar charts of value counts. Categories that appear in fewer than 1% of rows may cause issues with one-hot encoding and stratified splitting.

import matplotlib.pyplot as plt
import seaborn as sns

fig, axes = plt.subplots(1, 2, figsize=(12, 4))

# Numeric: histogram of account age
df['account_age_days'].hist(bins=40, ax=axes[0])
axes[0].set_title('Account age distribution')
axes[0].set_xlabel('Days')

# Categorical: churn rate by plan type
df.groupby('plan_type')['churned'].mean().plot(kind='bar', ax=axes[1])
axes[1].set_title('Churn rate by plan type')
axes[1].set_ylabel('Churn rate')

plt.tight_layout()
plt.savefig('univariate.png', dpi=150)

Summary Statistics Table

df.describe() produces count, mean, std, min, quartiles, and max for every numeric column. Examine it carefully: a max value orders of magnitude above the 99th percentile signals outliers. A min of zero in a 'days since last purchase' column may mean the customer purchased today — or it may be a sentinel for missing data. Understanding these edge cases prevents silent errors in downstream preprocessing.

stats = df.describe(percentiles=[0.01, 0.25, 0.5, 0.75, 0.99])
print(stats.T)  # transpose for readability

# Flag suspicious columns
for col in df.select_dtypes(include='number').columns:
    skew = df[col].skew()
    pct99 = df[col].quantile(0.99)
    max_val = df[col].max()
    if max_val > 5 * pct99:
        print(f'OUTLIER WARNING: {col} — max ({max_val:.1f}) >> 99th pct ({pct99:.1f}), skew={skew:.2f}')

Missing Value Analysis

Missing values must be profiled before imputation decisions are made. Compute the percentage of nulls per column with df.isnull().mean(). Columns with more than 50% missing may need to be dropped entirely. Understand the mechanism of missingness: is it missing completely at random (MCAR), or is it missing not at random (MNAR) — e.g., customers who churned deleted their account info? MNAR missingness is itself informative and should be encoded as a binary indicator.

missing = df.isnull().mean().sort_values(ascending=False)
missing_pct = missing[missing > 0] * 100
print('Missing value percentages:')
print(missing_pct.round(1))

import matplotlib.pyplot as plt
missing_pct.plot(kind='barh', figsize=(8, 5))
plt.xlabel('% missing')
plt.title('Missing values by column')
plt.tight_layout()
plt.savefig('missing.png', dpi=150)

Bivariate Analysis: Correlations

Bivariate analysis examines relationships between pairs of variables. For numeric-numeric relationships, compute a correlation matrix and visualise it as a heat map with seaborn.heatmap. Correlations above 0.95 between two features signal multicollinearity — both features carry almost identical information, so one can be dropped without losing predictive power. Also compute point-biserial correlations between numeric features and the binary target to identify the most predictive features upfront.

import seaborn as sns
import matplotlib.pyplot as plt

numeric_df = df.select_dtypes(include='number')
corr = numeric_df.corr()

plt.figure(figsize=(10, 8))
sns.heatmap(corr, annot=True, fmt='.2f', cmap='coolwarm', center=0)
plt.title('Correlation matrix')
plt.tight_layout()
plt.savefig('corr_heatmap.png', dpi=150)

# Highest corr pairs (excluding self-correlation)
high_corr = (
    corr.where(np.triu(np.ones(corr.shape), k=1).astype(bool))
    .stack().abs().sort_values(ascending=False)
)
print('Top correlated pairs:')
print(high_corr.head(5))

Target Variable Analysis

Always analyse the target variable separately. For binary classification, compute the positive class rate (df['churned'].mean()). Rates below 5% or above 95% indicate severe imbalance that affects algorithm choice and evaluation metrics. For regression targets, check normality — skewed targets often benefit from a log transform before training, especially for tree-based models which are immune, but critical for linear regression.

target = 'churned'
class_dist = df[target].value_counts(normalize=True)
print('Class distribution:')
print(class_dist)
print(f'\nPositive class rate: {df[target].mean():.3f}')
print(f'Imbalance ratio: {class_dist.max() / class_dist.min():.1f}:1')

# Visual
df[target].value_counts().plot(kind='bar')
import matplotlib.pyplot as plt
plt.title('Target class distribution')
plt.ylabel('Count')
plt.xticks([0, 1], ['Retained', 'Churned'], rotation=0)
plt.tight_layout()
plt.savefig('target_dist.png', dpi=150)

Outlier Detection and Treatment

Outliers can distort model training, especially for distance-based models (KNN, SVM) and linear regression. Use the IQR method (flag values outside [Q1 - 1.5·IQR, Q3 + 1.5·IQR]) or Z-score (flag values with |z| > 3) for initial detection. For each flagged outlier, investigate: is it a data entry error, a legitimate extreme value, or a sensor malfunction? Legitimate extreme values should be kept; errors should be corrected or removed.

def iqr_outliers(series):
    Q1, Q3 = series.quantile(0.25), series.quantile(0.75)
    IQR = Q3 - Q1
    lower, upper = Q1 - 1.5 * IQR, Q3 + 1.5 * IQR
    outlier_mask = (series < lower) | (series > upper)
    return outlier_mask, lower, upper

for col in df.select_dtypes(include='number').columns:
    mask, lo, hi = iqr_outliers(df[col])
    n_out = mask.sum()
    if n_out > 0:
        print(f'{col}: {n_out} outliers ({n_out/len(df)*100:.1f}%), '
              f'valid range=[{lo:.2f}, {hi:.2f}]')

Feature-Target Relationship Plots

For classification tasks, visualise how each numeric feature's distribution differs between classes using a violin plot or box plot grouped by the target. Features where the distributions strongly separate the two classes are likely to be predictive. For categorical features, a grouped bar chart of churn rate per category value quickly reveals which categories are associated with higher risk.

import seaborn as sns
import matplotlib.pyplot as plt

fig, axes = plt.subplots(1, 2, figsize=(12, 4))

# Numeric feature vs target: violin plot
sns.violinplot(
    data=df, x='churned', y='account_age_days',
    palette=['#2196F3', '#F44336'], ax=axes[0]
)
axes[0].set_xticklabels(['Retained', 'Churned'])
axes[0].set_title('Account age by churn status')

# Categorical feature vs target: bar plot
df.groupby('plan_type')['churned'].mean().plot(kind='bar', ax=axes[1])
axes[1].set_title('Churn rate by plan type')
axes[1].set_ylabel('Churn rate')
plt.tight_layout()
plt.savefig('feature_target.png', dpi=150)

Documenting EDA Findings

EDA findings must be documented in a reproducible Jupyter notebook shared with the team. At minimum, document: columns dropped and why, imputation decisions per column, outlier treatment, class imbalance magnitude, top predictive features, and any data quality issues escalated to the data engineering team. This notebook becomes the data quality section of the eventual model card and is invaluable when debugging production regressions months later.

# EDA findings summary (add as a markdown cell in the notebook)
findings = {
    'dropped_columns': ['customer_id (identifier)', 'last_login_ip (PII, not predictive)'],
    'imputation': {
        'days_since_support_contact': 'median (12% missing, MCAR)',
        'contract_end_days': 'mode (3% missing)'
    },
    'outliers': 'total_spend: 14 values > $50k capped at 99th percentile ($48,200)',
    'class_imbalance': '8.3% churn rate — use SMOTE or class_weight=balanced',
    'top_features': ['days_since_last_purchase', 'total_spend_90d', 'support_tickets'],
    'escalations': ['contract_type column has 847 unmapped legacy codes — check with engineering']
}
for key, val in findings.items():
    print(f'{key}: {val}')

Automated EDA Tools

For large datasets with hundreds of features, manual EDA is impractical. ydata-profiling (formerly pandas-profiling) generates an interactive HTML report with distributions, correlations, missing values, and outlier alerts for every column with a single function call. sweetviz produces comparison reports across train/test splits or target class segments. Use these as a starting point, but always follow up with domain-specific custom plots for the most important features.

# ydata-profiling: one line EDA report
# pip install ydata-profiling
from ydata_profiling import ProfileReport

profile = ProfileReport(
    df,
    title='Customer Churn EDA Report',
    explorative=True
)
profile.to_file('eda_report.html')
print('Report saved to eda_report.html')

# sweetviz: compare train vs test distribution
# pip install sweetviz
import sweetviz as sv
report = sv.analyze(df, target_feat='churned')
report.show_html('sweetviz_report.html')

Quick Check

Test your understanding of Machine Learning with Python concepts from this lesson.

Lesson Recap

In this lesson you learned: EDA profiles distributions, relationships, missing values, and outliers before any modelling, bivariate analysis (correlations, feature-target plots) identifies the most predictive features, and EDA findings must be documented in a reproducible notebook to guide preprocessing decisions and serve as the data quality record. Next up we run a model selection tournament to compare five algorithms on the same processed dataset.

Perguntas Frequentes

A aula “Tratamento de dados e análise exploratória de dados” é grátis?

Sim — o texto completo de “Tratamento de dados e análise exploratória de dados” é grátis para ler aqui na web. Para praticá-la interativamente (um editor de código integrado e um tutor de IA 24/7) e desbloquear o restante do curso de Machine Learning Academy, atualize para CoddyKit PRO. O curso de Machine Learning Academy inclui 4 aulas no total.

O que vou aprender em “Tratamento de dados e análise exploratória de dados”?

Carregue um conjunto de dados bruto, analise distribuições e correlações, identifique problemas de qualidade dos dados e documente as descobertas em um notebook Jupyter reproduzível. Você pratica Machine Learning Academy com código prático que executa diretamente no navegador, e um tutor de IA 24/7 responde suas dúvidas enquanto trabalha na aula.

Preciso ter experiência prévia para começar Machine Learning Academy?

Nenhuma experiência prévia é necessária. Machine Learning Academy no CoddyKit é estruturado para alunos iniciantes até avançados, então você pode começar aqui ou desde o início e aprender no seu ritmo. Esta é a aula 2 de 4.

Quanto tempo leva a aula “Tratamento de dados e análise exploratória de dados”?

A maioria das aulas CoddyKit leva cerca de 5–10 minutos. Cada uma é compacta e interativa, então você faz progresso constante e retoma exatamente de onde parou entre web e app.

Posso escrever e executar código nesta aula de Machine Learning Academy?

Sim. Cada aula de Machine Learning Academy inclui um editor de código integrado, então você escreve e executa código real direto no navegador e recebe feedback de IA instantaneamente — nenhuma configuração local necessária.

Todas as aulas deste curso

  1. Delimitação do projeto: definição do problema e dos critérios de sucesso
  2. Tratamento de dados e análise exploratória de dados
  3. Torneio de seleção de modelos: compare cinco algoritmos
  4. Empacotamento, documentação e apresentação do modelo final
← Voltar para Machine Learning Academy