---
title: "Classificazione II (notebook 5)"
author: "Dario Trevisan"
date: "22/10/2025"
output:
  html_notebook:
    toc: true
    toc_depth: 3
    toc_float: true
    theme: readable
    df_print: paged
    download_handler: true
  html_document:
    toc: true
    toc_depth: '3'
    df_print: paged
subtitle: "Statistica II - 750AA"
---



# Classificazione basata su Bayes


In questo notebook R consideriamo i metodi di classificazione basati sulla formula di Bayes: Naive Bayes, LDA (Linear Discriminant Analysis), QDA (Quadratic Discriminant Analysis), regressione logistica, regressione softmax. Utilizzeremo come in altre occasioni dataset generati ma anche dataset reali.


Iniziamo con caricare delle librerie necessarie. Installate i pacchetti se non sono già disponibili.

```{r}
# Carica le librerie necessarie
library(ggplot2)
library(caret) 
library(e1071)  # Per Naive Bayes semplificato
library(naivebayes) # Naive Bayes avanzato
library(MASS)   # Per LDA e QDA
```
## Datasets

Consideriamo 3 datasets: uno generato, uno dal pacchetto ``caret`` relativo a dati di individui per accesso al credito in Germania, e infine i dati sugli infortuni sul lavoro in Toscana. 

### Dataset generato

Generiamo una tabella con $4$ features: 2 di tipo discreto, 2 di tipo numerico e una etichetta binaria, e alleniamo un modello di Naive Bayes su di esso.


```{r}

# features (si può usare anche rbinom)
x1 <- sample( c(TRUE, FALSE), size=200, replace=TRUE, prob=c(0.2, 0.8))
x2 <- sample(  c(TRUE, FALSE), size=50, replace=TRUE, prob=c(0.5, 0.5))
y1 <- sample(  c(TRUE, FALSE), size=200, replace=TRUE, prob=c(0.3, 0.7))
y2 <- sample(  c(TRUE, FALSE), size=50, replace=TRUE, prob=c(0.2, 0.8))
z1 <- rnorm(200, mean=0, sd=1)
z2 <- rnorm(50, mean=2, sd=2)
w1 <- rpois(200, lambda=2)
w2 <- rpois(50, lambda=3)

# labels
data_generated <- data.frame("x" = c(x1, x2), "y"=c(y1, y2), "z"=c(z1, z2), "w"=c(w1, w2), "label"=as.factor(c(rep(-1, 200), rep(1,50))))

head(data_generated)
```

Partizioniamo il dataset in train e test usando il comando ``createDataPartition()`` dal pacchetto ``caret``. Questo campiona in modo casuale come ``sample()`` ma cerca di rispettare la anche distribuzione delle diverse classi.

```{r}
train_index <- createDataPartition(data_generated$label, p = 0.8, list = FALSE)
train_data_generated <- data_generated[train_index, ]
test_data_generated <- data_generated[-train_index, ]

print(paste("Taglia del train set:",nrow(train_data_generated) ))
print(paste("Taglia del test set:", nrow(test_data_generated) ))

```

### Dataset German Credit Data

Nel pacchetto ``caret`` vi sono diversi dataset precaricati. Usiamo il dataset ``GermanCredit`` per addestrare e testare i modelli di classificazione basati su Bayes.

```{r}
data("GermanCredit")

# Visualizza le prime righe del dataset

head(GermanCredit)

```

Suddividiamo il dataset in training e test.

```{r}
set.seed(42)

train_index_gc <- createDataPartition(GermanCredit$Class, p = 0.7, list = FALSE)
train_set_gc <- GermanCredit[train_index_gc, ]
test_set_gc <- GermanCredit[-train_index_gc, ]

print(paste("Taglia del train set:",nrow(train_set_gc) ))
print(paste("Taglia del test set:", nrow(test_set_gc) ))

```

### Dataset Infortuni sul Lavoro in Toscana

