{ "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "# Ekstrakcja cech" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "ExecuteTime": { "end_time": "2020-06-02T15:54:44.389766Z", "start_time": "2020-06-02T15:54:44.241529Z" } }, "outputs": [], "source": [ "%matplotlib inline\n", "\n", "import numpy as np\n", "\n", "import matplotlib.pyplot as plt\n", "from matplotlib.gridspec import GridSpec" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "ExecuteTime": { "end_time": "2020-06-02T15:54:45.073909Z", "start_time": "2020-06-02T15:54:44.856520Z" } }, "outputs": [], "source": [ "from sklearn.datasets import load_iris\n", "\n", "data = load_iris()\n", "\n", "X = data['data']\n", "y = data['target']\n", "\n", "X[:5], y[:5]" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Analiza składowych głównych\n", "\n", "W pierwszym kroku zobaczymy, w jaki sposób analiza składowych głównych (PCA) może posłużyć do redukcji wymiarowości zbioru danych. W metodzie PCA jest bardzo istotne, aby atrybuty redukowanego zbioru były porównywalne, więc konieczna jest normalizacja atrybutów. My posłużymy się standaryzacją." ] }, { "cell_type": "code", "execution_count": null, "metadata": { "ExecuteTime": { "end_time": "2020-06-02T15:54:47.739095Z", "start_time": "2020-06-02T15:54:47.733227Z" } }, "outputs": [], "source": [ "from sklearn.preprocessing import StandardScaler\n", "\n", "X_scaled = StandardScaler().fit(X).transform(X)\n", "\n", "X_scaled[:5], y[:5]" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Jako pierwszy przykład dokonamy redukcji zbioru danych z 4 wymiarów do 2 wymiarów. Kryterium, jakie maksymalizuje PCA, jest wariancja nowych wymiarów." ] }, { "cell_type": "code", "execution_count": null, "metadata": { "ExecuteTime": { "end_time": "2020-06-02T15:54:49.049068Z", "start_time": "2020-06-02T15:54:49.012339Z" } }, "outputs": [], "source": [ "from sklearn.decomposition import PCA\n", "\n", "pca = PCA(n_components=2)\n", "\n", "X_pca = pca.fit(X).transform(X)\n", "X_pca[:5], y[:5]" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Spójrzmy, jak wygląda zbiór danych po redukcji i jak można zinterpretować nowe wymiary." ] }, { "cell_type": "code", "execution_count": null, "metadata": { "ExecuteTime": { "end_time": "2020-06-02T15:54:52.144837Z", "start_time": "2020-06-02T15:54:51.942892Z" } }, "outputs": [], "source": [ "colrs = np.array(['red', 'green', 'blue'])\n", "\n", "fig = plt.figure(figsize=(6, 6))\n", "ax = fig.add_subplot(1, 1, 1)\n", "\n", "ax.set_title('PCA 2D', fontsize=20)\n", "ax.set_xlabel('składowa główna 1', fontsize=15)\n", "ax.set_ylabel('składowa główna 2', fontsize=15)\n", "ax.grid()\n", "\n", "ax.scatter(X_pca[:, 0], X_pca[:, 1], c=colrs[y], s=25)" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "ExecuteTime": { "end_time": "2020-06-02T15:56:08.559223Z", "start_time": "2020-06-02T15:56:08.556241Z" } }, "outputs": [], "source": [ "for i,v in enumerate(pca.explained_variance_ratio_):\n", " print(f'Wariancja tłumaczona przez składową {i+1}: {v:.4f}')" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "ExecuteTime": { "end_time": "2020-06-02T15:56:10.554228Z", "start_time": "2020-06-02T15:56:10.551276Z" } }, "outputs": [], "source": [ "print(pca.components_)" ] }, { "cell_type": "markdown", "metadata": { "ExecuteTime": { "end_time": "2020-06-02T15:09:11.309722Z", "start_time": "2020-06-02T15:09:11.306896Z" } }, "source": [ "Przykładowo, pierwsza z nowych współrzędnych jest wyliczana według wzoru:\n", "\n", "`pca_1 = 0.36 * 'sepal length (cm)' - 0.08 * 'sepal width (cm)' + 0.86 * 'petal length (cm)' + 0.36 * 'petal width (cm)'`" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Skoro pierwsza składowa tak dobrze tłumaczy wariancję, być może da się ten zbiór danych skompresować nawet bardziej?" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "ExecuteTime": { "end_time": "2020-06-02T15:56:15.581397Z", "start_time": "2020-06-02T15:56:15.575080Z" } }, "outputs": [], "source": [ "pca = PCA(n_components=1)\n", "\n", "X_pca = pca.fit(X).transform(X)\n", "X_pca[:5], y[:5]" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "ExecuteTime": { "end_time": "2020-06-02T15:56:49.887903Z", "start_time": "2020-06-02T15:56:49.709840Z" } }, "outputs": [], "source": [ "colrs = np.array(['red', 'green', 'blue'])\n", "\n", "fig = plt.figure(figsize=(6, 3))\n", "ax = fig.add_subplot(1, 1, 1)\n", "ax.set_title('PCA 1D', fontsize=20)\n", "ax.set_xlabel('składowa główna 1', fontsize=15)\n", "ax.set_ylim(-1., 1.)\n", "ax.grid()\n", "\n", "for c in np.unique(y):\n", " idx = y == c\n", " vals = X_pca[idx, 0]\n", " ax.scatter(vals, np.zeros_like(vals) + np.random.uniform(-0.1,\n", " 0.1, len(vals)), s=25, color=colrs[c])" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Samoorganizujące się mapy\n", "\n", "Poniższy kod pokazuje użycie SOM-ów (zwanych też mapami Kohonena) do redukcji wymiarowości problemu przez nienadzorowane uczenie sieci neuronowej. Posłużymy się do tego celu zbiorem `Iris` który oryginalnie posiada cztery wymiary.\n", "\n", "Przed wykonaniem ćwiczenia zainstaluj potrzebny pakiet wywołując polecenie\n", "\n", "```bash\n", "bash$ pip install minisom\n", "```\n", "\n", "lub uruchamiając polecenie bezpośrednio w komórce notatnika:\n", "\n", "```\n", "!pip install minisom\n", "```" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "ExecuteTime": { "end_time": "2020-06-02T15:57:10.619620Z", "start_time": "2020-06-02T15:57:10.615072Z" } }, "outputs": [], "source": [ "from minisom import MiniSom\n", "\n", "som_size = (5,5)\n", "som = MiniSom(som_size[0], som_size[1], 4, sigma=0.3, learning_rate=0.5)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Wagi sieci neuronowej mogą być inicjalizowane na dwa sposoby:\n", "\n", "- losowo (`random_weights_init()`\n", "- przy użyciu metody składowych głównych (`pca_weights_init`)\n", "\n", "Sam proces trenowania sieci może się także odbywać na dwa sposoby:\n", "\n", "- losowo (`train_random()`)\n", "- przy użyciu mini-batchy (`train_batch()`)" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "ExecuteTime": { "end_time": "2020-06-02T15:57:55.563106Z", "start_time": "2020-06-02T15:57:54.301317Z" } }, "outputs": [], "source": [ "# som.random_weights_init(X)\n", "# som.train_random(X, 10000, verbose=True)\n", "\n", "som.pca_weights_init(X)\n", "som.train_batch(X, 10000, verbose=True) " ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Pierwsza wizualizacja pokazuje odległości między poszczególnymi neuronami" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "ExecuteTime": { "end_time": "2020-06-02T15:57:57.465400Z", "start_time": "2020-06-02T15:57:57.033823Z" } }, "outputs": [], "source": [ "plt.figure(figsize=(8, 7))\n", "plt.pcolor(som.distance_map().T, cmap='bone_r')\n", "plt.colorbar()\n", "\n", "markers = ['o', 's', 'D']\n", "colors = ['C0', 'C1', 'C2']\n", "\n", "for cnt, xx in enumerate(X):\n", " w = som.winner(xx)\n", " plt.plot(w[0]+.5, w[1]+.5, markers[y[cnt]], markerfacecolor='None',\n", " markeredgecolor=colors[y[cnt]], markersize=12, markeredgewidth=2)\n", "\n", "plt.axis([0, som_size[0], 0, som_size[1]])\n", "plt.show()" ] }, { "cell_type": "markdown", "metadata": { "ExecuteTime": { "end_time": "2019-06-02T19:45:22.913336Z", "start_time": "2019-06-02T19:45:22.903483Z" } }, "source": [ "Druga wizualizacja pokazuje częstotliwość aktywacji poszczególnych neuronów" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "ExecuteTime": { "end_time": "2020-06-02T15:58:00.430588Z", "start_time": "2020-06-02T15:58:00.241592Z" } }, "outputs": [], "source": [ "plt.figure(figsize=(8, 7))\n", "frequencies = np.zeros(som_size)\n", "\n", "for position, values in som.win_map(X).items():\n", " frequencies[position[0], position[1]] = len(values)\n", "\n", "plt.pcolor(frequencies, cmap='Blues')\n", "plt.colorbar()\n", "plt.show()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Ostatnia wizualizacja wyświetla stopień jednorodności poszczególnych neuronów" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "ExecuteTime": { "end_time": "2020-06-02T15:58:02.256060Z", "start_time": "2020-06-02T15:58:01.790216Z" } }, "outputs": [], "source": [ "labels_map = som.labels_map(X, y)\n", "label_names = np.unique(y)\n", "\n", "plt.figure(figsize=(8, 7))\n", "the_grid = GridSpec(5, 5)\n", "\n", "for position in labels_map.keys():\n", "\n", " label_fracs = [labels_map[position][l] for l in label_names]\n", " plt.subplot(the_grid[2-position[1], position[0]], aspect=1)\n", " patches, texts = plt.pie(label_fracs)\n", "\n", "plt.legend(patches, data.target_names, bbox_to_anchor=(0, 1.5), ncol=3)\n", "plt.show()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Przypisanie każdego obiektu do konkretnego neuronu na samoorganizującej się mapie" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "ExecuteTime": { "end_time": "2020-06-02T15:57:38.816713Z", "start_time": "2020-06-02T15:57:38.774540Z" } }, "outputs": [], "source": [ "for x in X:\n", " print(f'{x}: {som.winner(x)}')" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [] } ], "metadata": { "kernelspec": { "display_name": "Python 3", "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", "version": "3.8.2" }, "toc": { "base_numbering": 1, "nav_menu": {}, "number_sections": false, "sideBar": true, "skip_h1_title": false, "title_cell": "Table of Contents", "title_sidebar": "Contents", "toc_cell": false, "toc_position": {}, "toc_section_display": true, "toc_window_display": false }, "varInspector": { "cols": { "lenName": 16, "lenType": 16, "lenVar": 40 }, "kernels_config": { "python": { "delete_cmd_postfix": "", "delete_cmd_prefix": "del ", "library": "var_list.py", "varRefreshCmd": "print(var_dic_list())" }, "r": { "delete_cmd_postfix": ") ", "delete_cmd_prefix": "rm(", "library": "var_list.r", "varRefreshCmd": "cat(var_dic_list()) " } }, "types_to_exclude": [ "module", "function", "builtin_function_or_method", "instance", "_Feature" ], "window_display": false } }, "nbformat": 4, "nbformat_minor": 2 }