-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathNN_function.R
130 lines (110 loc) · 5.92 KB
/
NN_function.R
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
library(neuralnet)
library(caret)
library(pROC)
NEURALNETWORK <- function(type,target,train_data,test_data,results,name_encoding) {
results <- cbind(results, name_encoding = c(0,0,0,0,0)) #nel dataframe results aggiungo una colonna che si chiama come il nome dell'encoding e inizializzo i valori a 0
all_columns <- names(train_data)
features <- setdiff(all_columns, target)
#mi assicuro che tutte le colonne siano numeriche (faccio i controlli su tutte tranne la target, sto assumendo che nei casi di regressione sia giusta e numerica)
non_numeric_columns <- sapply(train_data[,features], function(x) !is.numeric(x))
non_numeric_columns <- names(non_numeric_columns)[non_numeric_columns]
for (col in non_numeric_columns) {
train_data[[col]] <- as.numeric(train_data[[col]])
}
non_numeric_columns_test <- sapply(test_data[,features], function(x) !is.numeric(x))
non_numeric_columns_test <- names(non_numeric_columns_test)[non_numeric_columns_test]
for (col in non_numeric_columns_test) {
test_data[[col]] <- as.numeric(test_data[[col]])
}
#per la normalizzazione (salvo in columns_with_only_0_1 i nomi delle colonne one-hot-encoded)
columns_with_only_0_1 <- character(0)
for (col in features) {
column_values <- train_data[[col]]
if (all(column_values %in% c(0, 1))) {
columns_with_only_0_1 <- c(columns_with_only_0_1, col)
}
}
set.seed(123)
formula <- as.formula(paste(target, "~", paste(features, collapse = "+")))
#nota: sto dando per scontato che i dataset passati alla funzione siano già normalizzati con media e sd
switch (type,
"regression" = {
#Normalization:
feat_norm <- setdiff(all_columns, columns_with_only_0_1)
scaling_factors <- apply(train_data[, feat_norm], 2, function(x) c(mean(x), sd(x)))
scaled_train_data <- as.data.frame(scale(train_data[, feat_norm], center = scaling_factors[1,], scale = scaling_factors[2,]))
scaled_test_data <- as.data.frame(scale(test_data[, feat_norm], center = scaling_factors[1,], scale = scaling_factors[2,]))
#riaggiungo le variabili one-hot-encoded
for (col in columns_with_only_0_1) {
scaled_train_data[[col]] <- train_data[[col]]
scaled_test_data[[col]] <- test_data[[col]]
}
#NN:
nn_model <- neuralnet(formula, data = scaled_train_data, hidden = 10, threshold=0.1, rep=3, linear.output = TRUE)
for (i in 1:5) {
pr_nn <- predict(nn_model, rep=i, newdata = scaled_test_data)
#Tolgo la normalizzazione (questa era la formula per annullare la normalizzazione come l'avevo fatta io, ovviamente in caso va cambiata):
unscaled_predicted <- pr.nn * scaling_factors[2,target] + scaling_factors[1,target]
#Calcolo RMSE:
rmse <- sqrt(mean((unscaled_predicted- test_data[[target]])^2))
results[i,name_encoding] <- rmse
}
},
"bin_classification" = {
#Normalization:
feat_norm <- setdiff(features, columns_with_only_0_1)
scaling_factors <- apply(train_data[, feat_norm], 2, function(x) c(mean(x), sd(x)))
scaled_train_data <- as.data.frame(scale(train_data[, feat_norm], center = scaling_factors[1,], scale = scaling_factors[2,]))
scaled_test_data <- as.data.frame(scale(test_data[, feat_norm], center = scaling_factors[1,], scale = scaling_factors[2,]))
#riaggiungo la variabile target
scaled_train_data[[target]] <- train_data[[target]]
scaled_test_data[[target]] <- test_data[[target]]
#riaggiungo le variabili one-hot-encoded
for (col in columns_with_only_0_1) {
scaled_train_data[[col]] <- train_data[[col]]
scaled_test_data[[col]] <- test_data[[col]]
}
#NN:
nn_model <- neuralnet(formula, data = scaled_train_data, hidden = 10, threshold=0.1, rep=5, linear.output = FALSE)
for (i in 1:5) {
pr_nn_probs <- predict(nn_model, rep=i, newdata = scaled_test_data) #da le probabilità di ognuni classe
#rendo uniformi le classi predette e quella del test, per poter calcolare l'AUC
column_names <- unique(test_data[[target]])
max_column_indices <- max.col(pr_nn_probs)
pred_class_names <- column_names[max_column_indices]
pred_class_names <- as.numeric(pred_class_names)
#Calcolo AUC:
roc_obj <- roc(test_data[[target]], pred_class_names)
auc_score <- auc(roc_obj)
results[i,name_encoding] <- auc_score #salva nella colonna corrispondente i risultati della rete
}
},
"multiclass" = {
#Normalization:
feat_norm <- setdiff(features, columns_with_only_0_1)
scaling_factors <- apply(train_data[, feat_norm], 2, function(x) c(mean(x), sd(x)))
scaled_train_data <- as.data.frame(scale(train_data[, feat_norm], center = scaling_factors[1,], scale = scaling_factors[2,]))
scaled_test_data <- as.data.frame(scale(test_data[, feat_norm], center = scaling_factors[1,], scale = scaling_factors[2,]))
#riaggiungo la variabile target
scaled_train_data[[target]] <- train_data[[target]]
scaled_test_data[[target]] <- test_data[[target]]
#riaggiungo le variabili one-hot-encoded
for (col in columns_with_only_0_1) {
scaled_train_data[[col]] <- train_data[[col]]
scaled_test_data[[col]] <- test_data[[col]]
}
#NN:
train_data[[target]] <- as.factor(train_data[[target]]) #mi assicuro che sia in livelli, se lo sono già tutte non è necessario
nn_model <- neuralnet(formula, data = scaled_train_data, hidden = 10, threshold=0.1, rep=5, linear.output = FALSE)
for (i in 1:5) {
pr_nn_probs <- predict(nn_model, rep=i, newdata = scaled_test_data) #da le probabilità di ognuni classe
colnames(pr_nn_probs) <- unique(test_data[[target]])
#Calcolo AUNU:
library(mlr3measures)
aunu_score <- mauc_aunu(test_data[[target]], pr_nn_probs)
results[i,name_encoding] <- auc_score
}
}
)
return(results)
}