# początek jak zwykle
library(mlbench)
data(HouseVotes84)
data(Glass)
      # funkcja obliczająca błąd
err <- function(y.true, y.pred) { sum(y.pred!=y.true)/length(y.true) }

      # podzielmy dane na trenujące i testowe losowo w stosunku ok. 2:1
rhv <- runif(nrow(HouseVotes84))
hv.train <- HouseVotes84[rhv>=0.33,]
hv.test <- HouseVotes84[rhv<0.33,]
rg <- runif(nrow(Glass))
g.train <- Glass[rg>=0.33,]
g.test <- Glass[rg<0.33,]

      # klasyfikator pamięciowy (nearest neighbor)
      # jedna z dostępnych implementacji kNN jest w pakiecie class
      # są też inne (proszę poszukać)
if (! "class" %in% row.names(installed.packages()))
  install.packages("class")
library(class)

       # wyniki klasyfikacji przykładów testowych dla k=1, 3, 5
       # ważne: zbiory przykładów przekazujemy bez klas
       # (wektor klas jest osobnym trzecim argumentem)
g.pred.1nn <- knn(g.train[,-10], g.test[,-10],
g.train[,10], k=1)
g.pred.3nn <- knn(g.train[,-10], g.test[,-10], g.train[,10], k=3)
g.pred.5nn <- knn(g.train[,-10], g.test[,-10], g.train[,10], k=5)
      # odpowiednie błędy na zbiorze testowym
err(g.test$Type, g.pred.1nn)
err(g.test$Type, g.pred.3nn)
err(g.test$Type, g.pred.5nn)
      
      # a teraz ponownie to samo, ale po uprzednim przeskalowaniu atrybutów
      # średnie atrybutów (liczone na zbiorze trenującym!)
g.m <- apply(g.train[,-10], 2, mean)
      # odchylenia standardowe atrybutów (liczone na zbiorze trenującym!)
g.sd <- apply(g.train[,-10], 2, sd)
      # skalowanie atrybutów ze zbiorów trenującego i testowego
      # (od razu tutaj pomijamy klasy)
g.train.s <- scale(g.train[,-10], g.m, g.sd)
g.test.s <- scale(g.test[,-10], g.m, g.sd)
      # i klasyfikacja z użyciem przeskalowanych danych
g.pred.1nns <- knn(g.train.s, g.test.s, g.train[,10], k=1)
g.pred.3nns <- knn(g.train.s, g.test.s, g.train[,10], k=3)
g.pred.5nns <- knn(g.train.s, g.test.s, g.train[,10], k=5)
      # odpowiednie błędy na zbiorze testowym
err(g.test$Type, g.pred.1nns)
err(g.test$Type, g.pred.3nns)
err(g.test$Type, g.pred.5nns)
      # czy jest różnica?
			      
      # naiwny klasyfikator bayesowski
      # pakiet e1071 zawiera prostą implementację
if (! "e1071" %in% row.names(installed.packages()))
  install.packages("e1071")
library(e1071)

      # trenowanie i testowanie
hv.nb <- naiveBayes(Class ~ ., hv.train)
err(hv.test$Class, predict(hv.nb, hv.test[,-1]))
      # obejrzyjmy prawdopodobieństwa a priori dla klas
hv.nb$apriori
      # i warunkowe dla atrybutów względem klas
hv.nb$tables
      # przy predykcji możemy także zażądać podania prawdopodobieństw
predict(hv.nb, hv.test[,-1], type="raw")