📐 Guia de Estudo Completo

Análise de
Componentes Principais

Da intuição geométrica à implementação em produção — tudo que você precisa para dominar PCA.

estatística multivariada redução de dimensionalidade álgebra linear scikit-learn visualização machine learning
rolar

O que é PCA e por que importa?

Quando um fenômeno tem muitas variáveis, poucos padrões fundamentais costumam governá-lo. PCA é o instrumento para descobri-los.

"A maior parte da variabilidade do mundo real está concentrada em pouquíssimas dimensões — o PCA é o microscópio que as revela." — Karl Pearson, 1901 (adaptado)

A Análise de Componentes Principais (PCA — Principal Component Analysis) é uma técnica de redução de dimensionalidade que transforma um conjunto de variáveis possivelmente correlacionadas em um conjunto menor de variáveis não correlacionadas chamadas componentes principais.

Criada por Karl Pearson em 1901 para problemas de biometria, hoje alimenta aplicações em genômica, reconhecimento facial, compressão de imagens, finanças quantitativas, climatologia, espectroscopia e todo domínio que lide com dados de alta dimensionalidade.

1901 Ano de criação — Karl Pearson
O(np²) Complexidade computacional
SVD Algoritmo interno (sklearn)

Motivação: a maldição da dimensionalidade

Imagine medir 50 variáveis de cada espécime de uma expedição botânica: comprimento da folha, largura, espessura, concentração de clorofila, ângulo de inserção... A maioria dessas variáveis é correlacionada. Há muito menos do que 50 "padrões independentes" na natureza. PCA encontra esses padrões e descarta a redundância.

✅ Situações ideais

Variáveis contínuas correlacionadas · Alta dimensionalidade · Visualização de clusters · Pré-processamento para ML · Remoção de ruído · Compressão de dados · Feature engineering

❌ Evitar quando...

Variáveis categóricas ou binárias · Relações não-lineares complexas · Interpretabilidade é crítica · n < p sem regularização · Dados esparsos extremos

💡
Ideia central: PCA responde à pergunta — "quais são as direções de maior variabilidade nos dados?" Essas direções capturam a estrutura essencial com mínima perda de informação.

Visualizando a rotação dos eixos

PCA é, essencialmente, uma rotação do sistema de coordenadas para alinhar com as direções de maior espalhamento dos dados.

Considere dados biométricos: altura e envergadura de braços em 200 atletas. Esses dois atributos são fortemente correlacionados — pessoas mais altas tendem a ter maior envergadura. No gráfico de dispersão, os pontos formam uma elipse inclinada. PCA rotaciona os eixos para alinhar com essa elipse:

Demonstração Interativa — Rotação PCA
Ajuste a correlação, o número de amostras e o nível de ruído para ver como PC1 e PC2 se adaptam
0.70
100
0.18
Dados originais PC1 — maior variância PC2 — menor variância
🔭
Observe: com correlação alta (≥ 0.85), PC1 captura quase toda a variância — compressão eficiente para 1 dimensão. Com correlação próxima de zero, PC1 e PC2 têm variâncias similares — nenhuma dimensão é dispensável.

A metáfora da sombra

Segure um lápis obliquamente sob uma lâmpada. Dependendo do ângulo, a sombra projetada no papel pode ser quase tão longa quanto o lápis, ou quase um ponto. PCA encontra o ângulo que projeta a maior sombra possível — capturando a máxima variância em cada dimensão reduzida. Cada componente seguinte é perpendicular ao anterior e captura a maior variância restante.

A álgebra por trás do PCA

Covariância, autovalores e autovetores — três conceitos que formam a espinha dorsal do algoritmo.

3.1 — Matriz de Covariância

Para um dataset com p variáveis e n observações (centralizadas), a matriz de covariância Σ é p×p:

Elemento (i, j) da matriz de covariância
\[ \sigma_{ij} = \frac{1}{n-1} \sum_{k=1}^{n} (x_{ki} - \bar{x}_i)(x_{kj} - \bar{x}_j) \]

Exemplo concreto — dados climáticos de 4 variáveis: temperatura média, umidade relativa, velocidade do vento, precipitação mensal.

Matriz de covariância — estações meteorológicas
\[ \Sigma = \begin{pmatrix} 4.2 & 3.1 & -1.8 & 0.3 \\ 3.1 & 3.9 & -1.5 & 0.5 \\ -1.8 &-1.5 & 2.6 &-0.4 \\ 0.3 & 0.5 & -0.4 & 1.1 \end{pmatrix} \]

