|
1 |
| -# calssifier |
| 1 | +<div id="table-of-contents"> |
| 2 | +<h2>Table of Contents</h2> |
| 3 | +<div id="text-table-of-contents"> |
| 4 | +<ul> |
| 5 | +<li><a href="#orgheadline1">1. Introduccion</a></li> |
| 6 | +<li><a href="#orgheadline4">2. Implementacion</a> |
| 7 | +<ul> |
| 8 | +<li><a href="#orgheadline2">2.1. Clasificador Euclideo</a></li> |
| 9 | +<li><a href="#orgheadline3">2.2. Clasificador Estadistico</a></li> |
| 10 | +</ul> |
| 11 | +</li> |
| 12 | +<li><a href="#orgheadline5">3. Resultados UCI</a></li> |
| 13 | +<li><a href="#orgheadline6">4. Validacion Cruzada UCI</a></li> |
| 14 | +<li><a href="#orgheadline7">5. Dataset MNIST</a></li> |
| 15 | +<li><a href="#orgheadline8">6. Validacion cruzada MNIST</a></li> |
| 16 | +<li><a href="#orgheadline9">7. Anexo</a></li> |
| 17 | +</ul> |
| 18 | +</div> |
| 19 | +</div> |
| 20 | + |
| 21 | + |
| 22 | +# Introduccion<a id="orgheadline1"></a> |
| 23 | + |
| 24 | +Esta es la practica propuesta por la asignaura **Reconocimiento de Formas** de la |
| 25 | +Universidad Politecnica de Madrid (UPM), Espana<sup><a id="fnr.1" class="footref" href="#fn.1">1</a></sup>. |
| 26 | + |
| 27 | +La practica consiste en programar 2 reconocedores, uno basado en distancias euclideas |
| 28 | +y otro en probabilidades gausianas. Es cierto que la practica se propuso para ser |
| 29 | +hecha en python pero, debido a ciertos errores causados por el sistema de tipos |
| 30 | +en el que, al almacenar datos propios de la libreria *Numpy* <sup><a id="fnr.1.100" class="footref" href="#fn.1">1</a></sup> en estructuras built-in |
| 31 | +de python, los valores de las variables variaban al ser redondeadas o truncadas. Por |
| 32 | +ello he decidido hacer la practica en **Julia** <sup><a id="fnr.2" class="footref" href="#fn.2">2</a></sup>, un lenguaje de programacion matematico |
| 33 | +al estilo de Matlab <sup><a id="fnr.3" class="footref" href="#fn.3">3</a></sup>. |
| 34 | + |
| 35 | +Antes de nada, decir que es mi primer programa hecho en julia y, por tanto, no es |
| 36 | +de extraniar que el codigo no sea el mas optimo asi como que ciertas funciones esten |
| 37 | +tipadas y otras se haga uso de la inferencia de julia. |
| 38 | + |
| 39 | +# Implementacion<a id="orgheadline4"></a> |
| 40 | + |
| 41 | +NOTA: Toda la implementacion se puede encontrar aqui <https://github.com/Yawolf/calssifier> |
| 42 | + |
| 43 | +La implementacion de los clasificadores es sencilla. Como he mencionado antes, han sido |
| 44 | +programados en Julia, lo que nos permite un manejo de matrices muy bueno, facilitandonos |
| 45 | +la programacion. |
| 46 | + |
| 47 | +## Clasificador Euclideo<a id="orgheadline2"></a> |
| 48 | + |
| 49 | +Este clasificador se ajusta al siguiente algoritmo: |
| 50 | + |
| 51 | +<div class="VERBATIM"> |
| 52 | +get<sub>matrix</sub> from file |
| 53 | +get<sub>classes</sub> from matrix |
| 54 | +get<sub>average</sub> from matrix and classes |
| 55 | +categorize using matrix, classes and average |
| 56 | + |
| 57 | +</div> |
| 58 | + |
| 59 | +1. En primer lugar se obtiene la matriz leyendola del CSV o *.data* |
| 60 | +2. De la matriz que hemos leido se extraen las clases y se hace un *nub*<sup><a id="fnr.4" class="footref" href="#fn.4">4</a></sup> del vector |
| 61 | + resultante. |
| 62 | +3. Creando un diccionario usando las clases como key, calculamos la media de cada uno de |
| 63 | + los valores de los "vectores" de cada clase y se insertan como value. |
| 64 | +4. Una ve hecho todo lo anterior por cada elemento de la matriz se calcula su distancia |
| 65 | + euclidea con cada uno de los *averages* anteriores, el que este mas cerca sera la |
| 66 | + clase que se le asigne y se comparara con la que se nos da para ver si es verdad. |
| 67 | + |
| 68 | +Como se puede observar, el funcionamiento e implementacion de dicho reconocedor es |
| 69 | +sencillo. |
| 70 | + |
| 71 | +## Clasificador Estadistico<a id="orgheadline3"></a> |
| 72 | + |
| 73 | +Este clasificador tiene un algoritmo mas complejo de implementacion: |
| 74 | + |
| 75 | +<div class="VERBARIM"> |
| 76 | +get training and testing from file |
| 77 | +separate training by classes |
| 78 | +get covariance from classes |
| 79 | +get mean from classes |
| 80 | +classify using testing, classes, mean and covariance |
| 81 | + |
| 82 | +</div> |
| 83 | + |
| 84 | +1. En primer lugar se hace un split de la matriz dando lugar a 2 "submatrices", una |
| 85 | + sera la matriz de entrenamiento, otra sera la de testing |
| 86 | +2. Una vez obtenida la matriz de entrenamiento, esta se subdivide en otras matrices |
| 87 | + mas pequenias en la que todos los elementos de cada una de ellas pertenecen a la |
| 88 | + misma clase. Esto es, submatrices por clases. |
| 89 | +3. Una vez conseguidas las matrices de clases, se calcula la covarianza de cada una |
| 90 | + de ellas. |
| 91 | +4. Usando otra vez las matrices de clases se calcula la media de cada uno de los |
| 92 | + parametros de cada clase. |
| 93 | +5. Usando el subset *testing*, las matrices de clases, sus covarianzas y sus |
| 94 | + medias, se calcula la probabilidad de que, cada elemento del dataset *testing* |
| 95 | + pretenezca a una u otra clase, para ello se usa la formula de la distribucion |
| 96 | + gaussiana y se compara el resultado de la mejor opcion con el original. |
| 97 | + |
| 98 | +Siguiendo estos pasos se consigue reconocer estadisticamente cada elemnto. |
| 99 | + |
| 100 | +# Resultados UCI<a id="orgheadline5"></a> |
| 101 | + |
| 102 | +Ahora se presentaran los resultados para los dataset sacados de la UCI <sup><a id="fnr.5" class="footref" href="#fn.5">5</a></sup>. Estos |
| 103 | +dataset son los siquientes: |
| 104 | + |
| 105 | +- wine.data |
| 106 | +- cancer.data |
| 107 | +- iris.data |
| 108 | +- wineR.data |
| 109 | +- cancerR.data |
| 110 | +- irisR.data |
| 111 | + |
| 112 | +Todos ellos se pueden encontrar en la carpeta *test* de este repositorio. Cabe destacar |
| 113 | +que los dataset cuyo nombre termina en una 'R' cotienen los mismos datos que sus |
| 114 | +equivalentes sin 'R', solo que sus datos han sido desordenados para obetener una mejor |
| 115 | +aleatoriedad. |
| 116 | + |
| 117 | + $> sort -R wine.data >> wineR.data |
| 118 | + |
| 119 | +Se presentan ahora las tasas de acierto de los clasificadores, tanto el euclidiano como el |
| 120 | +estadistico: |
| 121 | + |
| 122 | +<table border="2" cellspacing="0" cellpadding="6" rules="groups" frame="hsides"> |
| 123 | + |
| 124 | + |
| 125 | +<colgroup> |
| 126 | +<col class="org-left" /> |
| 127 | + |
| 128 | +<col class="org-right" /> |
| 129 | + |
| 130 | +<col class="org-right" /> |
| 131 | + |
| 132 | +<col class="org-right" /> |
| 133 | +</colgroup> |
| 134 | +<thead> |
| 135 | +<tr> |
| 136 | +<th scope="col" class="org-left">Clasificador</th> |
| 137 | +<th scope="col" class="org-right">wine.data</th> |
| 138 | +<th scope="col" class="org-right">iris.data</th> |
| 139 | +<th scope="col" class="org-right">cancer.data</th> |
| 140 | +</tr> |
| 141 | +</thead> |
| 142 | + |
| 143 | +<tbody> |
| 144 | +<tr> |
| 145 | +<td class="org-left">Euclideo</td> |
| 146 | +<td class="org-right">72.47191011235955%</td> |
| 147 | +<td class="org-right">92.66666666666666%</td> |
| 148 | +<td class="org-right">61.86291739894551%</td> |
| 149 | +</tr> |
| 150 | + |
| 151 | + |
| 152 | +<tr> |
| 153 | +<td class="org-left">Estadistico</td> |
| 154 | +<td class="org-right">99.43820224719101%</td> |
| 155 | +<td class="org-right">98.0%</td> |
| 156 | +<td class="org-right">97.36379613356766%</td> |
| 157 | +</tr> |
| 158 | +</tbody> |
| 159 | +</table> |
| 160 | + |
| 161 | +Notese que la precision del clasificador estadistico es superior en muchos sentidos a la |
| 162 | +del euclideo, siendo este mas sencillo de programar, pero mas ineficiente a la hora de |
| 163 | +clasificar |
| 164 | + |
| 165 | +Un ejemplo de como se ejecutan los test: |
| 166 | + |
| 167 | + # Dentro del mismo direcotrio del src |
| 168 | + $> julia |
| 169 | + julia> include("clasific_eucl.jl") |
| 170 | + julia> include("clasific_estad.jl") |
| 171 | + julia> include("clasific_gauss.jl") |
| 172 | + julia> euclideo.start("wine.data") # euclideo |
| 173 | + ... |
| 174 | + julia> gauss.start("wine.data") # estadistico gaussiano |
| 175 | + |
| 176 | +# Validacion Cruzada UCI<a id="orgheadline6"></a> |
| 177 | + |
| 178 | +Ahora se van a presentar los resultados de la validacion cruzada, para ello se ha |
| 179 | +decidido que el fichero de entrenamiento y el de test sea el mismo, se han hecho |
| 180 | +10 folds para estar acorde al apartado siguiente. Los resultados son los siquientes |
| 181 | + |
| 182 | +<table border="2" cellspacing="0" cellpadding="6" rules="groups" frame="hsides"> |
| 183 | + |
| 184 | + |
| 185 | +<colgroup> |
| 186 | +<col class="org-left" /> |
| 187 | + |
| 188 | +<col class="org-right" /> |
| 189 | + |
| 190 | +<col class="org-right" /> |
| 191 | + |
| 192 | +<col class="org-right" /> |
| 193 | +</colgroup> |
| 194 | +<thead> |
| 195 | +<tr> |
| 196 | +<th scope="col" class="org-left">Clasificador</th> |
| 197 | +<th scope="col" class="org-right">wine.data</th> |
| 198 | +<th scope="col" class="org-right">iris.data</th> |
| 199 | +<th scope="col" class="org-right">cancer.data</th> |
| 200 | +</tr> |
| 201 | +</thead> |
| 202 | + |
| 203 | +<tbody> |
| 204 | +<tr> |
| 205 | +<td class="org-left">Euclideo</td> |
| 206 | +<td class="org-right">71.99197860962568%</td> |
| 207 | +<td class="org-right">92.66666666666666%</td> |
| 208 | +<td class="org-right">59.68614718614719%</td> |
| 209 | +</tr> |
| 210 | + |
| 211 | + |
| 212 | +<tr> |
| 213 | +<td class="org-left">Estadistico</td> |
| 214 | +<td class="org-right">99.43820224719101%</td> |
| 215 | +<td class="org-right">98.0%</td> |
| 216 | +<td class="org-right">97.36379613356766%</td> |
| 217 | +</tr> |
| 218 | +</tbody> |
| 219 | +</table> |
| 220 | + |
| 221 | +# Dataset MNIST<a id="orgheadline7"></a> |
| 222 | + |
| 223 | +Ahora se usara el dataset MNIST <sup><a id="fnr.6" class="footref" href="#fn.6">6</a></sup>, la cual cuentiene 60.000 elementos con 10 |
| 224 | +variables cada uno de ellos. |
| 225 | + |
| 226 | +Para ejecutar se usan estos mandatos: |
| 227 | + |
| 228 | + # Dentro del mismo direcotrio del src |
| 229 | + $> julia |
| 230 | + julia> include("clasific_eucl.jl") |
| 231 | + julia> include("clasific_estad.jl") |
| 232 | + julia> include("clasific_gauss.jl") |
| 233 | + julia> gauss.start("datos_procesados.npy",(1,500),1) # estadistico gaussiano |
| 234 | + |
| 235 | +En este caso estamos usando las primeras 500 filas del CSV para entrenar y, al haber |
| 236 | +pasado un 1 como argumento, usaremos el mismo subset para entrenar y para testear. |
| 237 | +Cambiando dicho flag, se usara el segundo subset para testear. |
| 238 | + |
| 239 | + julia> euclideo.start("datos_procesados.npy",(1,500),2) |
| 240 | + ... |
| 241 | + julia> gauss.start("datos_procesados.npy",(1,500),2) |
| 242 | + |
| 243 | +Los resultados son los siquientes: |
| 244 | + |
| 245 | +<table border="2" cellspacing="0" cellpadding="6" rules="groups" frame="hsides"> |
| 246 | + |
| 247 | + |
| 248 | +<colgroup> |
| 249 | +<col class="org-left" /> |
| 250 | + |
| 251 | +<col class="org-right" /> |
| 252 | + |
| 253 | +<col class="org-right" /> |
| 254 | +</colgroup> |
| 255 | +<thead> |
| 256 | +<tr> |
| 257 | +<th scope="col" class="org-left"> </th> |
| 258 | +<th scope="col" class="org-right">Estadistico</th> |
| 259 | +<th scope="col" class="org-right">Euclideo</th> |
| 260 | +</tr> |
| 261 | +</thead> |
| 262 | + |
| 263 | +<tbody> |
| 264 | +<tr> |
| 265 | +<td class="org-left">D1 and D1</td> |
| 266 | +<td class="org-right">84.90420168067226%</td> |
| 267 | +<td class="org-right">88.6%</td> |
| 268 | +</tr> |
| 269 | +</tbody> |
| 270 | + |
| 271 | +<tbody> |
| 272 | +<tr> |
| 273 | +<td class="org-left">D1 and D2</td> |
| 274 | +<td class="org-right">94.6%</td> |
| 275 | +<td class="org-right">85.8890756302521%</td> |
| 276 | +</tr> |
| 277 | + |
| 278 | + |
| 279 | +<tr> |
| 280 | +<td class="org-left"> </td> |
| 281 | +<td class="org-right"> </td> |
| 282 | +<td class="org-right"> </td> |
| 283 | +</tr> |
| 284 | +</tbody> |
| 285 | +</table> |
| 286 | + |
| 287 | +Se observa que para cantidades pequenias, el euclideo y el estadistico tienen una |
| 288 | +diferencia mucho menor que en el caso de tener muchos elementos. |
| 289 | + |
| 290 | +# Validacion cruzada MNIST<a id="orgheadline8"></a> |
| 291 | + |
| 292 | +Igual que en el apartado de validacion cruzada con UCI, aqui se ha subdividido la |
| 293 | +matriz en 10 submatrices. |
| 294 | + |
| 295 | +Los resultados son los siquientes: |
| 296 | + |
| 297 | +<table border="2" cellspacing="0" cellpadding="6" rules="groups" frame="hsides"> |
| 298 | + |
| 299 | + |
| 300 | +<colgroup> |
| 301 | +<col class="org-left" /> |
| 302 | + |
| 303 | +<col class="org-right" /> |
| 304 | + |
| 305 | +<col class="org-right" /> |
| 306 | +</colgroup> |
| 307 | +<thead> |
| 308 | +<tr> |
| 309 | +<th scope="col" class="org-left"> </th> |
| 310 | +<th scope="col" class="org-right">Euclideo</th> |
| 311 | +<th scope="col" class="org-right">Estadistico</th> |
| 312 | +</tr> |
| 313 | +</thead> |
| 314 | + |
| 315 | +<tbody> |
| 316 | +<tr> |
| 317 | +<td class="org-left">D1 and D1</td> |
| 318 | +<td class="org-right">88.6%</td> |
| 319 | +<td class="org-right">84.90420168067229%</td> |
| 320 | +</tr> |
| 321 | +</tbody> |
| 322 | + |
| 323 | +<tbody> |
| 324 | +<tr> |
| 325 | +<td class="org-left">D1 and D2</td> |
| 326 | +<td class="org-right">85.8890756302521%</td> |
| 327 | +<td class="org-right">94.6%</td> |
| 328 | +</tr> |
| 329 | +</tbody> |
| 330 | +</table> |
| 331 | + |
| 332 | +# Anexo<a id="orgheadline9"></a> |
| 333 | + |
| 334 | +<div id="footnotes"> |
| 335 | +<h2 class="footnotes">Footnotes: </h2> |
| 336 | +<div id="text-footnotes"> |
| 337 | + |
| 338 | +<div class="footdef"><sup><a id="fn.1" class="footnum" href="#fnr.1">1</a></sup> <div class="footpara">ETSIINF-UPM: <https://www.fi.upm.es/></div></div> |
| 339 | + |
| 340 | +<div class="footdef"><sup><a id="fn.2" class="footnum" href="#fnr.2">2</a></sup> <div class="footpara">Numpy: <http://www.numpy.org/></div></div> |
| 341 | + |
| 342 | +<div class="footdef"><sup><a id="fn.3" class="footnum" href="#fnr.3">3</a></sup> <div class="footpara">Julia-lang: <http://julialang.org/></div></div> |
| 343 | + |
| 344 | +<div class="footdef"><sup><a id="fn.4" class="footnum" href="#fnr.4">4</a></sup> <div class="footpara">nub: <http://hackage.haskell.org/package/base-4.8.1.0/docs/Data-List.html#v:nub></div></div> |
| 345 | + |
| 346 | +<div class="footdef"><sup><a id="fn.5" class="footnum" href="#fnr.5">5</a></sup> <div class="footpara">UCI: <http://archive.ics.uci.edu/ml/></div></div> |
| 347 | + |
| 348 | +<div class="footdef"><sup><a id="fn.6" class="footnum" href="#fnr.6">6</a></sup> <div class="footpara">MNIST: <http://yann.lecun.com/exdb/mnist/></div></div> |
| 349 | + |
| 350 | + |
| 351 | +</div> |
| 352 | +</div> |
0 commit comments