R-tahák
Vytvořeno na základě zápisků ze cvičení k Úvodu do strojového učení, ZS 2008/9 -- Tuetschek 16:20, 24 Jan 2009 (CET)
- Short R Reference Card, obsahuje většinu důležitých základních funkcí
 
Základní příkazy[editovat | editovat zdroj]
Nápověda:
- > ?func # nápověda pro funkci func
 
Potlačení chyb:
- try( ... ) # nezastaví program, když se stane chyba
 - Debugging: Debugging in R
 
Objekty, paměť[editovat | editovat zdroj]
Úplně všechno v R je objekt.
- summary(obj) # Použít pro zjištění něčeho o libovolném objektu
 - str(obr) # zjištění typu objektu (jiná informace
 - ls() # seznam všech objektů
 - ls.str() # zavolá str() na všechny existující objekty
 -  rm(object)  # smaže objekt object
- rm(list=ls()) # smaže úplně všechny objekty
 
 
Zavřu-li nějaký příkaz do závorek, vytiskne se jeho výsledek na výstup.
Počty[editovat | editovat zdroj]
Ovládání:
- ls # použitím jména funkce bez závorek se vypíše její zdroják, nezavolá se
 - m <- 15 # přiřazovací příkaz, nepoužívat =, je to obsolete!
 - a <- c(10,12, 16, pi) # vytvoření vektoru pomocí funkce c() (konkatenace)
 - b <- (1:8)*3 # sekvence čísel, může jít i pozpátku: c <- (8:1)/2 - 3
 -  R nemá ternární operátor (?), operátor ? je nápověda
- Místo ternárního operátoru se dá použít x <- if (condition){ value1 }else{ value2 };
 
 
Funkce s jedním argumentem, do kterého dám c(..) mi vrátí c(..) s výsledky pro každý člen původního vektoru. Všechny početní operace jsou totiž definovány na vektorech. S vektory se dá počítat všelijak. Dát ale pozor na sčítání vektorů různé délky, R si kratší z nich zacyklí a nevydá žádný warning.
- w <- x/2 + 1 # a x je vektor
 - y <- x + w * rnorm(x)
 - predict == test# je vektor hodnot TRUE a FALSE, podle toho, jestli se shodují hodnoty na stejných pozicích
 
Vnější vztahy[editovat | editovat zdroj]
Pracovní adresář (pro čtení, zápis souborů) -- vždycky je nějaký nastaven:
- getwd() # zjištění
 - setwd() # nastavení
 
Volání příkazů operačního systému:
- system("ls")
 
R-balíčky = knihovny: soubory funkcí, struktura: použít v Unixu locate, pak 00Index.html. Základní knihovna se jmenuje base.
- library(MASS) # nahrání knihovny MASS do paměti, umožní používat funkce v ní obsažené
 - installed.packages() # seznam všech nainstalovaných balíčků, co můžu nahrát do paměti
 - available.packages() # seznam všech balíčků, které se dají stáhnout
 -  download.packages(pkgs="e1071", destdir=getwd())  # stažení balíčku e1071 do aktuálního adresáře
- Stáhne se pod Windows ve formátu ZIP, pod Unixem v TGZ
 
 - install.packages(pkgs="e1071_1.5-18.tgz", lib.loc=getwd(), repos = NULL) # instalace balíčku do aktuálního adresáře (nebo adresáře libloc; v pkgs je celá cesta k nim), repos = NULL znamená, že se instalace provádí offline, šlo by instalovat i přímo z CRAN mirroru.
 - library(e1071,lib.loc=getwd()) # nahrání separátně nainstalované knihovny z nějakého adresáře
 
Před uzavřením R je možné uložit všechny objekty v paměti, ale lepší je to nedělat, ať mám opakovatelné pokusy.
Funkce[editovat | editovat zdroj]
# definice funkce, v názvech se slova zpravidla oddělují tečkou
foo.bar <- function( x, y=2 ) # můžu dát iniciální hodnoty parametrů
{
    # komentář
    return ( x ^ y ) # návratová hodnota: závorky nutné!
}
Přímá editace funkce z prostředí R se provádí příkazem edit(func).
Statistika[editovat | editovat zdroj]
Generátor náhodných čísel -- iniciální nastavení:
- set.seed(123) # pozor, některé hodnoty jsou vhodnější než jiné
 