σ(temp, umidade) = 3.1 → covariam positivamente · σ(temp, vento) = -1.8 → relação inversa

Interpretação dos elementos

Diagonal σᵢᵢ

Variância da variável i — o quanto ela se dispersa em torno da própria média.

Fora diagonal σᵢⱼ > 0

As variáveis i e j crescem juntas — correlação positiva.

Fora diagonal σᵢⱼ < 0

Quando i cresce, j tende a diminuir — correlação negativa.

3.2 — Autovalores e Autovetores

O PCA resolve a equação de autovalores/autovetores da matriz de covariância:

Equação fundamental do PCA
\[ \Sigma \mathbf{v} = \lambda \mathbf{v} \]

λ — Autovalor (eigenvalue)

Representa a variância capturada pelo componente principal correspondente. Os autovalores são ordenados do maior para o menor: λ₁ ≥ λ₂ ≥ … ≥ λₚ.

v — Autovetor (eigenvector)

Representa a direção do componente principal no espaço das variáveis originais. São os loadings — os pesos de cada variável original no componente.

3.3 — Exemplo numérico passo a passo

Considere duas medidas de qualidade do ar: concentração de PM2.5 e NO₂, já centralizadas:

Matriz de covariância 2×2
\[ \Sigma = \begin{pmatrix} 9.0 & 6.3 \\ 6.3 & 6.0 \end{pmatrix} \]

Resolvendo det(Σ − λI) = 0:

Cálculo dos autovalores
\[ (9 - \lambda)(6 - \lambda) - (6.3)^2 = 0 \] \[ \lambda^2 - 15\lambda + 14.31 = 0 \] \[ \lambda_1 \approx 14.05 \qquad \lambda_2 \approx 0.95 \]
📊
Interpretação: a proporção de variância explicada por PC1 é 14.05 / (14.05 + 0.95) = 93.7%. Com apenas 1 dimensão conseguimos representar 93.7% da variabilidade dos dois poluentes — compressão eficiente.

3.4 — Relação com SVD

Na prática computacional, o sklearn implementa PCA via Decomposição em Valores Singulares (SVD), numericamente mais estável que calcular autovalores diretamente:

SVD da matriz de dados centralizada X
\[ X = U \, S \, V^T \]

U = scores das amostras (n×k)  ·  S = valores singulares  ·  V = loadings (p×k)

Os autovetores da matriz de covariância são as colunas de V. Os autovalores são os quadrados dos valores singulares divididos por (n−1).

Passo a passo do PCA

Seis etapas que transformam dados brutos em componentes principais interpretáveis.

  1. Centralizar os dados (subtrair a média)

    Para cada variável, subtraia sua média. Move o centro de massa para a origem. Obrigatório — sem centralização, o PCA mede deslocamento, não variância.

    \[ X_c = X - \bar{X} \]
  2. Padronizar as variáveis (dividir pelo desvio padrão)

    Se as variáveis têm escalas diferentes (temperatura em °C vs. precipitação em mm), a de maior escala domina artificialmente. Use StandardScaler para variância unitária. Exceção: se todas estão na mesma unidade e você quer preservar diferenças de magnitude.

  3. Calcular a matriz de covariância

    Computa Σ = XᵀX / (n−1). O sklearn faz isso internamente via SVD — você não precisa calculá-la explicitamente. Com p variáveis, Σ é sempre p×p simétrica positiva semidefinida.

  4. Decompor em autovalores e autovetores

    Resolve Σv = λv para todos os p pares (λ, v). Retorna p autovetores ortogonais ordenados pelo autovalor correspondente — do maior para o menor.

  5. Selecionar os k componentes principais

    Escolha k com base na variância acumulada desejada (tipicamente 80–95%) ou pelo "cotovelo" no scree plot. Os k autovetores com maiores autovalores formam a matriz de projeção W de dimensão (p × k).

  6. Projetar os dados no novo espaço

    Multiplique os dados centralizados pela matriz de projeção. O resultado são os scores — coordenadas de cada observação no espaço dos k componentes principais.

    \[ Z = X_c \cdot W_k \qquad Z \in \mathbb{R}^{n \times k} \]

Quantos componentes manter?

O scree plot e a variância acumulada são os dois instrumentos diagnósticos fundamentais do PCA.

A proporção de variância explicada pelo k-ésimo componente é:

