TipCo se naučíte

V této kapitole se naučíte:

  • Co je vektor a jak ho reprezentovat
  • Rozdíl mezi skalárem a vektorem
  • Geometrickou interpretaci vektorů
  • Jak vypočítat délku (normu) vektoru
  • Pracovat s vektory v NumPy

7.1 Proč potřebujeme vektory?

V předchozích kapitolách jsme pracovali s jednotlivými čísly. Ale v reálném světě často potřebujeme popsat něco, co má více vlastností najednou:

  • Pozice má souřadnice x a y (nebo x, y, z ve 3D)
  • Rychlost má směr a velikost
  • Barva na obrazovce má složky R, G, B
  • Slovo v jazykovém modelu je reprezentováno stovkami čísel (embedding)

Pro všechny tyto případy používáme vektory.

PoznámkaVektory v AI

V neuronových sítích a jazykových modelech jsou vektory všudypřítomné:

  • Každé slovo je reprezentováno jako vektor (word embedding)
  • Vstupy a výstupy neuronů jsou vektory
  • Obrázky jsou reprezentovány jako vektory pixelů

7.2 Co je vektor?

Vektor je uspořádaná n-tice čísel. Můžeme si ho představit jako:

  1. Seznam čísel – matematicky
  2. Šipku v prostoru – geometricky
  3. Bod v prostoru – pozice
Kód
import numpy as np
import matplotlib.pyplot as plt

fig, ax = plt.subplots(figsize=(8, 8))

# Vektor v = [3, 2]
ax.annotate('', xy=(3, 2), xytext=(0, 0),
            arrowprops=dict(arrowstyle='->', color='blue', lw=3))
ax.plot(3, 2, 'bo', markersize=10)
ax.text(3.2, 2.2, 'v = [3, 2]', fontsize=14, color='blue')

# Složky vektoru
ax.plot([0, 3], [0, 0], 'r--', linewidth=2, label='x-složka = 3')
ax.plot([3, 3], [0, 2], 'g--', linewidth=2, label='y-složka = 2')

ax.axhline(y=0, color='k', linewidth=1)
ax.axvline(x=0, color='k', linewidth=1)
ax.grid(True, alpha=0.3)
ax.set_xlim(-1, 5)
ax.set_ylim(-1, 4)
ax.set_aspect('equal')
ax.set_xlabel('x')
ax.set_ylabel('y')
ax.set_title('Vektor v = [3, 2] jako šipka z počátku')
ax.legend()
plt.show()

Vektor jako šipka

7.2.1 Zápis vektorů

Vektory zapisujeme jako sloupec nebo řádek čísel:

\[\mathbf{v} = \begin{bmatrix} 3 \\ 2 \end{bmatrix} \quad \text{nebo} \quad \mathbf{v} = [3, 2]\]

PoznámkaKonvence
  • Vektory značíme tučně: \(\mathbf{v}\), \(\mathbf{w}\), \(\mathbf{x}\)
  • Nebo s šipkou: \(\vec{v}\)
  • Jednotlivá čísla ve vektoru jsou složky (komponenty)
  • Počet složek je dimenze vektoru
import numpy as np

# 2D vektor
v2 = np.array([3, 2])
print(f"2D vektor: {v2}")
print(f"Dimenze: {len(v2)}")

# 3D vektor
v3 = np.array([1, 2, 3])
print(f"\n3D vektor: {v3}")
print(f"Dimenze: {len(v3)}")

# Vektor s více dimenzemi (jako word embedding)
v100 = np.random.randn(100)
print(f"\n100D vektor (prvních 5 složek): {v100[:5].round(3)}...")
print(f"Dimenze: {len(v100)}")
2D vektor: [3 2]
Dimenze: 2

3D vektor: [1 2 3]
Dimenze: 3

100D vektor (prvních 5 složek): [-0.309 -0.812 -0.686 -0.428  1.389]...
Dimenze: 100

7.3 Skalár vs. vektor

Skalár Vektor
Jedno číslo Více čísel
Např. teplota: 25°C Např. pozice: [3, 2]
Pouze velikost Velikost + směr
x = 5 v = [3, 2]
# Skalár
import numpy as np

