Code
knitr::opts_chunk$set(
echo = TRUE,
message = FALSE,
warning = FALSE
)V nižšie uvedenom Chunku je urobené základné globálne nastavenie Chunkov v celom Notebooku.
knitr::opts_chunk$set(
echo = TRUE,
message = FALSE,
warning = FALSE
)Tento notebook demonštruje základné operácie v jazyku R so:
Tam, kde je to užitočné, sú zahrnuté malé cvičenia.
# Priradenie konštanty do premennej
a <- 7
b <- 3.5
# Arithmetic
sum_ab <- a + b # sucet
diff_ab <- a - b # rozdiel
prod_ab <- a * b # násobenie
quot_ab <- a / b # delenie
power_ab <- a ^ b # umocňovanie
mod_ab <- a %% 3 # zbytok po delení tromi (tzv modulo)
int_div_ab <- a %/% b # celočíselné delenie
# Rounding
round_b <- round(b) # zaokruhlovanie smerom k najblizsiemu celemu cislu
ceil_b <- ceiling(b) # najblizsie vyssie cele cislo
floor_b <- floor(b) # najblizsie nizsie cele cislo
a; b[1] 7
[1] 3.5
sum_ab; diff_ab; prod_ab; quot_ab; power_ab; mod_ab; int_div_ab[1] 10.5
[1] 3.5
[1] 24.5
[1] 2
[1] 907.4927
[1] 1
[1] 2
round_b; ceil_b; floor_b[1] 4
[1] 4
[1] 3
Poznámky
^ operátor umocňovania.%% je modulo, teda zbytok po delení,round(x, digits = 0) zaokrúhľovanie na určitý počet desatinných miest (digits=). ak digits = 0, potom ide o celočíselné zaokrúhľovanie🎮 Vlastný príklad – herné meny. Nasledujúce hodnoty sú vymyslené na tréning aritmetiky.
herne_kredity <- 4750
cena_vybavy <- 2850
zostatok_kreditov <- herne_kredity - cena_vybavy
bonus_percent <- 12.5
kredity_po_bonuse <- zostatok_kreditov * (1 + bonus_percent / 100)
round(kredity_po_bonuse, 2)[1] 2137.5
🎯 Quest 01 – CS2 ekonomika. Tím vyhral 15 kôl, za každé získal 3250 herných kreditov. Na výstroj minul 7200 kreditov. Zistite zostávajúci rozpočet a priemerný rozpočet na 5 hráčov.
vyhrate_kola <- 15
odmena_za_kolo <- 3250
naklady_na_vystroj <- 7200
pocet_hracov <- 5
rozpocet_timu <- vyhrate_kola * odmena_za_kolo - naklady_na_vystroj
rozpocet_na_hraca <- rozpocet_timu / pocet_hracov
rozpocet_timu; rozpocet_na_hraca[1] 41550
[1] 8310
first <- "Vladimir" # definovanie obsahu textovej premennej first
last <- "Gazda" # definovanie obsahu text. premennej last
full <- paste(first, last) # spojenie dvoch text. premennych do jednej (s medzerou)
full_nospace <- paste0(first, last) # spojenie bez medzery
csv_line <- paste("apple", "banana", "pear", sep = ",") # spojenie textov s oddelovacom ,
first; last; full; full_nospace; csv_line # bodkočiarka tu nahradzuje odskok na novy riadok [1] "Vladimir"
[1] "Gazda"
[1] "Vladimir Gazda"
[1] "VladimirGazda"
[1] "apple,banana,pear"
🎮 Vlastný príklad – menovka hráča.
prezdivka <- "PixelHunter"
tim <- "NIGHT RAIDERS"
mapa <- "Inferno"
popis_hraca <- paste(prezdivka, "hrá za", tim, "na mape", mapa)
popis_hraca[1] "PixelHunter hrá za NIGHT RAIDERS na mape Inferno"
paste0("#", prezdivka, "_MVP")[1] "#PixelHunter_MVP"
x <- "R is great!"
nchar(x) # počet znakov v retazci "R is great!"[1] 11
substr(x, 1, 5) # podreťazec od 1. do 5. znaku[1] "R is "
Tip: Knižnica stringr mnohé zaujímavé možnosti práce s textami, ale implicitné knižnice R pokrývajú väčšinu bežných potrieb páce s textami.
nchar(prezdivka) # počet znakov v prezývke[1] 11
substr(prezdivka, 1, 5) # prvých päť znakov prezývky[1] "Pixel"
p <- TRUE
q <- FALSE
!p # NOT[1] FALSE
p & q # AND[1] FALSE
p | q # OR[1] TRUE
xor(p, q) # exclusive OR - platí len jedno z p,alebo q[1] TRUE
3 < 5[1] TRUE
7 >= 7[1] TRUE
"cat" == "cat"[1] TRUE
"cat" != "dog" # vykricnik je tu v zmysle negacie. Napr.: !=, !>, !<, !TRUE[1] TRUE
!TRUE[1] FALSE
🎮 Vlastný príklad – postup do play-off.
vyhry <- 7
minimalne_vyhry <- 5
aktivny_hrac <- TRUE
postup <- (vyhry >= minimalne_vyhry) & aktivny_hrac
postup[1] TRUE
x <- 10
x > 5 & x < 20 # a sucasne - logicky prienik (sucin)[1] TRUE
x < 0 | x > 100 # alebo - logicke zjednotenie (sucet)[1] FALSE
# pri zlozitejsich vztahoch pouzivajte zatvorky ()vals <- c(TRUE, FALSE, TRUE, TRUE) # definicia vektora s logickymi hodnotamiv1 <- c(2, 4, 6, 8)
v2 <- 1:5 # postupnost 1,2,3,4,5
v3 <- seq(from = 0, to = 1, by = 0.25) # postupnost s krokom 0.25
v4 <- rep(3, times = 5) # 3,3,3,3,3 # 5 clenna postupnost trojak
v5 <- runif(5) # generovanie rovnomerne rozdelenych premennych v intervale [0,1]
v6 <- rnorm(5) # generovanie normalne rozdelenych premennych
v1; v2; v3; v4; v5[1] 2 4 6 8
[1] 1 2 3 4 5
[1] 0.00 0.25 0.50 0.75 1.00
[1] 3 3 3 3 3
[1] 0.3088054 0.5386144 0.2207791 0.4518826 0.5229187
🎮 Vlastný príklad – eliminácie v zápasoch.
eliminacie <- c(18, 24, 15, 29, 21, 26)
mena_map <- c("Mirage", "Inferno", "Nuke", "Ancient", "Anubis", "Dust2")
names(eliminacie) <- mena_map
eliminacie Mirage Inferno Nuke Ancient Anubis Dust2
18 24 15 29 21 26
v <- c(1, 2, 3, 4)
v + 10 # kazdy prvok vektora zvacsime o 10[1] 11 12 13 14
v * 2 # kazdy prvok vektora prenasobime 2[1] 2 4 6 8
(v + 1) / 2[1] 1.0 1.5 2.0 2.5
exp(v) # exponencialna funkcia z kazdeho prvku vektora[1] 2.718282 7.389056 20.085537 54.598150
sum(c(1,2,3) * c(1,1,1)) # správny skalárny súčin = 6[1] 6
crossprod(c(1,2,3),c(1,1,1)) # skalarny sucin - vysledok je matica 1x1 [,1]
[1,] 6
c(1,2,3)*c(1,1,1) # Hadamardov sucin (sucin zodpovedajucich prvkov vektora)[1] 1 2 3
length(c(1,2,3,4,5))[1] 5
length(v5) #vektor v5 je definovany vyssie[1] 5
c(1,2,3,4,5) + v5 # pozor, oba vektory musia mat rovnaky rozmer[1] 1.308805 2.538614 3.220779 4.451883 5.522919
x <- c(5, 12, 3, 18, 7, 0, 21)
x[1] # indexovanie - novy jedno-prvkovy vektor - prvy prvok vektora x[1] 5
x[2:4] # novy vektor s druhym az stvrtym prvkom vektora x[1] 12 3 18
x[-1] # novy vektor - vsetky prvky vektora x okrem prvého[1] 12 3 18 7 0 21
x[x > 10] # novy vektor definovany prvkami x vacsimi ako 10[1] 12 18 21
which(x > 10) # ktore prvky zodpovedaju podmienke vacsieho ako 10?[1] 2 4 7
y <- c(1, NA, 3, NA, 5)
is.na(y)[1] FALSE TRUE FALSE TRUE FALSE
mean(y) # NA[1] NA
mean(y, na.rm = TRUE) # remove NAs[1] 3
z <- c(10, 3, 5, 8, 2)
mean(z) # priemerna hodnota[1] 5.6
sd(z) # standardna odchylka[1] 3.361547
max(z) # maximalna hodnota[1] 10
summary(z) # rychly prehlad zakladnych statistik o vektore Min. 1st Qu. Median Mean 3rd Qu. Max.
2.0 3.0 5.0 5.6 8.0 10.0
sort(z) # rastuce usporiadanie [1] 2 3 5 8 10
sort(z, decreasing = TRUE) # klesajuce[1] 10 8 5 3 2
🎮 Vlastný príklad – hráčske štatistiky.
mean(eliminacie)[1] 22.16667
sd(eliminacie)[1] 5.192944
max(eliminacie)[1] 29
sort(eliminacie, decreasing = TRUE)Ancient Dust2 Inferno Anubis Mirage Nuke
29 26 24 21 18 15
🎯 Quest 02 – Body v zápasoch. Vektor w obsahuje body získané počas 20 herných kôl. Vypočítajte súčet bodov z kôl s párnym poradovým číslom (pozor: filtrujeme indexy, nie párne hodnoty).
w <- c(120, 180, 150, 220, 140, 260, 170, 190, 210, 160,
240, 180, 130, 270, 200, 250, 190, 230, 210, 300)
parne_kola <- seq(2, length(w), by = 2)
sum(w[parne_kola])[1] 2240
mean(w); max(w)[1] 200
[1] 300
m <- matrix(1:12, nrow = 3, ncol = 4) # hodnoty sú zadavane po stlpcoch
m_byrow <- matrix(1:12, nrow = 3, byrow = TRUE) # hodnoty su zadavane po riadkoch
m; m_byrow [,1] [,2] [,3] [,4]
[1,] 1 4 7 10
[2,] 2 5 8 11
[3,] 3 6 9 12
[,1] [,2] [,3] [,4]
[1,] 1 2 3 4
[2,] 5 6 7 8
[3,] 9 10 11 12
dim(m) # (rows, cols)[1] 3 4
m [,1] [,2] [,3] [,4]
[1,] 1 4 7 10
[2,] 2 5 8 11
[3,] 3 6 9 12
m[1, 2] # riadok 1, stlpec 2[1] 4
m[ , 3] # tretí stĺpec: R štandardne vráti vektor[1] 7 8 9
m[2, ] # druhý riadok: R štandardne vráti vektor[1] 2 5 8 11
m[1:2, 2:3] # podmatica tvorena riadkami 1, 2 a stlpcami 2, 3 [,1] [,2]
[1,] 4 7
[2,] 5 8
A <- matrix(c(1,2,3,4), nrow = 2)
B <- matrix(c(5,6,7,8), nrow = 2)
A + B # scitanie matic [,1] [,2]
[1,] 6 10
[2,] 8 12
A * B # Hadamard product - nasobenie po zodpovedajucich prvkoch [,1] [,2]
[1,] 5 21
[2,] 12 32
A %*% B # nasobenie matic [,1] [,2]
[1,] 23 31
[2,] 34 46
t(A) # transpozicia matice A - vymena riadkov a stlpcov [,1] [,2]
[1,] 1 2
[2,] 3 4
det(A) # determinant matice[1] -2
solve(A) # inverzia matice (ak je matica regularna - teda inverzia sa da spocitat) [,1] [,2]
[1,] -2 1.5
[2,] 1 -0.5
C <- cbind(1:3, 4:6) # - po stlpcoch
D <- rbind(1:3, 4:6) # - po riadkoch
C; D [,1] [,2]
[1,] 1 4
[2,] 2 5
[3,] 3 6
[,1] [,2] [,3]
[1,] 1 2 3
[2,] 4 5 6
M <- matrix(1:9, nrow = 3)
M [,1] [,2] [,3]
[1,] 1 4 7
[2,] 2 5 8
[3,] 3 6 9
apply(M, 1, sum) # suma po riadkoch[1] 12 15 18
apply(M, 2, mean) # priemery po stĺpcoch[1] 2 5 8
🎮 Vlastný príklad – skóre tímu. V riadkoch sú hráči, v stĺpcoch mapy; každé číslo je počet eliminácií.
skore <- matrix(c(21, 19, 25,
17, 22, 20,
24, 23, 18,
15, 18, 21), nrow = 4, byrow = TRUE)
rownames(skore) <- paste0("Hrac_", 1:4)
colnames(skore) <- c("Mirage", "Inferno", "Nuke")
skore Mirage Inferno Nuke
Hrac_1 21 19 25
Hrac_2 17 22 20
Hrac_3 24 23 18
Hrac_4 15 18 21
rowSums(skore) # výsledky hráčov naprieč mapamiHrac_1 Hrac_2 Hrac_3 Hrac_4
65 59 65 54
colSums(skore) # výsledky na jednotlivých mapách Mirage Inferno Nuke
77 82 84
apply(skore, 1, mean) # priemer podľa hráča Hrac_1 Hrac_2 Hrac_3 Hrac_4
21.66667 19.66667 21.66667 18.00000
apply(skore, 2, mean) # priemer podľa mapy Mirage Inferno Nuke
19.25 20.50 21.00
🎯 Quest 03 – Päť hráčov, päť máp. Zostavte maticu 5 × 5, v ktorej riadky predstavujú hráčov a stĺpce päť máp. Vypočítajte súčet eliminácií na jednotlivých mapách a maticový súčin (M^T M).
M2 <- matrix(c(18, 22, 17, 25, 20,
21, 19, 23, 16, 24,
15, 20, 18, 22, 19,
26, 24, 21, 23, 27,
17, 16, 20, 19, 22),
nrow = 5, byrow = TRUE)
rownames(M2) <- paste0("Hrac_", 1:5)
colnames(M2) <- c("Mirage", "Inferno", "Nuke", "Ancient", "Anubis")
M2 Mirage Inferno Nuke Ancient Anubis
Hrac_1 18 22 17 25 20
Hrac_2 21 19 23 16 24
Hrac_3 15 20 18 22 19
Hrac_4 26 24 21 23 27
Hrac_5 17 16 20 19 22
colSums(M2) # eliminácie podľa mapy Mirage Inferno Nuke Ancient Anubis
97 101 99 105 112
rowSums(M2) # eliminácie podľa hráčaHrac_1 Hrac_2 Hrac_3 Hrac_4 Hrac_5
102 103 94 121 94
t(M2) %*% M2 # súčin transponovanej a pôvodnej matice Mirage Inferno Nuke Ancient Anubis
Mirage 1955 1991 1945 2037 2225
Inferno 1991 2077 1995 2150 2276
Nuke 1945 1995 1983 2052 2241
Ancient 2037 2150 2052 2255 2341
Anubis 2225 2276 2241 2341 2550
Nech \(\mathbf A\) je štvorcová matica. Vlastné číslo (eigenvalue) \(\lambda\) a príslušný vlastný vektor (eigenvector) \(\mathbf v \ne \mathbf 0\) spĺňajú vzťah
\[ \mathbf A \mathbf v = \lambda \mathbf v. \]
Násobenie maticou \(\mathbf A\) teda pôsobí na vlastný vektor rovnako ako násobenie číslom \(\lambda\). Výsledok reprezentuje vektor rovnakého smeru, ale rozličných veľkostí:
Dĺžka sa násobí hodnotou \(|\lambda|\). Napríklad pri \(\lambda = 3\) sa vektor predĺži trojnásobne, pri \(\lambda = 0.5\) sa skráti na polovicu. Tento geometrický opis sa týka reálnych vlastných čísel a vektorov.
Použijeme symetrickú maticu, teda maticu, pre ktorú platí \(A^T = A\):1
\[ \mathbf A = \begin{pmatrix} 2 & 1 \\ 1 & 2 \end{pmatrix}. \]
Vlastné čísla nájdeme podľa nasledovného postupu:
\[\begin{eqnarray} \mathbf A \mathbf h & = & \lambda \mathbf h \\ \mathbf A \mathbf h - \lambda \mathbf h & = & \mathbf 0 \\ (\mathbf A - \lambda \mathbf I)\mathbf h & = & \mathbf 0, \end{eqnarray} \]
kde \(\mathbf I\) je jednotková matica.
Netriviálne (nenulové) riešenie tejto sústavy existuje vtedy, keď
\[ \det(\mathbf A-\lambda \mathbf I)=0. \]
V našom prípade
\[ \mathbf A-\lambda \mathbf I = \begin{pmatrix} 2-\lambda & 1 \\ 1 & 2-\lambda \end{pmatrix}, \]
a preto
\[ \det(\mathbf A-\lambda \mathbf I) = \begin{vmatrix} 2-\lambda & 1 \\ 1 & 2-\lambda \end{vmatrix} = (2-\lambda)^2-1. \]
Dostávame charakteristickú rovnicu
\[ (2-\lambda)^2-1 = \lambda^2-4\lambda+3 = (\lambda-3)(\lambda-1) = 0. \]
Vlastné čísla sú koreňmi (riešeniami) kvadratickej rovnice a teda
\[ \lambda_1=3, \qquad \lambda_2=1. \]
Vlastný vektor vypočítame zo vzťahu
\[ (\mathbf A-\lambda_1\mathbf I)\mathbf h_1=\mathbf 0. \]
Po dosadení \(\lambda_1=3\) dostávame
\[ \left[ \begin{pmatrix} 2 & 1\\ 1 & 2 \end{pmatrix} - 3 \begin{pmatrix} 1&0\\ 0&1 \end{pmatrix} \right] \begin{pmatrix} h_{11}\\ h_{21} \end{pmatrix} = \begin{pmatrix} 0\\ 0 \end{pmatrix}. \]
Teda
\[ \begin{pmatrix} -1&1\\ 1&-1 \end{pmatrix} \begin{pmatrix} h_{11}\\ h_{21} \end{pmatrix} = \begin{pmatrix} 0\\ 0 \end{pmatrix}. \]
Získame sústavu rovníc
\[ \begin{eqnarray} -h_{11}+h_{21} &=&0,\\ h_{11}-h_{21} &=&0, \end{eqnarray} \] pričom zavedieme ešte dodatočnú podmienku normalizácie vlastných vektorov2, teda
\[\sqrt{h_{11}^2 + h_{21}^2} = 1\]
Prvé dve rovnice vyjadrujú tú istú podmienku:
\[ h_{11}=h_{21}. \]
Teda z normalizačnej podmienky dostávame
\[\sqrt{h_{11}^2 + h_{21}^2} = 1 \Longleftrightarrow h_{11} = h_{21} = \pm \sqrt{\frac{1}{2}}\]
Môžeme preto napríklad zvoliť
\[ h_{11}=+\sqrt{\frac{1}{2}}, \]
a potom
\[ h_{21}=+\sqrt{\frac{1}{2}}. \]
Vlastný vektor zodpovedajúci vlastnému číslu \(\lambda_1=3\) môže byť teda
\[ \mathbf h_1= \begin{pmatrix} +\sqrt{\frac{1}{2}}\\ +\sqrt{\frac{1}{2}} \end{pmatrix}. \]
Každý nenulový násobok tohto vektora je však tiež vlastným vektorom. Napríklad
\[ \begin{pmatrix} +1\\ +1 \end{pmatrix} \]
predstavuje ten istý smer.
Keďže platí
\[ \begin{aligned} \left[ \begin{pmatrix} 2 & 1 \\ 1 & 2 \end{pmatrix} - 1 \cdot \begin{pmatrix} 1 & 0 \\ 0 & 1 \end{pmatrix} \right] \begin{pmatrix} h_{12} \\ h_{22} \end{pmatrix} &= \begin{pmatrix} 0 \\ 0 \end{pmatrix} \\[1em] \Longleftrightarrow \qquad \begin{pmatrix} 1 & 1 \\ 1 & 1 \end{pmatrix} \begin{pmatrix} h_{12} \\ h_{22} \end{pmatrix} &= \begin{pmatrix} 0 \\ 0 \end{pmatrix}. \end{aligned} \]
dostávame sústavu rovníc
\[ \begin{eqnarray} h_{12}+h_{22} &=&0,\\ h_{12}+h_{22} &=&0. \end{eqnarray} \]
Z toho vyplýva
\[ h_{22}=-h_{12}. \]
Ak zvolíme dodatočnú normalizačnú podmienku
\[\sqrt{h_{12}^2 + h_{22}^2} = 1,\] potom ak
\[ h_{12}=\sqrt{\frac{1}{2}}, \]
pre druhý prvok vektora bude platiť
\[ h_{22}=-\sqrt{\frac{1}{2}}. \]
Vlastný vektor zodpovedajúci vlastnému číslu \(\lambda_2=1\) teda môžeme zapísať ako
\[ \mathbf h_2= \begin{pmatrix} \sqrt{\frac{1}{2}}\\ -\sqrt{\frac{1}{2}} \end{pmatrix}. \]
Opäť platí, že ľubovoľný nenulový násobok tohto vektora je tiež vlastným vektorom.
Pre prvý vlastný vektor platí
\[ \mathbf A\mathbf h_1 = \begin{pmatrix} 2&1\\ 1&2 \end{pmatrix} \begin{pmatrix} \sqrt{\frac{1}{2}}\\ \sqrt{\frac{1}{2}} \end{pmatrix} = 3 \begin{pmatrix} \sqrt{\frac{1}{2}}\\ \sqrt{\frac{1}{2}} \end{pmatrix} = \lambda_1 \mathbf h_1 \]
Teda
\[ \mathbf A\mathbf h_1=\lambda_1\mathbf h_1. \]
Podobne sa to dá ukázať aj pre druhé vlastné číslo \(\lambda_2\) a druhý vlastný vektor \(\mathbf h_2\).
Dostávame teda dvojice vlastných čísel a vlastných vektorov:
\[ \lambda_1=3, \qquad \mathbf h_1= \begin{pmatrix} \sqrt{\frac{1}{2}}\\ \sqrt{\frac{1}{2}} \end{pmatrix}, \]
a
\[ \lambda_2=1, \qquad \mathbf h_2= \begin{pmatrix} \sqrt{\frac{1}{2}}\\ -\sqrt{\frac{1}{2}} \end{pmatrix}. \]
Keďže matica \(\mathbf A\) je symetrická, vlastné vektory zodpovedajúce rôznym vlastným číslam sú navzájom ortogonálne (navzájom kolmé a po dvojiciach ich skalárne súčiny sa rovnajú nule). Skutočne,
\[ \mathbf h_1^T\mathbf h_2 = \left( \sqrt{\frac{1}{2}},\sqrt{\frac{1}{2}} \right) \begin{pmatrix} \sqrt{\frac{1}{2}}\\ -\sqrt{\frac{1}{2}} \end{pmatrix} = \frac{1}{2} - \frac{1}{2} = 0. \]
Funkcia eigen() je súčasťou základného R; nepotrebujeme ďalšiu knižnicu. Argument symmetric = TRUE použijeme, keď vieme, že matica je symetrická. Pri všeobecnej matici môžeme napísať jednoducho eigen() a R symetriu skontroluje samo.
# Vytvorenie matice z analytického príkladu
A_eig <- matrix(c(2, 1,
1, 2),
nrow = 2, byrow = TRUE)
A_eig [,1] [,2]
[1,] 2 1
[2,] 1 2
# Výpočet vlastných čísel a vlastných vektorov
eig_A <- eigen(A_eig, symmetric = TRUE) #vyuzitie funkcie eigen()
eig_A # vysledok sa ulozil do listu, ktory sme nazvali eig_Aeigen() decomposition
$values
[1] 3 1
$vectors
[,1] [,2]
[1,] 0.7071068 -0.7071068
[2,] 0.7071068 0.7071068
#Dalej pristupime k rozbaleniu obsahu listu eig_A
lambda_A <- eig_A$values # vektor vlastných čísel - ulozenie do lambda_A
V_A <- eig_A$vectors # vlastné vektory v stĺpcoch ulozenie do V_A
lambda_A[1] 3 1
V_A [,1] [,2]
[1,] 0.7071068 -0.7071068
[2,] 0.7071068 0.7071068
Výsledok eig_A je list. Znak $ vyberá jeho pomenovanú zložku:
| Zápis v R | Význam |
|---|---|
eig_A$values |
Všetky vlastné čísla |
eig_A$vectors |
Vlastné vektory uložené v stĺpcoch |
eig_A$values[1] |
Prvé vlastné číslo |
eig_A$vectors[, 1] |
Vlastný vektor prislúchajúci prvému vlastnému číslu |
Pri reálnej symetrickej matici R vráti vlastné čísla zostupne; tu teda 3 a 1. Vlastné vektory majú jednotkovú dĺžku. Môžu sa preto líšiť od našich ručne zvolených vektorov mierkou alebo znamienkom. Vektory \(v\) aj \(-v\) sú rovnako správne: vlastný vektor nie je jednoznačný.
Ak potrebujeme iba vlastné čísla:
eigen(A_eig, symmetric = TRUE, only.values = TRUE)$values[1] 3 1
V R použijeme na násobenie matice a vektora operátor %*%. Operátor * používame pri násobení vektora skalárom.
lambda_1 <- lambda_A[1]
v_1 <- V_A[, 1]
lava_strana <- as.vector(A_eig %*% v_1)
prava_strana <- lambda_1 * v_1
cat("Ľavá strana je ", paste(lava_strana, collapse = ", "),
" a pravá strana je ", paste(prava_strana, collapse = ", "), "!", sep = "")Ľavá strana je 2.12132034355964, 2.12132034355964 a pravá strana je 2.12132034355964, 2.12132034355964!
Porovnáme dva vlastné vektory. Pri vlastnom vektore zostáva jeho obraz (transformácia) na tej istej priamke.
local({
povodne <- par(mfrow = c(1, 2), mar = c(4, 4, 3, 1))
on.exit(par(povodne))
priklady <- list(c(1, 1), c(1, -1))
nazvy <- c("Vlastný vektor: lambda = 3",
"Vlastný vektor: lambda = 1")
for (j in seq_along(priklady)) {
x_plot <- priklady[[j]]
Ax_plot <- as.vector(A_eig %*% x_plot)
plot(NA, xlim = c(-1.5, 3.5), ylim = c(-1.5, 3.5),
asp = 1, xlab = "Prvá súradnica", ylab = "Druhá súradnica",
main = nazvy[j], cex.main = 0.85)
abline(h = 0, v = 0, col = "grey80")
arrows(0, 0, Ax_plot[1], Ax_plot[2],
col = "darkorange2", lwd = 4, length = 0.12)
arrows(0, 0, x_plot[1], x_plot[2],
col = "steelblue4", lwd = 2, lty = 2, length = 0.10)
legend("topleft", legend = c("x", "Ax"),
col = c("steelblue4", "darkorange2"),
lty = c(2, 1), lwd = c(2, 4), bty = "n", cex = 0.8)
}
})V prostrednom obrázku sa šípky prekrývajú, pretože \(Ax = x\). Cyklus for opakuje rovnaký postup oba vektory. Funkcia local() udržiava pomocné premenné grafu oddelene od ostatných výpočtov.
B_eig <- matrix(c(2, 1, 0,
1, 2, 0,
0, 0, 4), nrow = 3, byrow = TRUE)
eig_B <- eigen(B_eig, symmetric = TRUE)
eig_B$values # 4, 3, 1[1] 4 3 1
eig_B$vectors [,1] [,2] [,3]
[1,] 0 0.7071068 0.7071068
[2,] 0 0.7071068 -0.7071068
[3,] 1 0.0000000 0.0000000
# Súčty štvorcov prvkov jednotlivých stĺpcov sú 1.
colSums(eig_B$vectors^2)[1] 1 1 1
# Overenie všetkých troch vlastných párov.
max(abs(B_eig %*% eig_B$vectors -
eig_B$vectors %*% diag(eig_B$values)))[1] 5.551115e-16
Pre štvorcovú maticu platí: súčet vlastných čísel sa rovná stope matice (súčtu diagonálnych prvkov) a ich súčin sa rovná determinantu. Vlastné čísla pritom počítame aj s ich násobnosťami.
c(sucet_vlastnych_cisel = sum(eig_B$values),
stopa_matice = sum(diag(B_eig))) # obe hodnoty sú 8sucet_vlastnych_cisel stopa_matice
8 8
c(sucin_vlastnych_cisel = prod(eig_B$values),
determinant = det(B_eig)) # obe hodnoty sú 12sucin_vlastnych_cisel determinant
12 12
🎯 FINAL BOSS – variančno-kovariančná matica herných štatistík.
Vymysleli sme osem zápasov jedného hráča CS2. Každý riadok predstavuje jeden zápas; stĺpce obsahujú eliminácie, asistencie a damage/10 (škálovaný damage pre prehľadnejšie hodnoty). Z herných dát zostavte variančno-kovariančnú maticu, vypočítajte jej vlastné čísla a vlastné vektory a overte výsledky. Ide o ilustračné údaje, nie o oficiálne herné dáta.
# 1. Vlastné herné dáta: 8 zápasov × 3 ukazovatele
herne_data <- data.frame(
eliminacie = c(12, 16, 21, 19, 27, 24, 30, 17),
asistencie = c(3, 5, 4, 7, 8, 6, 9, 4),
damage_10 = c(35, 42, 58, 53, 72, 65, 81, 46)
)
herne_data eliminacie asistencie damage_10
1 12 3 35
2 16 5 42
3 21 4 58
4 19 7 53
5 27 8 72
6 24 6 65
7 30 9 81
8 17 4 46
# 2. Variančno-kovariančná matica zo vzorky zápasov
C <- cov(herne_data)
C eliminacie asistencie damage_10
eliminacie 35.92857 10.92857 93.42857
asistencie 10.92857 4.50000 28.28571
damage_10 93.42857 28.28571 244.28571
# 3. Súčet podľa riadkov a stĺpcov (požiadavka vyučujúceho)
rowSums(C)eliminacie asistencie damage_10
140.28571 43.71429 366.00000
colSums(C)eliminacie asistencie damage_10
140.28571 43.71429 366.00000
apply(C, 1, sum)eliminacie asistencie damage_10
140.28571 43.71429 366.00000
apply(C, 2, sum)eliminacie asistencie damage_10
140.28571 43.71429 366.00000
# 4. Vlastné čísla a vlastné vektory
eig_C <- eigen(C, symmetric = TRUE)
eig_C$values[1] 283.3407060 1.2111801 0.1623997
eig_C$vectors [,1] [,2] [,3]
[1,] -0.3553793 -0.04698683 0.93354044
[2,] -0.1081106 -0.98996683 -0.09098232
[3,] -0.9284490 0.13325884 -0.34673399
# 5. Overenie C %*% V = V %*% diag(lambda)
L <- diag(eig_C$values)
lava <- C %*% eig_C$vectors
prava <- eig_C$vectors %*% L
maximalna_odchylka <- max(abs(lava - prava))
maximalna_odchylka[1] 1.705303e-13
all.equal(lava, prava, tolerance = 1e-10)[1] "Attributes: < Length mismatch: comparison on first 1 components >"
# 6. Vlastné čísla kovariančnej matice by mali byť nezáporné
all(eig_C$values >= -1e-10)[1] TRUE
# 7. Podiel variability vysvetlený jednotlivými komponentmi
podiel_variability <- eig_C$values / sum(eig_C$values) * 100
round(podiel_variability, 2)[1] 99.52 0.43 0.06
cov() vypočítala variančno-kovariančnú maticu z herných výsledkov.rowSums(C) a colSums(C) sumarizujú riadky a stĺpce; apply() ponúka univerzálny spôsob výpočtu. Súčet kovariancií nie je priemerné skóre hráča.eigen(C, symmetric = TRUE) vráti vlastné čísla a vlastné vektory symetrickej matice.max(abs(lava - prava)) má byť veľmi blízky nule, čím numericky overujeme vzťah (Cv = v).Poznámka k zadaniu: Vzorový analytický výklad vlastných čísel a vektorov z predlohy som zachoval ako učebný základ. Vlastným riešením je herný príklad vypočítaný z dát (nie z postupnosti
1:16).