Variância explicada
\[ \text{VE}_k = \frac{\lambda_k}{\sum_{i=1}^{p} \lambda_i} \]
Scree Plot Interativo — Variância por Componente
Selecione um domínio de dados e observe como a estrutura de variância muda. Barras azuis = componentes retidos (≥ threshold 85%).
Variância por componente
Variância acumulada

Critérios para escolha de k

Escolha o menor k tal que a variância acumulada ultrapasse o threshold desejado. Em dados ruidosos (sensores, imagens) costuma-se usar 80%. Em dados estruturados limpos (genômica, espectroscopia), pode-se exigir 95%+. A escolha do threshold é uma decisão de domínio, não matemática pura.
Plote os autovalores em ordem decrescente e identifique onde a curva "quebra" e achata (o cotovelo). Mantenha os componentes acima do cotovelo. A regra de Kaiser sugere manter apenas componentes com autovalor > 1.0 quando as variáveis estão padronizadas — pois um autovalor menor que 1 significa que o componente captura menos variância do que uma única variável padronizada.
Treine o modelo downstream (classificador, regressão, clustering) com diferentes valores de k e avalie via cross-validation. O k ótimo maximiza a métrica de interesse no conjunto de validação. Mais trabalhoso, mas matematicamente sólido e não depende de threshold arbitrário.
Em estudos científicos, mantém-se apenas os componentes que fazem sentido interpretativo — onde os loadings revelam um padrão reconhecível no domínio. Em dados climáticos, por exemplo, um PC que carrega positivamente temperatura e negativamente precipitação pode ser interpretado como "índice de aridez" — e vale mais do que um componente com 3% de variância extra sem interpretação clara.

Interpretando os componentes

Loadings são os autovetores — eles revelam o "significado" de cada componente principal em termos das variáveis originais.

O que são loadings?

Cada componente principal é uma combinação linear das variáveis originais. Os coeficientes são os loadings:

PC1 como combinação linear das variáveis originais
\[ \text{PC1} = w_{11} x_1 + w_{21} x_2 + \cdots + w_{p1} x_p \]

wᵢ₁ = loading da variável i no componente 1  ·  valores entre −1 e +1  ·  |w| alto = alta influência

Heatmap de Loadings — Dados Morfométricos de Pinguins

Exemplo clássico em biologia: medidas morfométricas de 3 espécies de pinguins (comprimento do bico, profundidade do bico, comprimento da nadadeira, massa corporal).

🐧
Interpretação: PC1 carrega positivamente todas as medidas físicas — é um fator de tamanho geral. PC2 diferencia bico vs. nadadeira/massa — um fator de forma do corpo. PC3 isola a profundidade do bico — diferencia espécies com bicos rasos vs. profundos.

Biplot interativo — Pinguins

O biplot sobrepõe os scores (posição de cada indivíduo no espaço PCA) e os vetores de loading (direção das variáveis originais). Vetores paralelos = variáveis correlacionadas; vetores perpendiculares = variáveis independentes.

Biplot — Dados morfométricos de pinguins (PC1 × PC2)
Pontos = indivíduos por espécie · Vetores = variáveis originais
Adelie Chinstrap Gentoo → vetores de loading
🗺️
Como ler um biplot: indivíduos próximos a um vetor têm valor alto naquela variável. Vetores longos = variável bem representada no plano PCA. Vetores paralelos = correlacionadas. Vetores perpendiculares ≈ independentes. Espécies separadas nos quadrantes revelam diferenças morfológicas reais.

PCA em Python — do zero à produção

Código completo e comentado com scikit-learn, pandas e matplotlib usando datasets reais e públicos.

7.1 — Pipeline básico com dados climáticos

pca_climatico.py
import numpy as np
import pandas as pd
from sklearn.preprocessing import StandardScaler
from sklearn.decomposition import PCA
import matplotlib.pyplot as plt

# ============================================================
# Dados: médias mensais de 5 variáveis climáticas
# em 12 estações meteorológicas do sul do Brasil
# ============================================================
dados = {
    'temp_media':    [22.1,18.3,25.4,14.2,28.7,16.9,23.5,19.8,26.1,13.5,21.0,24.3],
    'umidade_rel':   [72,68,80,65,75,71,77,69,82,63,70,78],
    'precip_mm':     [130,95,180,70,120,85,150,100,200,60,110,160],
    'vel_vento':     [12,18,9,22,7,20,11,16,8,25,14,10],
    'insolacao_h':   [210,185,240,160,260,175,220,195,250,150,200,235],
}
df = pd.DataFrame(dados)

