Data Mining u R-u: Priprema, Klasifikacija i Klasterovanje
Priprema podataka
Priprema podataka: medijana <- median(data$price, na.rm = TRUE)
data$price[is.na(data$price)] <- medijana
data <- data[complete.cases(data$price), ] izbacivanje NA vrednosti
Metrike evaluacije
#accuracy - procenat tačnih predikcija od ukupnog broja opservacija
#precision - udeo onih koje smo predvideli kao pozitivne, a koje su stvarno pozitivne
#recall - udeo stvarno pozitivnih koje smo predvideli kao pozitivne
#F1 - služi za evaluaciju modela kada su precision i recall u balansu
1. Klasifikaciona stabla
Izlazna varijabla mora biti faktor.
tree1.cm <- table(true = test.data$izlazna, predicted = tree1.pred)
tree1.eval <- getEvalMetrics(tree1.cm)
getEvalMetrics <- function(cm){...}Krosvalidacija: library(e1071) - pogledati u cheatsheetu.
2. K-means
Radi samo sa numeričkim podacima. Tražimo neki patern. Izbacujemo sve karakter varijable; ako su neke karakter varijable numeričke, prebacujemo ih prvo u faktor, pa zatim u numeričke, i to ako imaju neku pravilnost.
Brišemo one varijable koje imaju više od 10% ukupnog broja opservacija kao outlajere:
apply(data, 2, function(x) length(boxplot.stats(x)$out))
library(DescTools)
boxplot(data$in_spotify_charts, xlab = 'in_spotify_charts')
in_spotify_charts_W <- Winsorize(data$in_spotify_charts, probs = c(0, 0.92))Ako su outlajeri gore, koristimo (0, 0.95); dole (0.05, 1); dole i gore (0.05, 0.95).
normalize_var <- function(x){
if(sum(x, na.rm = TRUE) == 0) x else ((x - min(x, na.rm = TRUE)) / (max(x, na.rm = TRUE) - min(x, na.rm = TRUE)))
}
data.norm <- as.data.frame(apply(data, 2, normalize_var))
library(corrplot)
data_cor <- cor(data.norm)
corrplot.mixed(data_cor)
data.norm$in_spotify_charts <- NULLIzbacujemo jednu po jednu varijablu dok boje na slici ne budu svetle.
Priprema za elbow metodu
eval.metrics <- data.frame()
for(k in 2:8){
set.seed(1010)
km <- kmeans(data.norm, centers = k, iter.max = 20, nstart = 1000)
eval.metrics <- rbind(eval.metrics, c(k, km$tot.withinss, km$betweenss / km$totss))
}
colnames(eval.metrics) <- c("clusters", "tot.withinss", "ratio")
eval.metrics
source("Utility.R")
diff_df <- apply(eval.metrics, 2, compute.difference)
diff_df <- cbind(k = 2:8, diff_df)
diff_df
sum.stats <- summary.stats(data.norm, sample.3k$cluster, 3)
sum.stats3. KNN
Sve ulazne varijable moraju biti numeričke, a izlazna mora biti faktor. Algoritam je isti kao kod stabala, samo se dodatno radi standardizacija i uklanjanje outlajera.
sort(table(data$GoingTo))
data$GoingTo[data$GoingTo == ""] <- "Work"
data$FuelEconomy[data$FuelEconomy == "" | data$FuelEconomy == "-"] <- NA
shapiro.test(data$FuelEconomy)
data$Take407All <- ifelse(data$Congestion407 < percentil60 & data$Comments == "", yes = "Yes", no = "No")
data$DayOfWeek <- factor(data$DayOfWeek, levels = c("Monday", "Tuesday", "Wednesday", "Thursday", "Friday"))
library(ggplot2)
ggplot(data, aes(x = Date, fill = Take407All)) + geom_bar(position = "dodge")Standardizacija i provera outlajera
apply(X = data[, -7], 2, FUN = function(x) length(boxplot.stats(x)$out))
apply(X = data[, -7], 2, FUN = function(x) shapiro.test(x))
data.std <- apply(X = data[, c(1:3, 5:6)], 2, FUN = function(x) scale(x, center = median(x), scale = IQR(x)))
data.std <- as.data.frame(data.std) # OBAVEZNO!
data.std$expensive <- as.factor(data$expensive)
data.std$bedrooms <- data$bedrooms
str(data.std)Podela na trening i test skup.
Krosvalidacija sa 10 preklapanja
library(e1071)
library(caret)
numFolds <- trainControl(method = "cv", number = 10)
kGrid <- expand.grid(.k = seq(from = 3, to = 25, by = 2))
set.seed(1010)
knn.cv <- train(x = train.data[, -6], y = train.data$expensive, method = "knn", trControl = numFolds, tuneGrid = kGrid)
best_k <- knn.cv$bestTune$kKreiranje modela
library(class)
knn.pred <- knn(train = train.data[, -6], test = test.data[, -6], cl = train.data$expensive, k = best_k)
knn.cm <- table(true = test.data$expensive, predicted = knn.pred)4. Linearna regresija
Sve varijable, i ulazne i izlazne, moraju biti numeričke.
1. Učitavanje skupa podataka i priprema
podskup <- subset(data, (data$Platform == "PS2" | data$Platform == "PS3" | data$Platform == "PS4"))2. Korelaciona matrica
library(corrplot)
data_cor <- cor(data)
corrplot(data_cor, method = "number", type = "upper", diag = FALSE)3. Podela na trening i test
Isto kao i ranije.
4. Kreiranje modela
Prvo ide izlazna varijabla Balance, a zatim ulazne varijable koje smo ranije odredili: Limit, Rating i Income.
lm1 <- lm(Balance ~ Income + Limit + Rating, data = train.data)
summary(lm1)Provera multikolinearnosti i poboljšanje modela
Izbacujemo varijable koje su visoko korelisane.
library(car)
sort(sqrt(vif(lm1)))
lm2 <- lm(Balance ~ Income + Rating, data = train.data)
summary(lm2)
sort(sqrt(vif(lm2)))Kreiranje 4 grafika
graphics.off()
par(mfrow = c(2, 2))
plot(lm2)Metrike
RSS <- sum((lm2.pred - test.data$Balance)^2)
TSS <- sum((mean(train.data$Balance) - test.data$Balance)^2)
rsquared <- 1 - RSS / TSS
RMSE <- sqrt(RSS / nrow(test.data))
RMSE / mean(test.data$Balance)5. Naive Bayes
Radi samo sa faktorskim varijablama. Numeričke varijable moraju biti diskretizovane.
Nakon sređivanja podataka, diskretizujemo varijablu koja je integer:
install.packages("bnlearn")
library(bnlearn)
discretized <- discretize(data = data[, 2], method = "quantile", breaks = c(2))
noviDataSet <- as.data.frame(cbind(discretized, data[, c(1, 3, 4)]))
data <- noviDataSetBrojevi u vektoru su indeksi kolona sa numeričkim varijablama koje se diskretizuju, a breaks označava na koliko delova delimo.
Trening, test i kreiranje modela
library(e1071)
nb1 <- naiveBayes(price_category ~ ., data = train.data)
nb1
nb1.pred <- predict(nb1, newdata = test.data, type = "class")
nb1.cm <- table(true = test.data$price_category, predicted = nb1.pred)Zatim koristimo funkciju getEvalMetrics(cm).
ROC kriva
nb2.pred.prob <- predict(nb1, newdata = test.data, type = "raw")
nb2.pred.prob
install.packages("pROC")
library(pROC)
nb2.roc <- roc(response = as.integer(test.data$price_category), predictor = nb2.pred.prob[, 1], levels = c(2, 1))
plot.roc(nb2.roc)
nb2.roc$auc
plot.roc(nb2.roc, print.thres = TRUE, print.thres.best.method = "youden")
nb2.coords <- coords(nb2.roc, ret = c("accuracy", "spec", "sens", "thr"), x = "local maximas")