{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {
    "slideshow": {
     "slide_type": "slide"
    }
   },
   "source": [
    "## Uczenie maszynowe UMZ 2019/2020\n",
    "### 28 kwietnia 2020\n",
    "# 7a. Reprezentacja danych"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Na tym wykładzie dowiemy się, w jaki sposób reprezentować różnego rodzaju dane tak, żeby można było używać ich do uczenia maszynowego."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 14,
   "metadata": {},
   "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",
    "\n",
    "%matplotlib inline"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Plik *mieszkania4.tsv* zawiera dane wydobyte z serwisu *gratka.pl* dotyczące cen mieszkań w Poznaniu."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 15,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "     cena  Powierzchnia w m2  Liczba pokoi  Garaż  Liczba pięter w budynku  \\\n",
      "0  290386                 46             2  False                      5.0   \n",
      "1  450000                 59             2  False                      3.0   \n",
      "2  375000                 79             3  False                     16.0   \n",
      "3  400000                 63             3   True                      2.0   \n",
      "4  389285                 59             3  False                     13.0   \n",
      "\n",
      "   Piętro     Typ zabudowy Materiał budynku  Rok budowy  \\\n",
      "0  parter  apartamentowiec            cegła      2017.0   \n",
      "1       2        kamienica            cegła      1902.0   \n",
      "2       5             blok            płyta      1990.0   \n",
      "3       2             blok            cegła      2009.0   \n",
      "4      12             blok              NaN         NaN   \n",
      "\n",
      "                                                opis  \n",
      "0  Polecam mieszkanie 2 pokojowe o metrażu 46,68 ...  \n",
      "1  Ekskluzywna oferta - tylko u nas! Projekt arch...  \n",
      "2  Polecam do kupna przestronne mieszkanie trzypo...  \n",
      "3  Dla rodziny albo pod wynajem. Świetna lokaliza...  \n",
      "4                                                NaN  \n"
     ]
    }
   ],
   "source": [
    "# Wczytanie danych (mieszkania) przy pomocy biblioteki pandas\n",
    "\n",
    "alldata = pandas.read_csv(\n",
    "    'mieszkania4.tsv', header=0, sep='\\t',\n",
    "     usecols=['cena', 'Powierzchnia w m2', 'Liczba pokoi', 'Garaż', 'Liczba pięter w budynku', 'Piętro', 'Typ zabudowy', 'Materiał budynku', 'Rok budowy', 'opis'])\n",
    "\n",
    "print(alldata[:5])"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Jak widać powyżej, w pliku *mieszkania4.tsv* znajdują się dane różnych typów:\n",
    "* dane numeryczne (po prostu liczby):\n",
    "  * cena\n",
    "  * powierzchnia w m<sup>2</sup>\n",
    "  * liczba pokoi\n",
    "* dane częściowo numeryczne (liczby oraz wartości specjalne):\n",
    "  * liczba pięter w budynku\n",
    "  * piętro\n",
    "  * rok budowy\n",
    "* dane boole'owskie (prawda/fałsz):\n",
    "  * garaż\n",
    "* dane kategoryczne (wybór jednej z kilku kategorii):\n",
    "  * typ zabudowy\n",
    "* dane tekstowe (dowolny tekst):\n",
    "  * opis"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Algorytmy uczenia maszynowego działają na danych liczbowych. Z tego powodu musimy znaleźć właściwy sposób reprezentowania pozostałych danych."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Dane numeryczne"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Dane numeryczne to takie, które są liczbami. W większości przypadków możemy na nich operować bezpośrednio. Przykładem takich danych jest kolumna *Powierzchnia w m2* z powyższego przykładu:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 16,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[   46    59    79    63    90    66    32    38    68    43   185    64\n",
      "   165    71    73    51    70    48    42    33   203    88    41    31\n",
      "    45    62    60   295    53    84   170    56    47   228    44    67\n",
      "    49    37    87    36    55    57   118    65    30    28   230    54\n",
      "    52    95    50    26   171   282    77    40   150   300    39   145\n",
      "   370   140   225    29    61   135    27   270   177    85    92   132\n",
      "    75   200    74   219   220    96   235    20   153   318   104    58\n",
      "    72   117   189    81   111    35   280   141   195   120   250    97\n",
      "   154   114    76   287    34   180   160   176   148    98   217    86\n",
      "   260   198    78   183    80   163    82   100   156   320    89   103\n",
      "   159   125   340   149   175   237   110   182   186   106   233   197\n",
      "   136   162   157   240   211    83   196    69   102    91   108   130\n",
      "   510   143  1200   178   226   190   151   138   161   142   683   146\n",
      "    94   109   263   112   855   376   218   113   215   264   139   129\n",
      "   167   600    24   174   296   315   232   298   330    93   301   127\n",
      "   290   275   375   124   252   173   158    25   269   128   192   155\n",
      "    99   126   147   288   119   206   105   224   346   339   204  1100\n",
      "   392   243   101    18   202   205   107   199   137   134   144   216\n",
      "   172   239   116   364   121    23   267   369 11930   122   400   209\n",
      "   210   268   500   123   245    15    22   335   262   438   307   184\n",
      "   354   249   431   214   164   328   800    16   229   152   650   241\n",
      "   187   276   297   443   353   360   350   213    19   265]\n"
     ]
    }
   ],
   "source": [
    "print(pandas.unique(alldata['Powierzchnia w m2']))\n",
    "\n",
    "# (funkcja `pandas.unique` służy do pomijania duplikatów wartości)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Czasami w danej kolumnie oprócz liczb występują również inne wartości. Przykładem takiej cechy może być *Piętro*:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 17,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "['parter' '2' '5' '12' '1' '3' nan '8' '4' '16' '7' '6' 'poddasze' '9'\n",
      " '11' '13' '14' '10' '15' 'niski parter']\n"
     ]
    }
   ],
   "source": [
    "print(pandas.unique(alldata['Piętro']))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Jak widać powyżej, tutaj oprócz liczb pojawiają się pewne tekstowe wartości specjalne, takie jak `parter`, `poddasze` czy `niski parter`."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Takie wartości należy zamienić na liczby. Jak?\n",
    "* Wydaje się, że `parter` czy `niski parter` można z powodzeniem potraktować jako piętro „zerowe” i zamienić na `0`.\n",
    "* Z poddaszem sytuacja nie jest już tak oczywista. Czy mają Państwo jakieś propozycje?\n",
    "  * Może zamienić `poddasze` na wartość NaN (zobacz poniżej)?\n",
    "  * Może wykorzystać w tym celu wartość z sąsiedniej kolumny *Liczba pięter w budynku*?"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Można w tym celu wykorzystać funkcje [apply](https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.DataFrame.apply.html?highlight=apply#pandas.DataFrame.apply) i [to_numeric](https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.to_numeric.html) z biblioteki `pandas`."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 18,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Przed zamianą:\n",
      "122           1\n",
      "123           2\n",
      "124    poddasze\n",
      "125           5\n",
      "126      parter\n",
      "127           3\n",
      "Name: Piętro, dtype: object\n"
     ]
    }
   ],
   "source": [
    "print('Przed zamianą:')\n",
    "print(alldata['Piętro'][122:128])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 19,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\n",
      "Po zamianie:\n",
      "122    1.0\n",
      "123    2.0\n",
      "124    NaN\n",
      "125    5.0\n",
      "126    0.0\n",
      "127    3.0\n",
      "Name: Piętro, dtype: float64\n"
     ]
    }
   ],
   "source": [
    "# Zamiana wartości 'parter' i 'niski parter' w kolumnie 'Piętro' na 0.\n",
    "alldata['Piętro'] = alldata['Piętro'].apply(lambda x: 0 if x in ['parter', 'niski parter'] else x)\n",
    "\n",
    "# Zamiana wszystkich wartości w kolumnie 'Piętro' na numeryczne.\n",
    "# Parametr errors='coerce' powoduje, że napotkane nieliczbowe wartości będą zamieniane na NaN.\n",
    "alldata['Piętro'] = alldata['Piętro'].apply(pandas.to_numeric, errors='coerce')\n",
    "\n",
    "print()\n",
    "print('Po zamianie:')\n",
    "print(alldata['Piętro'][122:128])"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Wartości NaN"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Wartość NaN (zob. też na [Wikipedii](https://pl.wikipedia.org/wiki/NaN)) – to wartość numeryczna oznaczająca „nie-liczbę”, „wartość niezdefiniowaną”, np. niezdefiniowany wynik działania lub brak danych:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 20,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "nan\n",
      "nan\n",
      "nan\n",
      "nan\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "<ipython-input-20-d4d317707dde>:1: RuntimeWarning: invalid value encountered in sqrt\n",
      "  print(np.sqrt(-1))  # niezdefiniowany wynik działania (pierwiastek z liczby ujemnej)\n"
     ]
    }
   ],
   "source": [
    "print(np.sqrt(-1))  # niezdefiniowany wynik działania (pierwiastek z liczby ujemnej)\n",
    "\n",
    "print(alldata['Piętro'][14])  # brak danych na temat piętra w rekordzie 14.\n",
    "\n",
    "# Jak uzyskać wartość NaN?\n",
    "print(float('NaN'))\n",
    "print(np.nan)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Co można zrobić z wartością NaN?\n",
    "* Czasami można wartość NaN zamienić na `0`, np. być może w kolumnie „przychód” wartość NaN oznacza brak przychodu. Należy jednak być z tym ostrożnym. **W większości przypadków wstawienie 0 zamiast NaN będzie niepoprawne**, np. „rok 0” to nie to samo co „rok nieznany”. Nawet w kolumnie „cena” wartość NaN raczej oznacza, że cena jest nieznana, a to przecież nie to samo, co „cena równa 0 zł”.\n",
    "* **Najbezpieczniej jest usunąć cały rekord (wiersz), który zawiera jakąkolwiek wartość NaN**. Należy przy tym pamiętać, że pozbywamy się w ten sposób (być może wartościowych) danych. Jest to istotne zwłaszcza wtedy, gdy nasze dane zawierają dużo wartości niezdefiniowanych.\n",
    "* Wartość NaN można też zamienić na średnią, medianę, modę itp. z pozostałych wartości w zbiorze danych. To dobra opcja, jeżeli usunięcie całych wierszy zawierających NaN pozbawiłoby nas zbyt wielu rekordów.\n",
    "* Można użyć też bardziej zaawansowanych technik, np. [MICE](https://stats.stackexchange.com/questions/421545/multiple-imputation-by-chained-equations-mice-explained) czy KNN."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Przydatne artykuły na temat usuwania wartości niezdefiniowanych ze zbioru danych:\n",
    "* [Working with missing data in machine learning](https://towardsdatascience.com/working-with-missing-data-in-machine-learning-9c0a430df4ce)\n",
    "* [What’s the best way to handle NaN values?](https://towardsdatascience.com/whats-the-best-way-to-handle-nan-values-62d50f738fc)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Biblioteka `pandas` dostarcza narzędzi do automatycznego usuwania wartości NaN: [dropna](https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.DataFrame.dropna.html)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 21,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Liczba rekordów przed usunięciem NaN: 4938\n",
      "Liczba rekordów po usunięciu NaN: 888\n"
     ]
    }
   ],
   "source": [
    "print('Liczba rekordów przed usunięciem NaN:', len(alldata))\n",
    "\n",
    "alldata = alldata.dropna()  # usunięcie rekordów zawierających NaN\n",
    "\n",
    "print('Liczba rekordów po usunięciu NaN:', len(alldata))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Dane boole'owskie"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "W przypadku danych typu prawda/fałsz, wystarczy zamienić wartości `True` na `1`, a `False` na `0`:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 22,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Przed zamianą:\n",
      "0       False\n",
      "1       False\n",
      "2       False\n",
      "3        True\n",
      "13      False\n",
      "        ...  \n",
      "4909    False\n",
      "4917     True\n",
      "4918    False\n",
      "4920    False\n",
      "4937    False\n",
      "Name: Garaż, Length: 888, dtype: bool\n"
     ]
    }
   ],
   "source": [
    "print('Przed zamianą:')\n",
    "print(alldata['Garaż'])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 23,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\n",
      "Po zamianie:\n",
      "0       0\n",
      "1       0\n",
      "2       0\n",
      "3       1\n",
      "13      0\n",
      "       ..\n",
      "4909    0\n",
      "4917    1\n",
      "4918    0\n",
      "4920    0\n",
      "4937    0\n",
      "Name: Garaż, Length: 888, dtype: int64\n"
     ]
    }
   ],
   "source": [
    "alldata['Garaż'] = alldata['Garaż'].apply(lambda x: 1 if x == True else 0)\n",
    "\n",
    "print()\n",
    "print('Po zamianie:')\n",
    "print(alldata['Garaż'])"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Dane kategoryczne"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "O danych kategorycznych mówimy, jeżeli dane mogą przyjmować wartości ze skończonej listy („kategorii”), np.:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 27,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "['apartamentowiec', 'kamienica', 'blok', 'dom wielorodzinny/szeregowiec', 'plomba']\n"
     ]
    }
   ],
   "source": [
    "# \"Typ zabudowy\" może przyjmować jedną z następujących wartości:\n",
    "\n",
    "typ_zabudowy_values = list(pandas.unique(alldata['Typ zabudowy']))\n",
    "\n",
    "print(typ_zabudowy_values)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 28,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "['cegła', 'płyta', 'inne', 'pustak', 'silikat', 'beton']\n"
     ]
    }
   ],
   "source": [
    "# \"Materiał budynku\" może przyjmować jedną z następujących wartości:\n",
    "\n",
    "material_budynku_values = list(pandas.unique(alldata['Materiał budynku']))\n",
    "\n",
    "print(material_budynku_values)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Cechę kategoryczną można rozbić na skończoną liczbę cech boole'owskich:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 29,
   "metadata": {},
   "outputs": [],
   "source": [
    "# Skopiujmy dane, żeby przedstawić 2 alternatywne rozwiązania\n",
    "\n",
    "alldata_1 = alldata.copy()\n",
    "alldata_2 = alldata.copy()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 30,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Nowo utworzone kolumny (cechy boole'owskie):\n",
      "['Czy apartamentowiec?', 'Czy kamienica?', 'Czy blok?', 'Czy dom wielorodzinny/szeregowiec?', 'Czy plomba?']\n",
      "\n",
      "                       Typ zabudowy  Czy apartamentowiec?  Czy kamienica?  \\\n",
      "0                   apartamentowiec                  True           False   \n",
      "1                         kamienica                 False            True   \n",
      "2                              blok                 False           False   \n",
      "3                              blok                 False           False   \n",
      "13                             blok                 False           False   \n",
      "...                             ...                   ...             ...   \n",
      "4909                apartamentowiec                  True           False   \n",
      "4917  dom wielorodzinny/szeregowiec                 False           False   \n",
      "4918                           blok                 False           False   \n",
      "4920  dom wielorodzinny/szeregowiec                 False           False   \n",
      "4937  dom wielorodzinny/szeregowiec                 False           False   \n",
      "\n",
      "      Czy blok?  Czy dom wielorodzinny/szeregowiec?  Czy plomba?  \n",
      "0         False                               False        False  \n",
      "1         False                               False        False  \n",
      "2          True                               False        False  \n",
      "3          True                               False        False  \n",
      "13         True                               False        False  \n",
      "...         ...                                 ...          ...  \n",
      "4909      False                               False        False  \n",
      "4917      False                                True        False  \n",
      "4918       True                               False        False  \n",
      "4920      False                                True        False  \n",
      "4937      False                                True        False  \n",
      "\n",
      "[888 rows x 6 columns]\n"
     ]
    }
   ],
   "source": [
    "# Rozwiązanie 1\n",
    "\n",
    "select_column_names = []\n",
    "for typ_zabudowy in typ_zabudowy_values:\n",
    "    new_column_name = 'Czy {}?'.format(typ_zabudowy)\n",
    "    alldata_1[new_column_name] = (alldata_1['Typ zabudowy'] == typ_zabudowy)\n",
    "    select_column_names.append(new_column_name)\n",
    "\n",
    "print(\"Nowo utworzone kolumny (cechy boole'owskie):\")\n",
    "print(select_column_names)\n",
    "\n",
    "select_column_names = ['Typ zabudowy'] + select_column_names\n",
    "\n",
    "print()\n",
    "\n",
    "print(alldata_1[select_column_names])"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Nie trzeba tego robić ręcznie. Można do tego celu użyć funkcji [get_dummies](https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.get_dummies.html) z biblioteki `pandas`:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 31,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "        cena  Powierzchnia w m2  Liczba pokoi  Garaż  Liczba pięter w budynku  \\\n",
      "0     290386                 46             2      0                      5.0   \n",
      "1     450000                 59             2      0                      3.0   \n",
      "2     375000                 79             3      0                     16.0   \n",
      "3     400000                 63             3      1                      2.0   \n",
      "13    450000                 64             3      0                      4.0   \n",
      "...      ...                ...           ...    ...                      ...   \n",
      "4909  141300                 46             2      0                      1.0   \n",
      "4917  710000                120             4      1                      1.0   \n",
      "4918  858000                120             5      0                      3.0   \n",
      "4920  399000                 69             3      0                      2.0   \n",
      "4937  127900                 36             2      0                      2.0   \n",
      "\n",
      "      Piętro  Rok budowy                                               opis  \\\n",
      "0        0.0      2017.0  Polecam mieszkanie 2 pokojowe o metrażu 46,68 ...   \n",
      "1        2.0      1902.0  Ekskluzywna oferta - tylko u nas! Projekt arch...   \n",
      "2        5.0      1990.0  Polecam do kupna przestronne mieszkanie trzypo...   \n",
      "3        2.0      2009.0  Dla rodziny albo pod wynajem. Świetna lokaliza...   \n",
      "13       2.0      1992.0  Witam,Mam na imię Jędrzej i w biurze Platan po...   \n",
      "...      ...         ...                                                ...   \n",
      "4909     0.0      2014.0  !!! Apartamenty w Lusówku oddawane w stanie de...   \n",
      "4917     0.0      2013.0  Sprzedam lokal mieszkalny odrębna własność w b...   \n",
      "4918     3.0      1993.0  Polecam do kupna mieszkanie 5 pokojowe o pow. ...   \n",
      "4920     1.0      2008.0  Przestronne mieszkanie z pięknym widokiem!Dwup...   \n",
      "4937     2.0      2018.0  Sprzedaż nowego mieszkania w FAŁKOWIE - Osiedl...   \n",
      "\n",
      "      Typ zabudowy_apartamentowiec  Typ zabudowy_blok  \\\n",
      "0                                1                  0   \n",
      "1                                0                  0   \n",
      "2                                0                  1   \n",
      "3                                0                  1   \n",
      "13                               0                  1   \n",
      "...                            ...                ...   \n",
      "4909                             1                  0   \n",
      "4917                             0                  0   \n",
      "4918                             0                  1   \n",
      "4920                             0                  0   \n",
      "4937                             0                  0   \n",
      "\n",
      "      Typ zabudowy_dom wielorodzinny/szeregowiec  Typ zabudowy_kamienica  \\\n",
      "0                                              0                       0   \n",
      "1                                              0                       1   \n",
      "2                                              0                       0   \n",
      "3                                              0                       0   \n",
      "13                                             0                       0   \n",
      "...                                          ...                     ...   \n",
      "4909                                           0                       0   \n",
      "4917                                           1                       0   \n",
      "4918                                           0                       0   \n",
      "4920                                           1                       0   \n",
      "4937                                           1                       0   \n",
      "\n",
      "      Typ zabudowy_plomba  Materiał budynku_beton  Materiał budynku_cegła  \\\n",
      "0                       0                       0                       1   \n",
      "1                       0                       0                       1   \n",
      "2                       0                       0                       0   \n",
      "3                       0                       0                       1   \n",
      "13                      0                       0                       1   \n",
      "...                   ...                     ...                     ...   \n",
      "4909                    0                       0                       1   \n",
      "4917                    0                       0                       1   \n",
      "4918                    0                       0                       1   \n",
      "4920                    0                       0                       1   \n",
      "4937                    0                       0                       1   \n",
      "\n",
      "      Materiał budynku_inne  Materiał budynku_pustak  Materiał budynku_płyta  \\\n",
      "0                         0                        0                       0   \n",
      "1                         0                        0                       0   \n",
      "2                         0                        0                       1   \n",
      "3                         0                        0                       0   \n",
      "13                        0                        0                       0   \n",
      "...                     ...                      ...                     ...   \n",
      "4909                      0                        0                       0   \n",
      "4917                      0                        0                       0   \n",
      "4918                      0                        0                       0   \n",
      "4920                      0                        0                       0   \n",
      "4937                      0                        0                       0   \n",
      "\n",
      "      Materiał budynku_silikat  \n",
      "0                            0  \n",
      "1                            0  \n",
      "2                            0  \n",
      "3                            0  \n",
      "13                           0  \n",
      "...                        ...  \n",
      "4909                         0  \n",
      "4917                         0  \n",
      "4918                         0  \n",
      "4920                         0  \n",
      "4937                         0  \n",
      "\n",
      "[888 rows x 19 columns]\n"
     ]
    }
   ],
   "source": [
    "alldata_2 = pandas.get_dummies(alldata_2, columns=['Typ zabudowy', 'Materiał budynku'])\n",
    "\n",
    "print(alldata_2)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Zwróćmy uwagę, że dzięki użyciu `get_dummies` nowe kolumny zostały utworzone i nazwane automatycznie, nie trzeba też już ręcznie konwertować wartości boole'owskich do numerycznych."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Funkcja `get_dummies` do określenia, na ile i jakich kolumn podzielić daną kolumnę kategoryczną, używa bieżącej zawartości tabeli. Dlatego należy jej użyć przed dokonaniem podziału na zbiory uczący i testowy.\n",
    "\n",
    "Więcej na ten temat można przeczytać w artykule [How to use pandas.get_dummies with the test set](http://fastml.com/how-to-use-pd-dot-get-dummies-with-the-test-set)."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Dane tekstowe"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Przetwarzanie danych tekstowych to szeroki temat, którym można zapełnić cały wykład. Dlatego tutaj przedstawię tylko najważniejsze metody."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Możemy na przykład tworzyć cechy sprawdzające występowanie poszczególnych wyrazów lub ciągów znaków w tekście:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 15,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "      nowe_w_opisie                                               opis\n",
      "0              True  Polecam mieszkanie 2 pokojowe o metrażu 46,68 ...\n",
      "1             False  Ekskluzywna oferta - tylko u nas! Projekt arch...\n",
      "2             False  Polecam do kupna przestronne mieszkanie trzypo...\n",
      "3             False  Dla rodziny albo pod wynajem. Świetna lokaliza...\n",
      "13            False  Witam,Mam na imię Jędrzej i w biurze Platan po...\n",
      "...             ...                                                ...\n",
      "4920           True  Przestronne mieszkanie z pięknym widokiem!Dwup...\n",
      "4925           True  BEZ 2% PCC, BEZ PROWIZJI. Nowe mieszkanie 48,6...\n",
      "4928           True  Polecam do sprzedaży słoneczne mieszkanie dwup...\n",
      "4934          False  OKAZJA!! LUKSUSOWY APARTAMENT W SĄSIEDZTWIE PA...\n",
      "4937           True  Sprzedaż nowego mieszkania w FAŁKOWIE - Osiedl...\n",
      "\n",
      "[1333 rows x 2 columns]\n"
     ]
    }
   ],
   "source": [
    "alldata['nowe_w_opisie'] = alldata['opis'].apply(lambda x: True if 'nowe' in x.lower() else False)\n",
    "print(alldata[['nowe_w_opisie', 'opis']])"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Można też zamienić tekst na wektory używając algorytmów TF–IDF, Word2Vec lub podobnych."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Ciekawy artykuł na temat przygotowywania danych tekstowych do uczenia maszynowego można znaleźć na przykład tutaj: https://machinelearningmastery.com/prepare-text-data-machine-learning-scikit-learn/"
   ]
  }
 ],
 "metadata": {
  "celltoolbar": "Slideshow",
  "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.3"
  },
  "livereveal": {
   "start_slideshow_at": "selected",
   "theme": "amu"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 4
}