Compare commits

...

12 Commits

Author SHA1 Message Date
Paweł Skórzewski
d7950b818f Poprawka pliku do zadania 12 2022-05-26 10:26:16 +02:00
Paweł Skórzewski
67ba614235 Poprawka pliku do zadania 12 2022-05-26 10:25:16 +02:00
Paweł Skórzewski
3405d80635 Wykład 10 i 11 2022-05-20 09:39:29 +02:00
Paweł Skórzewski
52896c2a9d Fix lab 10 2022-05-12 12:31:26 +02:00
Paweł Skórzewski
b2c58746e5 Naiwny klasyfikator bayesowski 2022-04-08 09:24:18 +02:00
Paweł Skórzewski
da8b7f3840 Regresja wielomianowa - uaktualnienie wykładu 2022-04-01 10:17:51 +02:00
Paweł Skórzewski
44ae9e8b11 Usuwanie obserwacji odstających 2022-03-25 10:08:25 +01:00
Paweł Skórzewski
1f98b6813c Reprezentacja danych - uzupełnienie 2022-03-25 08:51:48 +01:00
Paweł Skórzewski
9420133937 Jeszcze drobne poprawki do lab. 4 2022-03-24 12:05:36 +01:00
Paweł Skórzewski
a847c25479 Rozbudowanie przykładu 04 2022-03-24 11:23:51 +01:00
Paweł Skórzewski
5f0e9bc9a9 Laboratoria 4 - ewaluacja 2022-03-24 10:35:07 +01:00
Paweł Skórzewski
3e4d0e7a93 Poprawka literówki 2022-03-17 12:54:29 +01:00
10 changed files with 624 additions and 45697 deletions

View File