Distribuce pravděpodobnosti[editovat | editovat zdroj]
Pro každou distribuci je v R několik funkcí, které se starají o generování apod., mají spec. prefixy (první znak názvu):
-  r  # generování náhodných vzorků, je tu opravdu dobrý generátor náh. čísel (tedy používat tohle!)
- První parametr je číslo (požadovaný počet vzorků), nebo vektor (počet vzorků = délka vektoru)
 
 - d # funkce hustoty pravděpodobnosti (pro každý bod mám "něco jako" pravděpodobnost, suma přes $ \mathbb{R} $ dává 1)
 - p # kumulativní distribuční funkce
 - q # kvantilová distribuční funkce
 
Distribuce
- -norm # normální rozdělení
 - -unif # rovnoměrné rozdělení
 - -binom # binomické rozdělení
 - -multinom # multinomické rozdělení
 
Testování parametrů rozdělení pro náhodný výběr (v proměnné x)
- mean(x) # střední hodnota
 - var(x) # rozptyl
 
Regrese[editovat | editovat zdroj]
Vytvoření modelu lineární regrese:
- fm <- lm( y ~ x, data= ... )  # na základě data framu, který má sloupce y a x, vytvořím model lin. regrese, kde y závisí na x
- Proměnná, která je závislá, musí být spojitá, ostatní se převedou na spojité, pokud jsou kategoriální
 
 - fm <- lm( y ~ ., data= ... ) # model, kde y závisí na všech ostatních sloupcích data framu
 
Predikce modelu a testování:
- trainedModel <- lm(y ~ ., data=train) # vytvoření modelu
 - prediction <- predict.lm(trainedModel, data=test) # vytvoření predikce, dá se pak porovnávat s výsledky testování
 
Lokální polynomická regrese:
- model <- loess(y ~ x, data=train) # vytvoření modelu (má spoustu dalších parametrů)
 - predict # predikce nemá vlastní funkci, používá se standardní pro všechno
 
Operace s daty[editovat | editovat zdroj]
I/O[editovat | editovat zdroj]
Načtení dat ze souboru:
- read.csv(filename, header=TRUE, sep=",") # načte data z CSV souboru, sep je oddělovač polí, pokud je header=TRUE, první řádek se bere jako hlavička
 
Převody datových typů[editovat | editovat zdroj]
Vytváření jednoho datového typu z jiného:
- c() # konkatenace vektorů / prvků do jednoho vektoru
 -  dummy <- data.frame(x,y,w)  # vytvoření data framu, vektory x,y,w budou jeho sloupce.
- Jedná se o kopírování, původní proměnné můžu zahodit
 
 -  matrix(data, cols, rows)  # vytvoření matice o dané šířce a výšce z vektoru
- Matici vytvoří i když délka dat není rovna cols*rows, ale vydá warning
 
 - rbind(col1, col2, col3) # vytvoří matici z dat, která budou jejími sloupci
 - cbind(row1, row2, row3) # totéž s řádky
 - l <- list(..); vector <- unlist(l); # vytvoření seznamu z vektoru a převod zpět (seznam může obsahovat vektory a seznamy, vektor je jednorozměrný)
 -  factor(data, levels=c(...), labels=c(...))  # vytvoření faktoru = enumu (levels -- udávám přípustné hodnoty, všechny další jsou hozeny na <NA>; labels -- udaným úrovním můžu dát jména, pokud chci).
- levels(my.factor) # ukáže jména všech hodnot faktoru
 - levels(my.factor) <- c("a","b","c") # do jmen hodnot faktoru lze i zapisovat
 
 
Informace o matici nebo data frame:
- ncol(dummy); length(dummy[1,]) # počet sloupců
 - nrow(dummy) # počet řádků
 
Explicitní konverze:
- as.-matrix, data.frame, vector, factor # podle toho, na co chci konvertovat
 
Dělení dat[editovat | editovat zdroj]
Výběr dat z matice nebo data frame:
- dummy[1,3] # 3. sloupec, 1. řádek (1 element)
 - dummy[1,] # první řádek (výsledek je jednořádkový data frame)
 - dummy[,-1] # vše až na první sloupec (výsledek je data frame)
 - dummy[,1] # první sloupec (výsledek je vektor)
 - indices <- c(1,3,5,7); dummy[indices,]; # vybrání jen některých řádků (můžu např. použít funkci sample), můžu i přímo zadat vektor
 - dummy[[column]] # vybere z data framu sloupec, který má název rovný hodnotě proměnné column (název se dá získat např. pomocí names)
 
Vytváření dat[editovat | editovat zdroj]
Generování vzorků:
- x <- seq(start, finish, step) # vytvoří vektor, který obsahuje čísla od start do finish s krokem step. Zavolám-li seq(1,20,5), dostanu čísla 1 6 11 16.
 -  sample(x, length, ...)  # vybírání náhodných vzorků -- z vektoru x vyberu length vzorků