teplota = 25.0
print(f"Skalár (teplota): {teplota}")

# Vektor
pozice = np.array([3.0, 2.0])
print(f"Vektor (pozice): {pozice}")
Skalár (teplota): 25.0
Vektor (pozice): [3. 2.]

7.4 Vektory v NumPy

NumPy je ideální nástroj pro práci s vektory.

7.4.1 Vytváření vektorů

# Ze seznamu
import numpy as np

v1 = np.array([1, 2, 3])
print("Ze seznamu:", v1)

# Nulový vektor
v_nuly = np.zeros(5)
print("Nulový vektor:", v_nuly)

# Vektor jedniček
v_jednicky = np.ones(4)
print("Vektor jedniček:", v_jednicky)

# Rovnoměrně rozložené hodnoty
v_linspace = np.linspace(0, 1, 5)
print("Linspace:", v_linspace)

# Náhodný vektor
np.random.seed(42)
v_nahodny = np.random.randn(4)
print("Náhodný:", v_nahodny.round(3))
Ze seznamu: [1 2 3]
Nulový vektor: [0. 0. 0. 0. 0.]
Vektor jedniček: [1. 1. 1. 1.]
Linspace: [0.   0.25 0.5  0.75 1.  ]
Náhodný: [ 0.497 -0.138  0.648  1.523]

7.4.2 Přístup k složkám

import numpy as np

v = np.array([10, 20, 30, 40, 50])

print(f"Celý vektor: {v}")
print(f"První složka (index 0): {v[0]}")
print(f"Třetí složka (index 2): {v[2]}")
print(f"Poslední složka: {v[-1]}")
print(f"Prvních 3 složky: {v[:3]}")
print(f"Od indexu 2 do konce: {v[2:]}")
Celý vektor: [10 20 30 40 50]
První složka (index 0): 10
Třetí složka (index 2): 30
Poslední složka: 50
Prvních 3 složky: [10 20 30]
Od indexu 2 do konce: [30 40 50]

7.5 Délka (norma) vektoru

Délka neboli norma vektoru je jeho “velikost”. Pro vektor \(\mathbf{v} = [v_1, v_2, ..., v_n]\):

\[\|\mathbf{v}\| = \sqrt{v_1^2 + v_2^2 + ... + v_n^2}\]

Toto je Euklidovská norma (nebo L2 norma).

Kód
import numpy as np
import matplotlib.pyplot as plt

fig, ax = plt.subplots(figsize=(8, 6))

v = np.array([3, 4])

# Vektor
ax.annotate('', xy=(3, 4), xytext=(0, 0),
            arrowprops=dict(arrowstyle='->', color='blue', lw=3))

# Složky
ax.plot([0, 3], [0, 0], 'r-', linewidth=2)
ax.plot([3, 3], [0, 4], 'g-', linewidth=2)

# Popisky
ax.text(1.5, -0.4, '3', fontsize=12, color='red', ha='center')
ax.text(3.3, 2, '4', fontsize=12, color='green')
ax.text(1, 2.5, '||v|| = 5', fontsize=14, color='blue', rotation=53)

# Pravoúhlý trojúhelník
ax.plot([2.7, 2.7, 3], [0, 0.3, 0.3], 'k-', linewidth=1)

ax.set_xlim(-0.5, 5)
ax.set_ylim(-1, 5)
ax.set_aspect('equal')
ax.grid(True, alpha=0.3)
ax.axhline(y=0, color='k', linewidth=0.5)
ax.axvline(x=0, color='k', linewidth=0.5)
ax.set_title('Délka vektoru v = [3, 4]: ||v|| = √(3² + 4²) = 5')
plt.show()

Délka vektoru
# Výpočet normy
import numpy as np

v = np.array([3, 4])

# Ručně
norma_rucne = np.sqrt(v[0]**2 + v[1]**2)
print(f"Norma (ručně): √({v[0]}² + {v[1]}²) = √{v[0]**2 + v[1]**2} = {norma_rucne}")

# Pomocí np.linalg.norm
norma = np.linalg.norm(v)
print(f"Norma (NumPy): {norma}")

