Análise multivariada com dados de solo, clima, espécies e economia.
knitr::opts_chunk$set(warning = FALSE, message = FALSE)
library(tidyverse)
## ── Attaching core tidyverse packages ──────────────────────── tidyverse 2.0.0 ──
## ✔ dplyr 1.1.4 ✔ readr 2.1.5
## ✔ forcats 1.0.0 ✔ stringr 1.5.1
## ✔ ggplot2 4.0.1 ✔ tibble 3.2.1
## ✔ lubridate 1.9.4 ✔ tidyr 1.3.1
## ✔ purrr 1.2.0
## ── Conflicts ────────────────────────────────────────── tidyverse_conflicts() ──
## ✖ dplyr::filter() masks stats::filter()
## ✖ dplyr::lag() masks stats::lag()
## ℹ Use the conflicted package (<http://conflicted.r-lib.org/>) to force all conflicts to become errors
library(FactoMineR)
library(factoextra)
## Welcome! Want to learn more? See two factoextra-related books at https://goo.gl/ve3WBa
library(cluster)
library(psych)
##
## Anexando pacote: 'psych'
##
## Os seguintes objetos são mascarados por 'package:ggplot2':
##
## %+%, alpha
library(GGally)
## Registered S3 method overwritten by 'GGally':
## method from
## +.gg ggplot2
library(plotly)
##
## Anexando pacote: 'plotly'
##
## O seguinte objeto é mascarado por 'package:ggplot2':
##
## last_plot
##
## O seguinte objeto é mascarado por 'package:stats':
##
## filter
##
## O seguinte objeto é mascarado por 'package:graphics':
##
## layout
library(corrplot)
## corrplot 0.95 loaded
dados <- read.csv("dataset_agroamazonia.csv")
# Disponivel em: https://raw.githubusercontent.com/leocbc/ANALISE-MULTIVARIADA/refs/heads/main/dataset_agroamazonia.csv
head(dados)
## Area_ID Latitude Longitude Especie Solo Prod_Anual_Ton Biomassa_t_ha
## 1 A001 -2.685649 -60.43496 Cacau Argissolo 29.96 18.58
## 2 A002 -3.342177 -59.53927 Cacau Argissolo 28.55 17.27
## 3 A003 -3.437038 -59.86948 Cacau Gleissolo 29.39 13.39
## 4 A004 -2.917896 -60.26652 Cupuaçu Neossolo 23.59 25.01
## 5 A005 -2.648850 -58.97968 Cacau Latossolo 29.33 14.68
## 6 A006 -3.123030 -59.17999 Castanha Neossolo 31.95 21.11
## Teor_Carbono_pct Indice_Sustentabilidade Custo_Producao_R..ha
## 1 45.07 0.67 2906.81
## 2 50.30 0.89 3225.89
## 3 58.72 0.69 2408.95
## 4 45.16 0.42 3433.00
## 5 52.10 0.65 3891.29
## 6 51.03 0.81 3507.04
## Preco_Venda_R..Ton CH4_emissao_kg_ha N2O_emissao_kg_ha Temp_Solo_C
## 1 919.17 57.96 6.06 25.52
## 2 700.74 79.71 6.06 30.29
## 3 970.64 79.79 4.12 25.43
## 4 1059.98 80.59 6.51 30.12
## 5 1207.18 57.19 6.36 26.99
## 6 904.19 42.22 4.34 30.27
## Umidade_Solo_pct Precipitacao_mm
## 1 44.28 2044.60
## 2 29.09 2443.79
## 3 40.50 1864.04
## 4 47.10 2354.28
## 5 44.94 2263.93
## 6 39.40 2699.78
summary(dados)
## Area_ID Latitude Longitude Especie
## Length:80 Min. :-3.774 Min. :-61.19 Length:80
## Class :character 1st Qu.:-3.294 1st Qu.:-60.47 Class :character
## Mode :character Median :-2.976 Median :-59.95 Mode :character
## Mean :-2.998 Mean :-59.97
## 3rd Qu.:-2.709 3rd Qu.:-59.44
## Max. :-2.223 Max. :-58.81
## Solo Prod_Anual_Ton Biomassa_t_ha Teor_Carbono_pct
## Length:80 Min. :14.93 Min. :12.31 Min. :37.78
## Class :character 1st Qu.:24.49 1st Qu.:17.07 1st Qu.:46.47
## Mode :character Median :29.02 Median :19.34 Median :49.73
## Mean :28.97 Mean :19.59 Mean :49.48
## 3rd Qu.:32.97 3rd Qu.:22.59 3rd Qu.:52.18
## Max. :50.71 Max. :28.23 Max. :58.93
## Indice_Sustentabilidade Custo_Producao_R..ha Preco_Venda_R..Ton
## Min. :0.3200 Min. :1648 Min. : 637.5
## 1st Qu.:0.5150 1st Qu.:3258 1st Qu.: 818.8
## Median :0.6650 Median :3672 Median : 901.4
## Mean :0.6636 Mean :3633 Mean : 898.8
## 3rd Qu.:0.8125 3rd Qu.:4050 3rd Qu.: 971.0
## Max. :0.9700 Max. :4952 Max. :1207.2
## CH4_emissao_kg_ha N2O_emissao_kg_ha Temp_Solo_C Umidade_Solo_pct
## Min. : 30.90 Min. :1.650 Min. :23.92 Min. :22.83
## 1st Qu.: 55.36 1st Qu.:3.605 1st Qu.:26.98 1st Qu.:40.12
## Median : 60.46 Median :4.725 Median :27.93 Median :44.41
## Mean : 62.15 Mean :4.660 Mean :27.99 Mean :43.89
## 3rd Qu.: 69.37 3rd Qu.:5.673 3rd Qu.:29.23 3rd Qu.:48.48
## Max. :102.86 Max. :7.800 Max. :33.81 Max. :57.05
## Precipitacao_mm
## Min. :1772
## 1st Qu.:2169
## Median :2380
## Mean :2364
## 3rd Qu.:2566
## Max. :3047
dados_num <- dados %>% select(where(is.numeric))
head(dados_num)
## Latitude Longitude Prod_Anual_Ton Biomassa_t_ha Teor_Carbono_pct
## 1 -2.685649 -60.43496 29.96 18.58 45.07
## 2 -3.342177 -59.53927 28.55 17.27 50.30
## 3 -3.437038 -59.86948 29.39 13.39 58.72
## 4 -2.917896 -60.26652 23.59 25.01 45.16
## 5 -2.648850 -58.97968 29.33 14.68 52.10
## 6 -3.123030 -59.17999 31.95 21.11 51.03
## Indice_Sustentabilidade Custo_Producao_R..ha Preco_Venda_R..Ton
## 1 0.67 2906.81 919.17
## 2 0.89 3225.89 700.74
## 3 0.69 2408.95 970.64
## 4 0.42 3433.00 1059.98
## 5 0.65 3891.29 1207.18
## 6 0.81 3507.04 904.19
## CH4_emissao_kg_ha N2O_emissao_kg_ha Temp_Solo_C Umidade_Solo_pct
## 1 57.96 6.06 25.52 44.28
## 2 79.71 6.06 30.29 29.09
## 3 79.79 4.12 25.43 40.50
## 4 80.59 6.51 30.12 47.10
## 5 57.19 6.36 26.99 44.94
## 6 42.22 4.34 30.27 39.40
## Precipitacao_mm
## 1 2044.60
## 2 2443.79
## 3 1864.04
## 4 2354.28
## 5 2263.93
## 6 2699.78
cor_matrix <- cor(dados_num)
p_matrix <- cor.mtest(dados_num)$p
corrplot(
cor_matrix,
p.mat = p_matrix, # Fornecer a matriz de p-valores
sig.level = 0.05, # Definir o nível de significância
insig = "blank", # Corresponder ao argumento desejado (deixa em branco)
type = "upper", # Exemplo: mostrar apenas a parte superior
order = "hclust",
tl.col = "black",
tl.srt = 45
)
dados_scaled <- scale(dados_num)
heatmap(cor(dados_num))
Calculo da PCA:
pca <- prcomp(dados_scaled)
Gráfico 2D:
fviz_pca_biplot(pca, label="var")
Gráfico 3D:
plot_ly(x=pca$x[,1], y=pca$x[,2], z=pca$x[,3],
type="scatter3d", mode="markers",
color=dados$Especie)
A Análise de Agrupamento (Cluster Analysis) busca descobrir agrupamentos naturais de observações (áreas, no nosso caso) com base em suas similaridades (ou distâncias/dissimilaridades). O método hierárquico cria uma estrutura em árvore (dendrograma), podendo ser aglomerativo (começa com observações individuais) ou divisivo (começa com um único grupo).
A escolha da métrica de distância é crucial, pois ela define o que significa “próximo” ou “similar” no seu conjunto de dados.
A distância Euclidiana entre dois pontos \(\mathbf{x}\) e \(\mathbf{y}\) é:
\[ D_E(\mathbf{x}, \mathbf{y}) = \sqrt{\sum_{i=1}^{n} (x_i - y_i)^2} \]
dados_scaled - é essencial).dist_eucl <- dist(dados_scaled)
A distância Manhattan entre dois pontos \(\mathbf{x}\) e \(\mathbf{y}\) é:
\[ D_M(\mathbf{x}, \mathbf{y}) = \sum_{i=1}^{n} \left| x_i - y_i \right| \]
Explicação da Distância de Manhattan (YouTube)
dist_manh <- dist(dados_scaled, method = "manhattan")
A distância de Mahalanobis é dada por:
\[ D_M(\mathbf{x}) = \sqrt{(\mathbf{x} - \boldsymbol{\mu})^\top \mathbf{S}^{-1} (\mathbf{x} - \boldsymbol{\mu})} \]
dist_mahal <- mahalanobis(dados_scaled, center=FALSE, cov=cov(dados_scaled))
Após a definição da distância, é necessário escolher o método de ligação (linkage), que define como a distância entre grupos de observações é calculada.
hc_ward <- hclust(dist_eucl, method="ward.D2")
hc_complete <- hclust(dist_eucl, method="complete")
hc_single <- hclust(dist_eucl, method="single")
hc_average <- hclust(dist_eucl, method="average")
O dendrograma mostra a sequência de fusão dos clusters. A altura do corte (rect.hclust) define o número final de grupos (k).
Plota o dendrograma usando o método de Ward e traça uma linha para sugerir 4 clusters. A escolha de ‘k’ deve ser baseada em critérios científicos/técnicos
plot(hc_ward, labels=dados$Area_ID)
plot(hc_ward, labels=dados$Area_ID)
rect.hclust(hc_ward, k=4, border=2:5)
O K-Means é um algoritmo de clusterização não hierárquica e particional, o que significa que ele divide um conjunto de dados (N observações) em um número pré-determinado (K) de clusters (agrupamentos). O objetivo é minimizar a variação (distância) dentro de cada cluster. Ele requer a definição prévia do número de clusters (k).
Passo 1: Escolha de K: O usuário deve definir o número de clusters desejados, K.
Passo 2: Centróides Iniciais: O algoritmo seleciona K pontos aleatórios do conjunto de dados para servir como os centróides iniciais dos clusters (representantes ou centros).
Passo 3: Atribuir Pontos: Cada ponto de dado restante é atribuído ao centróide mais próximo com base em uma métrica de distância (geralmente a Distância Euclidiana).
Para cada ponto x, ele é colocado no cluster cujo centróide é o mais próximo.
Passo 4: Recalcular Centróides: Após todos os pontos terem sido atribuídos, o centróide de cada cluster é recalculado. O novo centróide é o ponto médio (média) de todos os pontos de dado atualmente atribuídos àquele cluster
Considerando 4 grupos:
k4 <- kmeans(dados_scaled, 4)
k4
## K-means clustering with 4 clusters of sizes 19, 23, 21, 17
##
## Cluster means:
## Latitude Longitude Prod_Anual_Ton Biomassa_t_ha Teor_Carbono_pct
## 1 0.39111779 -0.7656249 0.4224490 -0.3323734 -0.6313788
## 2 -0.01014312 0.6021894 -0.2118889 0.6609333 -0.2890420
## 3 -0.02064460 -0.2692243 0.2136493 -0.1291240 0.3202340
## 4 -0.39790645 0.3735429 -0.4493954 -0.3632216 0.7011324
## Indice_Sustentabilidade Custo_Producao_R..ha Preco_Venda_R..Ton
## 1 -0.7434415 0.28283088 -0.39258515
## 2 0.3525770 0.29929734 -0.18672704
## 3 0.6689402 -0.65206808 0.63049697
## 4 -0.4724486 0.08445907 -0.08744685
## CH4_emissao_kg_ha N2O_emissao_kg_ha Temp_Solo_C Umidade_Solo_pct
## 1 -0.21601594 -0.6911993 0.21715562 0.34119081
## 2 0.87313408 0.1322675 0.07804069 -0.05439733
## 3 -0.07767496 -0.0209379 -0.94355289 -0.13997704
## 4 -0.84391805 0.6194311 0.81727754 -0.13482170
## Precipitacao_mm
## 1 -0.7253260
## 2 0.2589624
## 3 -0.3473664
## 4 0.8893973
##
## Clustering vector:
## [1] 3 2 3 2 3 4 1 3 1 4 4 2 2 1 3 2 3 1 1 1 3 2 1 1 4 3 2 3 4 2 2 3 3 2 3 3 3 3
## [39] 1 2 2 4 1 2 4 4 1 3 2 4 4 1 2 2 2 1 3 3 1 2 1 1 3 4 1 2 1 4 4 2 3 4 1 2 4 3
## [77] 4 2 4 2
##
## Within cluster sum of squares by cluster:
## [1] 202.5683 233.7776 201.3413 157.1057
## (between_SS / total_SS = 22.6 %)
##
## Available components:
##
## [1] "cluster" "centers" "totss" "withinss" "tot.withinss"
## [6] "betweenss" "size" "iter" "ifault"
Gráfico:
fviz_cluster(k4, data=dados_scaled)
Esse resultado, onde a Soma dos Quadrados (SS) entre clusters (Between_SS) representa 22,5% da Soma Total dos Quadrados (Total_SS), indica o quanto os clusters estão separados em relação à dispersão total dos dados. Ou seja, 22,5% da variância total nos dados foi explicada pela separação dos centróides dos clusters, ou seja, 77,5% da variância total dos dados ainda está contida dentro dos próprios clusters. Essa é a variância que o modelo de clusterização não conseguiu explicar através da separação.
O K-Nearest Neighbors (KNN) é um algoritmo de Aprendizado Supervisionado (necessita de rótulos/classes) e não-paramétrico, usado para classificação.
Quando um novo ponto (\(X_{novo}\)) de dado precisa ser classificado, o KNN executa os seguintes passos:
Passo 1: Definir K: Escolha um valor para K (o número de vizinhos a serem considerados). K é tipicamente um número ímpar para evitar empates na votação.
Passo 2: Calcular Distâncias: Calcule a distância de \(X_{novo}\) para todos os pontos no conjunto de treinamento. A métrica de distância mais comum é a Euclidiana, mas a de Manhattan também é usada.
Passo 3: Encontrar os K Vizinhos: Selecione os K pontos no conjunto de treinamento que possuem a menor distância em relação a \(X_{novo}\)
Passo 4: Votação por Maioria: O \(X_{novo}\) é atribuído à classe (rótulo) que for mais frequente entre esses K vizinhos.
resposta <- dados$Especie
indice <- sample(1:nrow(dados_scaled), size = 0.8 * nrow(dados_scaled))
indice
## [1] 13 73 61 7 53 17 35 41 56 44 69 65 16 6 21 31 55 76 14 15 46 66 71 12 72
## [26] 77 22 52 48 2 1 9 60 78 5 23 18 4 42 45 11 3 64 37 19 75 70 79 51 39
## [51] 59 27 49 43 80 32 29 62 54 50 57 38 40 58
treino_var <- dados_scaled[indice, ] # variáveis (numéricas e padronizadas)
treino_res <- resposta[indice] # Resposta (Especie)
head(treino_var)
## Latitude Longitude Prod_Anual_Ton Biomassa_t_ha Teor_Carbono_pct
## [1,] -0.2555237 -0.5742922 1.1201860 2.1052977 -0.3926804
## [2,] 0.5167360 -0.8270382 1.5162841 -0.9115900 0.2785145
## [3,] 0.6889085 -1.5309047 1.2215134 -1.9101186 -0.3675890
## [4,] 1.9636847 -0.5688907 0.7808927 -1.0367390 -2.2452621
## [5,] 0.4177303 0.3174583 0.7916396 0.2600168 0.8702534
## [6,] -1.3036692 -1.3203358 -1.1919212 0.9230398 0.9350728
## Indice_Sustentabilidade Custo_Producao_R..ha Preco_Venda_R..Ton
## [1,] 0.3953375 0.2626500 0.9277997
## [2,] 1.5858791 1.9310566 -2.1893533
## [3,] -0.5363908 -1.0597421 -0.7115193
## [4,] -1.5198817 1.9321120 0.2439819
## [5,] 0.6023882 1.0469358 0.1064642
## [6,] 1.2235403 -0.6547589 0.2767482
## CH4_emissao_kg_ha N2O_emissao_kg_ha Temp_Solo_C Umidade_Solo_pct
## [1,] 0.71824654 -0.4284167 -0.2342844 1.2380356
## [2,] -0.73046249 -0.8269439 1.0749702 1.7305313
## [3,] 0.21928500 0.6994904 1.9461473 -0.1927624
## [4,] 1.07440185 1.6318937 -0.4334106 -0.5331417
## [5,] 0.12637492 -0.2404322 1.0202105 -0.5376600
## [6,] -0.06460692 -1.1502773 -0.9162916 1.1792975
## Precipitacao_mm
## [1,] 0.6464328
## [2,] -1.9707806
## [3,] -0.7259107
## [4,] -1.3075177
## [5,] 0.8522479
## [6,] 0.9172958
head(treino_res)
## [1] "Cupuaçu" "Castanha" "Cupuaçu" "Cacau" "Castanha" "Açaí"
test_var <- dados_scaled[-indice, ]
test_res <- resposta[-indice]
library(class)
knn_prediction <- knn(
train = treino_var,
test = test_var,
cl = treino_res,
k = 3
)
summary(knn_prediction)
## Açaí Cacau Castanha Cupuaçu
## 5 6 2 3
Compara as classes preditas com as classes reais (do conjunto de teste).
confusion_matrix <- table(Classe_Real = test_res, Classe_Predita = knn_prediction)
confusion_matrix
## Classe_Predita
## Classe_Real Açaí Cacau Castanha Cupuaçu
## Açaí 2 3 0 1
## Cacau 1 2 2 0
## Castanha 2 0 0 0
## Cupuaçu 0 1 0 2
accuracy <- sum(diag(confusion_matrix)) / sum(confusion_matrix)
accuracy
## [1] 0.375