- defaultní hodnota length je délka x, tedy vytváří náhodnou permutaci daného vektoru
 - je-li x ne vektor, ale číslo, bere se vektor čísel od 1 do x.
 
 - indices <- sample(39)[1:25]; train <- data[indices,]; # vybrání náhodné podmnožiny, aby se zabránilo hierarchii v datech
 
Použití funkce na celý vektor / matici:
- apply(dummy, 1, mean) # použití funkce mean (jde definovat i vlastní bezejmenná funkce a přímo napsat do parametru) na řádky (prostř. hodnota = 1) / sloupce (2) data framu
 - lapply(vector, func) # použití funkce na všechny prvky vektoru, vrací vždy seznam
 - sapply(vector, func) # to samé, ale když dostane vektor, vrátí vektor
 
Převody charakteru dat[editovat | editovat zdroj]
Data atributů, se kterými pracuji, jsou buď spojitá (continuous) nebo kategoriální (categorical, disktrétní). Některé modely, algoritmy atd. pracují jen s jedním typem.
Převod kategoriálních atributů na spojité: mám-li např. atribut color se 3 hodnotami: red, blue, black, potom vytvořím 3 atributy: f-blue, f-black, f-red a dávám jim hodnoty 0 a 1. To, že je vždy 1 jen jeden, vůbec nevadí - sice to enormně zvětšuje dimenzi (počet atributů), ale to v praxi často vůbec nevadí (jen pozor na Curse of dimensionality).
Převod spojitých na kategoriální: např. vyrobím kategoriální parametr se 4 hodnotami excellent, good, average, bad ~ např. 4, 3, 2, 1 -- ale musím si pořád pamatovat, že to je jenom kódování a např. průměr nebo medián nemá moc smysl (v praxi ale často funguje). Jak přesně rozdělit data je otázka praxe, musíme o datech něco vědět, aby dělení mělo smysl. Funkce na dělení:
-  categ <- cut(continuous.data, c(-Inf,5,20,Inf), labels=c("low", "mid", "high") )  # pozor, velikost vektoru s hranicemi musí být o 1 větší než velikost vektoru s názvy jednotlivých levelů
- Pokud nedodám názvy levelů, vyrobí si R pochybné svoje s popisem intervalů, ze kterých hodnoty pocházejí
 
 - quantile(continuous.data, c(0,0.2,0.4,0.6,0.8,1)) # Pro dělení podle pravděpodobností padnutí do nějakého intervalu, defaultní je c(0,0.25,0.50,0.75,1).
 
Některé modely předpokládají určité vlastnosti dat (např. standardní normální rozdělení apod.). Měly by se upravit trénovací data a podle nich upravit stejně i testovací:
-  x <- scale(data, center=TRUE, scale=TRUE)  # vycentruje všechny sloupce matice kolem průměru a vyškáluje: vydělí jejich kvadratickým průměrem (použít pro trénovací data)
- pokud jsou center a scale čísla, použijí se přímo na odečtení / vydělení (použít pro testovací data)
 - pokud jsou hodnoty FALSE necentruje se a/nebo se neškáluje
 
 - attr(x, "scaled:center") # jediný možný přístup k center a scale spočítaných na trénovacích datech, která se pak mohou použít pro testovací data
 
Výpisy[editovat | editovat zdroj]
- paste("a", "b", "c", sep="") # slepování stringů
 -  gettextf("Insert a string here:%s", string.data)  # vkládání stringů do nějakého vzorce
- %s je string, %d integer (%x hexadecimálně), %f je double (%e v plovoucí čárce a %g se rozhoduje, jestli použít normální nebo plovoucí čárku), procento se píše %%.
 
 
Grafy, kreslení[editovat | editovat zdroj]
Histogram:
- truehist(x, nbins=25) # nbins určuje počet "přihrádek"
 
Graf:
-  plot(x, y1); lines(x, y2); ...  # první a další proměnná (čára) do grafu 
- parametr type je informace o druhu čar / bodů: b bod a čára, l jen čára, p jen body
 - u libovolných čar lty je druh (plná, čárkovaná, tečkovaná, čerchovaná ...), col je barva, pch je písmeno, které se použije jako bod, pokud type je nastaveno na b.
 - nastavení min. a max. hodnoty u obou os: xlim=c(min,max), ylim
 
 
