##### Rozdział 5: klasyfikacja z wykorzystaniem drzew decyzyjnych i reguł -------------------

#### Część 1: drzewa decyzyjne -------------------

## Drzewa decyzyjne ----
# obliczamy entropię segmentu dwuklasowego
-0.60 * log2(0.60) - 0.40 * log2(0.40)

curve(-x * log2(x) - (1 - x) * log2(1 - x),
      col = "red", xlab = "x", ylab = "Entropy", lwd = 4)

## Przykład: identyfikowanie ryzykownych pożyczek bankowych ----
## Etap 2: badanie i przygotowywanie danych ----
credit <- read.csv("credit.csv", stringsAsFactors = TRUE)
str(credit)

# przyglądamy się dwóm charakterystykom wnioskodawcy
table(credit$checking_balance)
table(credit$savings_balance)

# przyglądamy się dwóm charakterystykom pożyczki
summary(credit$months_loan_duration)
summary(credit$amount)

# przyglądamy się zmiennej klasowej
table(credit$default)

# tworzymy losowe próbki dla danych treningowych i testowych
# używamy set.seed, aby za każdym razem uzyskać tę samą sekwencję liczb losowych
set.seed(9829)
train_sample <- sample(1000, 900)

str(train_sample)

# dzielimy ramki danych
credit_train <- credit[train_sample, ]
credit_test  <- credit[-train_sample, ]

# sprawdzamy proporcje zmiennej klasowej
prop.table(table(credit_train$default))
prop.table(table(credit_test$default))

## Etap 3: trenowanie modelu na danych ----
# budujemy najprostsze drzewo decyzyjne
library(C50)
credit_model <- C5.0(default ~ ., data = credit_train)

# wyświetlamy podstawowe informacje o drzewie
credit_model

# wyświetlamy szczegółowe informacje o drzewie
summary(credit_model)

## Etap 4: ewaluacja modelu ----
# tworzymy wektor czynnikowy z prognozami na danych testowych
credit_pred <- predict(credit_model, credit_test)

# tabela krzyżowa z klasami przewidzianymi i rzeczywistymi
library(gmodels)
CrossTable(credit_test$default, credit_pred,
           prop.chisq = FALSE, prop.c = FALSE, prop.r = FALSE,
           dnn = c('actual default', 'predicted default'))

## Etap 5: poprawianie działania modelu ----

## Wzmacnianie dokładności drzew decyzyjnych
# wzmocnione drzewo decyzyjne z 10 próbami
credit_boost10 <- C5.0(default ~ ., data = credit_train,
                       trials = 10)
credit_boost10
summary(credit_boost10)

credit_boost_pred10 <- predict(credit_boost10, credit_test)
CrossTable(credit_test$default, credit_boost_pred10,
           prop.chisq = FALSE, prop.c = FALSE, prop.r = FALSE,
           dnn = c('actual default', 'predicted default'))

## Jak sprawić, żeby niektóre pomyłki były kosztowniejsze od innych

# tworzymy wymiary dla macierzy kosztów
matrix_dimensions <- list(c("no", "yes"), c("no", "yes"))
names(matrix_dimensions) <- c("predicted", "actual")
matrix_dimensions

# budujemy macierz
error_cost <- matrix(c(0, 1, 4, 0), nrow = 2, dimnames = matrix_dimensions)
error_cost

# stosujemy macierz kosztów do drzewa
credit_cost <- C5.0(default ~ ., data = credit_train,
                          costs = error_cost)
credit_cost_pred <- predict(credit_cost, credit_test)

CrossTable(credit_test$default, credit_cost_pred,
           prop.chisq = FALSE, prop.c = FALSE, prop.r = FALSE,
           dnn = c('actual default', 'predicted default'))

#### Etap 2: Modele uczące się reguł -------------------

## Przykład: identyfikowanie trujących grzybów ----
## Etap 2: badanie i przygotowywanie danych ---- 
mushrooms <- read.csv("mushrooms.csv", stringsAsFactors = TRUE)

# badamy strukturę ramki danych
str(mushrooms)

# odrzucamy cechę veil_type
mushrooms$veil_type <- NULL

# badamy rozkład klas
table(mushrooms$type)

## Etap 3: trenowanie modelu na danych ----
library(OneR)

# trenujemy OneR() na danych
mushroom_1R <- OneR(type ~ ., data = mushrooms)

## Etap 4: ewaluacja modelu ----
mushroom_1R

mushroom_1R_pred <- predict(mushroom_1R, mushrooms)
table(actual = mushrooms$type, predicted = mushroom_1R_pred)

## Etap 5: poprawianie działania modelu ----
library(RWeka)
mushroom_JRip <- JRip(type ~ ., data = mushrooms)
mushroom_JRip
summary(mushroom_JRip)

# Model uczący się reguł oparty na drzewach decyzyjnych C5.0
library(C50)
mushroom_c5rules <- C5.0(type ~ ., data = mushrooms, rules = TRUE)
summary(mushroom_c5rules)