# Pro vyšší dimenze
v_5d = np.array([1, 2, 3, 4, 5])
print(f"\nNorma 5D vektoru [1,2,3,4,5]: {np.linalg.norm(v_5d):.3f}")
Norma (ručně): √(3² + 4²) = √25 = 5.0
Norma (NumPy): 5.0

Norma 5D vektoru [1,2,3,4,5]: 7.416

7.5.1 Jednotkový vektor

Jednotkový vektor má délku 1. Vytvoříme ho normalizací – dělením vektoru jeho normou:

\[\hat{\mathbf{v}} = \frac{\mathbf{v}}{\|\mathbf{v}\|}\]

import numpy as np

v = np.array([3, 4])

# Normalizace
v_jednotkovy = v / np.linalg.norm(v)

print(f"Původní vektor: {v}")
print(f"Délka původního: {np.linalg.norm(v)}")
print(f"\nJednotkový vektor: {v_jednotkovy}")
print(f"Délka jednotkového: {np.linalg.norm(v_jednotkovy)}")
Původní vektor: [3 4]
Délka původního: 5.0

Jednotkový vektor: [0.6 0.8]
Délka jednotkového: 1.0
import numpy as np
import matplotlib.pyplot as plt

fig, ax = plt.subplots(figsize=(8, 6))

v = np.array([3, 4])
v_norm = v / np.linalg.norm(v)

# Původní vektor
ax.annotate('', xy=v, xytext=(0, 0),
            arrowprops=dict(arrowstyle='->', color='blue', lw=2))
ax.text(v[0]+0.1, v[1]+0.1, f'v = {list(v)}', color='blue', fontsize=11)

# Jednotkový vektor
ax.annotate('', xy=v_norm, xytext=(0, 0),
            arrowprops=dict(arrowstyle='->', color='red', lw=3))
ax.text(v_norm[0]+0.1, v_norm[1]+0.1, f'v̂ ≈ [{v_norm[0]:.2f}, {v_norm[1]:.2f}]',
        color='red', fontsize=11)

# Jednotková kružnice
theta = np.linspace(0, 2*np.pi, 100)
ax.plot(np.cos(theta), np.sin(theta), 'gray', linestyle='--', alpha=0.5)

ax.set_xlim(-0.5, 4)
ax.set_ylim(-0.5, 5)
ax.set_aspect('equal')
ax.grid(True, alpha=0.3)
ax.axhline(y=0, color='k', linewidth=0.5)
ax.axvline(x=0, color='k', linewidth=0.5)
ax.set_title('Normalizace: jednotkový vektor má délku 1')
ax.legend(['Jednotková kružnice'], loc='upper left')
plt.show()

Původní vs. jednotkový vektor

7.6 Různé typy norem

Kromě Euklidovské normy (L2) existují i další:

Norma Vzorec Význam
L1 (Manhattan) \(\sum_i |v_i|\) Součet absolutních hodnot
L2 (Euklidovská) \(\sqrt{\sum_i v_i^2}\) “Vzdušná vzdálenost”
L∞ (Maximum) \(\max_i |v_i|\) Největší složka
import numpy as np

v = np.array([3, -4, 2])

l1 = np.linalg.norm(v, ord=1)
l2 = np.linalg.norm(v, ord=2)  # Výchozí
l_inf = np.linalg.norm(v, ord=np.inf)

print(f"Vektor: {v}")
print(f"L1 norma: |3| + |-4| + |2| = {l1}")
print(f"L2 norma: √(9 + 16 + 4) = {l2:.3f}")
print(f"L∞ norma: max(|3|, |-4|, |2|) = {l_inf}")
Vektor: [ 3 -4  2]
L1 norma: |3| + |-4| + |2| = 9.0
L2 norma: √(9 + 16 + 4) = 5.385
L∞ norma: max(|3|, |-4|, |2|) = 4.0
TipNormy ve strojovém učení
  • L1 regularizace podporuje řídké váhy (mnoho nul)
  • L2 regularizace omezuje velikost vah (weight decay)

7.7 Geometrická interpretace

7.7.1 Vektor jako posunutí

Vektor můžeme chápat jako instrukci “posuň se o tolik”:

import numpy as np
import matplotlib.pyplot as plt