Grafické zobrazení distribuce:
- dd <- kde2d(x,y) # kde2d je z knihovny MASS, 2-rozměrná funkce hustoty
 - contour(dd) # dvourozměrná hustota ve "vrstevnicích"
 - image(dd) # barevný obrázek téhož
 
Výstup do souboru:
- png("output.png"); plot(x); dev.off(); # otevře PNG, zapíše požadovaný graf a zavře
 - pdf("output.pdf"); # totéž s PDF, výstup se dá potom importovat do Inkscape a dál editovat (a např. uložit jako EPS a vložit do TeXového zdrojáku)
 
Metody strojového učení[editovat | editovat zdroj]
Rozhodovací stromy[editovat | editovat zdroj]
Rpart (funguje na kategoriální proměnné):
- library(rpart) # nachází se v knihovně rpart (součástí std. balíčku R).
 - decision.tree <- rpart(y ~ feat1 + feat2, train.data) # vytvoření rozhodovacího stromu
 - prediction <- predict(decision.tree, test.data, type="class") # predikce podle testovacích dat; kdyby nebyl nastavený parametr type, potom by vracelo matici pravděpodobností klasifikace pro jednotlivé typy
 
Trees
- Funguje i na spojité proměnné, dělí vždy na dvě skupiny a kde dělit se rozhoduje podle maximálního snížení nějakého koeficientu přes všechna možná dělení.
 - library(tree) # součástí knihovny tree, kterou je nutné si nainstalovat
 -  model <- tree(y ~ ., train)  # natrénování, vytvoření stromu; interakce atributů jsou zakázané
- split # kritérium dělení (co se má co nejvíce snížit -- deviance / gini)
 
 - Predikce stejná jako pro Rpart.
 
K-nn[editovat | editovat zdroj]
K-nn funguje jen na spojité proměnné, je nutné tedy převést kategoriální data.
- library(class) # k-nn algoritmus se nachází v knihovně class (součást standardního balíčku R)
 -  predict <- knn(train, test, cl.train, k, use.all)  # samotný algoritmus
- train a test jsou trénovací a testovací data bez klasifikací (sloupce s výslednými proměnnými)
 - cl.train je sloupec klasifikací pro trénovací data
 - k je parametr k, tj. počet vzorků, které se mají použít
 - use.all -- pokud je více vzorků ve stejné vzdálenosti, mají se použít všechny, nebo jen vybraných max. k?
 
 - Rovnou vrací vektor předpovězených klasifikací pro testovací data.
 
Naive Bayes[editovat | editovat zdroj]
Je součásti knihovny e1071, pracuje se spojitými proměnnými i kategoriálními daty:
- library(e1071) # nutné ji mít nainstalovanou
 - model <- naiveBayes(y ~ ., train) # natrénování modelu, nelze používat interakce featur!
 - test1 <- test; test1$y <- NULL; predict(model, test1); # predikce, sloupec s výslednými hodnotami testovacích dat se pro použití ve funkci predict musí vyhodit, aby to fungovalo.
 
SVM[editovat | editovat zdroj]
Je součástí knihovny e1071, pracuje se spojitými proměnnými
- library(e1071) # nutné ji mít nainstalovanou
 -  model <- svm(y ~ ., train, type="C-classification", kernel="linear", cost=100)  # natrénování
- type používat jen C-classification
 - kernel máme i radial (s parametrem gamma (měřítko)) nebo polynomial (s parametrem gamma (měřítko), coef0 (posun) a degree (stupeň polynomu))
 - cost je váha penalizací (slack variables)
 
 - predict(model, test) # predikce
 - Funguje i na víc kategorií než + a -.
 
Testy úspěšnosti[editovat | editovat zdroj]
- mean(predict == test); # accuracy
 - table(predict, test); # vytvoří confusion matrix (kontingenční tabulku s počtem jednotlivých hodnot)
 
precision <- function( real, predict ){
    tp <- 0; fp <- 0;
    for(i in 1:length(real)){
	if (predict[i] == 1){
	    if (real[i] == 1) tp <- tp + 1
	    else fp <- fp + 1;
	}
    }
    return ( tp / (tp + fp));
}
recall <- function( real, predict ){
    tp <- 0; fn <- 0;
    for(i in 1:length(real)){
	if (real[i] == 1){
	    if (predict[i] == 1) tp <- tp + 1
	    else fn <- fn + 1;
	}
    }
    return ( tp / (tp + fn));  
}
f.measure <- function( real, predict ){
    r <- recall( real, predict )
    p <- precision( real, predict )
    return ( 2 * p * r / ( p + r ) );
}