# ============================================================
# 1. PADRONIZAÇÃO — variâncias muito diferentes entre variáveis
#    (temp em °C vs precipitação em mm vs vento em km/h)
# ============================================================
scaler = StandardScaler()
X_scaled = scaler.fit_transform(df)

# ============================================================
# 2. PCA DIAGNÓSTICO — todos os componentes para análise
# ============================================================
pca_full = PCA()
pca_full.fit(X_scaled)

var_ratio = pca_full.explained_variance_ratio_
cumvar    = np.cumsum(var_ratio)

print("Variância explicada por componente:")
for i, v in enumerate(var_ratio):
    print(f"  PC{i+1}: {v*100:.1f}%  (acumulado: {cumvar[i]*100:.1f}%)")

# Escolha automática: menor k com variância acumulada >= 85%
k = int(np.argmax(cumvar >= 0.85)) + 1
print(f"\nComponentes para >=85% variância: k = {k}")

# ============================================================
# 3. PCA FINAL com k componentes
# ============================================================
pca = PCA(n_components=k)
scores = pca.fit_transform(X_scaled)  # shape: (12, k)

# ============================================================
# 4. LOADINGS — a chave da interpretação
# ============================================================
loadings = pd.DataFrame(
    pca.components_.T,   # transposta: (n_features, k)
    index=df.columns,
    columns=[f'PC{i+1}' for i in range(k)]
)
print("\nLoadings (autovetores):")
print(loadings.round(3))

7.2 — Scree plot profissional

scree_plot.py
def plot_scree(pca_full, k_chosen, title="Scree Plot"):
    fig, axes = plt.subplots(1, 2, figsize=(12, 4))

    var  = pca_full.explained_variance_ratio_ * 100
    cum  = np.cumsum(var)
    n    = len(var)
    x    = range(1, n + 1)

    colors = ['#6c8ef5' if i < k_chosen else '#2a3050' for i in range(n)]
    axes[0].bar(x, var, color=colors, edgecolor='none', width=0.6)
    axes[0].set_xlabel('Componente Principal')
    axes[0].set_ylabel('Variância Explicada (%)')
    axes[0].set_title('Scree Plot')
    for i, v in enumerate(var):
        axes[0].text(i + 1, v + 0.5, f'{v:.1f}%', ha='center', fontsize=9)

    axes[1].plot(x, cum, 'o-', color='#f5a623', lw=2, ms=6)
    axes[1].axhline(85, color='#4fc3a1', ls='--', lw=1.5, label='85% threshold')
    axes[1].axvline(k_chosen, color='#6c8ef5', ls=':', lw=1.5, label=f'k = {k_chosen}')
    axes[1].set_ylim(0, 105)
    axes[1].set_xlabel('Número de Componentes')
    axes[1].set_ylabel('Variância Acumulada (%)')
    axes[1].set_title('Variância Acumulada')
    axes[1].legend()

    plt.suptitle(title, fontsize=13, fontweight='bold')
    plt.tight_layout()
    plt.show()

7.3 — Biplot com matplotlib

biplot.py
def biplot(scores, loadings, labels, feature_names,
           groups=None, palette=None, scale=2.5):
    """
    Biplot: scores das amostras + vetores de loading sobrepostos.
    groups: array de rótulos de grupos (ex: espécies, tratamentos)
    """
    fig, ax = plt.subplots(figsize=(9, 7))

    # Plotar amostras
    if groups is not None:
        for g in np.unique(groups):
            mask = groups == g
            ax.scatter(scores[mask, 0], scores[mask, 1],
                       label=g, s=60, alpha=0.8)
    else:
        ax.scatter(scores[:, 0], scores[:, 1], s=60, alpha=0.8)

    # Rótulos opcionais
    if labels is not None:
        for i, lbl in enumerate(labels):
            ax.annotate(lbl, (scores[i,0]+.05, scores[i,1]+.05),
                        fontsize=7, color='#666')

    # Vetores de loading
    for j, feat in enumerate(feature_names):
        vx = loadings.iloc[j, 0] * scale
        vy = loadings.iloc[j, 1] * scale
        ax.annotate("", xy=(vx, vy), xytext=(0, 0),
                    arrowprops=dict(arrowstyle="->", color='crimson', lw=1.8))
        ax.text(vx*1.08, vy*1.08, feat, color='crimson', fontsize=9, ha='center')

    ax.axhline(0, lw=0.5, ls='--', color='gray')
    ax.axvline(0, lw=0.5, ls='--', color='gray')
    ax.set_xlabel(f'PC1 ({pca.explained_variance_ratio_[0]*100:.1f}%)')
    ax.set_ylabel(f'PC2 ({pca.explained_variance_ratio_[1]*100:.1f}%)')
    ax.legend(title='Espécie')
    ax.set_title('Biplot PCA — Morfometria de Pinguins')
    plt.tight_layout()
    plt.show()