I dati sugli infortuni sul lavoro in Italia divisi per regione e con alta granularità sono disponibili online sul sito [Inail Open Data](https://dati.inail.it/portale/it/gli-open-data-inail/dati-storici/infortuni-sul-lavoro.html?page=1). Abbiamo scaricato il dataset relativo ai dati mensili e lo abbiamo salvato in formato CSV nella cartella ``datasets``. Carichiamo il dataset usando il pacchetto ``rio``.


```{r}

library(rio)

infortuni_toscana <- import("datasets/DatiConCadenzaMensileInfortuniToscana.csv")

head(infortuni_toscana)

```
Notiamo che in tutto il dataset comprende `r nrow(infortuni_toscana)` righe. 

Selezioniamo solo alcune colonne di features rilevanti.

```{r}
infortuni_toscana_tidy <- infortuni_toscana[ c(5, 7, 8, 9, 10, 11,13, 15)]


head(infortuni_toscana_tidy)
```

Un obiettivo potrebbe essere di classificare il luogo di nascita (ITALIA/ESTERO) dell'infortunato/a in base alle altre caratteristiche. Trasformiamo quindi la colonna *LuogoNascita* in una feature binaria (*NatItal*) ed estraiamo anche in questo caso il dataset in training e test set.

```{r}
set.seed(42)

infortuni_toscana_tidy$NatItal <- factor(infortuni_toscana_tidy$LuogoNascita == "ITAL")

# rimuoviamo la colonna LuogoNascita
infortuni_toscana_tidy$LuogoNascita <- NULL

# estraiamo train e test set usando la colonnna NatItal come label

train_index_it <- createDataPartition(infortuni_toscana_tidy$NatItal, p = 0.7, list = FALSE)

train_set_it <- infortuni_toscana_tidy[train_index_it, ]
test_set_it <- infortuni_toscana_tidy[-train_index_it, ]

print(paste("Taglia del train set:",nrow(train_set_it) ))
print(paste("Taglia del test set:", nrow(test_set_it) ))


```

## Naive Bayes

Ricordiamo che il classificatore Naive Bayes si basa sulla formula di Bayes, assumendo l'indipendenza condizionale tra le features data la label. La previsione per una nuova osservazione $x=(x_1, x_2, \ldots, x_d)$ viene effettuata calcolando la probabilità a posteriori per ciascuna label $\ell$ e scegliendo la label con la probabilità massima.

Ci sono vari pacchetti che contengono funzioni per calcolare classificatori Naive Bayes in R: ``caret`` (consigliato anche se un po' più lento), ``e1071`` e ``naivebayes``.


### Dataset generato

Vediamoli in azione sul dataset generato. Il comando è nel pacchetto ``caret`` è ``train()`` specificando nelle opzioni il metodo ``method="naive_bayes"``.  Bisogna anche specificare una *formula* come in altri modelli di regressione/classificazione in R (questo è il primo caso che vediamo).


```{r}

# Allenamento del modello Naive Bayes con caret
nb_model_caret <- train(label ~ ., data = train_data_generated, method = "naive_bayes")

#print(nb_model_caret)

# valuta sul test set
nb_pred_caret <- predict(nb_model_caret, test_data_generated)

confusionMatrix(nb_pred_caret, test_data_generated$label)
```

Confrontiamo con il pacchetto ``e1071``.

```{r}
# Allenamento del modello Naive Bayes con e1071

nb_model_e1071 <- naiveBayes(label ~ x+z+w, data = train_data_generated)

# la formula indica che vogliamo prevedere la colonna "label" in funzione di tutte le altre colonne (features). Se avessimo voluto usare solo alcune features ad esempio la colonna x, avremmo scritto ad esempio label ~ x

print(nb_model_e1071)

```

Facciamo ora le previsioni sul test set e calcoliamo la matrice di confusione e l'accuratezza. Il comando è `predict()` come per altri modelli in R. La sintassi richiede di specificare il modello allenato e il dataset su cui fare le previsioni.

```{r}
# Previsione sul test set

nb_pred_e1071 <- predict(nb_model_e1071, test_data_generated)

# il vettore contiene le etichette classificate.
# verifichiamo l'accuratezza e altre metriche con la matrice di confusione

nb_conf_matrix_e1071 <- confusionMatrix(nb_pred_e1071, test_data_generated$label)

print(nb_conf_matrix_e1071)


```


Possiamo anche plottare la curva ROC per valutare la performance del classificatore al variare della soglia di accetazione (o equivalentemente delle probabilità a priori). Usiamo il pacchetto ``pROC`` per calcolare e plottare la curva ROC.

```{r}
library(pROC)

# Ci servono le probabilità predette per la classe positiva, non soltanto l'etichetta predetta. Per questo specifichiamo type="raw" e prendiamo la seconda colonna (corrispondente alla classe +1)

nb_pred_prob_e1071 <- predict(nb_model_e1071, test_data_generated, type = "raw")[, 2]

# Calcola la ROC curve ed esegui un plot usando ggroc (pacchetto pROC). Specifichiamo legacy.axes=TRUE per avere FPR nelle ascisse

roc_nb_e1071 <- roc(test_data_generated$label, nb_pred_prob_e1071)

ggroc(roc_nb_e1071, legacy.axes = TRUE) +
  ggtitle("ROC Curve per Naive Bayes dataset generato") +
  xlab("False Positive Rate") +
  ylab("True Positive Rate")

auc(roc_nb_e1071)

```

Per confronto, applichiamo invece la funzione `naive_bayes()` dal pacchetto `naivebayes`.

```{r}
# Allenamento del modello Naive Bayes con naivebayes

nb_model_nb <- naive_bayes(label ~ ., data = train_data_generated)

print(nb_model_nb)

nb_pred_nb <- predict(nb_model_nb, test_data_generated[1:2])

# Confrontiamo le due previsioni

table(nb_pred_nb, nb_pred_e1071)

```

Applichiamo infine $k$-nn sullo stesso dataset per confronto. Usiamo sempre il pacchetto `caret` per coerenza.

```{r}
# Allenamento del modello KNN


# usiamo il pacchetto caret e cross validation per scegliere il valore di k
knn_model_generated <- train(label ~ ., data = train_data_generated, method="knn", tuneLength=10)

print(knn_model_generated)
plot(knn_model_generated)
```

```{r}
# Previsione sul test set
knn_pred_generated <- predict(knn_model_generated, test_data_generated)

# Matrice di confusione e accuratezza
knn_conf_matrix_generated <- confusionMatrix(knn_pred_generated, test_data_generated$label)

print(knn_conf_matrix_generated)
```
### Dataset German Credit Data

Applichiamo ora Naive Bayes sul dataset German Credit Data. Visualizziamo prima la correlazione tra le features usando una heatmap.

```{r}
library(ggcorrplot)

# Calcola la matrice di correlazione relativa al training set per gli individui con una buona/cattiva classificazione di credito

cor_matrix_gc <- cor(train_set_gc[train_set_gc$Class=="Good", sapply(train_set_gc, is.numeric)])
# Plot della heatmap
ggcorrplot(cor_matrix_gc, 
           method = "square", 
           type = "full", 
           lab = FALSE, 
           title = "Matrice di Correlazione - German Credit Data", tl.cex=0)

```
Applichiamo Naive Bayes per determinare se un individuo ha un buon o cattivo credito (colonna *Class*).

```{r}

# Allenamento del modello Naive Bayes

nb_model_gc <- naiveBayes(Class ~ ., data = train_set_gc)

# Previsione sul test set

nb_pred_gc <- predict(nb_model_gc, test_set_gc)

# Matrice di confusione e accuratezza

nb_conf_matrix_gc <- confusionMatrix(nb_pred_gc, test_set_gc$Class)

print(nb_conf_matrix_gc)


```

Plottiamo anche in questo caso la curva ROC.

```{r}
# attenzione: se usate caret il comando per ottenere le probabilità predette è leggermente diverso "prob" invece di "raw"

nb_pred_prob_gc <- predict(nb_model_gc, test_set_gc, type = "raw")[, 2]

# Calcola la ROC curve ed esegui un plot usando ggroc (pacchetto pROC). Specifichiamo legacy.axes=TRUE per avere FPR nelle ascisse

roc_nb_e1071 <- roc(test_set_gc$Class, nb_pred_prob_gc, levels=c("Good", "Bad"))

ggroc(roc_nb_e1071, legacy.axes = TRUE) +
  ggtitle("ROC Curve per Naive Bayes dataset generato") +
  xlab("False Positive Rate") +
  ylab("True Positive Rate")


```
Ci chiediamo: quali delle features sono più importanti per la classificazione? Usiamo la funzione `varImp()` dal pacchetto `caret` per calcolare l'importanza delle variabili ed eventualmente effettuare una *selezione delle features* per aumentare l'intepretabilità del modello.

```{r}

# Calcola l'importanza delle variabili

var_imp_gc <- varImp(nb_model_gc)

print(var_imp_gc)
```

**Esercizio:** Provate a rifare l'analisi di Naive Bayes usando solo le prime 5 features più importanti (in base alla classifica calcolata sopra). Come cambiano le performance del modello?


### Dataset Infortuni sul Lavoro in Toscana

Applichiamo Naive Bayes sul dataset degli infortuni sul lavoro in Toscana per prevedere se l'infortunato è nato in Italia o all'estero (colonna *NatItal*).

```{r}

# Allenamento del modello Naive Bayes

#nb_model_it <- train(NatItal ~ ., data =train_set_it, method="naive_bayes")

nb_model_it <- naiveBayes(NatItal ~ ., data = train_set_it)
# Previsione sul test set

nb_pred_it <- predict(nb_model_it, test_set_it)

```

Consideriamo la performance con la solita matrice di confusione.

```{r}

# Matrice di confusione e accuratezza

nb_conf_matrix_it <- confusionMatrix(as.factor(nb_pred_it), as.factor(test_set_it$NatItal))

print(nb_conf_matrix_it)

```

```{r}
nb_pred_prob_it <- predict(nb_model_it, test_set_it, type = "raw")[, 2]

# Calcola la ROC curve ed esegui un plot usando ggroc (pacchetto pROC). Specifichiamo legacy.axes=TRUE per avere FPR nelle ascisse


roc_nb_it <- roc(test_set_it$NatItal, nb_pred_prob_it, levels=c("TRUE", "FALSE"))

ggroc(roc_nb_it, legacy.axes = TRUE) +
  ggtitle("ROC Curve per Naive Bayes dataset INAIL") +
  xlab("False Positive Rate") +
  ylab("True Positive Rate")
```


## LDA e QDA

Applichiamo lda al dataset generato. Il comando per allenare il modello è `lda()` dal pacchetto `MASS`. Oppure il comando `train()` dal pacchetto `caret` specificando `method="lda"`.`

```{r}

# Allenamento del modello LDA

lda_model_generated <- lda(label ~ ., data = train_data_generated)
# Previsione sul test set
lda_pred_generated <- predict(lda_model_generated, test_data_generated)
# Matrice di confusione e accuratezza
lda_conf_matrix_generated <- confusionMatrix(lda_pred_generated$class, test_data_generated$label)
print(lda_conf_matrix_generated)


```
Applichiamo anche QDA per confronto. Il comando è ``qda()``.

```{r}

# Allenamento del modello QDA
qda_model_generated <- qda(label ~ ., data = train_data_generated)
# Previsione sul test set
qda_pred_generated <- predict(qda_model_generated, test_data_generated)
# Matrice di confusione e accuratezza
qda_conf_matrix_generated <- confusionMatrix(qda_pred_generated$class, test_data_generated$label)
print(qda_conf_matrix_generated)
```

Confrontiamo le curve ROC per i due modelli (LDA e QDA).

```{r}

lda_pred_prob_generated <- predict(lda_model_generated, test_data_generated)$posterior[, 2]
qda_pred_prob_generated <- predict(qda_model_generated, test_data_generated)$posterior[, 2]
# Calcola la ROC curve ed esegui un plot usando ggroc (pacchetto pROC). Specifichiamo legacy.axes=TRUE per avere FPR nelle ascisse
roc_lda_generated <- roc(test_data_generated$label, lda_pred_prob_generated)
roc_qda_generated <- roc(test_data_generated$label, qda_pred_prob_generated)
ggroc(roc_lda_generated, legacy.axes = TRUE, color="blue") +
  ggtitle("ROC Curve per LDA (blu) e QDA (verde) - Dataset Generato") +
  xlab("False Positive Rate") +
  ylab("True Positive Rate") +
  geom_line(data = ggroc(roc_qda_generated)$data, aes(x = 1 - specificity, y = sensitivity), color="green") +
  theme(legend.position = "bottom") +
  guides(color = guide_legend(override.aes = list(size = 4)))
```
### Dataset German Credit Data

Applichiamo ora LDA sul dataset German Credit Data.

```{r eval=FALSE}
# Allenamento del modello LDA

# se applicato interamente al dataset abbiamo un errore perchè alcune colonne all'interno dei gruppi sono costanti. Questo crea dei problemi nella stima della varianza. Rimuoviamole.

#train_set_gc[c(25, 26, 30, 33, 36,  39, 42, 44)] <- NULL

gc_tidy <- train_set_gc[1:10]

lda_model_gc <- train(Class ~ ., data = gc_tidy, method="lda")
# Previsione sul test set
lda_pred_gc <- predict(lda_model_gc, test_set_gc[1:10])

# Matrice di confusione e accuratezza
lda_conf_matrix_gc <- confusionMatrix(lda_pred_gc, test_set_gc$Class)
print(lda_conf_matrix_gc)

```

Plottiamo anche in questo caso la curva ROC (sovrapponendola a quella di Naive Bayes per confronto).

```{r eval=FALSE}

lda_pred_prob_gc <- predict(lda_model_gc, test_set_gc, type="prob")[, 2]

# Calcola la ROC curve ed esegui un plot usando ggroc (pacchetto pROC). Specifichiamo legacy.axes=TRUE per avere FPR nelle ascisse

roc_lda_gc <- roc(test_set_gc$Class, lda_pred_prob_gc, levels=c("Good", "Bad"))

ggroc(roc_lda_gc, legacy.axes = TRUE, color="blue") +
  ggtitle("ROC Curve per Naive Bayes (rosso) e LDA (blu)- German Credit Data") +
  xlab("False Positive Rate") +
  ylab("True Positive Rate") +
  geom_line(data = ggroc(roc_nb_e1071)$data, aes(x = 1 - specificity, y = sensitivity), color="red") +
  theme(legend.position = "bottom") +
  guides(color = guide_legend(override.aes = list(size = 4)))

```
Vediamo che LDA migliora leggermente le performance rispetto a Naive Bayes in questo caso. 


### Dataset Infortuni sul Lavoro in Toscana

Applichiamo ora LDA e QDA sul dataset degli infortuni sul lavoro in Toscana per prevedere se l'infortunato è nato in Italia o all'estero (colonna *NatItal*). Usiamo prima LDA.

```{r}

# Allenamento del modello LDA
lda_model_it <- lda(NatItal ~ ., data = train_set_it)
# Previsione sul test set
lda_pred_it <- predict(lda_model_it, test_set_it)
# Matrice di confusione e accuratezza
lda_conf_matrix_it <- confusionMatrix(lda_pred_it$class, test_set_it$NatItal)
print(lda_conf_matrix_it)

```

Confrontiamo le previsioni dei due modelli (LDA e Naive Bayes).

```{r}

# tabella di contingenza

table(lda_pred_it$class, nb_pred_it)

```
Confrontiamo le curve ROC.

```{r}

lda_pred_prob_it <- predict(lda_model_it, test_set_it)$posterior[, 2]
# Calcola la ROC curve ed esegui un plot usando ggroc (pacchetto pROC). Specifichiamo legacy.axes=TRUE per avere FPR nelle ascisse

roc_lda_it <- roc(test_set_it$NatItal, lda_pred_prob_it, levels=c("TRUE", "FALSE"))

ggroc(roc_lda_it, legacy.axes = TRUE, color="blue") +
  ggtitle("ROC Curve per Naive Bayes (rosso) e LDA (blu)- INAIL Toscana") +
  xlab("False Positive Rate") +
  ylab("True Positive Rate") +
  geom_line(data = ggroc(roc_nb_it)$data, aes(x = 1 - specificity, y = sensitivity), color="red") +
  theme(legend.position = "bottom") +
  guides(color = guide_legend(override.aes = list(size = 4)))


```
Non stupisce che il modello LDA abbia performance peggiori: non sta utilizzando le colonne discrete in modo ottimale.

**Esercizio:** Provate a rifare l'analisi di LDA usando solo le colonne numeriche del dataset e trasformando eventuali factor in numerici (come il genere). Come cambiano le performance del modello?

## Regressione Logistica

Consideriamo il dataset generato, che contiene 4 features (tutte numeriche) e due sole labels. Il comando per applicare la regressione logistica in R è `glm()` specificando `family=binomial`. Possiamo in alternativa usare il pacchetto `caret` con `method="multinom"` (per la regressione logistica multinomiale, che funziona anche per il caso binario).


```{r}
# Allenamento del modello di regressione logistica
log_model_generated <- glm(label ~ ., data = train_data_generated, family = binomial)

#con la funzione summary() otteniamo un riassunto del modello
summary(log_model_generated)
```
```{r}


# Previsione sul test set
log_pred_generated_prob <- predict(log_model_generated, test_data_generated, type = "response")

# Convertiamo le probabilità in etichette
log_pred_generated <- ifelse(log_pred_generated_prob > 0.5, 1, -1)

# Matrice di confusione e accuracy

log_conf_matrix_generated <- confusionMatrix(as.factor(log_pred_generated), test_data_generated$label)
print(log_conf_matrix_generated)

```

Plottiamo ora le curve ROC per i tre metodi (Naive Bayes, LDA, Regressione Logistica) per confronto.

```{r}

log_pred_prob_generated <- predict(log_model_generated, test_data_generated, type = "response")

# Calcola la ROC curve ed esegui un plot usando ggroc (pacchetto pROC). Specifichiamo legacy.axes=TRUE per avere FPR nelle ascisse
roc_log_generated <- roc(test_data_generated$label, log_pred_prob_generated)
ggroc(roc_log_generated, legacy.axes = TRUE, color="green") +
  ggtitle("ROC: NB (rosso), LDA (blu) e RL (verde) - Dataset Generato") +
  xlab("False Positive Rate") +
  ylab("True Positive Rate") +
  geom_line(data = ggroc(roc_nb_e1071)$data, aes(x = 1 - specificity, y = sensitivity), color="red") +
  geom_line(data = ggroc(roc_lda_generated)$data, aes(x = 1 - specificity, y = sensitivity), color="blue") +
  theme(legend.position = "bottom") +
  guides(color = guide_legend(override.aes = list(size = 4)))
```


Consideriamo infine un modello di classificazione nel caso multi-classe. Per semplicità aggiungiamo una terza classe al dataset generato.

```{r}

# Aggiungiamo una terza classe al dataset generato
x3 <- sample( 0:1, size=80, replace=TRUE, prob=c(0.2, 0.8))
y3 <- sample( 0:1, size=80, replace=TRUE, prob=c(0.5, 0.5))
z3 <- rnorm(80, mean=0, sd=2)
w3 <- rpois(80, lambda=5)

data_generated_multi <- data.frame("x" = c(x1, x2, x3), "y"=c(y1, y2, y3), "z"=c(z1, z2, z3), "w"=c(w1, w2, w3), "label"=as.factor(c(rep(-1, 200), rep(1,50), rep(0,80))))

# Suddivisione in train e test set
train_index_multi <- createDataPartition(data_generated_multi$label, p = 0.7, list = FALSE)
train_data_generated_multi <- data_generated_multi[train_index_multi, ]
test_data_generated_multi <- data_generated_multi[-train_index_multi, ]

ggplot(data_generated_multi, aes(x =z, y = w, color = label)) +
  geom_point() +
  labs(title = "Dataset Fittizio Multi-classe", x = "feature 3", y = "feature 4")

```

Applichiamo prima una strategia euristica one-vs-all per la regressione logistica multi-classe.

```{r}
# Allenamento del modello di regressione logistica one-vs-all
log_models_multi <- list()

classes <- levels(train_data_generated_multi$label)
for (cls in classes) {
  binary_labels <- ifelse(train_data_generated_multi$label == cls, 1, 0)
  log_models_multi[[cls]] <- glm(binary_labels ~ ., data = train_data_generated_multi, family = binomial)
}
# Previsione sul test set
log_pred_multi <- sapply(classes, function(cls) {
  predict(log_models_multi[[cls]], test_data_generated_multi, type = "response")
})
log_pred_multi_labels <- apply(log_pred_multi, 1, function(probs) {
  classes[which.max(probs)]
})
# Matrice di confusione e accuracy
log_conf_matrix_multi <- confusionMatrix(as.factor(log_pred_multi_labels), test_data_generated_multi$label)
print(log_conf_matrix_multi)
```
Applichiamo ora una regressione multinomiale usando il pacchetto ``caret``.

```{r}

# Allenamento del modello di regressione logistica multi classe
log_model_multi <- train(label ~ ., data = train_data_generated_multi, trControl = trainControl(verboseIter = FALSE),  trace = FALSE, method = "multinom")

# Previsione sul test set
log_pred_multi_caret <- predict(log_model_multi, test_data_generated_multi)
# Matrice di confusione e accuracy
log_conf_matrix_multi_caret <- confusionMatrix(log_pred_multi_caret, test_data_generated_multi$label)
print(log_conf_matrix_multi_caret)

```
**Esercizio:** Applicare la regressione logistica al dataset German Credit Data e confrontare le performance con Naive Bayes e LDA viste in precedenza.

## Esercizi

1. Generare una tabella con 30 righe e 8 colonne con dati casuali. Aggiungere una quinta colonna contenente una classificazione binaria, generata anche essa casualmente. Calcolare la discrepanza tra la classificazione originaria e il risultato di una classificazione logistica. Se si ripete questo esperimento per 1000 volte, calcolare valore medio e deviazione standard della discrepanza.

2. Generare una tabella A con 170 righe e 7 colonne, in modo che l’ultima colonna contenga valori binari relativi all’appartenenza a una o l’altra di due classi. Generare una seconda tabella B con 5 righe e 6 colonne. Implementare una classificazione degli individui nella tabella B applicando alla tabella A la classificazione logistica e la analisi discriminante lineare. Confrontare i risultati dei due metodi.

3. Confrontare i metodi di regressione logistica e analisi discriminante lineare e quadratica sul dataset [titanic](https://www.kaggle.com/datasets/yasserh/titanic-dataset) usando l’autovalidazione, per stabilire il metodo migliore.


4. Determinare il migliore metodo di classificazione (tra quelli studiati nel corso) per il dataset ``Pima.tr`` (pacchetto MASS). Usare poi i modelli per classificare i nuovi dati contenuti nel dataset ``Pima.te`` e verificare se il miglior modello stabilito nella prima parte sia effettivamente il più efficace.


## Nota sui blocchi

Potete creare un blocco iniziale e non visualizzare il codice di *tutti* i blocchi in un R notebook usande il comando: ``knitr::opts_chunk$set(warning = FALSE, message = FALSE, echo=FALSE)``