@ -31,23 +31,24 @@
},
{
"cell_type": "code",
"execution_count": 1,
"execution_count": 15,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"[[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"
"[[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"
]
}
],
@ -57,6 +58,8 @@
"\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",
@ -64,11 +67,12 @@
" '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\"\"\"\n",
" \"\"\"Wstępne przetworzenie danych, np. zamiana wartości tekstowych na liczby\"\"\"\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",
@ -78,8 +82,14 @@
"\n",
"# Wczytanie danych\n",
"data = pd.read_csv(dataset_filename, header=0, sep='\\t')\n",
"columns = data.columns[1:] # wszystkie kolumny oprócz pierwszej (\"cena\")\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",
"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",
@ -98,7 +108,12 @@
"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"
"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)"
]
},
{
@ -126,7 +141,7 @@
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.8.3"
"version": "3.7.6"
},
"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": 4,
"execution_count": 1,
"metadata": {},
"outputs": [],
"source": [
@ -82,18 +82,16 @@
},
{
"cell_type": "code",
"execution_count": 1,
"execution_count": 2,
"metadata": {},
"outputs": [
{
"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"
"name": "stdout",
"output_type": "stream",
"text": [
"x_train shape: (60000, 28, 28, 1)\n",
"60000 train samples\n",
"10000 test samples\n"
]
}
],
@ -123,7 +121,7 @@
},
{
"cell_type": "code",
"execution_count": 6,
"execution_count": 3,
"metadata": {},
"outputs": [
{
@ -176,23 +174,23 @@
},
{
"cell_type": "code",
"execution_count": 9,
"execution_count": 7,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"422/422 [==============================] - 38s 91ms/step - loss: 0.0556 - accuracy: 0.9826 - val_loss: 0.0412 - val_accuracy: 0.9893\n"
"422/422 [==============================] - 40s 94ms/step - loss: 0.1914 - accuracy: 0.9418 - val_loss: 0.0718 - val_accuracy: 0.9803\n"
]
},
{
"data": {
"text/plain": [
"<tensorflow.python.keras.callbacks.History at 0x1a50b35a070>"
"<tensorflow.python.keras.callbacks.History at 0x1de55106d00>"
]
},
"execution_count": 9,
"execution_count": 7,
"metadata": {},
"output_type": "execute_result"
}
@ -200,12 +198,9 @@
"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, epochs=1, batch_size=batch_size, epochs=epochs, validation_split=0.1)"
"model.fit(x_train, y_train, batch_size=128, epochs=5, validation_split=0.1)"
]
},
{
@ -248,7 +243,7 @@
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.8.3"
"version": "3.8.5"
},
"livereveal": {
"start_slideshow_at": "selected",

File diff suppressed because one or more lines are too long

View File

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

View File

@ -14,15 +14,23 @@
},
{
"cell_type": "markdown",
"metadata": {},
"metadata": {
"slideshow": {
"slide_type": "subslide"
}
},
"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": {},
"execution_count": 1,
"metadata": {
"slideshow": {
"slide_type": "notes"
}
},
"outputs": [],
"source": [
"# Przydatne importy\n",
@ -37,15 +45,23 @@
},
{
"cell_type": "markdown",
"metadata": {},
"metadata": {
"slideshow": {
"slide_type": "subslide"
}
},
"source": [
"Plik *mieszkania4.tsv* zawiera dane wydobyte z serwisu *gratka.pl* dotyczące cen mieszkań w Poznaniu."
]
},
{
"cell_type": "code",
"execution_count": 15,
"metadata": {},
"execution_count": 2,
"metadata": {
"slideshow": {
"slide_type": "subslide"
}
},
"outputs": [
{
"name": "stdout",
@ -86,7 +102,11 @@
},
{
"cell_type": "markdown",
"metadata": {},
"metadata": {
"slideshow": {
"slide_type": "subslide"
}
},
"source": [
"Jak widać powyżej, w pliku *mieszkania4.tsv* znajdują się dane różnych typów:\n",
"* dane numeryczne (po prostu liczby):\n",
@ -101,35 +121,52 @@
" * 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": {},
"metadata": {
"slideshow": {
"slide_type": "subslide"
}
},
"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": {},
"metadata": {
"slideshow": {
"slide_type": "slide"
}
},
"source": [
"## Dane numeryczne"
]
},
{
"cell_type": "markdown",
"metadata": {},
"metadata": {
"slideshow": {
"slide_type": "subslide"
}
},
"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": {},
"execution_count": 3,
"metadata": {
"slideshow": {
"slide_type": "subslide"
}
},
"outputs": [
{
"name": "stdout",
@ -168,15 +205,23 @@
},
{
"cell_type": "markdown",
"metadata": {},
"metadata": {
"slideshow": {
"slide_type": "subslide"
}
},
"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": {},
"execution_count": 4,
"metadata": {
"slideshow": {
"slide_type": "subslide"
}
},
"outputs": [
{
"name": "stdout",
@ -192,26 +237,78 @@
]
},
{
"cell_type": "markdown",
"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"
}
},
"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": {},
"metadata": {
"slideshow": {
"slide_type": "subslide"
}
},
"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*?"
" * 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?"
]
},
{
"cell_type": "markdown",
"metadata": {},
"metadata": {
"slideshow": {
"slide_type": "subslide"
}
},
"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`."
]
@ -219,7 +316,11 @@
{
"cell_type": "code",
"execution_count": 18,
"metadata": {},
"metadata": {
"slideshow": {
"slide_type": "subslide"
}
},
"outputs": [
{
"name": "stdout",
@ -244,7 +345,11 @@
{
"cell_type": "code",
"execution_count": 19,
"metadata": {},
"metadata": {
"slideshow": {
"slide_type": "subslide"
}
},
"outputs": [
{
"name": "stdout",
@ -277,14 +382,22 @@
},
{
"cell_type": "markdown",
"metadata": {},
"metadata": {
"slideshow": {
"slide_type": "slide"
}
},
"source": [
"### Wartości NaN"
]
},
{
"cell_type": "markdown",
"metadata": {},
"metadata": {
"slideshow": {
"slide_type": "subslide"
}
},
"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:"
]
@ -292,7 +405,11 @@
{
"cell_type": "code",
"execution_count": 20,
"metadata": {},
"metadata": {
"slideshow": {
"slide_type": "subslide"
}
},
"outputs": [
{
"name": "stdout",
@ -325,7 +442,11 @@
},
{
"cell_type": "markdown",
"metadata": {},
"metadata": {
"slideshow": {
"slide_type": "subslide"
}
},
"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",
@ -336,7 +457,11 @@
},
{
"cell_type": "markdown",
"metadata": {},
"metadata": {
"slideshow": {
"slide_type": "subslide"
}
},
"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",
@ -345,7 +470,11 @@
},
{
"cell_type": "markdown",
"metadata": {},
"metadata": {
"slideshow": {
"slide_type": "subslide"
}
},
"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)"
]
@ -353,7 +482,11 @@
{
"cell_type": "code",
"execution_count": 21,
"metadata": {},
"metadata": {
"slideshow": {
"slide_type": "subslide"
}
},
"outputs": [
{
"name": "stdout",
@ -374,14 +507,22 @@
},
{
"cell_type": "markdown",
"metadata": {},
"metadata": {
"slideshow": {
"slide_type": "slide"
}
},
"source": [
"## Dane boole'owskie"
]
},
{
"cell_type": "markdown",
"metadata": {},
"metadata": {
"slideshow": {
"slide_type": "subslide"
}
},
"source": [
"W przypadku danych typu prawda/fałsz, wystarczy zamienić wartości `True` na `1`, a `False` na `0`:"
]
@ -389,7 +530,11 @@
{
"cell_type": "code",
"execution_count": 22,
"metadata": {},
"metadata": {
"slideshow": {
"slide_type": "subslide"
}
},
"outputs": [
{
"name": "stdout",
@ -419,7 +564,11 @@
{
"cell_type": "code",
"execution_count": 23,
"metadata": {},
"metadata": {
"slideshow": {
"slide_type": "subslide"
}
},
"outputs": [
{
"name": "stdout",
@ -452,14 +601,22 @@
},
{
"cell_type": "markdown",
"metadata": {},
"metadata": {
"slideshow": {
"slide_type": "slide"
}
},
"source": [
"## Dane kategoryczne"
]
},
{
"cell_type": "markdown",
"metadata": {},
"metadata": {
"slideshow": {
"slide_type": "subslide"
}
},
"source": [
"O danych kategorycznych mówimy, jeżeli dane mogą przyjmować wartości ze skończonej listy („kategorii”), np.:"
]
@ -467,7 +624,11 @@
{
"cell_type": "code",
"execution_count": 27,
"metadata": {},
"metadata": {
"slideshow": {
"slide_type": "subslide"
}
},
"outputs": [
{
"name": "stdout",
@ -488,7 +649,11 @@
{
"cell_type": "code",
"execution_count": 28,
"metadata": {},
"metadata": {
"slideshow": {
"slide_type": "subslide"
}
},
"outputs": [
{
"name": "stdout",
@ -508,7 +673,11 @@
},
{
"cell_type": "markdown",
"metadata": {},
"metadata": {
"slideshow": {
"slide_type": "subslide"
}
},
"source": [
"Cechę kategoryczną można rozbić na skończoną liczbę cech boole'owskich:"
]
@ -516,7 +685,11 @@
{
"cell_type": "code",
"execution_count": 29,
"metadata": {},
"metadata": {
"slideshow": {
"slide_type": "subslide"
}
},
"outputs": [],
"source": [
"# Skopiujmy dane, żeby przedstawić 2 alternatywne rozwiązania\n",
@ -528,7 +701,11 @@
{
"cell_type": "code",
"execution_count": 30,
"metadata": {},
"metadata": {
"slideshow": {
"slide_type": "subslide"
}
},
"outputs": [
{
"name": "stdout",
@ -588,7 +765,11 @@
},
{
"cell_type": "markdown",
"metadata": {},
"metadata": {
"slideshow": {
"slide_type": "subslide"
}
},
"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`:"
]
@ -596,7 +777,11 @@
{
"cell_type": "code",
"execution_count": 31,
"metadata": {},
"metadata": {
"slideshow": {
"slide_type": "subslide"
}
},
"outputs": [
{
"name": "stdout",
@ -705,14 +890,22 @@
},
{
"cell_type": "markdown",
"metadata": {},
"metadata": {
"slideshow": {
"slide_type": "subslide"
}
},
"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": {},
"metadata": {
"slideshow": {
"slide_type": "subslide"
}
},
"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",
@ -721,21 +914,33 @@
},
{
"cell_type": "markdown",
"metadata": {},
"metadata": {
"slideshow": {
"slide_type": "slide"
}
},
"source": [
"## Dane tekstowe"
]
},
{
"cell_type": "markdown",
"metadata": {},
"metadata": {
"slideshow": {
"slide_type": "subslide"
}
},
"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": {},
"metadata": {
"slideshow": {
"slide_type": "subslide"
}
},
"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:"
]
@ -743,7 +948,11 @@
{
"cell_type": "code",
"execution_count": 15,
"metadata": {},
"metadata": {
"slideshow": {
"slide_type": "subslide"
}
},
"outputs": [
{
"name": "stdout",
@ -773,14 +982,22 @@
},
{
"cell_type": "markdown",
"metadata": {},
"metadata": {
"slideshow": {
"slide_type": "subslide"
}
},
"source": [
"Można też zamienić tekst na wektory używając algorytmów TFIDF, Word2Vec lub podobnych."
]
},
{
"cell_type": "markdown",
"metadata": {},
"metadata": {
"slideshow": {
"slide_type": "subslide"
}
},
"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 baywsowski jest klasyfikatorem generatywnym (ponieważ wyznacza $P( x \\,|\\, y )$).\n",
"* Klasyfikatory dyskryminatywne wyznaczają granicę klas (*decision boundary*) bezpośrednio.\n",
"* Naiwny klasyfikator bayesowski 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,7 +370,11 @@
{
"cell_type": "code",
"execution_count": 9,
"metadata": {},
"metadata": {
"slideshow": {
"slide_type": "subslide"
}
},
"outputs": [
{
"name": "stdout",
@ -474,7 +478,11 @@
},
{
"cell_type": "markdown",
"metadata": {},
"metadata": {
"slideshow": {
"slide_type": "subslide"
}
},
"source": [
"Aby teraz przewidzieć klasę $y$ dla dowolnego zestawu cech $x$, wystarczy sprawdzić, dla której klasy prawdopodobieństwo *a posteriori* jest większe:"
]
@ -482,7 +490,11 @@
{
"cell_type": "code",
"execution_count": 13,
"metadata": {},
"metadata": {
"slideshow": {
"slide_type": "notes"
}
},
"outputs": [],
"source": [
"# Funkcja klasyfikująca (funkcja predykcji)\n",
@ -497,7 +509,11 @@
{
"cell_type": "code",
"execution_count": 14,
"metadata": {},
"metadata": {
"slideshow": {
"slide_type": "fragment"
}
},
"outputs": [
{
"name": "stdout",
@ -520,7 +536,11 @@
},
{
"cell_type": "markdown",
"metadata": {},
"metadata": {
"slideshow": {
"slide_type": "notes"
}
},
"source": [
"Zobaczmy, jak to wygląda na wykresie. Narysujemy w tym celu granicę między klasą 1 a 0:"
]
@ -528,7 +548,11 @@
{
"cell_type": "code",
"execution_count": 15,
"metadata": {},
"metadata": {
"slideshow": {
"slide_type": "notes"
}
},
"outputs": [],
"source": [
"# Wykres granicy klas dla naiwnego Bayesa\n",
@ -903,7 +927,11 @@
{
"cell_type": "code",
"execution_count": 27,
"metadata": {},
"metadata": {
"slideshow": {
"slide_type": "notes"
}
},
"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": 9,
"execution_count": 5,
"metadata": {
"scrolled": true,
"slideshow": {
@ -981,19 +981,15 @@
"name": "stdout",
"output_type": "stream",
"text": [
"Model: \"sequential_1\"\n",
"Model: \"sequential\"\n",
"_________________________________________________________________\n",
"Layer (type) Output Shape Param # \n",
"=================================================================\n",
"dense_3 (Dense) (None, 512) 401920 \n",
"dense (Dense) (None, 512) 401920 \n",
"_________________________________________________________________\n",
"dropout (Dropout) (None, 512) 0 \n",
"dense_1 (Dense) (None, 512) 262656 \n",
"_________________________________________________________________\n",
"dense_4 (Dense) (None, 512) 262656 \n",
"_________________________________________________________________\n",
"dropout_1 (Dropout) (None, 512) 0 \n",
"_________________________________________________________________\n",
"dense_5 (Dense) (None, 10) 5130 \n",
"dense_2 (Dense) (None, 10) 5130 \n",
"=================================================================\n",
"Total params: 669,706\n",
"Trainable params: 669,706\n",
@ -1004,10 +1000,8 @@
],
"source": [
"model = keras.Sequential()\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(512, activation='tanh', input_shape=(784,)))\n",
"model.add(Dense(512, activation='tanh'))\n",
"model.add(Dense(num_classes, activation='softmax'))\n",
"\n",
"model.summary() # wyświetl podsumowanie architektury sieci"
@ -1015,7 +1009,7 @@
},
{
"cell_type": "code",
"execution_count": 10,
"execution_count": 6,
"metadata": {
"slideshow": {
"slide_type": "subslide"
@ -1036,55 +1030,28 @@
},
{
"cell_type": "code",
"execution_count": 12,
"metadata": {
"slideshow": {
"slide_type": "subslide"
}
},
"execution_count": 7,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"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"
"[[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"
]
},
{
"data": {
"text/plain": [
"<tensorflow.python.keras.callbacks.History at 0x228eac95ac0>"
]
},
"execution_count": 12,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"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))"
"print(y_train[:10])"
]
},
{
@ -1100,8 +1067,61 @@
"name": "stdout",
"output_type": "stream",
"text": [
"Test loss: 0.0757974311709404\n",
"Test accuracy: 0.9810000061988831\n"
"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"
]
}
],

View File

@ -31,6 +31,8 @@
}
},
"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ń."
]