7.4 — Pipeline correto para ML (prevenindo data leakage)

pipeline_ml.py
from sklearn.pipeline import Pipeline
from sklearn.model_selection import train_test_split, cross_val_score
from sklearn.ensemble import RandomForestClassifier

# Exemplo: classificar espécies de íris com PCA + RandomForest
# (o mesmo padrão aplica-se a qualquer dataset)
from sklearn.datasets import load_iris
iris = load_iris()
X, y = iris.data, iris.target

X_train, X_test, y_train, y_test = train_test_split(
    X, y, test_size=0.2, random_state=42, stratify=y
)

# Pipeline garante fit APENAS no treino — sem data leakage
pipe = Pipeline([
    ('scaler', StandardScaler()),
    ('pca',    PCA(n_components=2)),
    ('clf',    RandomForestClassifier(n_estimators=100, random_state=42)),
])

# Cross-validation no pipeline inteiro — correto
cv_scores = cross_val_score(pipe, X_train, y_train, cv=5, scoring='accuracy')
print(f"Acurácia CV: {cv_scores.mean():.3f} ± {cv_scores.std():.3f}")

pipe.fit(X_train, y_train)
print(f"Acurácia test: {pipe.score(X_test, y_test):.3f}")

# Acessar PCA dentro do pipeline
pca_in_pipe = pipe.named_steps['pca']
print(f"Variância explicada: {pca_in_pipe.explained_variance_ratio_.round(3)}")

7.5 — Reconstrução e erro de compressão

reconstrucao.py
# PCA como autoencoder linear: comprimir → reconstruir
# Aplicação: compressão de espectros de reflectância (sensoriamento remoto)

def compression_error(X_scaled, n_components):
    pca_k = PCA(n_components=n_components)
    scores_k = pca_k.fit_transform(X_scaled)
    X_reconstructed = pca_k.inverse_transform(scores_k)
    mse = np.mean((X_scaled - X_reconstructed) ** 2)
    return mse

# Avaliar erro para diferentes k
ks = range(1, X_scaled.shape[1] + 1)
errors = [compression_error(X_scaled, k) for k in ks]

plt.plot(ks, errors, 'o-', color='#6c8ef5')
plt.xlabel('Número de componentes k')
plt.ylabel('MSE de reconstrução')
plt.title('Erro de compressão PCA')
plt.yscale('log')  # log scale para ver a curva melhor
plt.show()

# k → p: erro → 0 (reconstrução perfeita com todos os componentes)

Os 7 erros que todo mundo comete

Erros que podem invalidar completamente sua análise — e como evitá-los.

⛔ Armadilha 1 — Não padronizar antes do PCA

O problema: em dados climáticos, precipitação (0–500 mm) tem variância bruta muito maior que temperatura (10–35 °C). Sem padronização, precipitação domina completamente o PCA, independente de sua relevância real para o fenômeno estudado.

A solução: use StandardScaler() antes de PCA(). Exceção: se todas as variáveis estão na mesma unidade (ex: expressão de genes em log-CPM) e você quer preservar diferenças de magnitude.

⛔ Armadilha 2 — Data leakage no scaler/PCA

O problema: ao fazer fit_transform(X_todo) antes de dividir treino/teste, o scaler e o PCA "veem" o conjunto de teste durante o ajuste. Isso infla artificialmente a performance — o modelo aprendeu estatísticas do teste sem saber.

A solução: use sklearn.Pipeline. O pipeline garante que toda a cadeia de transformação faz fit apenas nos dados de treino.

⚠️ Armadilha 3 — Interpretar scores como variáveis originais

O problema: dizer "espécimes com PC1 alto têm maior temperatura" pode ser correto ou totalmente errado, dependendo dos loadings. PC1 é uma combinação linear de todas as variáveis — você precisa verificar os loadings antes de qualquer afirmação.

