<jupyter_start><jupyter_text>PCA (Principal Component Analysis)--- IntroduçãoSão cada vez mais comuns a elevada quantidade de variáveis explicativas, porém quanto maior a quantidade de variáveis, mais difícil a interpretação da solução. A análise de componentes principais (Principal Component Analysis, PCA) é a técnica para reduzir a dimensionalidade desses conjuntos de dados, aumentando a interpretabilidade concomitante a minimização da perda de informações. Isso é feito criando novas variáveis não correlacionadas, preservando o máximo de variabilidade possível. Preservar o máximo de variabilidade possível, se traduz em encontrar novas variáveis que são funções lineares daquelas no conjunto de dados original.Em regressão linear, geralmente determinamos a linha de melhor ajuste ao conjunto de dados, mas aqui no PCA, determinamos várias linhas ortogonais entre si no espaço n-dimensional, de melhor ajuste ao conjunto de dados. Ortogonal significa que essas linhas estão em ângulo reto entre si. O número de dimensões será o mesmo que o número de variáveis. Por exemplo, um conjunto de dados com 3 variáveis terá espaço tridimensional.A análise de componentes principais é essencialmente apenas uma transformação de coordenadas. Considerando dados bidimencionais, por exemplo, os dados originais são plotados em um eixo X' e um eixo Y'. O método de PCA procura girar esses dois eixos para que o novo eixo X fique ao longo da direção da variação máxima nos dados. Como a técnica exige que os eixos sejam perpendiculares, em duas dimensões, a escolha de X' determinará Y'. Você obtém os dados transformados lendo os valores x e y deste novo conjunto de eixos, X 'e Y'. Para mais de duas dimensões, o primeiro eixo está na direção da maior variação; o segundo, na direção da segunda maior variação; e assim por diante. Procedimento para uma análise de componentes principaisConsidere a matriz $X_{n \times p}$ composta por observações de $p$ características de $n$ indivíduos de uma população. As características observadas são representadas pelas variáveis $X_1, X_2, X_3, \cdots, X_p$.$$  X = \left [ \begin{array}{ccccc}x_{11} & x_{12} & x_{13} & \cdots & x_{1p}\\ x_{21} & x_{22} & x_{23} & \cdots & x_{2p}\\ \vdots & \vdots & \vdots & \cdots & \vdots  \\x_{n1} & x_{n2} & x_{n3} & \cdots & x_{np}\\    \end{array} \right ] $$ Passo 1Para dados em que as variáveis $X_i$ estão em escalas diferentes (por exemplo $X_1$ representa o valor de um carro e $X_2$ o consumo de gasolina), é necessário padronizar os dados. Isso porque os componentes são influenciados pela escala das variáveis, justamente porque as matrizes de covariâncias, $\Sigma$ ou $\hat{\Sigma} = S$, são sensíveis à escala de um par de variáveis. Considere  $\bar{x_j}$ a média da variável $X_j$; $s(X_j)$ o desvio padrão de $X_j$; sendo $i = 1, 2,3,4,\cdots, n$ e $j = 1, 2,3,4,\cdots, p$. Com isso, a padronização pode ser realizada por meio da equação abaixo: - Média 0 e desvio padrão 1: $$ x'_{ij}= \frac{x_{ij}-\bar{X_j}}{s(X_j)} $$  Passo 2Calcular a matriz de **covariância** ou **correlação**. Caso as variáveis estejam em escalas diferentes, é possível calcular a matriz de correlação nos dados originais. Esta possibilidade se deve ao fato de que a matriz de covariâncias das variáveis padronizadas é igual a matriz de correlação das variáveis originais. $$  S = \left [ \begin{array}{ccccc}\hat{Var}(x_1) & \hat{Cov}(x_1x_2) & \hat{Cov}(x_1x_3) & \cdots & \hat{Cov}(x_1x_p)\\ \hat{Cov}(x_2x_1) &\hat{Var}(x_2)& \hat{Cov}(x_2x_3) & \cdots & \hat{Cov}(x_2x_p)\\ \vdots & \vdots & \vdots & \cdots & \vdots  \\\hat{Cov}(x_px_1) & \hat{Cov}(x_px_2)  & \hat{Cov}(x_px_3)  & \cdots & \hat{Var}(x_p)\\    \end{array} \right ] $$$$  R = \left [ \begin{array}{ccccc}1 & r(x_1x_2) & r(x_1x_3) & \cdots & r(x_1x_p)\\ r(x_2x_1) & 1 & r(x_2x_3) & \cdots & r(x_2x_p)\\ \vdots & \vdots & \vdots & \cdots & \vdots  \\r(x_px_1) & r(x_px_2)  & r(x_px_3)  & \cdots & 1\\    \end{array} \right ] $$Em que:$$ \begin{array}{ccc}\hat{Var}(x_j) = \frac{\sum_{i=1}^{n}(x_{ij}-\bar{x}_j}{n-1}, & \hat{Cov}(x_{j1},x_{j2}) = \frac{\sum_{i=1}^n(x_{ij1}-\bar{x_{j1}})(x_{ij2}-\bar{x_{j2}})}{n-1}, &r(x_{j1},x_{j2}) = \frac{\hat{Cov}(x_{j1},x_{j2})}{S_{xj1}S_{xj2}}   \end{array} $$ Passo 3As componentes principais são determinadas através da equação característica da matriz S ou R:$$det[R - \lambda I]= 0 $$Em que $I$ é a matriz identidade de dimensão $p\times p$. Se R ou S tem posto completo igual a $p$, então $det[R - \lambda I]= 0$, que pode ser reescrito como $\mid R - \lambda I \mid = 0$, terá $p$ soluções. Lembrando que ter posto completo significa que nenhuma coluna é combinação linear de outra.Considere que $\lambda_1,\lambda_2,\lambda_3, \cdots, \lambda_p$ sejam as raízes da equação característica de R ou S, então temos que  $\lambda_1 > \lambda_2 > \lambda_3 > \cdots, \lambda_p$. Chamamos $\lambda_i$ de autovalor. Além disso, para cada autovalor há um autovetor $\tilde{a}_i$ associado.$$  \tilde{a}_i = \left [ \begin{array}{c}a_{i1}\\ a_{i2}\\ \vdots \\a_{ip} \\    \end{array} \right ] $$O cálculo do autovetor $\tilde{a}_i$, pode ser realizado considerando a seguinte propriedade:$$ R\tilde{a}_i =  \lambda_i \tilde{a}_i $$Este resultado deve ser normalizado:$$ a_i = \frac{\tilde{a}_i }{\mid \tilde{a}_i  \mid}$$desta forma a soma dos quadrados dos coeficientes é igual a 1 e são ortogonais entre si.  Passo 4O cálculo da i-ésima componente principal é dado por:$$Z_i = a_{i1}X_1 + a_{i2}X_2 + a_{i3}X_3 + \cdots + a_{ip}X_p $$em que $a_{i1}$ são as componetes do autovetor $a_i$ associado ao autovalor $\lambda_i$.  Carregando o Dataset e Realizando uma Análise Exploratória dos Dados---<jupyter_code># Bibliotecas
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import seaborn as sns
from sklearn.datasets import load_breast_cancer
# Carregando dataset do load_breast_cancer
data = load_breast_cancer()
type(data)
data['data']
pd.DataFrame(data['data'])
data.keys()
data['feature_names']
df = pd.DataFrame(data['data'], columns=data['feature_names'])
df.head()
data['target']
df.head()
df['target'] = data['target']
df.head()<jupyter_output><empty_output><jupyter_text>Passo 1: Padronização do nosso conjunto de dados<jupyter_code># Separando apenas as features para transformar (X)
X = df.drop('target', axis=1)
X.head()
from sklearn.preprocessing import StandardScaler
scaler = StandardScaler()
scaler.fit(X) # FIT é calcular a média e a variância de cada uma das variáveis.
scaler.mean_
scaler.var_
X_scaled = scaler.transform(X)
X_scaled # Transformou em média ZERO e desvio padrão UM
pd.DataFrame(X_scaled).describe()<jupyter_output><empty_output><jupyter_text>Resumindo a utilização do StandardScaler...<jupyter_code># OUTRO MÉTODO - MAIS RÁPIDO!!
scaler = StandardScaler()
X_scaled = scaler.fit_transform(X)
X_scaled<jupyter_output><empty_output><jupyter_text>Passo 2: Calcular a matriz de covariância [...]  Utilizando a biblioteca do Sklearn1. Padronizar as *features*2. Aplicar o PCA  Aplicando o PCAhttps://scikit-learn.org/stable/modules/generated/sklearn.decomposition.PCA.html<jupyter_code>from sklearn.decomposition import PCA
pca = PCA()
pca.fit(X_scaled) # Esse FIT vai calcular os novos eixos<jupyter_output><empty_output><jupyter_text>Obtendo a matriz de dados transformada<jupyter_code>X_pca = pca.transform(X_scaled)  # Vai padronizar
X_pca # As features convertidas em novos eixos com outros valores
X.head() # Features originais
X_pca = pd.DataFrame(X_pca, columns=[f'C{i}' for i in range(1, X.shape[1] + 1)])
X_pca<jupyter_output><empty_output><jupyter_text>Analisando a variância explicada<jupyter_code>pca.explained_variance_
pca.explained_variance_ratio_ # Variância em percentuais
pca.explained_variance_ratio_.cumsum() # Soma acumulada
plt.figure(figsize=(20, 8))
plt.plot(X_pca.columns, pca.explained_variance_ratio_.cumsum())
plt.bar(X_pca.columns, pca.explained_variance_ratio_)<jupyter_output><empty_output><jupyter_text>Realizando a transformada inversa<jupyter_code>pd.DataFrame(X_scaled)
X_inverted = pca.inverse_transform(X_pca)
pd.DataFrame(X_inverted)
X_original = scaler.inverse_transform(X_inverted)
pd.DataFrame(X_original)
X.head()<jupyter_output><empty_output><jupyter_text>Aplicando o PCA com otimização de variáveis<jupyter_code>pca = PCA(n_components=0.95) # Corte as minhas variáveis para obter 95% das informações das originais
X_pca_optimized = pca.fit_transform(X_scaled)
X_pca_optimized.shape
X_pca_optimized.shape<jupyter_output><empty_output>
{'fraction_non_alphanumeric': 0.1181380039967086, 'fraction_numerical': 0.013988480075232162, 'mean_word_length': 5.232967032967033, 'pattern_counts': {'":': 0, '<': 33, '<?xml version=': 0, '>': 36, 'https://': 1, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'chain_length': '8', 'dir': 'jupyter-structured-clean-dedup', 'id': '5188', 'license': 'MIT', 'n_tokens_mistral': 3343, 'n_tokens_neox': 3224, 'n_words': 962, 'path': 'PCA.ipynb', 'repo_name': 'fabiobarreto-data-science/Data-Science---Let-s-Code', 'size': '8507'}