fig, ax = plt.subplots(figsize=(8, 6))

# Několik vektorů z různých počátků
starts = [(0, 0), (2, 1), (1, 3)]
v = np.array([2, 1])

colors = ['blue', 'green', 'red']
for start, color in zip(starts, colors):
    end = (start[0] + v[0], start[1] + v[1])
    ax.annotate('', xy=end, xytext=start,
                arrowprops=dict(arrowstyle='->', color=color, lw=2))
    ax.plot(*start, 'o', color=color, markersize=8)

ax.text(4.5, 2, 'Všechny šipky reprezentují\nstejný vektor v = [2, 1]',
        fontsize=11, bbox=dict(boxstyle='round', facecolor='wheat'))

ax.set_xlim(-1, 6)
ax.set_ylim(-1, 5)
ax.set_aspect('equal')
ax.grid(True, alpha=0.3)
ax.set_title('Stejný vektor z různých počátků')
plt.show()

Vektor jako posunutí

7.7.2 Polohový vektor

Polohový vektor má počátek v nule a určuje pozici bodu:

import matplotlib.pyplot as plt

fig, ax = plt.subplots(figsize=(8, 6))

body = {'A': [2, 3], 'B': [4, 1], 'C': [1, 4]}
barvy = ['blue', 'red', 'green']

for (nazev, bod), barva in zip(body.items(), barvy):
    ax.annotate('', xy=bod, xytext=(0, 0),
                arrowprops=dict(arrowstyle='->', color=barva, lw=2))
    ax.plot(*bod, 'o', color=barva, markersize=10)
    ax.text(bod[0]+0.15, bod[1]+0.15, f'{nazev}{bod}', fontsize=11, color=barva)

ax.axhline(y=0, color='k', linewidth=1)
ax.axvline(x=0, color='k', linewidth=1)
ax.grid(True, alpha=0.3)
ax.set_xlim(-0.5, 5)
ax.set_ylim(-0.5, 5)
ax.set_aspect('equal')
ax.set_title('Polohové vektory bodů A, B, C')
plt.show()

Polohové vektory bodů

7.8 Aplikace v praxi

7.8.1 Word Embeddings

V jazykových modelech je každé slovo reprezentováno jako vektor (typicky 100-1000 dimenzí):

# Simulace word embeddingů (zjednodušeno na 3D pro vizualizaci)
import numpy as np

np.random.seed(42)

# Podobná slova mají podobné vektory
slova = {
    'král': np.array([0.5, 0.8, 0.2]),
    'královna': np.array([0.6, 0.9, 0.3]),
    'muž': np.array([0.4, 0.2, 0.1]),
    'žena': np.array([0.5, 0.3, 0.2]),
    'jablko': np.array([-0.5, 0.1, 0.8]),
    'pomeranč': np.array([-0.4, 0.2, 0.7])
}

print("Word embeddings (3D zjednodušení):")
for slovo, vektor in slova.items():
    print(f"  {slovo:10}: {vektor}")
Word embeddings (3D zjednodušení):
  král      : [0.5 0.8 0.2]
  královna  : [0.6 0.9 0.3]
  muž       : [0.4 0.2 0.1]
  žena      : [0.5 0.3 0.2]
  jablko    : [-0.5  0.1  0.8]
  pomeranč  : [-0.4  0.2  0.7]
Kód
import matplotlib.pyplot as plt

from mpl_toolkits.mplot3d import Axes3D

fig = plt.figure(figsize=(10, 8))
ax = fig.add_subplot(111, projection='3d')

barvy = {'král': 'blue', 'královna': 'blue', 'muž': 'green',
         'žena': 'green', 'jablko': 'red', 'pomeranč': 'red'}

for slovo, vektor in slova.items():
    ax.scatter(*vektor, c=barvy[slovo], s=100)
    ax.text(vektor[0], vektor[1], vektor[2], f'  {slovo}', fontsize=10)

ax.set_xlabel('Dimenze 1')
ax.set_ylabel('Dimenze 2')
ax.set_zlabel('Dimenze 3')
ax.set_title('Word embeddings: podobná slova jsou blízko sebe')
plt.show()

Word embeddings ve 3D prostoru

7.8.2 RGB barvy