A solução: sempre analise pca.components_ (loadings) e nomeie cada componente com base nos loadings dominantes antes de interpretar os scores.

⚠️ Armadilha 4 — Aplicar PCA em variáveis categóricas

O problema: encodar categorias como números (tipo de solo: argiloso=0, arenoso=1, humoso=2) cria uma falsa estrutura métrica. A distância entre categorias não é real e distorce a covariância.

A solução: para dados mistos (contínuos + categóricos), use prince.FAMD (Factor Analysis of Mixed Data) ou MCA (Multiple Correspondence Analysis) para dados puramente categóricos.

⚠️ Armadilha 5 — Ignorar outliers

O problema: PCA maximiza variância — e outliers aumentam artificialmente a variância. Uma única medição errada de um sensor (spike) pode torcer o primeiro componente principal inteiramente na sua direção, escondendo a estrutura real dos dados.

A solução: antes do PCA, detecte outliers via z-score (|z| > 3) ou distância de Mahalanobis. Para dados com muitos outliers, considere RobustPCA (baseado em decomposição Low-Rank + Sparse).

💡 Armadilha 6 — Usar threshold fixo sem critério de domínio

O problema: "80% de variância" é um atalho útil, mas não universal. Em imagens hiperespectrais de satélite, 80% pode ainda incluir ruído significativo. Em dados de expressão gênica de células únicas, 95% pode ser insuficiente.

A solução: combine pelo menos dois critérios: variância acumulada + cotovelo do scree plot + validação downstream na tarefa de interesse.

💡 Armadilha 7 — PCA em dados intrinsecamente não-lineares

O problema: PCA só captura estrutura linear. Dados em manifolds curvos (trajetórias celulares no desenvolvimento, órbitas planetárias perturbadas, clusters em espiral) são mal representados por projeções lineares.

A solução: use Kernel PCA (estrutura não-linear com kernel RBF), UMAP (para visualização preservando estrutura global) ou t-SNE (para visualização de clusters).

Quando PCA não é suficiente

O ecossistema de redução de dimensionalidade vai muito além do PCA clássico — cada técnica tem seu nicho.

Técnica Tipo Quando usar Custo Interpretabilidade
PCA clássico Linear Baseline, dados contínuos correlacionados, compressão Baixo O(np²) Alta (loadings)
Kernel PCA Não-linear Estrutura circular, espiral ou radial; kernel RBF/poly/sigmoid Alto O(n²) Baixa
t-SNE Não-linear Visualização de clusters em 2D/3D; não para features de ML Alto O(n log n) Muito baixa
UMAP Não-linear Visualização preservando estrutura global; mais rápido que t-SNE Médio Baixa
ICA Linear Separação de fontes independentes (EEG, áudio, fMRI) Médio Média
NMF Linear Dados não-negativos: imagens, texto (TF-IDF), espectros Raman Médio Alta (aditiva)
FAMD Misto Dados mistos contínuo + categórico; generalização do PCA Médio Alta
Autoencoder Neural Grandes volumes, estrutura arbitrária, compressão não-linear Muito alto Muito baixa
🧠
Curiosidade matemática: um autoencoder linear (sem funções de ativação não-lineares) aprende exatamente o mesmo subespaço que o PCA. Uma rede neural com gradiente descendente "redescobre" a matemática de 1901 — a otimização de mínimos quadrados converge para a mesma solução independentemente do método.

Árvore de decisão para escolha da técnica

Dados mistos (numérico + categórico)? → FAMD / MCA
└─ Só numérico:
    Estrutura linear? → PCA
    └─ Estrutura não-linear:
        Objetivo = visualização de clusters? → UMAP ou t-SNE
        Objetivo = features para ML? → Kernel PCA ou Autoencoder
        Dados não-negativos (espectros, imagens)? → NMF
        Separar fontes independentes (EEG, fMRI)? → ICA

PCA em domínios reais

Quatro aplicações concretas que ilustram a versatilidade do PCA em ciência, engenharia e medicina.

Caso 1 — Genômica: GWAS e estrutura populacional

Em estudos de associação genômica ampla (GWAS), matrizes de genótipos chegam a 500.000+ SNPs por indivíduo. PCA nos genótipos revela a estrutura populacional: os primeiros 2–3 componentes separam populações europeias, africanas e asiáticas no espaço PCA. Esse resultado é usado para controlar efeitos de confundimento por ancestralidade nos modelos de associação.

