PCA na mão e no Python

Leandro Cruvinel
8 min readOct 30, 2019

--

PCA, ou principal component analysis é uma técnica para reduzir a dimensão de um conjunto de dados preservando, de certa forma, suas propriedades. Executar essa técnica na mão ou sem ajuda de funções prontas é um bom exercício para aprender a fundo o que está por trás desse processo. Nesse tutorial faremos um exemplo de PCA na mão, sempre conferindo as contas com Python e, depois, faremos o mesmo exemplo usando a biblioteca Scikit-learn.

Photo by William Iven on Unsplash

Pequeno exemplo de PCA para fazer na mão

Como utilizaremos o Python para conferir nossas contas, importaremos as bibliotecas necessárias.

Os códigos serão apresentados por imagens por ser mais produtivo produzir o post dessa forma. Uma versão deste post, com código copiáveis, pode ser encontrada nesse link.

Utilizaremos as seguintes matrizes para esse trabalho:

A matriz X representa as features, enquanto y representa o target. Declararemos essas matrizes no Python:

Precisaremos das médias de cada coluna de X. Para o cálculo da média da coluna i basta fazer a seguinte conta:

com n sendo o número de linhas da matriz X. Podemos conferir as contas no Python usando a biblioteca numpy:

Nossa própria tarefa é determinar a matriz de covariância. Para isso, vamos usar uma matriz M auxiliar. Para determinar M subtraia a média da coluna i da coluna respectiva. Como no nosso exemplo todas as entradas de M estão multiplicadas por 1/3, para ficar mais elegante, colocamos 1/3 em evidência.

Para realizar a mesma conta no Python, use o código a seguir:

A matriz de covariância é de X é dada por:

onde n é o número de linhas de X.

Logo,

No Python:

Próximo passo é determinar auto-valores e auto-vetores da matriz de covariância C. Os auto-valores 𝜆 de C são raizes de

onde I é a matriz identidade.

Cada auto-valor 𝜆 tem auto-vetores associados. Apesar de auto-vetores nunca serem nulos, se incluírmos o vetor nulo no conjunto dos auto-vetores associados e chamarmos esse novo conjunto de 𝑉(𝜆), temos que 𝑉𝜆 é o conjunto solução do seguinte sistema:

Tomaremos geradores unitários de 𝑉(1) e de 𝑉(1/3), a saber, tomaremos os seguintes auto-vetores:

Essa escolha não é única e isso pode dar pequenas diferenças nos resultados finais.

No Python:

Obtemos o seguinte resultado:

Agora, ordenaremos os auto-valores do maior para o menor. Isso é necessário apenas se não tiverem ordenados dessa forma.

Nosso próximo passo é calcular o quanto cada componente (auto-vetores) estão representando (de certa forma) a variabilidade dos nossos dados. Para isso usaremos duas medidas.

A variância explicada de cada auto-valor 𝜆 é dada por:

A variância explicada acumulada de cada auto-valor 𝜆 é a sobra das variâncias explicadas de todos auto-valores até 𝜆 considerando a ordem do maior para o maior e incluindo o próprio 𝜆.

Em Python:

Vejamos de forma sumarizada que temos até o momento:

Obtemos:

Bom, isso é tudo! Considerando os dados originais como pares ordenados em ℝ², pois X possui apenas duas colunas, ao mudar da base canônica para a base composta pelos auto-vetores encontrados, teremos uma nova representação do conjunto X. Graficamente fica da seguinte forma:

Se compararmos com o original:

Vimos que os vetores foram rotacionados 45º no sentido anti-horário.

Os códigos para a criação das duas figuras acima, respectivamente, são:

e

  • Os dados originais foram rotacionados por um ângulo de 45º uma vez que os auto-vetores são perpendiculares e obtidos dos eixos x e y por uma rotação de 45º no sentido anti-horário.
  • Nossos dados possuiam 2 colunas, mas poderiam possuir bem mais. Além disso escolhermos 2 componentes para visualização gráfica, esse número também pode ser mais, desde que seja menor que o número de colunas.
  • A ideia do PCA é diminuir a dimensão do conjunto de dados original escolhendo um número menor de componentes para projeção sobre estas.
  • O processo de redução de dimensão facilita processamento e armazenamento de dados.

Fazendo com uso de biblioteca

Agora vejamos o mesmo exemplo utilizando a biblioteca Scikit-learn.

Isso é tudo, agora vejamos as informações para fins de comparação.

Obtemos:

Observe que, como a escolha dos auto-vetores não é única, o algoritmo implementado na biblioteca Scikit-learn escolheu auto-vetores diferentes dos nossos. Mas, isso não é problema, pois só houve inversão de sinal. Logo, quando fizermos a visualização gráfica da mudança de coordenada, haverá uma inversão da figura. Vejamos o código para verificar tal fato:

E o gráfico fica:

Perfeito! Mas essa técnica serve para reduzir dimensões. Como nosso exemplo é apenas para fins educacionais, é hora de aprender com exemplos reais como usar o poderoso PCA!

PCA no conjunto de dados Iris

No próximo exemplo utilizaremos PCA para reduzir o conjunto de dados Iris de 4 para 2 features. O conjunto pode ser baixado no repositório UCI. O link encontra-se nas referências.

Faremos novamente passo a passo. O código é análogo ao código usado no exemplo anterior.

Para imprimir as informações sumarizadas:

Então

Com duas componentes temos uma variância explicada cumulativa de 97%. Utilizaremos então, apenas duas componentes. Para visualizar as informações graficamente utilizamos o seguinte código:

Obtemos então

Experimente trabalhar com outros conjuntos de dados com um maior número de features.

Vejamos agora o mesmo exemplo utilizando a biblioteca Scikit-learn.

PCA no conjunto de dados Iris com biblioteca

Novamente, carregamos o conjunto de dados.

Repetimos então o processo, só que, desta vez, utilizando o PCA já pronto.

Na próxima seção veremos outra aplicação.

PCA para redução de dimensão em imagens

Outra aplicação é a redução de dimensão em imagens. Para esse exemplo, escolhemos a imagem Pássaro mineiro barulhento retirada do site Pixabay. A imagem foi transformada em escala de cinza utilizando o software GIMP.

Primeiro, carregaremos a imagem.

Observe que a matriz tem 1920 linhas e 1899 colunas. Aplicaremos, em seguida, a técnica PCA.

O número 0.99 passado como parâmetro para o métodos PCA diz que queremos um número de componentes que nos garanta 99% de variância explicada cumulativa. Observe que para isso, utilizou-se 145 componentes. Isso é uma redução imensa, uma vez que a original possuia 1899 colunas. Queremos ver, caso necessário recuperar a imagem, como essas imagens ficam com a dimensão reduzida. Para isso serão necessários duas funções auxiliares.

A primeira função reduz a imagem X mantendo var_exp de variância explicada cumulativa. Compararemos 3 valores: 0.99, 0.95 e 0.90.

A segunda função mostra o gráfico. Utilizaremos ela para comparar as imagens obtidas com a original.

Por fim, obtemos a seguinte figura:

Referências

--

--

Leandro Cruvinel
Leandro Cruvinel

Written by Leandro Cruvinel

Math Professor | Data Scientist | Web developer

Responses (3)