|
| 1 | +{ |
| 2 | + "cells": [ |
| 3 | + { |
| 4 | + "cell_type": "markdown", |
| 5 | + "metadata": {}, |
| 6 | + "source": [ |
| 7 | + "# Selección de modelo\n", |
| 8 | + "\n", |
| 9 | + "El objetivo de realizar selección de modelo es, a partir de una serie de datos $(x,y)$ y cierta clase de hipótesis $\\mathcal{H}$. Encontrar el $h\\in \\mathcal{H}$ que minimiza el error $e(h)=P_{D}[h(x) \\neq y]$. Claramente la hipótesis $h$ que minimiza el error en los datos sobre una cantidad suficiente de datos, produce un error $e(h)$ pequeño. El objetivo es balancear la complejidad de $\\mathcal{H}$ con el ajuste de $h\\in \\mathcal{H}$ a los datos de entrenamiento. Es claro que una hipótesis muy simple puede no contener una buena aproximación a la función que queremos aprender, mientras que una $h$ muy compleja puede ajustarse muy bien a los datos pero no ser tan buena en la generalización a nuevos datos. Esto se vuelve particularmente importante cuando se tienen pocos datos o estos resultan muy ruidosos. \n" |
| 10 | + ] |
| 11 | + }, |
| 12 | + { |
| 13 | + "cell_type": "markdown", |
| 14 | + "metadata": {}, |
| 15 | + "source": [ |
| 16 | + "\n", |
| 17 | + "# Estrategias para selección de modelo\n", |
| 18 | + "\n", |
| 19 | + "Es importante notar que la complejidad de la clase de modelos es una variable a determinar por el algoritmo de aprendizaje. La selección de modelo se realiza usualmente de la siguiente manera:\n", |
| 20 | + "- Se selecciona una función candidata $h_i$ de cierta clase $H_i$, para esto es conveniente, en general, minimizar el error empírico. \n", |
| 21 | + "- Se utiliza algún criterio para seleccionar una de las $h\\in {h_1,h_2,...}$ de manera que el error $e(h)$ sea lo suficientemente pequeño. \n", |
| 22 | + "\n" |
| 23 | + ] |
| 24 | + }, |
| 25 | + { |
| 26 | + "cell_type": "markdown", |
| 27 | + "metadata": {}, |
| 28 | + "source": [ |
| 29 | + "# 1. Validación cruzada\n", |
| 30 | + "\n", |
| 31 | + "Cuando se evalúan diferentes configuraciones de un modelo general, lo que se hace es evaluar diferentes \"hiperparámetros\" para los estimadores. Tales como $\\lambda$ en el caso de regresión lineal con regularización que se realizó previamente. Cuando se escoje un valor de un hiperparáemtetro escogido manuealmente, existe la posibilidad de realizar sobreajuste (overfitting) del conjunto de prueba debido a que los hiperparámetros pueden ser manipulados de manera que el estimador se comporte óptimamente, de manera que se introduce un conocimiento al modelo que invalidala idea de tener un desempeño de generalización. Para resolver este problema, es posible crear OTRO subconjunto de datos de manera que este se pueda mantener \"afuera\" del conjunto de prueba y funcione como un conjunto de validación durante el proceso de entrenamiento. \n", |
| 32 | + "\n", |
| 33 | + "Para realizar validación cruzada, se realiza una estimación directa de $e(h_i)$. Para esto, se dividen los datos en conjuntos $(X_{train},Y_{train})$ y $(X_{test},Y_{test})$, donde cada conjunto contiene $1-\\alpha$ y $alpha$ veces la cantidad total de datos. \n", |
| 34 | + "Con estos datos se halla la hipótesis candidata $h_d\\in \\mathcal{H}_d$ minimizando el error empírico en el conjunto de datos de entrenamiento (X_{train},Y_{train}). Posteriormente, se selecciona la hipótesis candidata con el menor error empírico en $(X_{test},Y_{test})$. \n", |
| 35 | + "\n", |
| 36 | + "\n", |
| 37 | + "\n", |
| 38 | + "\\begin{equation}\n", |
| 39 | + "h_{d^*}={argmin}_{h_i}{\\hat{e}_{(X_{test},Y_{test})} (h_d)}\n", |
| 40 | + "\\end{equation}\n", |
| 41 | + "\n", |
| 42 | + "Claramente, la selección de $\\alpha$ también tiene consecuencias sobre la estimación y el modelo obtenido. Si se selecciona un $\\alpha$ muy pequeño, es posible tener una estimación pobre de $e(h)$ debido a que no se tienen suficientes datos para estimar el error empírico en un conjunto de prueba. Si se selecciona un $\\alpha$ muy grande, se corre el riesgo de realizar un aprendizaje pobre debido a que no se tienen los suficientes datos para entrenar el modelo. El criterio de Chernoff es útil determinar qué cantidad $n$ de datos es necesaria para estimar $e(h)$ con precisión $\\epsilon$ y confianza $1-\\delta$:\n", |
| 43 | + "\n", |
| 44 | + "\\begin{equation}\n", |
| 45 | + "n \\geq \\frac{1}{2\\epsilon^2} \\ln{\\frac{2}{\\delta}}\n", |
| 46 | + "\\end{equation}\n", |
| 47 | + "\n", |
| 48 | + "Sin embargo, el estimativo de $e(h_d)$ usualmente es ruidoso, por lo que es importante considerar diferentes alternativas para realizar \\textit{validación cruzada}.\n", |
| 49 | + "\n", |
| 50 | + "Sin embargo, al realizar particiones de los datos, se reduce el número de muestras que pueden ser utilizadas para aprender el modelo. Una solución a este problema se llama \"validación cruzada (CV)\". \n", |
| 51 | + "\n", |
| 52 | + "\n" |
| 53 | + ] |
| 54 | + }, |
| 55 | + { |
| 56 | + "cell_type": "code", |
| 57 | + "execution_count": 3, |
| 58 | + "metadata": {}, |
| 59 | + "outputs": [ |
| 60 | + { |
| 61 | + "name": "stdout", |
| 62 | + "output_type": "stream", |
| 63 | + "text": [ |
| 64 | + "0.3797778160123945\n" |
| 65 | + ] |
| 66 | + } |
| 67 | + ], |
| 68 | + "source": [ |
| 69 | + "e=0.99\n", |
| 70 | + "delta=1-0.95\n", |
| 71 | + "import numpy as np\n", |
| 72 | + "print((1/(2*e**2))*np.log(2/delta))" |
| 73 | + ] |
| 74 | + }, |
| 75 | + { |
| 76 | + "cell_type": "markdown", |
| 77 | + "metadata": {}, |
| 78 | + "source": [ |
| 79 | + "#### Iteradores\n", |
| 80 | + "También es posible utilizar diferentes estrategias de validación cruzada pasando un objeto de tipo iterador (por defecto scikit-learn utilizará KFold o StratifiedKFold)" |
| 81 | + ] |
| 82 | + }, |
| 83 | + { |
| 84 | + "cell_type": "code", |
| 85 | + "execution_count": null, |
| 86 | + "metadata": {}, |
| 87 | + "outputs": [], |
| 88 | + "source": [] |
| 89 | + }, |
| 90 | + { |
| 91 | + "cell_type": "markdown", |
| 92 | + "metadata": {}, |
| 93 | + "source": [ |
| 94 | + "# Validación cruzada k-multiple\n", |
| 95 | + "\n", |
| 96 | + "La idea es obtener un mejor estimativo de $e(h)$. Para esto, teniendo una clase $\\mathcal{H}$, el conjunto de datos $S=(X,Y)$ se divide en $S_1,S_2,...,S_k$. Para cada $i=1,2,...k$ se halla $h_i$ minimizando el error empírico en $\\cup_{j\\neq i} S_j$. Luego, se estima el error calculando el error empírico $\\hat{e}_{S_i}(h_i)$. Luego se realiza un promedio de los valores obtenidos \n", |
| 97 | + "\n", |
| 98 | + "\\begin{equation}\n", |
| 99 | + "\\hat{e}(h_d)=\\frac{1}{k} \\sum_{i=1}^{k}{\\hat{e}s_i (h_i)}\n", |
| 100 | + "\\end{equation}\n", |
| 101 | + "\n", |
| 102 | + "Para el $d^*$ que corresponde \"fold\" con menor valor de riesgo empírico, se halla $h$ minimizando el error empírico en $S$. Es importante mencionar que la validación cruzada k-fold es un proceso costoso computacionalmente y carece de soporte teórico, sin embargo, es ampliamente usado en la práctica. \n", |
| 103 | + "\n", |
| 104 | + "## K fold y Leave-one-out.\n", |
| 105 | + "En k-fold se segmentan los datos en $k$ grupos, se corren los algoritmos en $k-1$ grupos y se evalúa el riesgo del último grupo. Se repiite esto hasta que todos los grupos se hallan entrenando, por lo que se tienen $k$ números de errores que se deben promediar. Leave-one-out es el caso en el que se tiene $k=n$. La idea es que este método es más robusto, dado que se entrena en una mayor cantidad de datos y todavía se tienen promedios del riesgo estimado. el reto es que ahora se está reutilizando la información en diferentes entrenamientos y conjuntos de validación por lo que los términos en los promedios no son independientes. [1]\n", |
| 106 | + "\n", |
| 107 | + "\n" |
| 108 | + ] |
| 109 | + }, |
| 110 | + { |
| 111 | + "cell_type": "code", |
| 112 | + "execution_count": null, |
| 113 | + "metadata": {}, |
| 114 | + "outputs": [], |
| 115 | + "source": [] |
| 116 | + }, |
| 117 | + { |
| 118 | + "cell_type": "markdown", |
| 119 | + "metadata": {}, |
| 120 | + "source": [ |
| 121 | + "# Comparación de comportamiento de objetos de validación cruzada" |
| 122 | + ] |
| 123 | + }, |
| 124 | + { |
| 125 | + "cell_type": "code", |
| 126 | + "execution_count": null, |
| 127 | + "metadata": {}, |
| 128 | + "outputs": [], |
| 129 | + "source": [] |
| 130 | + }, |
| 131 | + { |
| 132 | + "cell_type": "markdown", |
| 133 | + "metadata": {}, |
| 134 | + "source": [ |
| 135 | + "# Aplicaciones: \n", |
| 136 | + "\n", |
| 137 | + "## Búsqueda de parámetros utilizando gridsearch:\n", |
| 138 | + "Scikit-learn incorpora un objeto que, dados unos datos, calcula el score durante el ajuste de cierto estimador o parámetro y escoge los parámetros que maximizan el score de validación cruzada. Este objeto toma un estimado durante la construcción y devuelve un estimador. \n" |
| 139 | + ] |
| 140 | + }, |
| 141 | + { |
| 142 | + "cell_type": "code", |
| 143 | + "execution_count": null, |
| 144 | + "metadata": {}, |
| 145 | + "outputs": [], |
| 146 | + "source": [] |
| 147 | + }, |
| 148 | + { |
| 149 | + "cell_type": "code", |
| 150 | + "execution_count": null, |
| 151 | + "metadata": {}, |
| 152 | + "outputs": [], |
| 153 | + "source": [] |
| 154 | + }, |
| 155 | + { |
| 156 | + "cell_type": "markdown", |
| 157 | + "metadata": {}, |
| 158 | + "source": [ |
| 159 | + "## Eliminación de características:\n", |
| 160 | + "\n", |
| 161 | + "Es posible realizar una eliminación recursiva de características con una sintonización automática del número de características seleccionadas con cross-validation. Para realizar esta aplicación primero es importante presentar algunas funciones útiles. \n", |
| 162 | + "\n", |
| 163 | + "### Nuevo! make_classification\n", |
| 164 | + "\n", |
| 165 | + "Genera un objeto para solucionar un problema multiclase, en general. Este objeto soluciona el problema creando clusters de puntos normalmente distribuidos sobre los vértices de un n_informativo hipercubo con lados de tamaño $2*class_sep$. Introduce interdependencia entre las características y añade diferentes tipos de ruido a los datos. \n", |
| 166 | + "to the data.\n", |
| 167 | + "\n", |
| 168 | + "### Nuevo! RFECV \n", |
| 169 | + "Realiza RANKING con eliminación recursiva y validación cruzada de características de las mejores características de los modelos. \n" |
| 170 | + ] |
| 171 | + }, |
| 172 | + { |
| 173 | + "cell_type": "code", |
| 174 | + "execution_count": null, |
| 175 | + "metadata": {}, |
| 176 | + "outputs": [], |
| 177 | + "source": [] |
| 178 | + }, |
| 179 | + { |
| 180 | + "cell_type": "markdown", |
| 181 | + "metadata": {}, |
| 182 | + "source": [ |
| 183 | + "\n", |
| 184 | + "# Minimización de Riesgo Estructurado. \n", |
| 185 | + "\n", |
| 186 | + "En este caso, a partir de una secuencia de hipótesis $\\mathcal{H}_1 \\subset \\mathcal{H}_2 \\subset ...$, se tiene una función candidata $h_d$ de cada clase $\\mathcal{H}_d$ que minimiza el error empírico en $\\mathcal{H}_d$, luego, se escoge $d^*$ como ${arg_{g} min}(\\hat{e}(h_d)+p(d))$ donde $p(d)$ es una función creciente de $d$ que penaliza funciones de alta complejidad. \n" |
| 187 | + ] |
| 188 | + }, |
| 189 | + { |
| 190 | + "cell_type": "code", |
| 191 | + "execution_count": null, |
| 192 | + "metadata": {}, |
| 193 | + "outputs": [], |
| 194 | + "source": [] |
| 195 | + }, |
| 196 | + { |
| 197 | + "cell_type": "code", |
| 198 | + "execution_count": null, |
| 199 | + "metadata": {}, |
| 200 | + "outputs": [], |
| 201 | + "source": [] |
| 202 | + } |
| 203 | + ], |
| 204 | + "metadata": { |
| 205 | + "kernelspec": { |
| 206 | + "display_name": "Python 3", |
| 207 | + "language": "python", |
| 208 | + "name": "python3" |
| 209 | + }, |
| 210 | + "language_info": { |
| 211 | + "codemirror_mode": { |
| 212 | + "name": "ipython", |
| 213 | + "version": 3 |
| 214 | + }, |
| 215 | + "file_extension": ".py", |
| 216 | + "mimetype": "text/x-python", |
| 217 | + "name": "python", |
| 218 | + "nbconvert_exporter": "python", |
| 219 | + "pygments_lexer": "ipython3", |
| 220 | + "version": "3.7.4" |
| 221 | + } |
| 222 | + }, |
| 223 | + "nbformat": 4, |
| 224 | + "nbformat_minor": 2 |
| 225 | +} |
0 commit comments