genomica_pca.py
# Dados: matriz genótipo (n_amostras × n_SNPs) codificada 0/1/2
# PCA para controle de estratificação populacional
from sklearn.decomposition import PCA

# TruncatedSVD é mais eficiente para matrizes esparsas gigantes
from sklearn.decomposition import TruncatedSVD

# Para matrizes densas menores, PCA padrão funciona bem
pca_geno = PCA(n_components=10)          # primeiros 10 PCs
scores_geno = pca_geno.fit_transform(X_genotipos_centered)

# Os PCs são usados como covariáveis no modelo de regressão logística
# para controlar estratificação (Price et al., 2006 — Nature Genetics)
pcs_df = pd.DataFrame(
    scores_geno,
    columns=[f'PC{i}' for i in range(1, 11)]
)
# Adicionar ao modelo: logit(doença ~ SNP_alvo + PC1 + ... + PC10)

Caso 2 — Sensoriamento remoto: compressão de imagens hiperespectrais

Sensores como o AVIRIS capturam imagens em 224 bandas espectrais. Bandas adjacentes são altamente correlacionadas. PCA reduz para 10–15 componentes preservando >99% da variância, comprimindo o volume de dados em 15× e melhorando a performance de classificadores de cobertura do solo.

🛰️
Por que funciona tão bem em imagens hiperespectrais? Bandas espectrais adjacentes medem reflectância em comprimentos de onda muito próximos — são quase idênticas. A matriz de covariância tem estrutura de bloco. PC1 captura a reflectância global ("brilho"), PC2 a inclinação do espectro ("cor"), PCs seguintes capturam feições específicas de materiais (água, vegetação, minerais).

Caso 3 — Finanças quantitativas: fatores de risco

Em uma carteira de 500 ações, os retornos diários são altamente correlacionados (movimentos de mercado). PCA nos retornos revela fatores latentes: PC1 é tipicamente o "fator de mercado" (sobe quando o mercado sobe), PC2 diferencia setor de tecnologia do financeiro, etc. Essa é a base do modelo de Arbitrage Pricing Theory (APT).

fatores_risco.py
# Retornos diários de 100 ações — shape: (252_dias, 100_acoes)
# PCA revela os fatores de risco latentes

retornos_scaled = StandardScaler().fit_transform(retornos_df)
pca_fin = PCA(n_components=5)
fatores = pca_fin.fit_transform(retornos_scaled)

loadings_fin = pd.DataFrame(
    pca_fin.components_.T,
    index=retornos_df.columns,    # tickers das ações
    columns=[f'Fator_{i}' for i in range(1, 6)]
)

# Interpretação típica:
# Fator_1: cargas positivas em todas as ações → fator de mercado (beta)
# Fator_2: tech positivo, financeiro negativo → rotação de setor
# Fator_3: large-caps vs small-caps → fator de tamanho (SMB)

# Variância explicada — quanto cada fator explica do risco total
print(pca_fin.explained_variance_ratio_.round(3))

Caso 4 — Neurociência: análise de atividade neural em população

Registros simultâneos de centenas de neurônios produzem dados de altíssima dimensão. PCA revela a dinâmica de população: os primeiros componentes capturam trajetórias coletivas de ativação durante tarefas motoras ou cognitivas, revelando a geometria do espaço de estados neurais muito mais claramente do que analisar neurônios individualmente.

✅ Padrão geral de aplicação

Em todos esses domínios, o padrão é o mesmo: dados de alta dimensão com estrutura de covariância → padronizar → PCA → interpretar os primeiros componentes no contexto do domínio → usar scores como features reduzidas ou visualizações. A técnica é a mesma; o que muda é o significado dos componentes.

Teste seu conhecimento

Quatro questões conceituais para consolidar o que você aprendeu.

1. Você aplica PCA em dados de qualidade do ar com 8 variáveis (PM2.5, PM10, NO₂, SO₂, CO, O₃, temperatura, umidade) sem padronizar. PC1 captura 78% da variância e é dominado por CO (que varia de 0 a 50.000 μg/m³). O que isso provavelmente indica?

  • CO é genuinamente o poluente mais importante para a qualidade do ar nessa região.
  • CO domina porque tem variância bruta muito maior (escala absoluta), não por importância real.
  • Os dados de qualidade do ar têm intrinsecamente apenas 1 dimensão relevante.
  • Há muitos outliers no dataset que precisam ser removidos antes do PCA.