Každá barva na obrazovce je vektor tří složek:

# Barvy jako RGB vektory (0-255)
import numpy as np
import matplotlib.pyplot as plt

barvy = {
    'Červená': np.array([255, 0, 0]),
    'Zelená': np.array([0, 255, 0]),
    'Modrá': np.array([0, 0, 255]),
    'Žlutá': np.array([255, 255, 0]),
    'Tyrkysová': np.array([0, 255, 255]),
    'Fialová': np.array([255, 0, 255]),
    'Oranžová': np.array([255, 165, 0]),
}

fig, ax = plt.subplots(figsize=(10, 3))

for i, (nazev, rgb) in enumerate(barvy.items()):
    ax.add_patch(plt.Rectangle((i, 0), 1, 1, color=rgb/255))
    ax.text(i+0.5, -0.15, nazev, ha='center', fontsize=9)
    ax.text(i+0.5, 0.5, f'[{rgb[0]},{rgb[1]},{rgb[2]}]',
            ha='center', va='center', fontsize=8, color='white' if sum(rgb) < 400 else 'black')

ax.set_xlim(0, len(barvy))
ax.set_ylim(-0.3, 1)
ax.axis('off')
ax.set_title('Barvy jako RGB vektory')
plt.show()

Barvy jako vektory

7.8.3 Pozice ve hře

# Pozice postav ve 2D hře
import numpy as np

hrac = np.array([5.0, 3.0])
nepritel = np.array([8.0, 7.0])
poklad = np.array([2.0, 6.0])

print(f"Hráč: {hrac}")
print(f"Nepřítel: {nepritel}")
print(f"Poklad: {poklad}")

# Vzdálenost k pokladu
vzdalenost = np.linalg.norm(poklad - hrac)
print(f"\nVzdálenost hráče k pokladu: {vzdalenost:.2f}")
Hráč: [5. 3.]
Nepřítel: [8. 7.]
Poklad: [2. 6.]

Vzdálenost hráče k pokladu: 4.24

7.9 Řešené příklady

7.9.1 Příklad 1: Vytvoření a norma

Vytvořte vektor \(\mathbf{v} = [1, 2, 2]\) a vypočítejte jeho délku.

import numpy as np

v = np.array([1, 2, 2])
norma = np.linalg.norm(v)

print(f"Vektor: {v}")
print(f"Norma: √(1² + 2² + 2²) = √(1 + 4 + 4) = √9 = {norma}")
Vektor: [1 2 2]
Norma: √(1² + 2² + 2²) = √(1 + 4 + 4) = √9 = 3.0

7.9.2 Příklad 2: Normalizace

Normalizujte vektor \(\mathbf{u} = [4, 0, 3]\).

import numpy as np

u = np.array([4, 0, 3])
norma_u = np.linalg.norm(u)
u_jednotkovy = u / norma_u

print(f"Původní: {u}")
print(f"Norma: √(16 + 0 + 9) = √25 = {norma_u}")
print(f"Jednotkový: {u_jednotkovy}")
print(f"Ověření délky: {np.linalg.norm(u_jednotkovy)}")
Původní: [4 0 3]
Norma: √(16 + 0 + 9) = √25 = 5.0
Jednotkový: [0.8 0.  0.6]
Ověření délky: 1.0

7.9.3 Příklad 3: Různé normy

Vypočítejte L1, L2 a L∞ normu vektoru \(\mathbf{w} = [-3, 4, 0, 2]\).

import numpy as np

w = np.array([-3, 4, 0, 2])

print(f"Vektor: {w}")
print(f"L1: |-3| + |4| + |0| + |2| = {np.linalg.norm(w, 1)}")
print(f"L2: √(9 + 16 + 0 + 4) = √29 ≈ {np.linalg.norm(w, 2):.3f}")
print(f"L∞: max(3, 4, 0, 2) = {np.linalg.norm(w, np.inf)}")
Vektor: [-3  4  0  2]
L1: |-3| + |4| + |0| + |2| = 9.0
L2: √(9 + 16 + 0 + 4) = √29 ≈ 5.385
L∞: max(3, 4, 0, 2) = 4.0

7.9.4 Příklad 4: Vzdálenost bodů

