2022-12-06 09:55:40 +01:00
{
"cells": [
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "slide"
}
},
"source": [
"### Uczenie maszynowe\n",
"# 8. Uczenie nienadzorowane"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "notes"
}
},
"source": [
"Wyobraźmy sobie, że mamy następujący problem:\n",
"\n",
"Mamy zbiór okazów roślin i dysponujemy pewnymi danymi na ich temat (długość płatków kwiatów, ich szerokość itp.), ale zupełnie **nie wiemy**, do jakich gatunków one należą (nie wiemy nawet, ile jest tych gatunków).\n",
"\n",
"Chcemy automatycznie podzielić zbiór posiadanych okazów na nie więcej niż $k$ grup (klastrów) ($k$ ustalamy z góry), czyli dokonać **grupowania (klastrowania)** zbioru przykładów.\n",
"\n",
"Jest to zagadnienie z kategorii uczenia nienadzorowanego.\n",
"\n",
"W celu jego rozwiązania użyjemy algorytmu $k$ średnich."
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "slide"
}
},
"source": [
"## 8.1. Algorytm $k$ średnich"
]
},
{
"cell_type": "code",
2022-12-09 15:06:17 +01:00
"execution_count": 1,
2022-12-06 09:55:40 +01:00
"metadata": {
"slideshow": {
"slide_type": "notes"
}
},
"outputs": [],
"source": [
"# Przydatne importy\n",
"\n",
"import ipywidgets as widgets\n",
"import matplotlib.pyplot as plt\n",
"import numpy as np\n",
"import pandas\n",
"import random\n",
"import seaborn\n",
"\n",
"%matplotlib inline"
]
},
{
"cell_type": "code",
2022-12-09 15:06:17 +01:00
"execution_count": 2,
2022-12-06 09:55:40 +01:00
"metadata": {
"slideshow": {
"slide_type": "notes"
}
},
"outputs": [],
"source": [
"# Wczytanie danych (gatunki kosaćców)\n",
"\n",
"data_iris_raw = pandas.read_csv('iris.csv')\n",
"data_iris = pandas.DataFrame()\n",
"data_iris['x1'] = data_iris_raw['sl']\n",
"data_iris['x2'] = data_iris_raw['sw']\n",
"data_iris['x3'] = data_iris_raw['pl']\n",
"data_iris['x4'] = data_iris_raw['sw']\n",
"\n",
"# Nie używamy w ogóle kolumny ostatniej kolumny (\"Gatunek\"), \n",
"# ponieważ chcemy dokonać uczenia nienadzorowanego.\n",
"# Przyjmujemy, że w ogóle nie dysponujemy danymi na temat gatunku,\n",
"# mamy tylko 150 nieznanych roślin.\n",
"\n",
"X = data_iris.values\n",
"Xs = data_iris.values[:, 2:4]"
]
},
{
"cell_type": "code",
2022-12-09 15:06:17 +01:00
"execution_count": 3,
2022-12-06 09:55:40 +01:00
"metadata": {
"slideshow": {
"slide_type": "notes"
}
},
"outputs": [],
"source": [
"# Wykres danych\n",
"def plot_unlabeled_data(X, col1=0, col2=1, x1label=r'$x_1$', x2label=r'$x_2$'): \n",
" fig = plt.figure(figsize=(16*.7, 9*.7))\n",
" ax = fig.add_subplot(111)\n",
" fig.subplots_adjust(left=0.1, right=0.9, bottom=0.1, top=0.9)\n",
" X1 = X[:, col1].tolist()\n",
" X2 = X[:, col2].tolist()\n",
" ax.scatter(X1, X2, c='k', marker='o', s=50, label='Dane')\n",
" ax.set_xlabel(x1label)\n",
" ax.set_ylabel(x2label)\n",
" ax.margins(.05, .05)\n",
" return fig"
]
},
{
"cell_type": "code",
2022-12-09 15:06:17 +01:00
"execution_count": 4,
2022-12-06 09:55:40 +01:00
"metadata": {
"slideshow": {
"slide_type": "notes"
}
},
"outputs": [],
"source": [
"# Przygotowanie interaktywnego wykresu\n",
"\n",
"dropdown_arg1 = widgets.Dropdown(options=[0, 1, 2, 3], value=2, description='arg1')\n",
"dropdown_arg2 = widgets.Dropdown(options=[0, 1, 2, 3], value=3, description='arg2')\n",
"\n",
"def interactive_unlabeled_data(arg1, arg2):\n",
" fig = plot_unlabeled_data(\n",
" X, col1=arg1, col2=arg2, x1label='$x_{}$'.format(arg1), x2label='$x_{}$'.format(arg2))"
]
},
{
"cell_type": "code",
2022-12-09 15:06:17 +01:00
"execution_count": 5,
2022-12-06 09:55:40 +01:00
"metadata": {
2022-12-09 15:06:17 +01:00
"scrolled": true,
2022-12-06 09:55:40 +01:00
"slideshow": {
"slide_type": "subslide"
}
},
"outputs": [
{
"data": {
"application/vnd.jupyter.widget-view+json": {
2022-12-09 15:06:17 +01:00
"model_id": "fff79223f9b24b198bd1ae328be8cb5f",
2022-12-06 09:55:40 +01:00
"version_major": 2,
"version_minor": 0
},
"text/plain": [
"interactive(children=(Dropdown(description='arg1', index=2, options=(0, 1, 2, 3), value=2), Dropdown(descripti…"
]
},
"metadata": {},
"output_type": "display_data"
},
{
"data": {
"text/plain": [
"<function __main__.interactive_unlabeled_data(arg1, arg2)>"
]
},
2022-12-09 15:06:17 +01:00
"execution_count": 5,
2022-12-06 09:55:40 +01:00
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"widgets.interact(interactive_unlabeled_data, arg1=dropdown_arg1, arg2=dropdown_arg2)"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "notes"
}
},
"source": [
"Powyższy wykres przedstawia surowe dane.\n",
"Ponieważ nasze obserwacje mają 4 współrzędne, na płaskim wykresie możemy przedstawić tylko dwie z nich.\n",
"\n",
"Dlatego powyższy wykres umożliwia wybór dwóch współrzędnych, na które chcemy rzutować.\n",
"\n",
"Wszystkie takie „rzuty” przedstawia również wykres poniżej."
]
},
{
"cell_type": "code",
2022-12-09 15:06:17 +01:00
"execution_count": 6,
2022-12-06 09:55:40 +01:00
"metadata": {
"slideshow": {
"slide_type": "skip"
}
},
"outputs": [
2022-12-09 15:06:17 +01:00
{
"name": "stderr",
"output_type": "stream",
"text": [
"/home/pawel/.local/lib/python3.10/site-packages/seaborn/axisgrid.py:2095: UserWarning: The `size` parameter has been renamed to `height`; please update your code.\n",
" warnings.warn(msg, UserWarning)\n"
]
},
2022-12-06 09:55:40 +01:00
{
"data": {
"text/plain": [
2022-12-09 15:06:17 +01:00
"<seaborn.axisgrid.PairGrid at 0x7fa3b4118d90>"
2022-12-06 09:55:40 +01:00
]
},
2022-12-09 15:06:17 +01:00
"execution_count": 6,
2022-12-06 09:55:40 +01:00
"metadata": {},
"output_type": "execute_result"
},
{
"data": {
2022-12-09 15:06:17 +01:00
"image/png": "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
2022-12-06 09:55:40 +01:00
"text/plain": [
2022-12-09 15:06:17 +01:00
"<Figure size 1050x600 with 20 Axes>"
2022-12-06 09:55:40 +01:00
]
},
2022-12-09 15:06:17 +01:00
"metadata": {},
2022-12-06 09:55:40 +01:00
"output_type": "display_data"
}
],
"source": [
"seaborn.pairplot(data_iris, vars=data_iris.columns, size=1.5, aspect=1.75)"
]
},
{
"cell_type": "code",
2022-12-09 15:06:17 +01:00
"execution_count": 7,
2022-12-06 09:55:40 +01:00
"metadata": {
"slideshow": {
"slide_type": "notes"
}
},
"outputs": [],
"source": [
"# Odległość euklidesowa\n",
"def euclidean_distance(x1, x2):\n",
" return np.linalg.norm(x1 - x2)"
]
},
{
"cell_type": "code",
2022-12-09 15:06:17 +01:00
"execution_count": 8,
2022-12-06 09:55:40 +01:00
"metadata": {
"slideshow": {
"slide_type": "notes"
}
},
"outputs": [],
"source": [
"# Algorytm k średnich\n",
"def k_means(X, k, distance=euclidean_distance):\n",
" history = []\n",
" Y = []\n",
" \n",
" # Wylosuj centroid dla każdej klasy\n",
" centroids = [[random.uniform(X.min(axis=0)[f], X.max(axis=0)[f])\n",
" for f in range(X.shape[1])]\n",
" for c in range(k)]\n",
" history.append((centroids, Y))\n",
"\n",
" # Powtarzaj, dopóki klasy się zmieniają\n",
" while True:\n",
" distances = [[distance(centroids[c], x) for c in range(k)] for x in X]\n",
" Y_new = [d.index(min(d)) for d in distances]\n",
" if Y_new == Y:\n",
" break\n",
" Y = Y_new\n",
" history.append((centroids, Y))\n",
" XY = np.asarray(np.concatenate((X, np.matrix(Y).T), axis=1))\n",
" Xc = [XY[XY[:, 2] == c][:, :-1] for c in range(k)]\n",
" centroids = [[Xc[c].mean(axis=0)[f] for f in range(X.shape[1])]\n",
" for c in range(k)]\n",
" history.append((centroids, Y))\n",
"\n",
" result = history[-1][1]\n",
" return result, history"
]
},
{
"cell_type": "code",
2022-12-09 15:06:17 +01:00
"execution_count": 9,
2022-12-06 09:55:40 +01:00
"metadata": {
"slideshow": {
"slide_type": "notes"
}
},
"outputs": [],
"source": [
"# Wykres danych - klastrowanie\n",
"def plot_clusters(X, Y, k, centroids=None):\n",
" color = ['r', 'g', 'b', 'c', 'm', 'y', 'k']\n",
" fig = plt.figure(figsize=(16*.7, 9*.7))\n",
" ax = fig.add_subplot(111)\n",
" fig.subplots_adjust(left=0.1, right=0.9, bottom=0.1, top=0.9)\n",
"\n",
" if not Y:\n",
" ax.scatter(X[:, 0], X[:, 1], c='gray', marker='o', s=25, label='Dane')\n",
"\n",
" X1 = [[x for x, y in zip(X[:, 0].tolist(), Y) if y == c] for c in range(k)]\n",
" X2 = [[x for x, y in zip(X[:, 1].tolist(), Y) if y == c] for c in range(k)]\n",
"\n",
" for c in range(k):\n",
" ax.scatter(X1[c], X2[c], c=color[c], marker='o', s=25, label='Dane')\n",
" if centroids:\n",
" ax.scatter([centroids[c][0]], [centroids[c][1]], c=color[c], marker='+', s=500, label='Centroid')\n",
" \n",
" ax.set_xlabel(r'$x_1$')\n",
" ax.set_ylabel(r'$x_2$')\n",
" ax.margins(.05, .05)\n",
" return fig"
]
},
{
"cell_type": "code",
2022-12-09 15:06:17 +01:00
"execution_count": 10,
2022-12-06 09:55:40 +01:00
"metadata": {
"slideshow": {
"slide_type": "subslide"
}
},
"outputs": [
{
"data": {
2022-12-09 15:06:17 +01:00
"image/png": "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
2022-12-06 09:55:40 +01:00
"text/plain": [
2022-12-09 15:06:17 +01:00
"<Figure size 1120x630 with 1 Axes>"
2022-12-06 09:55:40 +01:00
]
},
2022-12-09 15:06:17 +01:00
"metadata": {},
2022-12-06 09:55:40 +01:00
"output_type": "display_data"
}
],
"source": [
"Ys, history = k_means(Xs, 2)\n",
"fig = plot_clusters(Xs, Ys, 2, centroids=history[-1][0]),"
]
},
{
"cell_type": "code",
2022-12-09 15:06:17 +01:00
"execution_count": 11,
2022-12-06 09:55:40 +01:00
"metadata": {
"slideshow": {
"slide_type": "notes"
}
},
"outputs": [],
"source": [
"# Przygotowanie interaktywnego wykresu\n",
"\n",
"MAXSTEPS = 15\n",
"\n",
"slider_k = widgets.IntSlider(min=1, max=7, step=1, value=2, description=r'$k$', width=300)\n",
"\n",
"def interactive_kmeans_k(steps, history, k):\n",
" if steps >= len(history) or steps == MAXSTEPS:\n",
" steps = len(history) - 1\n",
" fig = plot_clusters(Xs, history[steps][1], k, centroids=history[steps][0])\n",
" \n",
"def interactive_kmeans(k):\n",
" slider_steps = widgets.IntSlider(min=0, max=MAXSTEPS, step=1, value=0, description=r'steps', width=300)\n",
" _, history = k_means(Xs, k)\n",
" widgets.interact(interactive_kmeans_k, steps=slider_steps,\n",
" history=widgets.fixed(history), k=widgets.fixed(k))"
]
},
{
"cell_type": "code",
2022-12-09 15:06:17 +01:00
"execution_count": 17,
2022-12-06 09:55:40 +01:00
"metadata": {
"slideshow": {
"slide_type": "subslide"
}
},
"outputs": [
{
"data": {
"application/vnd.jupyter.widget-view+json": {
2022-12-09 15:06:17 +01:00
"model_id": "792bfa09b0d14970ad900188eb04aba6",
2022-12-06 09:55:40 +01:00
"version_major": 2,
"version_minor": 0
},
"text/plain": [
"interactive(children=(IntSlider(value=2, description='$k$', max=7, min=1), Button(description='Run Interact', …"
]
},
"metadata": {},
"output_type": "display_data"
},
{
"data": {
"text/plain": [
"<function __main__.interactive_kmeans(k)>"
]
},
2022-12-09 15:06:17 +01:00
"execution_count": 17,
2022-12-06 09:55:40 +01:00
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"widgets.interact_manual(interactive_kmeans, k=slider_k) "
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "subslide"
}
},
"source": [
"### Algorytm $k$ średnich – dane wejściowe\n",
"\n",
"* $k$ – liczba klastrów\n",
"* zbiór uczący $X = \\{ x^{(1)}, x^{(2)}, \\ldots, x^{(m)} \\}$, $x^{(i)} \\in \\mathbb{R}^n$"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "fragment"
}
},
"source": [
"Na wejściu nie ma zbioru $Y$, ponieważ jest to uczenie nienadzorowane!"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "subslide"
}
},
"source": [
"### Algorytm $k$ średnich – pseudokod\n",
"\n",
"1. Zainicjalizuj losowo $k$ centroidów (środków ciężkości klastrów): $\\mu_1, \\ldots, \\mu_k$.\n",
"1. Powtarzaj dopóki przyporządkowania klastrów się zmieniają:\n",
" 1. Dla $i = 1$ do $m$:\n",
" za $y^{(i)}$ przyjmij klasę najbliższego centroidu.\n",
" 1. Dla $c = 1$ do $k$:\n",
" za $\\mu_c$ przyjmij średnią wszystkich punktów $x^{(i)}$ takich, że $y^{(i)} = c$."
]
},
{
"cell_type": "code",
"execution_count": 13,
"metadata": {
"slideshow": {
"slide_type": "subslide"
}
},
"outputs": [],
"source": [
"# Algorytm k średnich\n",
"def kmeans(X, k, distance=euclidean_distance):\n",
" Y = []\n",
" centroids = [[random.uniform(X.min(axis=0)[f],X.max(axis=0)[f])\n",
" for f in range(X.shape[1])]\n",
" for c in range(k)] # Wylosuj centroidy\n",
" while True:\n",
" distances = [[distance(centroids[c], x) for c in range(k)]\n",
" for x in X] # Oblicz odległości\n",
" Y_new = [d.index(min(d)) for d in distances]\n",
" if Y_new == Y:\n",
" break # Jeśli nic się nie zmienia, przerwij\n",
" Y = Y_new\n",
" XY = np.asarray(np.concatenate((X,np.matrix(Y).T),axis=1))\n",
" Xc = [XY[XY[:, 2] == c][:, :-1] for c in range(k)]\n",
" centroids = [[Xc[c].mean(axis=0)[f]\n",
" for f in range(X.shape[1])]\n",
" for c in range(k)] # Przesuń centroidy\n",
" return Y"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "subslide"
}
},
"source": [
"* Liczba klastrów jest określona z góry i wynosi $k$."
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "fragment"
}
},
"source": [
"* Jeżeli w którymś kroku algorytmu jedna z klas nie zostanie przyporządkowana żadnemu z przykładów, pomija się ją – w ten sposób wynikiem działania algorytmu może być mniej niż $k$ klastrów."
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "subslide"
}
},
"source": [
"### Funkcja kosztu dla problemu klastrowania\n",
"\n",
"$$ J \\left( y^{(i)}, \\ldots, y^{(m)}, \\mu_{1}, \\ldots, \\mu_{k} \\right) = \\frac{1}{m} \\sum_{i=1}^{m} || x^{(i)} - \\mu_{y^{(i)}} || ^2 $$"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "fragment"
}
},
"source": [
"* Zauważmy, że z każdym krokiem algorytmu $k$ średnich koszt się zmniejsza (lub ewentualnie pozostaje taki sam)."
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "subslide"
}
},
"source": [
"### Wielokrotna inicjalizacja\n",
"\n",
"* Algorytm $k$ średnich zawsze znajdzie lokalne minimum funkcji kosztu $J$, ale nie zawsze będzie to globalne minimum."
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "fragment"
}
},
"source": [
"* Aby temu zaradzić, można uruchomić algorytm $k$ średnich wiele razy, za każdym razem z innym losowym położeniem centroidów (tzw. **wielokrotna losowa inicjalizacja** – *multiple random initialization*). Za każdym razem obliczamy koszt $J$. Wybieramy ten wynik, który ma najniższy koszt."
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "subslide"
}
},
"source": [
"### Wybór liczby klastrów $k$\n",
"\n",
"Ile powinna wynosić liczba grup $k$?\n",
"* Najlepiej wybrać $k$ ręcznie w zależności od kształtu danych i celu, który chcemy osiągnąć."
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "slide"
}
},
"source": [
"## 8.2. Analiza głównych składowych"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "notes"
}
},
"source": [
"Analiza głównych składowych to inny przykład zagadnienia z dziedziny uczenia nienadzorowanego.\n",
"\n",
"Polega na próbie zredukowania liczby wymiarów dla danych wielowymiarowych, czyli zmniejszenia liczby cech, gdy rozpatrujemy przykłady o dużej liczbie cech."
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "subslide"
}
},
"source": [
"### Redukcja liczby wymiarów\n",
"\n",
"Z jakich powodów chcemy redukować liczbę wymiarów?"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "fragment"
}
},
"source": [
"* Chcemy pozbyć się nadmiarowych cech, np. „długość w cm” / „długość w calach”, „długość” i „szerokość” / „powierzchnia”."
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "fragment"
}
},
"source": [
"* Chcemy znaleźć bardziej optymalną kombinację cech."
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "fragment"
}
},
"source": [
"* Chcemy przyspieszyć działanie algorytmów."
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "fragment"
}
},
"source": [
"* Chcemy zwizualizować dane."
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "subslide"
}
},
"source": [
"### Błąd rzutowania\n",
"\n",
"**Błąd rzutowania** – błąd średniokwadratowy pomiędzy danymi oryginalnymi a danymi zrzutowanymi."
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "subslide"
}
},
"source": [
"### Sformułowanie problemu\n",
"\n",
"**Analiza głównych składowych** (*Principal Component Analysis*, PCA):\n",
"\n",
"Zredukować liczbę wymiarów z $n$ do $k$, czyli znaleźć $k$ wektorów $u^{(1)}, u^{(2)}, \\ldots, u^{(k)}$ takich, że rzutowanie danych na podprzeztrzeń rozpiętą na tych wektorach minimalizuje błąd rzutowania."
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "subslide"
}
},
"source": [
"* **Uwaga:** analiza głównych składowych to (mimo pozornych podobieństw) zupełnie inne zagadnienie niż regresja liniowa!"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "subslide"
}
},
"source": [
"### Algorytm PCA\n",
"\n",
"1. Dany jest zbiór składający się z $x^{(1)}, x^{(2)}, \\ldots, x^{(m)} \\in \\mathbb{R}^n$.\n",
"1. Chcemy zredukować liczbę wymiarów z $n$ do $k$ ($k < n$).\n",
"1. W ramach wstępnego przetwarzania dokonujemy skalowania i normalizacji średniej.\n",
"1. Znajdujemy macierz kowariancji:\n",
" $$ \\Sigma = \\frac{1}{m} \\sum_{i=1}^{n} \\left( x^{(i)} \\right) \\left( x^{(i)} \\right)^T $$\n",
"1. Znajdujemy wektory własne macierzy $\\Sigma$ (rozkład SVD):\n",
" $$ (U, S, V) := \\mathop{\\rm SVD}(\\Sigma) $$\n",
"1. Pierwszych $k$ kolumn macierzy $U$ to szukane wektory."
]
},
{
"cell_type": "code",
"execution_count": 14,
"metadata": {
"slideshow": {
"slide_type": "subslide"
}
},
"outputs": [],
"source": [
"from sklearn.preprocessing import StandardScaler\n",
"\n",
"# Algorytm PCA - implementacja\n",
"def pca(X, k):\n",
" X_std = StandardScaler().fit_transform(X) # normalizacja\n",
" mean_vec = np.mean(X_std, axis=0)\n",
" cov_mat = np.cov(X_std.T) # macierz kowariancji\n",
" n = cov_mat.shape[0]\n",
" eig_vals, eig_vecs = np.linalg.eig(cov_mat) # wektory własne\n",
" eig_pairs = [(np.abs(eig_vals[i]), eig_vecs[:, i])\n",
" for i in range(len(eig_vals))]\n",
" eig_pairs.sort()\n",
" eig_pairs.reverse()\n",
" matrix_w = np.hstack([eig_pairs[i][1].reshape(n, 1)\n",
" for i in range(k)]) # wybór\n",
" return X_std.dot(matrix_w) # transformacja"
]
},
{
"cell_type": "code",
"execution_count": 15,
"metadata": {
"slideshow": {
"slide_type": "subslide"
}
},
"outputs": [
{
"data": {
2022-12-09 15:06:17 +01:00
"image/png": "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
2022-12-06 09:55:40 +01:00
"text/plain": [
2022-12-09 15:06:17 +01:00
"<Figure size 1120x630 with 1 Axes>"
2022-12-06 09:55:40 +01:00
]
},
2022-12-09 15:06:17 +01:00
"metadata": {},
2022-12-06 09:55:40 +01:00
"output_type": "display_data"
}
],
"source": [
"# X - dane ze zbioru \"iris\" z poprzedniego przykładu\n",
"\n",
"X_pca = pca(X, 2)\n",
"fig = plot_unlabeled_data(X_pca)"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "notes"
}
},
"source": [
"Analiza głównych składowych umożliwiła stworzenie powyższego wykresu, który wizualizuje 4-wymiarowe dane ze zbioru *iris* na 2-wymiarowej płaszczyźnie.\n",
"\n",
"Współrzędne $x_1$ i $x_2$, stanowiące osi wykresu, zostały uzyskane w wyniku działania algorytmu PCA (nie są to żadne z oryginalnych cech ze zbioru *iris* – długość płatka, szerokość płatka itp.)."
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "subslide"
}
},
"source": [
"Tutaj można zobaczyć, jak algorytmy redukcji wymiarów (w tym PCA) działają w praktyce:\n",
" * https://projector.tensorflow.org\n",
" * https://biit.cs.ut.ee/clustvis\n",
" * https://labriata.github.io/jsinscience/pca/index.html"
]
}
],
"metadata": {
"celltoolbar": "Slideshow",
"kernelspec": {
2022-12-09 15:06:17 +01:00
"display_name": "Python 3 (ipykernel)",
2022-12-06 09:55:40 +01:00
"language": "python",
"name": "python3"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
2022-12-09 15:06:17 +01:00
"version": "3.10.6"
2022-12-06 09:55:40 +01:00
},
"livereveal": {
"start_slideshow_at": "selected",
"theme": "white"
}
},
"nbformat": 4,
"nbformat_minor": 4
}