2. Em um biplot de dados morfométricos de pinguins, os vetores de "comprimento_nadadeira" e "massa_corporal" formam um ângulo de aproximadamente 15°. O que isso revela?

  • As variáveis são fortemente correlacionadas — pinguins com maior massa tendem a ter nadadeiras mais longas.
  • As variáveis têm correlação negativa — nadadeiras longas implicam menor massa.
  • As variáveis são independentes — não há relação entre elas no plano PCA.
  • A variável com vetor mais curto é menos importante para o modelo.

3. Você está treinando um classificador de espécies de plantas usando 30 variáveis morfológicas. Qual é o fluxo CORRETO para incorporar PCA no pipeline?

  • Aplicar PCA.fit_transform() em todo o dataset, depois dividir em treino e teste.
  • Padronizar todo o dataset com StandardScaler, dividir em treino/teste, depois ajustar PCA só no treino.
  • Usar sklearn.Pipeline(StandardScaler → PCA → Classificador) com fit() apenas no treino.
  • Retreinar PCA do zero em cada fold do cross-validation manualmente, fora do Pipeline.

4. Em dados de expressão gênica (RNA-seq) de 200 amostras e 20.000 genes, você roda PCA e obtém: PC1 = 35% variância, PC2 = 18%, PC3 = 8%, ... Qual seria a melhor interpretação dos primeiros componentes nesse contexto?

  • PC1 representa o gene mais expresso nas amostras.
  • PC1 pode capturar efeito de batch; PCs seguintes podem separar tipos celulares ou condições biológicas.
  • PCA não é adequado para dados de expressão gênica pois são dados de contagem.
  • 35% em PC1 indica que os dados têm estrutura insuficiente e PCA não se aplica.

Termos e conceitos-chave

Referência rápida para os termos técnicos essenciais do PCA.

Componente Principal (PC)
Nova variável gerada pelo PCA — combinação linear das variáveis originais que maximiza a variância capturada e é ortogonal a todos os outros PCs.
Autovalor (Eigenvalue) λ
Escalar que indica a variância capturada pelo componente correspondente. Maior autovalor = componente mais importante. Soma de todos os λ = variância total.
Autovetor (Eigenvector) v
Vetor unitário que define a direção de um componente principal. Satisfaz Σv = λv. Os autovetores são mutuamente ortogonais (perpendiculares).
Loading
Coeficiente do autovetor — indica quanto cada variável original contribui para um componente. Valores entre −1 e +1. Alto |loading| = alta influência da variável no componente.
Score
Coordenada de uma observação no espaço dos componentes principais. Obtido por Z = X_c · W_k. É a "projeção" do dado original no novo espaço reduzido.
Matriz de Covariância (Σ)
Matriz p×p simétrica positiva semidefinida. Diagonal = variâncias. Fora da diagonal = covariâncias. É o ponto de partida da decomposição PCA.
Scree Plot
Gráfico dos autovalores ordenados de forma decrescente. O "cotovelo" da curva sugere o número ótimo de componentes a reter. Nome vem do acúmulo de detritos na base de uma falésia (scree).
Biplot
Visualização que sobrepõe scores das amostras (pontos) e vetores de loading das variáveis no mesmo plano PCA. Permite ver estrutura de grupos e correlações entre variáveis simultaneamente.
Variância Explicada
Proporção da variância total capturada por um PC: λₖ / Σλᵢ. A variância acumulada soma os k primeiros componentes. Critério principal para escolha de k.
SVD — Decomposição em Valores Singulares
Algoritmo interno do sklearn para PCA: X = USVᵀ. Mais estável numericamente que calcular autovalores diretamente. Os autovetores são as colunas de V.
Erro de Reconstrução
MSE entre os dados originais e a versão reconstruída após compressão: ||X - X̂||². Aumenta com menor k. Usado para detecção de anomalias e avaliação de compressão.
Ortogonalidade
Propriedade fundamental: os componentes principais são perpendiculares entre si (produto interno = 0). Garante que são linearmente independentes e não correlacionados.
Data Leakage
Contaminação do modelo com informação do conjunto de teste durante transformações (scaler, PCA). Infla artificialmente métricas de validação. Prevenido com sklearn Pipeline.
Regra de Kaiser
Critério de seleção de componentes: reter apenas PCs com autovalor > 1.0 (quando variáveis padronizadas). Justificativa: autovalor < 1 significa que o PC captura menos variância do que uma variável original sozinha.