Vypočítejte vzdálenost mezi body A[1, 2, 3] a B[4, 6, 3].

import numpy as np

A = np.array([1, 2, 3])
B = np.array([4, 6, 3])

# Vektor z A do B
AB = B - A
print(f"Vektor AB: {AB}")

# Vzdálenost = délka vektoru AB
vzdalenost = np.linalg.norm(AB)
print(f"Vzdálenost: √(3² + 4² + 0²) = √25 = {vzdalenost}")
Vektor AB: [3 4 0]
Vzdálenost: √(3² + 4² + 0²) = √25 = 5.0

7.9.5 Příklad 5: Nejbližší slovo

Máme word embeddings. Které slovo je nejblíže slovu “král”?

# Použijeme data z dřívějška
import numpy as np

kral = slova['král']

print("Vzdálenosti od slova 'král':")
for nazev, vektor in slova.items():
    if nazev != 'král':
        vzdalenost = np.linalg.norm(vektor - kral)
        print(f"  {nazev:10}: {vzdalenost:.3f}")
Vzdálenosti od slova 'král':
  královna  : 0.173
  muž       : 0.616
  žena      : 0.500
  jablko    : 1.360
  pomeranč  : 1.192

7.10 Cvičení

VarováníCvičení 1: Vytvoření vektoru

Vytvořte vektor obsahující čísla 10, 20, 30, 40, 50 a zjistěte jeho dimenzi.

Výsledek: dimenze = 5

Řešení
import numpy as np

v = np.array([10, 20, 30, 40, 50])
print(f"Vektor: {v}")
print(f"Dimenze: {len(v)}")
VarováníCvičení 2: Norma vektoru

Vypočítejte délku vektoru \(\mathbf{v} = [5, 12]\).

Výsledek: 13

Řešení
import numpy as np

v = np.array([5, 12])
print(f"Norma: √(25 + 144) = √169 = {np.linalg.norm(v)}")
VarováníCvičení 3: Jednotkový vektor

Najděte jednotkový vektor ve směru \(\mathbf{u} = [0, 3, 4]\).

Výsledek: [0, 0.6, 0.8]

Řešení
import numpy as np

u = np.array([0, 3, 4])
norma = np.linalg.norm(u)  # = 5
u_hat = u / norma
print(f"Jednotkový: {u_hat}")
VarováníCvičení 4: Vzdálenost

Jaká je vzdálenost mezi body P[1, 1, 1] a Q[4, 5, 1]?

Výsledek: 5

Řešení
import numpy as np

P = np.array([1, 1, 1])
Q = np.array([4, 5, 1])
vzdalenost = np.linalg.norm(Q - P)
print(f"Vzdálenost: {vzdalenost}")  # √(9 + 16 + 0) = 5
VarováníCvičení 5: L1 norma

Vypočítejte L1 normu vektoru \(\mathbf{w} = [2, -3, 1, -4]\).

Výsledek: 10

Řešení
import numpy as np

w = np.array([2, -3, 1, -4])
l1 = np.linalg.norm(w, ord=1)
print(f"L1: |2| + |-3| + |1| + |-4| = {l1}")
VarováníCvičení 6: RGB mix

Smícháním jaké barvy (RGB vektor) vznikne bílá?

Výsledek: [255, 255, 255]

Řešení

Bílá vznikne smícháním maximální intenzity všech složek:

import numpy as np

bila = np.array([255, 255, 255])
print(f"Bílá: {bila}")

7.11 Shrnutí

PoznámkaCo si zapamatovat
  • Vektor je uspořádaná n-tice čísel (seznam, pole)
  • Vektor má směr a velikost (normu)
  • Norma (délka): \(\|\mathbf{v}\| = \sqrt{\sum v_i^2}\)
  • Jednotkový vektor má délku 1: \(\hat{\mathbf{v}} = \frac{\mathbf{v}}{\|\mathbf{v}\|}\)
  • V NumPy: np.array(), np.linalg.norm()
  • Vektory se používají všude: pozice, barvy, word embeddings

V další kapitole se naučíme operace s vektory – sčítání, násobení, a především skalární součin, který je základem pro měření podobnosti.