Compare commits

..

No commits in common. "master" and "master" have entirely different histories.

10 changed files with 45697 additions and 624 deletions

View File

@ -31,24 +31,23 @@
},
{
"cell_type": "code",
"execution_count": 15,
"execution_count": 1,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"[[302322.47270869]\n",
" [283694.74995925]\n",
" [276290.72977935]\n",
" [477362.89530745]\n",
" [420862.62245119]\n",
" [312510.3868097 ]\n",
" [362445.20969959]\n",
" [335753.83506582]\n",
" [759239.88142398]\n",
" [684376.72797254]]\n",
"Błąd średniokwadratowy wynosi 29811493540.217434\n"
"[[289411.43360715]\n",
" [285930.72623304]\n",
" [229893.92602325]\n",
" [823267.1750005 ]\n",
" [821038.18583152]\n",
" [356875.19267371]\n",
" [409340.86981766]\n",
" [278401.700237 ]\n",
" [301680.27997255]\n",
" [281051.71865054]]\n"
]
}
],
@ -58,8 +57,6 @@
"\n",
"from sklearn.linear_model import LinearRegression # Model regresji liniowej z biblioteki scikit-learn\n",
"\n",
"from sklearn.metrics import mean_squared_error\n",
"\n",
"\n",
"FEATURES = [\n",
" 'Powierzchnia w m2',\n",
@ -67,12 +64,11 @@
" 'Liczba pięter w budynku',\n",
" 'Piętro',\n",
" 'Rok budowy',\n",
" 'ładne w opisie'\n",
"]\n",
"\n",
"\n",
"def preprocess(data):\n",
" \"\"\"Wstępne przetworzenie danych, np. zamiana wartości tekstowych na liczby\"\"\"\n",
" \"\"\"Wstępne przetworzenie danych\"\"\"\n",
" data = data.replace({'parter': 0, 'poddasze': 0}, regex=True)\n",
" data = data.applymap(np.nan_to_num) # Zamienia \"NaN\" na liczby\n",
" return data\n",
@ -82,14 +78,8 @@
"\n",
"# Wczytanie danych\n",
"data = pd.read_csv(dataset_filename, header=0, sep='\\t')\n",
"\n",
"# Jeżeli chcemy, możemy stworzyć nową cechę (kolumnę) na podstawie istniejącej\n",
"# Poniższa cecha mówi, czy kolumna \"opis\" zawiera słowo \"ładne\"\n",
"data['ładne w opisie'] = data['opis'].apply(\n",
" lambda x: True if 'ładne' in str(x) else False)\n",
"\n",
"columns = data.columns[1:] # wszystkie kolumny oprócz pierwszej (\"cena\")\n",
"data = data[FEATURES + ['cena']] # wybór cech\n",
"data = data[(data[\"Powierzchnia w m2\"] < 10000) & (data[\"cena\"] > 1000)] # Odrzucenie obserwacji odstających\n",
"data = preprocess(data) # wstępne przetworzenie danych\n",
"\n",
"# Podział danych na zbiory uczący i testowy\n",
@ -108,12 +98,7 @@
"x_test = pd.DataFrame(data_test[FEATURES])\n",
"y_predicted = model.predict(x_test) # predykcja wyników na podstawie modelu\n",
"\n",
"print(y_predicted[:10]) # Pierwsze 10 wyników\n",
"\n",
"# Ewaluacja\n",
"mse = mean_squared_error(y_predicted, y_expected) # Błąd średniokwadratowy na zbiorze testowym\n",
"\n",
"print(\"Błąd średniokwadratowy wynosi \", mse)"
"print(y_predicted[:10]) # Pierwsze 10 wyników"
]
},
{
@ -141,7 +126,7 @@
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.7.6"
"version": "3.8.3"
},
"livereveal": {
"start_slideshow_at": "selected",

File diff suppressed because one or more lines are too long

View File

@ -69,7 +69,7 @@
},
{
"cell_type": "code",
"execution_count": 1,
"execution_count": 4,
"metadata": {},
"outputs": [],
"source": [
@ -82,16 +82,18 @@
},
{
"cell_type": "code",
"execution_count": 2,
"execution_count": 1,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"x_train shape: (60000, 28, 28, 1)\n",
"60000 train samples\n",
"10000 test samples\n"
"ename": "NameError",
"evalue": "name 'keras' is not defined",
"output_type": "error",
"traceback": [
"\u001b[1;31m---------------------------------------------------------------------------\u001b[0m",
"\u001b[1;31mNameError\u001b[0m Traceback (most recent call last)",
"\u001b[1;32m<ipython-input-1-d9ae37c68de4>\u001b[0m in \u001b[0;36m<module>\u001b[1;34m\u001b[0m\n\u001b[0;32m 5\u001b[0m \u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 6\u001b[0m \u001b[1;31m# podział danych na zbiory uczący i testowy\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[1;32m----> 7\u001b[1;33m \u001b[1;33m(\u001b[0m\u001b[0mx_train\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0my_train\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m,\u001b[0m \u001b[1;33m(\u001b[0m\u001b[0mx_test\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0my_test\u001b[0m\u001b[1;33m)\u001b[0m \u001b[1;33m=\u001b[0m \u001b[0mkeras\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mdatasets\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mmnist\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mload_data\u001b[0m\u001b[1;33m(\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m\u001b[0;32m 8\u001b[0m \u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 9\u001b[0m \u001b[1;31m# skalowanie wartości pikseli do przedziału [0, 1]\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n",
"\u001b[1;31mNameError\u001b[0m: name 'keras' is not defined"
]
}
],
@ -121,7 +123,7 @@
},
{
"cell_type": "code",
"execution_count": 3,
"execution_count": 6,
"metadata": {},
"outputs": [
{
@ -174,23 +176,23 @@
},
{
"cell_type": "code",
"execution_count": 7,
"execution_count": 9,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"422/422 [==============================] - 40s 94ms/step - loss: 0.1914 - accuracy: 0.9418 - val_loss: 0.0718 - val_accuracy: 0.9803\n"
"422/422 [==============================] - 38s 91ms/step - loss: 0.0556 - accuracy: 0.9826 - val_loss: 0.0412 - val_accuracy: 0.9893\n"
]
},
{
"data": {
"text/plain": [
"<tensorflow.python.keras.callbacks.History at 0x1de55106d00>"
"<tensorflow.python.keras.callbacks.History at 0x1a50b35a070>"
]
},
"execution_count": 7,
"execution_count": 9,
"metadata": {},
"output_type": "execute_result"
}
@ -198,9 +200,12 @@
"source": [
"# Uczenie modelu\n",
"\n",
"batch_size = 128\n",
"epochs = 15\n",
"\n",
"model.compile(loss=\"categorical_crossentropy\", optimizer=\"adam\", metrics=[\"accuracy\"])\n",
"\n",
"model.fit(x_train, y_train, batch_size=128, epochs=5, validation_split=0.1)"
"model.fit(x_train, y_train, epochs=1, batch_size=batch_size, epochs=epochs, validation_split=0.1)"
]
},
{
@ -243,7 +248,7 @@
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.8.5"
"version": "3.8.3"
},
"livereveal": {
"start_slideshow_at": "selected",

File diff suppressed because one or more lines are too long

View File

@ -261,9 +261,7 @@
"### Metryki dla zadań regresji\n",
"\n",
"Dla zadań regresji możemy zastosować np.:\n",
" * błąd średniokwadratowy (*mean-square error*, MSE):\n",
" $$ \\mathrm{MSE} \\, = \\, \\frac{1}{m} \\sum_{i=1}^{m} \\left( \\hat{y}^{(i)} - y^{(i)} \\right)^2 $$\n",
" * pierwiastek z błędu średniokwadratowego (*root-mean-square error*, RMSE):\n",
" * błąd średniokwadratowy (*root-mean-square error*, RMSE):\n",
" $$ \\mathrm{RMSE} \\, = \\, \\sqrt{ \\frac{1}{m} \\sum_{i=1}^{m} \\left( \\hat{y}^{(i)} - y^{(i)} \\right)^2 } $$\n",
" * średni błąd bezwzględny (*mean absolute error*, MAE):\n",
" $$ \\mathrm{MAE} \\, = \\, \\frac{1}{m} \\sum_{i=1}^{m} \\left| \\hat{y}^{(i)} - y^{(i)} \\right| $$"
@ -295,7 +293,7 @@
},
{
"cell_type": "code",
"execution_count": 1,
"execution_count": 24,
"metadata": {
"slideshow": {
"slide_type": "notes"
@ -317,7 +315,7 @@
},
{
"cell_type": "code",
"execution_count": 2,
"execution_count": 25,
"metadata": {
"slideshow": {
"slide_type": "notes"
@ -336,7 +334,7 @@
},
{
"cell_type": "code",
"execution_count": 3,
"execution_count": 26,
"metadata": {
"slideshow": {
"slide_type": "notes"
@ -408,7 +406,7 @@
},
{
"cell_type": "code",
"execution_count": 4,
"execution_count": 27,
"metadata": {
"slideshow": {
"slide_type": "notes"
@ -432,7 +430,7 @@
},
{
"cell_type": "code",
"execution_count": 5,
"execution_count": 28,
"metadata": {
"slideshow": {
"slide_type": "subslide"
@ -458,7 +456,7 @@
},
{
"cell_type": "code",
"execution_count": 6,
"execution_count": 29,
"metadata": {
"slideshow": {
"slide_type": "notes"
@ -505,7 +503,7 @@
},
{
"cell_type": "code",
"execution_count": 7,
"execution_count": 30,
"metadata": {
"slideshow": {
"slide_type": "notes"
@ -533,7 +531,7 @@
},
{
"cell_type": "code",
"execution_count": 8,
"execution_count": 31,
"metadata": {
"slideshow": {
"slide_type": "subslide"
@ -563,7 +561,7 @@
},
{
"cell_type": "code",
"execution_count": 9,
"execution_count": 32,
"metadata": {
"slideshow": {
"slide_type": "notes"
@ -585,7 +583,7 @@
},
{
"cell_type": "code",
"execution_count": 10,
"execution_count": 33,
"metadata": {
"slideshow": {
"slide_type": "subslide"
@ -599,7 +597,7 @@
},
{
"cell_type": "code",
"execution_count": 11,
"execution_count": 34,
"metadata": {
"slideshow": {
"slide_type": "notes"
@ -619,7 +617,7 @@
},
{
"cell_type": "code",
"execution_count": 12,
"execution_count": 35,
"metadata": {
"slideshow": {
"slide_type": "subslide"
@ -629,7 +627,7 @@
{
"data": {
"application/vnd.jupyter.widget-view+json": {
"model_id": "6325cec10a034a9d96d862dee900013d",
"model_id": "32929ab5e3024128bd39a6c165e50196",
"version_major": 2,
"version_minor": 0
},
@ -646,7 +644,7 @@
"<function __main__.interactive_classification(highlight)>"
]
},
"execution_count": 12,
"execution_count": 35,
"metadata": {},
"output_type": "execute_result"
}
@ -1187,10 +1185,9 @@
"# Odrzućmy obserwacje odstające\n",
"alldata_no_outliers = [\n",
" (index, item) for index, item in alldata.iterrows() \n",
" if item.price > 10000 and item.sqrMetres < 1000]\n",
" if item.price > 100 and item.sqrMetres > 10]\n",
"\n",
"# Alternatywnie można to zrobić w następujący sposób\n",
"alldata_no_outliers = alldata.loc[(alldata['price'] > 10000) & (alldata['sqrMetres'] < 1000)]"
"alldata_no_outliers = alldata.loc[(alldata['price'] > 100) & (alldata['sqrMetres'] > 100)]"
]
},
{

View File

@ -14,23 +14,15 @@
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "subslide"
}
},
"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": 1,
"metadata": {
"slideshow": {
"slide_type": "notes"
}
},
"execution_count": 14,
"metadata": {},
"outputs": [],
"source": [
"# Przydatne importy\n",
@ -45,23 +37,15 @@
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "subslide"
}
},
"metadata": {},
"source": [
"Plik *mieszkania4.tsv* zawiera dane wydobyte z serwisu *gratka.pl* dotyczące cen mieszkań w Poznaniu."
]
},
{
"cell_type": "code",
"execution_count": 2,
"metadata": {
"slideshow": {
"slide_type": "subslide"
}
},
"execution_count": 15,
"metadata": {},
"outputs": [
{
"name": "stdout",
@ -102,11 +86,7 @@
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "subslide"
}
},
"metadata": {},
"source": [
"Jak widać powyżej, w pliku *mieszkania4.tsv* znajdują się dane różnych typów:\n",
"* dane numeryczne (po prostu liczby):\n",
@ -121,52 +101,35 @@
" * garaż\n",
"* dane kategoryczne (wybór jednej z kilku kategorii):\n",
" * typ zabudowy\n",
" * materiał budynku\n",
"* dane tekstowe (dowolny tekst):\n",
" * opis"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "subslide"
}
},
"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": {
"slideshow": {
"slide_type": "slide"
}
},
"metadata": {},
"source": [
"## Dane numeryczne"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "subslide"
}
},
"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": 3,
"metadata": {
"slideshow": {
"slide_type": "subslide"
}
},
"execution_count": 16,
"metadata": {},
"outputs": [
{
"name": "stdout",
@ -205,23 +168,15 @@
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "subslide"
}
},
"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": 4,
"metadata": {
"slideshow": {
"slide_type": "subslide"
}
},
"execution_count": 17,
"metadata": {},
"outputs": [
{
"name": "stdout",
@ -236,79 +191,27 @@
"print(pandas.unique(alldata['Piętro']))"
]
},
{
"cell_type": "code",
"execution_count": 7,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"1 897\n",
"parter 833\n",
"2 719\n",
"3 669\n",
"4 549\n",
"5 260\n",
"7 78\n",
"8 63\n",
"9 59\n",
"6 55\n",
"11 39\n",
"12 35\n",
"10 32\n",
"14 25\n",
"13 25\n",
"16 11\n",
"poddasze 5\n",
"15 4\n",
"niski parter 1\n",
"Name: Piętro, dtype: int64"
]
},
"execution_count": 7,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"alldata['Piętro'].value_counts() # ile razy która wartość występuje"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "subslide"
}
},
"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": {
"slideshow": {
"slide_type": "subslide"
}
},
"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*?\n",
" * Skoro `poddasze` pojawia się tylko w nielicznych przykładach, może w ogóle odrzucić te przykłady?"
" * Może wykorzystać w tym celu wartość z sąsiedniej kolumny *Liczba pięter w budynku*?"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "subslide"
}
},
"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`."
]
@ -316,11 +219,7 @@
{
"cell_type": "code",
"execution_count": 18,
"metadata": {
"slideshow": {
"slide_type": "subslide"
}
},
"metadata": {},
"outputs": [
{
"name": "stdout",
@ -345,11 +244,7 @@
{
"cell_type": "code",
"execution_count": 19,
"metadata": {
"slideshow": {
"slide_type": "subslide"
}
},
"metadata": {},
"outputs": [
{
"name": "stdout",
@ -382,22 +277,14 @@
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "slide"
}
},
"metadata": {},
"source": [
"### Wartości NaN"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "subslide"
}
},
"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:"
]
@ -405,11 +292,7 @@
{
"cell_type": "code",
"execution_count": 20,
"metadata": {
"slideshow": {
"slide_type": "subslide"
}
},
"metadata": {},
"outputs": [
{
"name": "stdout",
@ -442,11 +325,7 @@
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "subslide"
}
},
"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",
@ -457,11 +336,7 @@
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "subslide"
}
},
"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",
@ -470,11 +345,7 @@
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "subslide"
}
},
"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)"
]
@ -482,11 +353,7 @@
{
"cell_type": "code",
"execution_count": 21,
"metadata": {
"slideshow": {
"slide_type": "subslide"
}
},
"metadata": {},
"outputs": [
{
"name": "stdout",
@ -507,22 +374,14 @@
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "slide"
}
},
"metadata": {},
"source": [
"## Dane boole'owskie"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "subslide"
}
},
"metadata": {},
"source": [
"W przypadku danych typu prawda/fałsz, wystarczy zamienić wartości `True` na `1`, a `False` na `0`:"
]
@ -530,11 +389,7 @@
{
"cell_type": "code",
"execution_count": 22,
"metadata": {
"slideshow": {
"slide_type": "subslide"
}
},
"metadata": {},
"outputs": [
{
"name": "stdout",
@ -564,11 +419,7 @@
{
"cell_type": "code",
"execution_count": 23,
"metadata": {
"slideshow": {
"slide_type": "subslide"
}
},
"metadata": {},
"outputs": [
{
"name": "stdout",
@ -601,22 +452,14 @@
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "slide"
}
},
"metadata": {},
"source": [
"## Dane kategoryczne"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "subslide"
}
},
"metadata": {},
"source": [
"O danych kategorycznych mówimy, jeżeli dane mogą przyjmować wartości ze skończonej listy („kategorii”), np.:"
]
@ -624,11 +467,7 @@
{
"cell_type": "code",
"execution_count": 27,
"metadata": {
"slideshow": {
"slide_type": "subslide"
}
},
"metadata": {},
"outputs": [
{
"name": "stdout",
@ -649,11 +488,7 @@
{
"cell_type": "code",
"execution_count": 28,
"metadata": {
"slideshow": {
"slide_type": "subslide"
}
},
"metadata": {},
"outputs": [
{
"name": "stdout",
@ -673,11 +508,7 @@
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "subslide"
}
},
"metadata": {},
"source": [
"Cechę kategoryczną można rozbić na skończoną liczbę cech boole'owskich:"
]
@ -685,11 +516,7 @@
{
"cell_type": "code",
"execution_count": 29,
"metadata": {
"slideshow": {
"slide_type": "subslide"
}
},
"metadata": {},
"outputs": [],
"source": [
"# Skopiujmy dane, żeby przedstawić 2 alternatywne rozwiązania\n",
@ -701,11 +528,7 @@
{
"cell_type": "code",
"execution_count": 30,
"metadata": {
"slideshow": {
"slide_type": "subslide"
}
},
"metadata": {},
"outputs": [
{
"name": "stdout",
@ -765,11 +588,7 @@
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "subslide"
}
},
"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`:"
]
@ -777,11 +596,7 @@
{
"cell_type": "code",
"execution_count": 31,
"metadata": {
"slideshow": {
"slide_type": "subslide"
}
},
"metadata": {},
"outputs": [
{
"name": "stdout",
@ -890,22 +705,14 @@
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "subslide"
}
},
"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": {
"slideshow": {
"slide_type": "subslide"
}
},
"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",
@ -914,33 +721,21 @@
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "slide"
}
},
"metadata": {},
"source": [
"## Dane tekstowe"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "subslide"
}
},
"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": {
"slideshow": {
"slide_type": "subslide"
}
},
"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:"
]
@ -948,11 +743,7 @@
{
"cell_type": "code",
"execution_count": 15,
"metadata": {
"slideshow": {
"slide_type": "subslide"
}
},
"metadata": {},
"outputs": [
{
"name": "stdout",
@ -982,22 +773,14 @@
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "subslide"
}
},
"metadata": {},
"source": [
"Można też zamienić tekst na wektory używając algorytmów TFIDF, Word2Vec lub podobnych."
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "subslide"
}
},
"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/"
]

File diff suppressed because one or more lines are too long

View File

@ -105,7 +105,7 @@
"\n",
" * Wartość wyrażenia normalizacyjnego nie wpływa na wynik klasyfikacji.\n",
"\n",
"*Przykład*: obserwacja nietypowa ma małe prawdopodobieństwo względem dowolnej klasy, wyrażenie normalizacyjne sprawia, że to prawdopodobieństwo staje się porównywalne z prawdopodobieństwami typowych obserwacji, ale nie wpływa na klasyfikację!"
"_Przykład_: obserwacja nietypowa ma małe prawdopodobieństwo względem dowolnej klasy, wyrażenie normalizacyjne sprawia, że to prawdopodobieństwo staje się porównywalne z prawdopodobieństwami typowych obserwacji, ale nie wpływa na klasyfikację!"
]
},
{
@ -119,8 +119,8 @@
"### Klasyfikatory dyskryminatywne a generatywne\n",
"\n",
"* Klasyfikatory generatywne tworzą model rozkładu prawdopodobieństwa dla każdej z klas.\n",
"* Klasyfikatory dyskryminatywne wyznaczają granicę klas (*decision boundary*) bezpośrednio.\n",
"* Naiwny klasyfikator bayesowski jest klasyfikatorem generatywnym (ponieważ wyznacza $P( x \\,|\\, y )$).\n",
"* Klasyfikatory dyskryminatywne wyznaczają granicę klas (_decision boundary_) bezpośrednio.\n",
"* Naiwny klasyfikator baywsowski jest klasyfikatorem generatywnym (ponieważ wyznacza $P( x \\,|\\, y )$).\n",
"* Wszystkie klasyfikatory generatywne są probabilistyczne, ale nie na odwrót.\n",
"* Regresja logistyczna jest przykładem klasyfikatora dyskryminatywnego."
]
@ -135,7 +135,7 @@
"source": [
"### Założenie niezależności dla naiwnego klasyfikatora bayesowskiego\n",
"\n",
"* Naiwny klasyfikator bayesowski jest *naiwny*, ponieważ zakłada, że poszczególne cechy są niezależne od siebie:\n",
"* Naiwny klasyfikator bayesowski jest _naiwny_, ponieważ zakłada, że poszczególne cechy są niezależne od siebie:\n",
"$$ P( x_1, \\ldots, x_n \\,|\\, y ) \\,=\\, \\prod_{i=1}^n P( x_i \\,|\\, x_1, \\ldots, x_{i-1}, y ) \\,=\\, \\prod_{i=1}^n P( x_i \\,|\\, y ) $$\n",
"* To założenie jest bardzo przydatne ze względów obliczeniowych, ponieważ bardzo często mamy do czynienia z ogromną liczbą cech (bitmapy, słowniki itp.)"
]
@ -370,11 +370,7 @@
{
"cell_type": "code",
"execution_count": 9,
"metadata": {
"slideshow": {
"slide_type": "subslide"
}
},
"metadata": {},
"outputs": [
{
"name": "stdout",
@ -478,11 +474,7 @@
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "subslide"
}
},
"metadata": {},
"source": [
"Aby teraz przewidzieć klasę $y$ dla dowolnego zestawu cech $x$, wystarczy sprawdzić, dla której klasy prawdopodobieństwo *a posteriori* jest większe:"
]
@ -490,11 +482,7 @@
{
"cell_type": "code",
"execution_count": 13,
"metadata": {
"slideshow": {
"slide_type": "notes"
}
},
"metadata": {},
"outputs": [],
"source": [
"# Funkcja klasyfikująca (funkcja predykcji)\n",
@ -509,11 +497,7 @@
{
"cell_type": "code",
"execution_count": 14,
"metadata": {
"slideshow": {
"slide_type": "fragment"
}
},
"metadata": {},
"outputs": [
{
"name": "stdout",
@ -536,11 +520,7 @@
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "notes"
}
},
"metadata": {},
"source": [
"Zobaczmy, jak to wygląda na wykresie. Narysujemy w tym celu granicę między klasą 1 a 0:"
]
@ -548,11 +528,7 @@
{
"cell_type": "code",
"execution_count": 15,
"metadata": {
"slideshow": {
"slide_type": "notes"
}
},
"metadata": {},
"outputs": [],
"source": [
"# Wykres granicy klas dla naiwnego Bayesa\n",
@ -927,11 +903,7 @@
{
"cell_type": "code",
"execution_count": 27,
"metadata": {
"slideshow": {
"slide_type": "notes"
}
},
"metadata": {},
"outputs": [
{
"name": "stdout",

View File

@ -266,7 +266,7 @@
}
},
"source": [
"$$ f(x_1, x_2) = \\max(x_1, x_2) \\hskip{12em} \\\\\n",
"$$ f(x_1, x_2) = \\max(x_1 + x_2) \\hskip{12em} \\\\\n",
"\\to \\qquad \\frac{\\partial f}{\\partial x_1} = \\mathbb{1}_{x \\geq y}, \\quad \\frac{\\partial f}{\\partial x_2} = \\mathbb{1}_{y \\geq x}, \\quad \\nabla f = (\\mathbb{1}_{x \\geq y}, \\mathbb{1}_{y \\geq x}) $$ "
]
},
@ -755,7 +755,7 @@
"\n",
"Pojedyncza iteracja:\n",
"* Dla parametrów $\\Theta = (\\Theta^{(1)},\\ldots,\\Theta^{(L)})$ utwórz pomocnicze macierze zerowe $\\Delta = (\\Delta^{(1)},\\ldots,\\Delta^{(L)})$ o takich samych wymiarach (dla uproszczenia opuszczono wagi $\\beta$).\n",
"* Dla $m$ przykładów we wsadzie (*batch*), $i = 1,\\ldots,m$:\n",
"* Dla $m$ przykładów we wsadzie (_batch_), $i = 1,\\ldots,m$:\n",
" * Wykonaj algortym propagacji wstecznej dla przykładu $(x^{(i)}, y^{(i)})$ i przechowaj gradienty $\\nabla_{\\Theta}J^{(i)}(\\Theta)$ dla tego przykładu;\n",
" * $\\Delta := \\Delta + \\dfrac{1}{m}\\nabla_{\\Theta}J^{(i)}(\\Theta)$\n",
"* Wykonaj aktualizację wag: $\\Theta := \\Theta - \\alpha \\Delta$"
@ -969,7 +969,7 @@
},
{
"cell_type": "code",
"execution_count": 5,
"execution_count": 9,
"metadata": {
"scrolled": true,
"slideshow": {
@ -981,15 +981,19 @@
"name": "stdout",
"output_type": "stream",
"text": [
"Model: \"sequential\"\n",
"Model: \"sequential_1\"\n",
"_________________________________________________________________\n",
"Layer (type) Output Shape Param # \n",
"=================================================================\n",
"dense (Dense) (None, 512) 401920 \n",
"dense_3 (Dense) (None, 512) 401920 \n",
"_________________________________________________________________\n",
"dense_1 (Dense) (None, 512) 262656 \n",
"dropout (Dropout) (None, 512) 0 \n",
"_________________________________________________________________\n",
"dense_2 (Dense) (None, 10) 5130 \n",
"dense_4 (Dense) (None, 512) 262656 \n",
"_________________________________________________________________\n",
"dropout_1 (Dropout) (None, 512) 0 \n",
"_________________________________________________________________\n",
"dense_5 (Dense) (None, 10) 5130 \n",
"=================================================================\n",
"Total params: 669,706\n",
"Trainable params: 669,706\n",
@ -1000,8 +1004,10 @@
],
"source": [
"model = keras.Sequential()\n",
"model.add(Dense(512, activation='tanh', input_shape=(784,)))\n",
"model.add(Dense(512, activation='tanh'))\n",
"model.add(Dense(512, activation='relu', input_shape=(784,)))\n",
"model.add(Dropout(0.2))\n",
"model.add(Dense(512, activation='relu'))\n",
"model.add(Dropout(0.2))\n",
"model.add(Dense(num_classes, activation='softmax'))\n",
"\n",
"model.summary() # wyświetl podsumowanie architektury sieci"
@ -1009,7 +1015,7 @@
},
{
"cell_type": "code",
"execution_count": 6,
"execution_count": 10,
"metadata": {
"slideshow": {
"slide_type": "subslide"
@ -1030,28 +1036,55 @@
},
{
"cell_type": "code",
"execution_count": 7,
"metadata": {},
"execution_count": 12,
"metadata": {
"slideshow": {
"slide_type": "subslide"
}
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"[[0. 0. 0. 0. 0. 1. 0. 0. 0. 0.]\n",
" [1. 0. 0. 0. 0. 0. 0. 0. 0. 0.]\n",
" [0. 0. 0. 0. 1. 0. 0. 0. 0. 0.]\n",
" [0. 1. 0. 0. 0. 0. 0. 0. 0. 0.]\n",
" [0. 0. 0. 0. 0. 0. 0. 0. 0. 1.]\n",
" [0. 0. 1. 0. 0. 0. 0. 0. 0. 0.]\n",
" [0. 1. 0. 0. 0. 0. 0. 0. 0. 0.]\n",
" [0. 0. 0. 1. 0. 0. 0. 0. 0. 0.]\n",
" [0. 1. 0. 0. 0. 0. 0. 0. 0. 0.]\n",
" [0. 0. 0. 0. 1. 0. 0. 0. 0. 0.]]\n"
"Epoch 1/10\n",
"469/469 [==============================] - 20s 42ms/step - loss: 0.0957 - accuracy: 0.9708 - val_loss: 0.0824 - val_accuracy: 0.9758\n",
"Epoch 2/10\n",
"469/469 [==============================] - 20s 43ms/step - loss: 0.0693 - accuracy: 0.9793 - val_loss: 0.0807 - val_accuracy: 0.9772\n",
"Epoch 3/10\n",
"469/469 [==============================] - 18s 38ms/step - loss: 0.0563 - accuracy: 0.9827 - val_loss: 0.0861 - val_accuracy: 0.9758\n",
"Epoch 4/10\n",
"469/469 [==============================] - 18s 37ms/step - loss: 0.0485 - accuracy: 0.9857 - val_loss: 0.0829 - val_accuracy: 0.9794\n",
"Epoch 5/10\n",
"469/469 [==============================] - 19s 41ms/step - loss: 0.0428 - accuracy: 0.9876 - val_loss: 0.0955 - val_accuracy: 0.9766\n",
"Epoch 6/10\n",
"469/469 [==============================] - 22s 47ms/step - loss: 0.0377 - accuracy: 0.9887 - val_loss: 0.0809 - val_accuracy: 0.9794\n",
"Epoch 7/10\n",
"469/469 [==============================] - 17s 35ms/step - loss: 0.0338 - accuracy: 0.9904 - val_loss: 0.1028 - val_accuracy: 0.9788\n",
"Epoch 8/10\n",
"469/469 [==============================] - 17s 36ms/step - loss: 0.0322 - accuracy: 0.9911 - val_loss: 0.0937 - val_accuracy: 0.9815\n",
"Epoch 9/10\n",
"469/469 [==============================] - 18s 37ms/step - loss: 0.0303 - accuracy: 0.9912 - val_loss: 0.0916 - val_accuracy: 0.9829.0304 - accu\n",
"Epoch 10/10\n",
"469/469 [==============================] - 16s 34ms/step - loss: 0.0263 - accuracy: 0.9926 - val_loss: 0.0958 - val_accuracy: 0.9812\n"
]
},
{
"data": {
"text/plain": [
"<tensorflow.python.keras.callbacks.History at 0x228eac95ac0>"
]
},
"execution_count": 12,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"print(y_train[:10])"
"model.compile(loss='categorical_crossentropy', optimizer=keras.optimizers.RMSprop(), metrics=['accuracy'])\n",
"\n",
"model.fit(x_train, y_train, batch_size=128, epochs=10, verbose=1,\n",
" validation_data=(x_test, y_test))"
]
},
{
@ -1067,61 +1100,8 @@
"name": "stdout",
"output_type": "stream",
"text": [
"Epoch 1/10\n",
"469/469 [==============================] - 11s 24ms/step - loss: 0.2807 - accuracy: 0.9158 - val_loss: 0.1509 - val_accuracy: 0.9550\n",
"Epoch 2/10\n",
"469/469 [==============================] - 11s 24ms/step - loss: 0.1242 - accuracy: 0.9619 - val_loss: 0.1076 - val_accuracy: 0.9677\n",
"Epoch 3/10\n",
"469/469 [==============================] - 11s 24ms/step - loss: 0.0812 - accuracy: 0.9752 - val_loss: 0.0862 - val_accuracy: 0.9723\n",
"Epoch 4/10\n",
"469/469 [==============================] - 11s 24ms/step - loss: 0.0587 - accuracy: 0.9820 - val_loss: 0.0823 - val_accuracy: 0.9727\n",
"Epoch 5/10\n",
"469/469 [==============================] - 11s 24ms/step - loss: 0.0416 - accuracy: 0.9870 - val_loss: 0.0735 - val_accuracy: 0.9763\n",
"Epoch 6/10\n",
"469/469 [==============================] - 11s 24ms/step - loss: 0.0318 - accuracy: 0.9897 - val_loss: 0.0723 - val_accuracy: 0.9761s: 0.0318 - accuracy: \n",
"Epoch 7/10\n",
"469/469 [==============================] - 11s 23ms/step - loss: 0.0215 - accuracy: 0.9940 - val_loss: 0.0685 - val_accuracy: 0.9792\n",
"Epoch 8/10\n",
"469/469 [==============================] - 11s 23ms/step - loss: 0.0189 - accuracy: 0.9943 - val_loss: 0.0705 - val_accuracy: 0.9786\n",
"Epoch 9/10\n",
"469/469 [==============================] - 11s 24ms/step - loss: 0.0148 - accuracy: 0.9957 - val_loss: 0.0674 - val_accuracy: 0.9790\n",
"Epoch 10/10\n",
"469/469 [==============================] - 11s 23ms/step - loss: 0.0092 - accuracy: 0.9978 - val_loss: 0.0706 - val_accuracy: 0.9798\n"
]
},
{
"data": {
"text/plain": [
"<tensorflow.python.keras.callbacks.History at 0x1bde5f96b50>"
]
},
"execution_count": 8,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"model.compile(loss='categorical_crossentropy', optimizer=keras.optimizers.Adam(), metrics=['accuracy'])\n",
"\n",
"model.fit(x_train, y_train, batch_size=128, epochs=10, verbose=1,\n",
" validation_data=(x_test, y_test))"
]
},
{
"cell_type": "code",
"execution_count": 9,
"metadata": {
"slideshow": {
"slide_type": "subslide"
}
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Test loss: 0.07055816799402237\n",
"Test accuracy: 0.9797999858856201\n"
"Test loss: 0.0757974311709404\n",
"Test accuracy: 0.9810000061988831\n"
]
}
],

View File

@ -31,8 +31,6 @@
}
},
"source": [
"* Złożenie funkcji liniowych jest funkcją liniową.\n",
"* Głównym zadaniem funkcji aktywacji jest wprowadzenie nieliniowości do sieci neuronowej, żeby model mógł odwzorowywać nie tylko liniowe zależności między danymi.\n",
"* Każda funkcja aktywacji ma swoje zalety i wady.\n",
"* Różne rodzaje funkcji aktywacji nadają się do różnych zastosowań."
]