uczenie-maszynowe/wyk/09_SVM_i_drzewa_decyzyjne.ipynb
2023-12-14 18:04:47 +01:00

937 lines
96 KiB
Plaintext
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

{
"cells": [
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "slide"
}
},
"source": [
"### Uczenie maszynowe\n",
"# 9. Przegląd metod uczenia nadzorowanego część 2"
]
},
{
"cell_type": "code",
"execution_count": 8,
"metadata": {
"slideshow": {
"slide_type": "notes"
}
},
"outputs": [],
"source": [
"# Przydatne importy\n",
"\n",
"import ipywidgets as widgets\n",
"import matplotlib.pyplot as plt\n",
"import numpy as np\n",
"import pandas\n",
"\n",
"%matplotlib inline"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "slide"
}
},
"source": [
"## 9.1. Maszyny wektorów nośnych"
]
},
{
"cell_type": "code",
"execution_count": 9,
"metadata": {
"slideshow": {
"slide_type": "notes"
}
},
"outputs": [],
"source": [
"# Wczytanie danych (gatunki kosaćców)\n",
"\n",
"data_iris = pandas.read_csv('iris.csv')\n",
"data_iris_setosa = pandas.DataFrame()\n",
"data_iris_setosa['dł. płatka'] = data_iris['pl'] # \"pl\" oznacza \"petal length\"\n",
"data_iris_setosa['szer. płatka'] = data_iris['pw'] # \"pw\" oznacza \"petal width\"\n",
"\n",
"# SVM to metoda klasyfikacji dwuklasowej.\n",
"# Poszczególne klasy będziemy oznaczać jako \"1\" i \"-1\":\n",
"data_iris_setosa['Iris setosa?'] = data_iris['Gatunek'].apply(lambda x: 1 if x=='Iris-setosa' else -1)\n",
"\n",
"m, n_plus_1 = data_iris_setosa.values.shape\n",
"n = n_plus_1 - 1\n",
"X = data_iris_setosa.values[:, 0:n].reshape(m, n)\n",
"Y = np.array(data_iris_setosa.values[:, 2])"
]
},
{
"cell_type": "code",
"execution_count": 10,
"metadata": {
"slideshow": {
"slide_type": "subslide"
}
},
"outputs": [
{
"data": {
"image/png": "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\n",
"text/plain": [
"<Figure size 640x480 with 1 Axes>"
]
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [
"ax = plt.gca()\n",
"ax.scatter(X[:, 0], X[:, 1], c=Y, cmap='coolwarm')\n",
"ax.set_aspect('equal')"
]
},
{
"cell_type": "code",
"execution_count": 11,
"metadata": {
"slideshow": {
"slide_type": "subslide"
}
},
"outputs": [
{
"data": {
"text/html": [
"<style>#sk-container-id-2 {color: black;background-color: white;}#sk-container-id-2 pre{padding: 0;}#sk-container-id-2 div.sk-toggleable {background-color: white;}#sk-container-id-2 label.sk-toggleable__label {cursor: pointer;display: block;width: 100%;margin-bottom: 0;padding: 0.3em;box-sizing: border-box;text-align: center;}#sk-container-id-2 label.sk-toggleable__label-arrow:before {content: \"▸\";float: left;margin-right: 0.25em;color: #696969;}#sk-container-id-2 label.sk-toggleable__label-arrow:hover:before {color: black;}#sk-container-id-2 div.sk-estimator:hover label.sk-toggleable__label-arrow:before {color: black;}#sk-container-id-2 div.sk-toggleable__content {max-height: 0;max-width: 0;overflow: hidden;text-align: left;background-color: #f0f8ff;}#sk-container-id-2 div.sk-toggleable__content pre {margin: 0.2em;color: black;border-radius: 0.25em;background-color: #f0f8ff;}#sk-container-id-2 input.sk-toggleable__control:checked~div.sk-toggleable__content {max-height: 200px;max-width: 100%;overflow: auto;}#sk-container-id-2 input.sk-toggleable__control:checked~label.sk-toggleable__label-arrow:before {content: \"▾\";}#sk-container-id-2 div.sk-estimator input.sk-toggleable__control:checked~label.sk-toggleable__label {background-color: #d4ebff;}#sk-container-id-2 div.sk-label input.sk-toggleable__control:checked~label.sk-toggleable__label {background-color: #d4ebff;}#sk-container-id-2 input.sk-hidden--visually {border: 0;clip: rect(1px 1px 1px 1px);clip: rect(1px, 1px, 1px, 1px);height: 1px;margin: -1px;overflow: hidden;padding: 0;position: absolute;width: 1px;}#sk-container-id-2 div.sk-estimator {font-family: monospace;background-color: #f0f8ff;border: 1px dotted black;border-radius: 0.25em;box-sizing: border-box;margin-bottom: 0.5em;}#sk-container-id-2 div.sk-estimator:hover {background-color: #d4ebff;}#sk-container-id-2 div.sk-parallel-item::after {content: \"\";width: 100%;border-bottom: 1px solid gray;flex-grow: 1;}#sk-container-id-2 div.sk-label:hover label.sk-toggleable__label {background-color: #d4ebff;}#sk-container-id-2 div.sk-serial::before {content: \"\";position: absolute;border-left: 1px solid gray;box-sizing: border-box;top: 0;bottom: 0;left: 50%;z-index: 0;}#sk-container-id-2 div.sk-serial {display: flex;flex-direction: column;align-items: center;background-color: white;padding-right: 0.2em;padding-left: 0.2em;position: relative;}#sk-container-id-2 div.sk-item {position: relative;z-index: 1;}#sk-container-id-2 div.sk-parallel {display: flex;align-items: stretch;justify-content: center;background-color: white;position: relative;}#sk-container-id-2 div.sk-item::before, #sk-container-id-2 div.sk-parallel-item::before {content: \"\";position: absolute;border-left: 1px solid gray;box-sizing: border-box;top: 0;bottom: 0;left: 50%;z-index: -1;}#sk-container-id-2 div.sk-parallel-item {display: flex;flex-direction: column;z-index: 1;position: relative;background-color: white;}#sk-container-id-2 div.sk-parallel-item:first-child::after {align-self: flex-end;width: 50%;}#sk-container-id-2 div.sk-parallel-item:last-child::after {align-self: flex-start;width: 50%;}#sk-container-id-2 div.sk-parallel-item:only-child::after {width: 0;}#sk-container-id-2 div.sk-dashed-wrapped {border: 1px dashed gray;margin: 0 0.4em 0.5em 0.4em;box-sizing: border-box;padding-bottom: 0.4em;background-color: white;}#sk-container-id-2 div.sk-label label {font-family: monospace;font-weight: bold;display: inline-block;line-height: 1.2em;}#sk-container-id-2 div.sk-label-container {text-align: center;}#sk-container-id-2 div.sk-container {/* jupyter's `normalize.less` sets `[hidden] { display: none; }` but bootstrap.min.css set `[hidden] { display: none !important; }` so we also need the `!important` here to be able to override the default hidden behavior on the sphinx rendered scikit-learn.org. See: https://github.com/scikit-learn/scikit-learn/issues/21755 */display: inline-block !important;position: relative;}#sk-container-id-2 div.sk-text-repr-fallback {display: none;}</style><div id=\"sk-container-id-2\" class=\"sk-top-container\"><div class=\"sk-text-repr-fallback\"><pre>SVC(C=10000000000.0, kernel=&#x27;linear&#x27;)</pre><b>In a Jupyter environment, please rerun this cell to show the HTML representation or trust the notebook. <br />On GitHub, the HTML representation is unable to render, please try loading this page with nbviewer.org.</b></div><div class=\"sk-container\" hidden><div class=\"sk-item\"><div class=\"sk-estimator sk-toggleable\"><input class=\"sk-toggleable__control sk-hidden--visually\" id=\"sk-estimator-id-2\" type=\"checkbox\" checked><label for=\"sk-estimator-id-2\" class=\"sk-toggleable__label sk-toggleable__label-arrow\">SVC</label><div class=\"sk-toggleable__content\"><pre>SVC(C=10000000000.0, kernel=&#x27;linear&#x27;)</pre></div></div></div></div></div>"
],
"text/plain": [
"SVC(C=10000000000.0, kernel='linear')"
]
},
"execution_count": 11,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"from sklearn.svm import SVC # \"Support vector classifier\"\n",
"model = SVC(kernel='linear', C=1E10)\n",
"model.fit(X, Y)"
]
},
{
"cell_type": "code",
"execution_count": 12,
"metadata": {
"slideshow": {
"slide_type": "notes"
}
},
"outputs": [],
"source": [
"def plot_svc_decision_function(model, plot_support=True):\n",
" \"\"\"Plot the decision function for a 2D SVC\"\"\"\n",
" ax = plt.gca()\n",
" xlim = ax.get_xlim()\n",
" ylim = ax.get_ylim()\n",
" \n",
" # create grid to evaluate model\n",
" x = np.linspace(xlim[0], xlim[1], 30)\n",
" y = np.linspace(ylim[0], ylim[1], 30)\n",
" Y, X = np.meshgrid(y, x)\n",
" xy = np.vstack([X.ravel(), Y.ravel()]).T\n",
" P = model.decision_function(xy).reshape(X.shape)\n",
" \n",
" # plot decision boundary and margins\n",
" ax.contour(X, Y, P, colors=['orange', 'green', 'orange'],\n",
" levels=[-1, 0, 1], alpha=0.5,\n",
" linestyles=['--', '-', '--'])\n",
" \n",
" # plot support vectors\n",
" if plot_support:\n",
" ax.scatter(model.support_vectors_[:, 0],\n",
" model.support_vectors_[:, 1],\n",
" s=300, linewidth=1, edgecolors='purple', facecolors='none')\n",
" ax.set_aspect('equal')"
]
},
{
"cell_type": "code",
"execution_count": 13,
"metadata": {
"slideshow": {
"slide_type": "subslide"
}
},
"outputs": [
{
"data": {
"image/png": "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\n",
"text/plain": [
"<Figure size 640x480 with 1 Axes>"
]
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [
"plt.scatter(X[:, 0], X[:, 1], c=Y, cmap='coolwarm')\n",
"plot_svc_decision_function(model)"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "subslide"
}
},
"source": [
"**Maszyna wektorów nośnych** (*support vector machine*) próbuje oddzielić punkty należące do różnych klas <small>(<span style=\"color:red\">czerwone</span> i <span style=\"color:blue\">niebieskie</span> kropki)</small> za pomocą <span style=\"color:green\">**hiperpłaszczyzny** <small>(zielona ciągła linia)</small></span> w taki sposób, żeby <span style=\"color:orange\">**margines** <small>(obszar między pomarańczowymi przerywanymi liniami)</small></span> był jak największy."
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "fragment"
}
},
"source": [
"Punkty, które stykają się z marginesem, nazywamy <span style=\"color:purple\">**wektorami nośnymi** <small>(fioletowe kółka)</small></span> stąd nazwa metody."
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "subslide"
}
},
"source": [
"W celu znalezienia hiperpłaszczyzny wykorzystywana jest funkcja kosztu *hinge loss*:\n",
"$$ J(y) = \\max(0, 1 - t \\cdot y) , $$\n",
"gdzie $t$ to oczekiwana wartość klasyfikacji ($1$ lub $-1$), a $y$ to wyjście klasyfikatora."
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "fragment"
}
},
"source": [
" W przypadku *liniowej* maszyny wektorów nośnych:\n",
" $$ y = w \\cdot x + b , $$\n",
" gdzie $w$ i $b$ to parametry hiperpłaszczyzny, a $x$ to wejście klasyfikatora (wektor cech)."
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "subslide"
}
},
"source": [
"Nauczenie klasyfikatora SVM sprowadza się do znalezienia parametrów hiperpłaszczyzny, która minimalizuje funkcję kosztu. Można to zrobić np. za pomocą metody spadku gradientu."
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "subslide"
}
},
"source": [
"Jeżeli klas nie da się oddzielić za pomocą hiperpłaszczyzny, można przekształcić dane wejściowe za pomocą odpowiedniej funkcji (tzw. *kernel trick*) tak, aby przekształcone dane były oddzielalne."
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "slide"
}
},
"source": [
"## 9.2. Drzewa decyzyjne"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "slide"
}
},
"source": [
"### Drzewa decyzyjne przykład"
]
},
{
"cell_type": "code",
"execution_count": 14,
"metadata": {
"scrolled": true,
"slideshow": {
"slide_type": "subslide"
}
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
" Day Outlook Humidity Wind Play\n",
"0 1 Sunny High Weak No\n",
"1 2 Sunny High Strong No\n",
"2 3 Overcast High Weak Yes\n",
"3 4 Rain High Weak Yes\n",
"4 5 Rain Normal Weak Yes\n",
"5 6 Rain Normal Strong No\n",
"6 7 Overcast Normal Strong Yes\n",
"7 8 Sunny High Weak No\n",
"8 9 Sunny Normal Weak Yes\n",
"9 10 Rain Normal Weak Yes\n",
"10 11 Sunny Normal Strong Yes\n",
"11 12 Overcast High Strong Yes\n",
"12 13 Overcast Normal Weak Yes\n",
"13 14 Rain High Strong No\n"
]
}
],
"source": [
"alldata = pandas.read_csv('tennis.tsv', sep='\\t')\n",
"print(alldata)"
]
},
{
"cell_type": "code",
"execution_count": 15,
"metadata": {
"slideshow": {
"slide_type": "subslide"
}
},
"outputs": [
{
"data": {
"text/plain": [
"{'Outlook': {'Overcast', 'Rain', 'Sunny'},\n",
" 'Humidity': {'High', 'Normal'},\n",
" 'Wind': {'Strong', 'Weak'}}"
]
},
"execution_count": 15,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"# Dane jako lista słowników\n",
"data = alldata.T.to_dict().values()\n",
"features = ['Outlook', 'Humidity', 'Wind']\n",
"\n",
"# Możliwe wartości w poszczególnych kolumnach\n",
"values = {feature: set(row[feature] for row in data)\n",
" for feature in features}\n",
"values"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "subslide"
}
},
"source": [
"* Czy John zagra w tenisa, jeżeli będzie padać, przy wysokiej wilgotności i silnym wietrze?\n",
"* Algorytm drzew decyzyjnych spróbuje _zrozumieć_ „taktykę” Johna.\n",
"* Wykorzystamy metodę „dziel i zwyciężaj”."
]
},
{
"cell_type": "code",
"execution_count": 16,
"metadata": {
"slideshow": {
"slide_type": "subslide"
}
},
"outputs": [],
"source": [
"# Podziel dane\n",
"def split(features, data):\n",
" values = {feature: list(set(row[feature]\n",
" for row in data))\n",
" for feature in features}\n",
" if not features:\n",
" return data\n",
" return {val: split(features[1:],\n",
" [row for row in data\n",
" if row[features[0]] == val])\n",
" for val in values[features[0]]}"
]
},
{
"cell_type": "code",
"execution_count": 17,
"metadata": {
"slideshow": {
"slide_type": "subslide"
}
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"\n",
"\tOutlook\tHumid\tWind\tPlay\n",
"Day 1:\tSunny\tHigh\tWeak\tNo\n",
"Day 2:\tSunny\tHigh\tStrong\tNo\n",
"Day 8:\tSunny\tHigh\tWeak\tNo\n",
"Day 9:\tSunny\tNormal\tWeak\tYes\n",
"Day 11:\tSunny\tNormal\tStrong\tYes\n",
"\n",
"\tOutlook\tHumid\tWind\tPlay\n",
"Day 3:\tOvercast\tHigh\tWeak\tYes\n",
"Day 7:\tOvercast\tNormal\tStrong\tYes\n",
"Day 12:\tOvercast\tHigh\tStrong\tYes\n",
"Day 13:\tOvercast\tNormal\tWeak\tYes\n",
"\n",
"\tOutlook\tHumid\tWind\tPlay\n",
"Day 4:\tRain\tHigh\tWeak\tYes\n",
"Day 5:\tRain\tNormal\tWeak\tYes\n",
"Day 6:\tRain\tNormal\tStrong\tNo\n",
"Day 10:\tRain\tNormal\tWeak\tYes\n",
"Day 14:\tRain\tHigh\tStrong\tNo\n"
]
}
],
"source": [
"split_data = split(['Outlook'], data)\n",
"\n",
"for outlook in values['Outlook']:\n",
" print('\\n\\tOutlook\\tHumid\\tWind\\tPlay')\n",
" for row in split_data[outlook]:\n",
" print('Day {Day}:\\t{Outlook}\\t{Humidity}\\t{Wind}\\t{Play}'\n",
" .format(**row))"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "subslide"
}
},
"source": [
"Obserwacja: John lubi grać, gdy jest pochmurnie.\n",
"\n",
"W pozostałych przypadkach podzielmy dane ponownie:"
]
},
{
"cell_type": "code",
"execution_count": 18,
"metadata": {
"slideshow": {
"slide_type": "subslide"
}
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"\n",
"\tOutlook\tHumid\tWind\tPlay\n",
"Day 1:\tSunny\tHigh\tWeak\tNo\n",
"Day 2:\tSunny\tHigh\tStrong\tNo\n",
"Day 8:\tSunny\tHigh\tWeak\tNo\n",
"\n",
"\tOutlook\tHumid\tWind\tPlay\n",
"Day 9:\tSunny\tNormal\tWeak\tYes\n",
"Day 11:\tSunny\tNormal\tStrong\tYes\n"
]
}
],
"source": [
"split_data_sunny = split(['Outlook', 'Humidity'], data)\n",
"\n",
"for humidity in values['Humidity']:\n",
" print('\\n\\tOutlook\\tHumid\\tWind\\tPlay')\n",
" for row in split_data_sunny['Sunny'][humidity]:\n",
" print('Day {Day}:\\t{Outlook}\\t{Humidity}\\t{Wind}\\t{Play}'\n",
" .format(**row))"
]
},
{
"cell_type": "code",
"execution_count": 19,
"metadata": {
"slideshow": {
"slide_type": "subslide"
}
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"\n",
"\tOutlook\tHumid\tWind\tPlay\n",
"Day 4:\tRain\tHigh\tWeak\tYes\n",
"Day 5:\tRain\tNormal\tWeak\tYes\n",
"Day 10:\tRain\tNormal\tWeak\tYes\n",
"\n",
"\tOutlook\tHumid\tWind\tPlay\n",
"Day 6:\tRain\tNormal\tStrong\tNo\n",
"Day 14:\tRain\tHigh\tStrong\tNo\n"
]
}
],
"source": [
"split_data_rain = split(['Outlook', 'Wind'], data)\n",
"\n",
"for wind in values['Wind']:\n",
" print('\\n\\tOutlook\\tHumid\\tWind\\tPlay')\n",
" for row in split_data_rain['Rain'][wind]:\n",
" print('Day {Day}:\\t{Outlook}\\t{Humidity}\\t{Wind}\\t{Play}'\n",
" .format(**row))"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "subslide"
}
},
"source": [
"* Outlook=\n",
" * Overcast\n",
" * → Playing\n",
" * Sunny\n",
" * Humidity=\n",
" * High\n",
" * → Not playing\n",
" * Normal\n",
" * → Playing\n",
" * Rain\n",
" * Wind=\n",
" * Weak\n",
" * → Playing\n",
" * Strong\n",
" * → Not playing"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "subslide"
}
},
"source": [
"* (9/5)\n",
" * Outlook=Overcast (4/0)\n",
" * YES\n",
" * Outlook=Sunny (2/3)\n",
" * Humidity=High (0/3)\n",
" * NO\n",
" * Humidity=Normal (2/0)\n",
" * YES\n",
" * Outlook=Rain (3/2)\n",
" * Wind=Weak (3/0)\n",
" * YES\n",
" * Wind=Strong (0/2)\n",
" * NO"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "slide"
}
},
"source": [
"### Algorytm ID3"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "subslide"
}
},
"source": [
"Pseudokod algorytmu:\n",
"\n",
"* podziel(węzeł, zbiór przykładów):\n",
" 1. A ← najlepszy atrybut do podziału zbioru przykładów\n",
" 1. Dla każdej wartości atrybutu A, utwórz nowy węzeł potomny\n",
" 1. Podziel zbiór przykładów na podzbiory według węzłów potomnych\n",
" 1. Dla każdego węzła potomnego i podzbioru:\n",
" * jeżeli podzbiór jest jednolity: zakończ\n",
" * w przeciwnym przypadku: podziel(węzeł potomny, podzbiór)"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "subslide"
}
},
"source": [
"Jak wybrać „najlepszy atrybut”?\n",
"* powinien zawierać jednolity podzbiór\n",
"* albo przynajmniej „w miarę jednolity”\n",
"\n",
"Skąd wziąć miarę „jednolitości” podzbioru?\n",
"* miara powinna być symetryczna (4/0 vs. 0/4)"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "subslide"
}
},
"source": [
"### Entropia\n",
"\n",
"$$ H(S) = - p_{(+)} \\log p_{(+)} - p_{(-)} \\log p_{(-)} $$\n",
"\n",
"* $S$ podzbiór przykładów\n",
"* $p_{(+)}$, $p_{(-)}$ procent pozytywnych/negatywnych przykładów w $S$"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "fragment"
}
},
"source": [
"Entropię można traktować jako „liczbę bitów” potrzebną do sprawdzenia, czy losowo wybrany $x \\in S$ jest pozytywnym, czy negatywnym przykładem."
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "subslide"
}
},
"source": [
"Przykład:\n",
"\n",
"* (3 TAK / 3 NIE):\n",
"$$ H(S) = -\\frac{3}{6} \\log\\frac{3}{6} - \\frac{3}{6} \\log\\frac{3}{6} = 1 \\mbox{ bit} $$\n",
"* (4 TAK / 0 NIE):\n",
"$$ H(S) = -\\frac{4}{4} \\log\\frac{4}{4} - \\frac{0}{4} \\log\\frac{0}{4} = 0 \\mbox{ bitów} $$"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "subslide"
}
},
"source": [
"### *Information gain*\n",
"\n",
"*Information gain* różnica między entropią przed podziałem a entropią po podziale (podczas podziału entropia zmienia się):\n",
"\n",
"$$ \\mathop{\\rm Gain}(S,A) = H(S) - \\sum_{V \\in \\mathop{\\rm Values(A)}} \\frac{|S_V|}{|S|} H(S_V) $$"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "subslide"
}
},
"source": [
"Przykład:\n",
"\n",
"$$ \\mathop{\\rm Gain}(S, Wind) = H(S) - \\frac{8}{14} H(S_{Wind={\\rm Weak}}) - \\frac{6}{14} H(S_{Wind={\\rm Strong}}) = \\\\\n",
"= 0.94 - \\frac{8}{14} \\cdot 0.81 - \\frac{6}{14} \\cdot 1.0 = 0.049 $$"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "subslide"
}
},
"source": [
"* _Information gain_ jest całkiem sensowną heurystyką wskazującą, który atrybut jest najlepszy do dokonania podziału.\n",
"* **Ale**: _information gain_ przeszacowuje użyteczność atrybutów, które mają dużo różnych wartości.\n",
"* **Przykład**: gdybyśmy wybrali jako atrybut *datę*, otrzymalibyśmy bardzo duży *information gain*, ponieważ każdy podzbiór byłby jednolity, a nie byłoby to ani trochę użyteczne!"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "subslide"
}
},
"source": [
"### _Information gain ratio_\n",
"\n",
"$$ \\mathop{\\rm GainRatio}(S, A) = \\frac{ \\mathop{\\rm Gain}(S, A) }{ -\\sum_{V \\in \\mathop{\\rm Values}(A)} \\frac{|S_V|}{|S|} \\log\\frac{|S_V|}{|S|} } $$"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "fragment"
}
},
"source": [
"* _Information gain ratio_ może być lepszym wyborem heurystyki wskazującej najużyteczniejszy atrybut, jeżeli atrybuty mają wiele różnych wartości."
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "subslide"
}
},
"source": [
"### Drzewa decyzyjne a formuły logiczne\n",
"\n",
"Drzewo decyzyjne można pzekształcić na formułę logiczną w postaci normalnej (DNF):\n",
"\n",
"$$ Play={\\rm True} \\Leftrightarrow \\left( Outlook={\\rm Overcast} \\vee \\\\\n",
"( Outlook={\\rm Rain} \\wedge Wind={\\rm Weak} ) \\vee \\\\\n",
"( Outlook={\\rm Sunny} \\wedge Humidity={\\rm Normal} ) \\right) $$"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "subslide"
}
},
"source": [
"### Klasyfikacja wieloklasowa przy użyciu drzew decyzyjnych\n",
"\n",
"Algorytm przebiega analogicznie, zmienia się jedynie wzór na entropię:\n",
"\n",
"$$ H(S) = -\\sum_{y \\in Y} p_{(y)} \\log p_{(y)} $$"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "subslide"
}
},
"source": [
"### Skuteczność algorytmu ID3\n",
"\n",
"* Przyjmujemy, że wśród danych uczących nie ma duplikatów (tj. przykładów, które mają jednakowe cechy $x$, a mimo to należą do różnych klas $y$).\n",
"* Wówczas algorytm drzew decyzyjnych zawsze znajdzie rozwiązanie, ponieważ w ostateczności będziemy mieli węzły 1-elementowe na liściach drzewa."
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "subslide"
}
},
"source": [
"### Nadmierne dopasowanie drzew decyzyjnych\n",
"\n",
"* Zauważmy, że w miarę postępowania algorytmu dokładność przewidywań drzewa (*accuracy*) liczona na zbiorze uczącym dąży do 100% (i w ostateczności osiąga 100%, nawet kosztem jednoelementowych liści).\n",
"* Takie rozwiązanie niekoniecznie jest optymalne. Dokładność na zbiorze testowym może być dużo niższa, a to oznacza nadmierne dopasowanie."
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "subslide"
}
},
"source": [
"#### Jak zapobiec nadmiernemu dopasowaniu?\n",
"\n",
"Aby zapobiegać nadmiernemu dopasowaniu drzew decyzyjnych, należy je przycinać (*pruning*)."
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "subslide"
}
},
"source": [
"Można tego dokonywać na kilka sposobów:\n",
"* Można zatrzymywać procedurę podziału w pewnym momencie (np. kiedy podzbiory staja się zbyt małe).\n",
"* Można najpierw wykonać algorytm ID3 w całości, a następnie przyciąć drzewo, np. kierując się wynikami uzyskanymi na zbiorze walidacyjnym.\n",
"* Algorytm _sub-tree replacement pruning_ (algorytm zachłanny)."
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "subslide"
}
},
"source": [
"#### Algorytm _Sub-tree replacement pruning_\n",
"\n",
"1. Dla każdego węzła:\n",
" 1. Udaj, że usuwasz węzeł wraz z całym zaczepionym w nim poddrzewem.\n",
" 1. Dokonaj ewaluacji na zbiorze walidacyjnym.\n",
"1. Usuń węzeł, którego usunięcie daje największą poprawę wyniku.\n",
"1. Powtarzaj, dopóki usuwanie węzłów poprawia wynik."
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "subslide"
}
},
"source": [
"### Zalety drzew decyzyjnych\n",
"\n",
"* Zasadę działania drzew decyzyjnych łatwo zrozumieć człowiekowi.\n",
"* Atrybuty, które nie wpływają na wynik, mają _gain_ równy 0, zatem są od razu pomijane przez algorytm.\n",
"* Po zbudowaniu, drzewo decyzyjne jest bardzo szybkim klasyfikatorem (złożoność $O(d)$, gdzie $d$ jest głębokościa drzewa)."
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "subslide"
}
},
"source": [
"### Wady drzew decyzyjnych\n",
"\n",
"* ID3 jest algorytmem zachłannym może nie wskazać najlepszego drzewa.\n",
"* Nie da się otrzymać granic klas (*decision boundaries*), które nie są równoległe do osi wykresu."
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "slide"
}
},
"source": [
"### Lasy losowe"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "subslide"
}
},
"source": [
"#### Algorytm lasów losowych idea\n",
"\n",
"* Algorytm lasów losowych jest rozwinięciem algorytmu ID3.\n",
"* Jest to bardzo wydajny algorytm klasyfikacji.\n",
"* Zamiast jednego, będziemy budować $k$ drzew."
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "subslide"
}
},
"source": [
"#### Algorytm lasów losowych budowa lasu\n",
"\n",
"1. Weź losowy podzbiór $S_r$ zbioru uczącego.\n",
"1. Zbuduj pełne (tj. bez przycinania) drzewo decyzyjne dla $S_r$, używając algorytmu ID3 z następującymi modyfikacjami:\n",
" * podczas podziału używaj losowego $d$-elementowego podzbioru atrybutów,\n",
" * obliczaj _gain_ względem $S_r$.\n",
"1. Powyższą procedurę powtórz $k$-krotnie, otrzymując $k$ drzew ($T_1, T_2, \\ldots, T_k$)."
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "subslide"
}
},
"source": [
"#### Algorytm lasów losowych predykcja\n",
"\n",
"1. Sklasyfikuj $x$ według każdego z drzew $T_1, T_2, \\ldots, T_k$ z osobna.\n",
"1. Użyj głosowania większościowego: przypisz klasę przewidzianą przez najwięcej drzew."
]
}
],
"metadata": {
"celltoolbar": "Slideshow",
"kernelspec": {
"display_name": "Python 3 (ipykernel)",
"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.10.12"
},
"livereveal": {
"start_slideshow_at": "selected",
"theme": "white"
}
},
"nbformat": 4,
"nbformat_minor": 4
}