├── 1 Search ├── 1 Blind Search │ ├── BrFS.ipynb │ ├── README.md │ ├── code │ │ ├── BrFS.py │ │ ├── __pycache__ │ │ │ ├── BrFS.cpython-38.pyc │ │ │ ├── node.cpython-38.pyc │ │ │ ├── open_list.cpython-38.pyc │ │ │ └── puzzle.cpython-38.pyc │ │ ├── node.py │ │ ├── open_list.py │ │ ├── problems_r8.txt │ │ ├── puzzle.py │ │ └── test_brfs_puzzle.py │ └── img │ │ ├── alg2.1.png │ │ └── alg2.3.png ├── 2 Informed Search │ ├── 2_A_.ipynb │ ├── BrFS.py │ ├── README.md │ ├── __pycache__ │ │ ├── BrFS.cpython-38.pyc │ │ ├── node.cpython-38.pyc │ │ ├── open_list.cpython-38.pyc │ │ └── puzzle.cpython-38.pyc │ ├── node.py │ ├── open_list.py │ ├── problems_r8.txt │ ├── puzzle.py │ └── test_brfs_puzzle.py └── 3 Adversarial Search │ └── 3_Adversarial_Search.ipynb ├── 2 Programacion Logica ├── 1.swinb ├── 2.swinb └── 3.swinb ├── 3 Machine Learning ├── 1 regresion.ipynb ├── 2 Neural Networks.ipynb └── 3 clustering_Kmeans.ipynb └── README.md /1 Search/1 Blind Search/BrFS.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "nbformat": 4, 3 | "nbformat_minor": 0, 4 | "metadata": { 5 | "colab": { 6 | "name": "1. BrFS", 7 | "provenance": [], 8 | "collapsed_sections": [] 9 | }, 10 | "kernelspec": { 11 | "name": "python3", 12 | "display_name": "Python 3" 13 | }, 14 | "language_info": { 15 | "name": "python" 16 | } 17 | }, 18 | "cells": [ 19 | { 20 | "cell_type": "markdown", 21 | "source": [ 22 | "Accesible en: https://colab.research.google.com/drive/16AS-V5F66s4KWzpCRfLhCi9KM_l0vdyx?usp=sharing" 23 | ], 24 | "metadata": { 25 | "id": "HGXRILQ0V8Tm" 26 | } 27 | }, 28 | { 29 | "cell_type": "markdown", 30 | "source": [ 31 | "# Búsqueda\n", 32 | "\n", 33 | "En esta clase resolveremos un problema claśico, el 8-puzzle, utilizando Breadth-First Search (BrFS).\n", 34 | "\n", 35 | "\n" 36 | ], 37 | "metadata": { 38 | "id": "9zqyxrzboFLK" 39 | } 40 | }, 41 | { 42 | "cell_type": "markdown", 43 | "source": [ 44 | "La clase `Node` representa un search state genérico, que será útil para cualquier problema de búsqueda. \n", 45 | "\n", 46 | "Cada uno de los estados de búsqueda, tendrá asociado un puntaje almacenado en la propiedad `key`, el cual nos indicará cuando un nodo es mejor (o solo mas prometedor) que otro. En este caso, a menor `key`, mas prometedor es el nodo. \n", 47 | "\n", 48 | "Tendrá los métodos __gt__ y __lt__ implementan los operadores mayor y menor que, y verifican que si nodo `v` es menor que un nodo `u`, el nodo `v` es mejor." 49 | ], 50 | "metadata": { 51 | "id": "sy4ypMzcogBd" 52 | } 53 | }, 54 | { 55 | "cell_type": "code", 56 | "execution_count": null, 57 | "metadata": { 58 | "id": "tqksIGtK6ezG" 59 | }, 60 | "outputs": [], 61 | "source": [ 62 | "class Node:\n", 63 | " def __init__(self, search_state, parent=None, action=''):\n", 64 | " self.state = search_state # El estado (en este caso, objeto de tipo puzzle)\n", 65 | " self.parent = parent # El estado padre.\n", 66 | " self.action = action # El nombre de la accion que derivó en este estado (string)\n", 67 | " \n", 68 | " def __repr__(self):\n", 69 | " return self.state.__repr__()\n", 70 | "\n", 71 | " # Función utilizada para reconstruir la solución. Llama al método trace del estado padre hasta que no exista padre.\n", 72 | " def trace(self): \n", 73 | " s = ''\n", 74 | " if self.parent:\n", 75 | " s = self.parent.trace()\n", 76 | " s += '-' + self.action + '->'\n", 77 | " s += str(self.state)\n", 78 | " return s" 79 | ] 80 | }, 81 | { 82 | "cell_type": "markdown", 83 | "source": [ 84 | "#clase Puzzle\n", 85 | "\n", 86 | "Esta representa un estado del problema. La función mas importante es el método `succ`, que se encarga de la generación de estados sucesores." 87 | ], 88 | "metadata": { 89 | "id": "tql96P2Rpx9n" 90 | } 91 | }, 92 | { 93 | "cell_type": "code", 94 | "source": [ 95 | "import sys\n", 96 | "import copy\n", 97 | "import numpy as np\n", 98 | "\n", 99 | "\n", 100 | "class Puzzle:\n", 101 | " goal8 = list(range(9))\n", 102 | " def __init__(self, board=None, blank=-1):\n", 103 | " if not board:\n", 104 | " self.x = 3\n", 105 | " self.size = 9\n", 106 | " self.board = [i for i in range(0, self.size)]\n", 107 | " self.blank = 0\n", 108 | " else:\n", 109 | " self.board = board\n", 110 | " if len(self.board) == 9:\n", 111 | " self.x = 3\n", 112 | " self.size = 9\n", 113 | " else:\n", 114 | " print('puzzle size not supported')\n", 115 | " sys.exit(1)\n", 116 | " if blank == -1:\n", 117 | " self.blank = board.index(0)\n", 118 | "\n", 119 | "\n", 120 | " def __hash__(self):\n", 121 | " return hash(tuple(self.board))\n", 122 | "\n", 123 | " def __eq__(self, other):\n", 124 | " return self.board == other.board\n", 125 | "\n", 126 | " def __repr__(self):\n", 127 | " def tostr(d):\n", 128 | " if d > 0:\n", 129 | " return \"%2d\" % (d)\n", 130 | " else:\n", 131 | " return \" \"\n", 132 | " s = '\\n'\n", 133 | " for i in range(0, self.x):\n", 134 | " s += \"|\"\n", 135 | " s += \"|\".join([tostr(d) for d in self.board[i*self.x:i*self.x+self.x]])\n", 136 | " s += \"|\\n\"\n", 137 | " return s\n", 138 | "\n", 139 | " def successors(self):\n", 140 | " '''\n", 141 | " Crea una lista de tuplas de la forma (estado, accion, costo)\n", 142 | " donde estado es el estado sucesor de self que se genera al ejecutar\n", 143 | " accion (un string) y costo (un numero real) es el costo de accion\n", 144 | " '''\n", 145 | " def create_child(newblank):\n", 146 | " child = copy.deepcopy(self)\n", 147 | " child.blank = newblank\n", 148 | " child.board[child.blank] = 0\n", 149 | " child.board[self.blank] = self.board[newblank]\n", 150 | " return child\n", 151 | "\n", 152 | " succ = []\n", 153 | " if self.blank > self.x - 1:\n", 154 | " c = create_child(self.blank-self.x)\n", 155 | " succ.append((c, 'down', 1))\n", 156 | " if self.blank % self.x > 0:\n", 157 | " c = create_child(self.blank-1)\n", 158 | " succ.append((c, 'right', 1))\n", 159 | " if self.blank % self.x < self.x - 1:\n", 160 | " c = create_child(self.blank+1)\n", 161 | " succ.append((c, 'left', 1))\n", 162 | " if self.blank < self.size - self.x:\n", 163 | " c = create_child(self.blank+self.x)\n", 164 | " succ.append((c, 'up', 1))\n", 165 | " return succ\n", 166 | "\n", 167 | " def is_goal(self):\n", 168 | " return Puzzle.goal8 == self.board " 169 | ], 170 | "metadata": { 171 | "id": "JZkr7Qm66r4_" 172 | }, 173 | "execution_count": null, 174 | "outputs": [] 175 | }, 176 | { 177 | "cell_type": "markdown", 178 | "source": [ 179 | "# Open List\n", 180 | "Como es una implementación de búsqueda en anchura, la OPEN es implementada como una cola" 181 | ], 182 | "metadata": { 183 | "id": "yHyOz-_sWuX8" 184 | } 185 | }, 186 | { 187 | "cell_type": "code", 188 | "source": [ 189 | "from collections import deque \n", 190 | "\n", 191 | "class OpenList_BrFS:\n", 192 | " # Inicia una lista vacia\n", 193 | " def __init__(self):\n", 194 | " self.items = deque([])\n", 195 | "\n", 196 | " # La cantidad de elementos en el heap\n", 197 | " @staticmethod\n", 198 | " def size(self):\n", 199 | " return len(self.items)\n", 200 | "\n", 201 | " # Retorna el mejor elemento del heap\n", 202 | " def top(self):\n", 203 | " if self.size == 0:\n", 204 | " return None\n", 205 | " else:\n", 206 | " return self.items[0]\n", 207 | "\n", 208 | " # Retorna el primer elemento y lo elimina\n", 209 | " def extract(self):\n", 210 | " if len(self.items):\n", 211 | " return self.items.popleft()\n", 212 | " else : \n", 213 | " None\n", 214 | "\n", 215 | " # Inserta un elemento en el heap\n", 216 | " def insert(self, element):\n", 217 | " self.items.append(element)\n", 218 | "\n", 219 | " # Verifica si esta vacia\n", 220 | " def is_empty(self):\n", 221 | " return self.size == 0\n" 222 | ], 223 | "metadata": { 224 | "id": "w50CoA2xY7T9" 225 | }, 226 | "execution_count": null, 227 | "outputs": [] 228 | }, 229 | { 230 | "cell_type": "code", 231 | "source": [ 232 | "import time\n", 233 | "\n", 234 | "class BrFS:\n", 235 | " def __init__(self, initial_state):\n", 236 | " self.expansions = 0\n", 237 | " self.initial_state = initial_state\n", 238 | " self.solution = None\n", 239 | " self.open = OpenList_BrFS()\n", 240 | " self.generated = {}\n", 241 | "\n", 242 | "\n", 243 | "\n", 244 | " def search(self):\n", 245 | " self.start_time = time.process_time()\n", 246 | " \n", 247 | " initial_node = Node(self.initial_state)\n", 248 | " initial_node.g = 0\n", 249 | " self.open.insert(initial_node) \n", 250 | " self.generated[self.initial_state] = initial_node # para cada estado alguna vez generado, generated almacena el Node object que le corresponde\n", 251 | "\n", 252 | " while not self.open.is_empty(): # Mientras la OPEN no esté vacia (ciclo de expansiones) \n", 253 | " n = self.open.extract() # extrae n de la open (el con menor key (en este caso profundidad))\n", 254 | "\n", 255 | " if n.state.is_goal(): # Si el estado extraido es el estado objetivo (el problema resuelto)\n", 256 | " self.end_time = time.process_time() \n", 257 | " self.solution = n # Define el estado extraido como solución (para reconstruirlo luego)\n", 258 | " return n\n", 259 | " succ = n.state.successors() # Genera los sucesores\n", 260 | " self.expansions += 1 # Aumenta en 1 las expansiones\n", 261 | " for child_state, action, cost in succ: # Por cada uno de los estados sucesores\n", 262 | " child_node = self.generated.get(child_state) # Si no existe en generados retorna 0 (false)\n", 263 | " path_cost = n.g + cost # costo del camino encontrado hasta child_state\n", 264 | " if child_node is None : # si el estado no existe en OPEN U CLOSE\n", 265 | " child_node = Node(child_state, n) # creamos el nodo de child_state\n", 266 | " self.generated[child_state] = child_node # lo agregamos a generados\n", 267 | " child_node.action = action # definimos el nombre de la acción del nodo\n", 268 | " child_node.parent = n # definimos el padre\n", 269 | " child_node.g = path_cost # aumentamos el costo del camino con el costo de la accion\n", 270 | " self.open.insert(child_node) # agrega el nodo a la OPEN \n", 271 | " \n", 272 | " self.end_time = time.process_time() \n", 273 | " print(\"No solution found\") # Si el ciclo de expansiones termina sin encontrar solución, no existe solución.\n", 274 | " return None\n", 275 | "\n", 276 | " " 277 | ], 278 | "metadata": { 279 | "id": "Z7IkA9ZGY8Lf" 280 | }, 281 | "execution_count": null, 282 | "outputs": [] 283 | }, 284 | { 285 | "cell_type": "code", 286 | "source": [ 287 | "problem = Puzzle([4, 7, 5, 0, 8, 2, 6, 1, 3])\n", 288 | "\n", 289 | "s = BrFS(problem) \n", 290 | "result = s.search()\n", 291 | "print('Expansiones: %10d' % s.expansions )\n", 292 | "print('Generados: %10d' % len(s.generated) )\n", 293 | "print('Costo: %10d' % result.g )\n", 294 | "print('Tiempo: %10.2f' % (s.end_time-s.start_time) )\n", 295 | "\n", 296 | "print(\"Solucion*-***************************************\")\n", 297 | "print(result.trace())" 298 | ], 299 | "metadata": { 300 | "colab": { 301 | "base_uri": "https://localhost:8080/" 302 | }, 303 | "id": "TsGLjxaaZAwm", 304 | "outputId": "1d3a2c38-8c3a-4a4c-cabe-d7360e7440d8" 305 | }, 306 | "execution_count": null, 307 | "outputs": [ 308 | { 309 | "output_type": "stream", 310 | "name": "stdout", 311 | "text": [ 312 | "Expansiones: 142540\n", 313 | "Generados: 161359\n", 314 | "Costo: 25\n", 315 | "Tiempo: 10.64\n", 316 | "Solucion*-***************************************\n", 317 | "\n", 318 | "| 4| 7| 5|\n", 319 | "| | 8| 2|\n", 320 | "| 6| 1| 3|\n", 321 | "-down->\n", 322 | "| | 7| 5|\n", 323 | "| 4| 8| 2|\n", 324 | "| 6| 1| 3|\n", 325 | "-left->\n", 326 | "| 7| | 5|\n", 327 | "| 4| 8| 2|\n", 328 | "| 6| 1| 3|\n", 329 | "-left->\n", 330 | "| 7| 5| |\n", 331 | "| 4| 8| 2|\n", 332 | "| 6| 1| 3|\n", 333 | "-up->\n", 334 | "| 7| 5| 2|\n", 335 | "| 4| 8| |\n", 336 | "| 6| 1| 3|\n", 337 | "-right->\n", 338 | "| 7| 5| 2|\n", 339 | "| 4| | 8|\n", 340 | "| 6| 1| 3|\n", 341 | "-down->\n", 342 | "| 7| | 2|\n", 343 | "| 4| 5| 8|\n", 344 | "| 6| 1| 3|\n", 345 | "-right->\n", 346 | "| | 7| 2|\n", 347 | "| 4| 5| 8|\n", 348 | "| 6| 1| 3|\n", 349 | "-up->\n", 350 | "| 4| 7| 2|\n", 351 | "| | 5| 8|\n", 352 | "| 6| 1| 3|\n", 353 | "-up->\n", 354 | "| 4| 7| 2|\n", 355 | "| 6| 5| 8|\n", 356 | "| | 1| 3|\n", 357 | "-left->\n", 358 | "| 4| 7| 2|\n", 359 | "| 6| 5| 8|\n", 360 | "| 1| | 3|\n", 361 | "-left->\n", 362 | "| 4| 7| 2|\n", 363 | "| 6| 5| 8|\n", 364 | "| 1| 3| |\n", 365 | "-down->\n", 366 | "| 4| 7| 2|\n", 367 | "| 6| 5| |\n", 368 | "| 1| 3| 8|\n", 369 | "-right->\n", 370 | "| 4| 7| 2|\n", 371 | "| 6| | 5|\n", 372 | "| 1| 3| 8|\n", 373 | "-right->\n", 374 | "| 4| 7| 2|\n", 375 | "| | 6| 5|\n", 376 | "| 1| 3| 8|\n", 377 | "-up->\n", 378 | "| 4| 7| 2|\n", 379 | "| 1| 6| 5|\n", 380 | "| | 3| 8|\n", 381 | "-left->\n", 382 | "| 4| 7| 2|\n", 383 | "| 1| 6| 5|\n", 384 | "| 3| | 8|\n", 385 | "-down->\n", 386 | "| 4| 7| 2|\n", 387 | "| 1| | 5|\n", 388 | "| 3| 6| 8|\n", 389 | "-down->\n", 390 | "| 4| | 2|\n", 391 | "| 1| 7| 5|\n", 392 | "| 3| 6| 8|\n", 393 | "-right->\n", 394 | "| | 4| 2|\n", 395 | "| 1| 7| 5|\n", 396 | "| 3| 6| 8|\n", 397 | "-up->\n", 398 | "| 1| 4| 2|\n", 399 | "| | 7| 5|\n", 400 | "| 3| 6| 8|\n", 401 | "-up->\n", 402 | "| 1| 4| 2|\n", 403 | "| 3| 7| 5|\n", 404 | "| | 6| 8|\n", 405 | "-left->\n", 406 | "| 1| 4| 2|\n", 407 | "| 3| 7| 5|\n", 408 | "| 6| | 8|\n", 409 | "-down->\n", 410 | "| 1| 4| 2|\n", 411 | "| 3| | 5|\n", 412 | "| 6| 7| 8|\n", 413 | "-down->\n", 414 | "| 1| | 2|\n", 415 | "| 3| 4| 5|\n", 416 | "| 6| 7| 8|\n", 417 | "-right->\n", 418 | "| | 1| 2|\n", 419 | "| 3| 4| 5|\n", 420 | "| 6| 7| 8|\n", 421 | "\n" 422 | ] 423 | } 424 | ] 425 | }, 426 | { 427 | "cell_type": "code", 428 | "source": [ 429 | "#prblema 3 : 03 0 1 8 7 2 4 5 6 3\n", 430 | "\n", 431 | "problem = Puzzle([0, 1, 8, 7, 2, 4, 5, 6, 3])\n", 432 | "\n", 433 | "s = BrFS(problem) \n", 434 | "result = s.search()\n", 435 | "print('Expansiones: %10d' % s.expansions )\n", 436 | "print('Generados: %10d' % len(s.generated) )\n", 437 | "print('Costo: %10d' % result.g )\n", 438 | "print('Tiempo: %10.2f' % (s.end_time-s.start_time) )\n", 439 | "\n", 440 | "print(\"Solucion*-***************************************\")\n", 441 | "print(result.trace())" 442 | ], 443 | "metadata": { 444 | "colab": { 445 | "base_uri": "https://localhost:8080/" 446 | }, 447 | "id": "tVHD5iLoRg2U", 448 | "outputId": "9a6f8650-a7b5-4c52-b967-fe558dab7e71" 449 | }, 450 | "execution_count": null, 451 | "outputs": [ 452 | { 453 | "output_type": "stream", 454 | "name": "stdout", 455 | "text": [ 456 | "Expansiones: 44479\n", 457 | "Generados: 61733\n", 458 | "Costo: 20\n", 459 | "Tiempo: 3.18\n", 460 | "Solucion*-***************************************\n", 461 | "\n", 462 | "| | 1| 8|\n", 463 | "| 7| 2| 4|\n", 464 | "| 5| 6| 3|\n", 465 | "-left->\n", 466 | "| 1| | 8|\n", 467 | "| 7| 2| 4|\n", 468 | "| 5| 6| 3|\n", 469 | "-up->\n", 470 | "| 1| 2| 8|\n", 471 | "| 7| | 4|\n", 472 | "| 5| 6| 3|\n", 473 | "-left->\n", 474 | "| 1| 2| 8|\n", 475 | "| 7| 4| |\n", 476 | "| 5| 6| 3|\n", 477 | "-down->\n", 478 | "| 1| 2| |\n", 479 | "| 7| 4| 8|\n", 480 | "| 5| 6| 3|\n", 481 | "-right->\n", 482 | "| 1| | 2|\n", 483 | "| 7| 4| 8|\n", 484 | "| 5| 6| 3|\n", 485 | "-up->\n", 486 | "| 1| 4| 2|\n", 487 | "| 7| | 8|\n", 488 | "| 5| 6| 3|\n", 489 | "-up->\n", 490 | "| 1| 4| 2|\n", 491 | "| 7| 6| 8|\n", 492 | "| 5| | 3|\n", 493 | "-right->\n", 494 | "| 1| 4| 2|\n", 495 | "| 7| 6| 8|\n", 496 | "| | 5| 3|\n", 497 | "-down->\n", 498 | "| 1| 4| 2|\n", 499 | "| | 6| 8|\n", 500 | "| 7| 5| 3|\n", 501 | "-left->\n", 502 | "| 1| 4| 2|\n", 503 | "| 6| | 8|\n", 504 | "| 7| 5| 3|\n", 505 | "-up->\n", 506 | "| 1| 4| 2|\n", 507 | "| 6| 5| 8|\n", 508 | "| 7| | 3|\n", 509 | "-left->\n", 510 | "| 1| 4| 2|\n", 511 | "| 6| 5| 8|\n", 512 | "| 7| 3| |\n", 513 | "-down->\n", 514 | "| 1| 4| 2|\n", 515 | "| 6| 5| |\n", 516 | "| 7| 3| 8|\n", 517 | "-right->\n", 518 | "| 1| 4| 2|\n", 519 | "| 6| | 5|\n", 520 | "| 7| 3| 8|\n", 521 | "-up->\n", 522 | "| 1| 4| 2|\n", 523 | "| 6| 3| 5|\n", 524 | "| 7| | 8|\n", 525 | "-right->\n", 526 | "| 1| 4| 2|\n", 527 | "| 6| 3| 5|\n", 528 | "| | 7| 8|\n", 529 | "-down->\n", 530 | "| 1| 4| 2|\n", 531 | "| | 3| 5|\n", 532 | "| 6| 7| 8|\n", 533 | "-left->\n", 534 | "| 1| 4| 2|\n", 535 | "| 3| | 5|\n", 536 | "| 6| 7| 8|\n", 537 | "-down->\n", 538 | "| 1| | 2|\n", 539 | "| 3| 4| 5|\n", 540 | "| 6| 7| 8|\n", 541 | "-right->\n", 542 | "| | 1| 2|\n", 543 | "| 3| 4| 5|\n", 544 | "| 6| 7| 8|\n", 545 | "\n" 546 | ] 547 | } 548 | ] 549 | }, 550 | { 551 | "cell_type": "code", 552 | "source": [ 553 | "#prblema 3 : 03 0 1 8 7 2 4 5 6 3\n", 554 | "\n", 555 | "problem = Puzzle([3, 1, 2, 0, 4, 5, 6, 7, 8])\n", 556 | "\n", 557 | "s = BrFS(problem) \n", 558 | "result = s.search()\n", 559 | "print('Expansiones: %10d' % s.expansions )\n", 560 | "print('Generados: %10d' % len(s.generated) )\n", 561 | "print('Costo: %10d' % result.g )\n", 562 | "print('Tiempo: %10.2f' % (s.end_time-s.start_time) )\n", 563 | "\n", 564 | "print(\"Solucion*-***************************************\")\n", 565 | "print(result.trace())" 566 | ], 567 | "metadata": { 568 | "colab": { 569 | "base_uri": "https://localhost:8080/" 570 | }, 571 | "id": "V9xRERWIR9l0", 572 | "outputId": "464f03a4-f4bc-4ff5-9569-06360eb4d76f" 573 | }, 574 | "execution_count": null, 575 | "outputs": [ 576 | { 577 | "output_type": "stream", 578 | "name": "stdout", 579 | "text": [ 580 | "Expansiones: 1\n", 581 | "Generados: 4\n", 582 | "Costo: 1\n", 583 | "Tiempo: 0.00\n", 584 | "Solucion*-***************************************\n", 585 | "\n", 586 | "| 3| 1| 2|\n", 587 | "| | 4| 5|\n", 588 | "| 6| 7| 8|\n", 589 | "-down->\n", 590 | "| | 1| 2|\n", 591 | "| 3| 4| 5|\n", 592 | "| 6| 7| 8|\n", 593 | "\n" 594 | ] 595 | } 596 | ] 597 | }, 598 | { 599 | "cell_type": "markdown", 600 | "source": [ 601 | "# Preguntas:\n", 602 | "- La solución encontrada es la solución óptima (no existe otra solución con menor costo)? ¿Por que? Demuestrelo.\n", 603 | "- Convierta la clase BrFS a la clase DFS (Depth-First Search [Búsqueda en profundidad]) y al la clase Dijkstra (que implementa el algoritmo de Dijkstra). \n", 604 | "- ¿La solución encontrada por DFS es la óptima? ¿Por que? Demuestrelo.\n", 605 | "- ¿El algoritmo de Dijkstra realiza el mismo procedimiento y esfuerzo (cantidad de expansiones) que el algoritmo BFS? ¿Por que?" 606 | ], 607 | "metadata": { 608 | "id": "VmT2jgkjrXGf" 609 | } 610 | } 611 | ] 612 | } -------------------------------------------------------------------------------- /1 Search/1 Blind Search/README.md: -------------------------------------------------------------------------------- 1 | # Algoritmos de búsqueda 2 | 3 | ![Algoritmo de búsqueda genérico](img/alg2.1.png) 4 | ![Improve](img/alg2.3.png) 5 | 6 | 7 | Partes fundamentales de un algoritmo de búsqueda: 8 | - `Open` list: Lista de estados abiertos (generados pero no expandidos). Cola de prioridad 9 | - `Close` list: Lista de estados cerrados (ya expandidos). Tabla hash. 10 | - `s` y `u`: Estados. Representan un estado del problema en un momento determinado. 11 | - `Goal()`: Función que recibe un estado y determina si corresponde a un estado objetivo. 12 | - `Succ()`: Función que recibe un estado `s` y genera los estados sucesores. Los estados sucesores son todos aquellos estados $v \in V$ que derivan de aplicar todas las acciones disponibles. 13 | - `Ìmprove(u,v)`: Agrega cada estado sucesor a la lista de `Open`, sí corresponde. 14 | 15 | 16 | Bibliografia: 17 | Edelkamp, S., & Schrodl, S. (2011). Heuristic search: theory and applications. Elsevier. -------------------------------------------------------------------------------- /1 Search/1 Blind Search/code/BrFS.py: -------------------------------------------------------------------------------- 1 | from node import Node 2 | import time 3 | from open_list import OpenList_BrFS 4 | 5 | class BrFS: 6 | def __init__(self, initial_state): 7 | self.expansions = 0 8 | #self.generated = 0 # es la lista de estados generados OPEN U CLOSE 9 | self.initial_state = initial_state 10 | self.solution = None 11 | self.open = OpenList_BrFS() 12 | self.generated = {} 13 | 14 | 15 | 16 | def search(self): 17 | self.start_time = time.process_time() 18 | 19 | initial_node = Node(self.initial_state) 20 | initial_node.g = 0 21 | self.open.insert(initial_node) 22 | self.generated[self.initial_state] = initial_node # para cada estado alguna vez generado, generated almacena el Node object que le corresponde 23 | 24 | while not self.open.is_empty(): # Mientras la OPEN no esté vacia (ciclo de expansiones) 25 | n = self.open.extract() # extrae n de la open (el con menor key (en este caso profundidad)) 26 | 27 | if n.state.is_goal(): # Si el estado extraido es el estado objetivo (el problema resuelto) 28 | self.end_time = time.process_time() 29 | self.solution = n # Define el estado extraido como solución (para reconstruirlo luego) 30 | return n 31 | succ = n.state.successors() # Genera los sucesores 32 | self.expansions += 1 # Aumenta en 1 las expansiones 33 | for child_state, action, cost in succ: # Por cada uno de los estados sucesores 34 | child_node = self.generated.get(child_state) # Si no existe en generados retorna 0 (false) 35 | path_cost = n.g + cost # costo del camino encontrado hasta child_state 36 | if child_node is None : # si el estado no existe en OPEN U CLOSE 37 | child_node = Node(child_state, n) # creamos el nodo de child_state 38 | self.generated[child_state] = child_node # lo agregamos a generados 39 | child_node.action = action # definimos el nombre de la acción del nodo 40 | child_node.parent = n # definimos el padre 41 | child_node.g = path_cost # aumentamos el costo del camino con el costo de la accion 42 | self.open.insert(child_node) # agrega el nodo a la OPEN 43 | 44 | self.end_time = time.process_time() 45 | print("No solution found") # Si el ciclo de expansiones termina sin encontrar solución, no existe solución. 46 | return None 47 | 48 | 49 | -------------------------------------------------------------------------------- /1 Search/1 Blind Search/code/__pycache__/BrFS.cpython-38.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/matgreco/IntroAI/35ab1725bb4343b41f66957dbf0f2766da327a50/1 Search/1 Blind Search/code/__pycache__/BrFS.cpython-38.pyc -------------------------------------------------------------------------------- /1 Search/1 Blind Search/code/__pycache__/node.cpython-38.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/matgreco/IntroAI/35ab1725bb4343b41f66957dbf0f2766da327a50/1 Search/1 Blind Search/code/__pycache__/node.cpython-38.pyc -------------------------------------------------------------------------------- /1 Search/1 Blind Search/code/__pycache__/open_list.cpython-38.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/matgreco/IntroAI/35ab1725bb4343b41f66957dbf0f2766da327a50/1 Search/1 Blind Search/code/__pycache__/open_list.cpython-38.pyc -------------------------------------------------------------------------------- /1 Search/1 Blind Search/code/__pycache__/puzzle.cpython-38.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/matgreco/IntroAI/35ab1725bb4343b41f66957dbf0f2766da327a50/1 Search/1 Blind Search/code/__pycache__/puzzle.cpython-38.pyc -------------------------------------------------------------------------------- /1 Search/1 Blind Search/code/node.py: -------------------------------------------------------------------------------- 1 | class Node: 2 | def __init__(self, search_state, parent=None, action=''): 3 | self.state = search_state 4 | self.parent = parent # Es el estado padre. 5 | if parent: # compatibilidad con DFS/BrFS 6 | self.depth = parent.depth + 1 7 | else: 8 | self.depth = 0 9 | self.action = action # es el nombre de la accion 10 | #self.heap_index = 0 11 | 12 | def __repr__(self): 13 | return self.state.__repr__() 14 | 15 | def trace(self): # reconstruye la solución 16 | s = '' 17 | if self.parent: 18 | s = self.parent.trace() 19 | s += '-' + self.action + '->' 20 | s += str(self.state) 21 | return s 22 | -------------------------------------------------------------------------------- /1 Search/1 Blind Search/code/open_list.py: -------------------------------------------------------------------------------- 1 | import heapq 2 | from collections import deque 3 | 4 | class OpenList_BrFS: 5 | # Inicia una lista vacia 6 | def __init__(self): 7 | self.items = deque([]) 8 | 9 | # La cantidad de elementos en el heap 10 | @staticmethod 11 | def size(self): 12 | return len(self.items) 13 | 14 | # Retorna el mejor elemento del heap 15 | def top(self): 16 | if self.size == 0: 17 | return None 18 | else: 19 | return self.items[0] 20 | 21 | # Retorna el primer elemento y lo elimina 22 | def extract(self): 23 | if len(self.items): 24 | return self.items.popleft() 25 | else : 26 | None 27 | 28 | # Inserta un elemento en el heap 29 | def insert(self, element): 30 | self.items.append(element) 31 | 32 | # Verifica si esta vacia 33 | def is_empty(self): 34 | return self.size == 0 35 | 36 | 37 | class OpenList: 38 | # Inicia una lista vacia 39 | def __init__(self): 40 | self.items = [] 41 | 42 | # La cantidad de elementos en el heap 43 | @staticmethod 44 | def size(self): 45 | return len(self.items) 46 | 47 | # Retorna el mejor elemento del heap 48 | def top(self): 49 | if self.size == 0: 50 | return None 51 | else: 52 | return self.items[0] 53 | # Retorna el mejor elemento del heap y lo elimina 54 | def extract(self): 55 | if len(self.items): 56 | return heapq.heappop(self.items) 57 | else : 58 | None 59 | 60 | # Inserta un elemento en el heap 61 | def insert(self, element): 62 | heapq.heappush(self.items, element) 63 | 64 | # Verifica si esta vacia 65 | def is_empty(self): 66 | return self.size == 0 67 | -------------------------------------------------------------------------------- /1 Search/1 Blind Search/code/problems_r8.txt: -------------------------------------------------------------------------------- 1 | 00 4 7 5 0 8 2 6 1 3 2 | 01 6 8 7 4 3 2 1 5 0 3 | 02 0 6 7 1 2 4 3 8 5 4 | 03 0 1 8 7 2 4 5 6 3 5 | 04 5 0 8 7 2 4 6 1 3 6 | 05 0 4 6 2 1 5 3 8 7 7 | 06 0 2 8 4 5 1 7 6 3 8 | 07 2 3 8 0 4 1 6 7 5 9 | 08 5 7 3 0 2 8 4 1 6 10 | 09 0 4 2 1 3 8 6 5 7 11 | 10 4 5 8 1 3 0 6 7 2 12 | 11 3 8 4 7 5 2 6 1 0 13 | 12 2 1 5 0 6 8 7 3 4 14 | 13 4 8 2 5 6 0 7 1 3 15 | 14 4 6 2 3 7 0 5 1 8 16 | 15 2 4 7 3 5 0 1 8 6 17 | 16 4 5 1 8 7 3 0 2 6 18 | 17 7 6 3 1 5 4 2 0 8 19 | 18 3 7 8 6 5 0 4 2 1 20 | 19 0 1 8 5 2 7 4 6 3 21 | 20 1 6 5 3 4 7 2 8 0 22 | 21 2 4 1 0 6 5 3 7 8 23 | 22 4 2 0 5 8 1 7 3 6 24 | 23 7 1 5 8 2 3 6 0 4 25 | 24 4 5 6 8 1 3 2 0 7 26 | 25 7 1 5 4 0 6 3 2 8 27 | 26 3 6 2 5 7 4 1 0 8 28 | 27 6 3 7 0 2 4 5 1 8 29 | 28 7 2 8 6 0 4 3 5 1 30 | 29 6 5 4 1 8 7 3 0 2 31 | 30 0 3 7 2 8 5 6 1 4 32 | 31 0 8 1 7 5 4 3 2 6 33 | 32 8 5 2 0 4 1 7 3 6 34 | 33 2 7 3 1 5 4 0 6 8 35 | 34 0 5 7 8 2 6 3 4 1 36 | 35 5 1 3 0 8 6 7 4 2 37 | 36 5 7 1 6 3 4 2 8 0 38 | 37 0 2 3 7 4 1 8 6 5 39 | 38 1 2 4 7 8 5 3 6 0 40 | 39 3 8 7 2 4 1 6 5 0 41 | 40 1 4 2 6 0 5 8 7 3 42 | 41 8 5 7 4 2 1 3 0 6 43 | 42 5 7 8 1 0 4 3 6 2 44 | 43 8 3 2 0 7 1 6 4 5 45 | 44 5 2 3 7 6 4 0 1 8 46 | 45 1 2 0 5 4 7 3 8 6 47 | 46 5 3 2 7 1 0 8 4 6 48 | 47 6 7 8 1 0 3 2 4 5 49 | 48 2 3 0 5 6 7 1 4 8 50 | 49 4 0 2 1 5 3 8 7 6 51 | 50 0 7 5 2 6 8 1 4 3 52 | 51 3 6 7 5 2 0 8 1 4 53 | 52 3 0 1 7 8 5 4 6 2 54 | 53 4 6 8 0 3 1 5 7 2 55 | 54 3 7 2 8 1 6 0 4 5 56 | 55 0 1 6 3 8 2 7 5 4 57 | 56 3 7 5 4 1 0 2 6 8 58 | 57 3 7 5 1 0 4 8 6 2 59 | 58 6 7 8 0 3 1 4 2 5 60 | 59 2 5 8 3 1 0 7 4 6 61 | 60 0 7 8 5 1 2 4 6 3 62 | 61 3 4 1 0 6 5 7 2 8 63 | 62 1 8 2 3 4 7 5 0 6 64 | 63 2 5 8 0 6 4 1 3 7 65 | 64 3 6 8 5 0 2 7 4 1 66 | 65 5 4 0 1 7 6 2 3 8 67 | 66 0 7 2 1 4 8 3 6 5 68 | 67 2 7 4 8 3 6 0 5 1 69 | 68 3 1 8 4 7 2 6 5 0 70 | 69 6 8 4 1 5 0 7 2 3 71 | 70 8 7 5 0 1 3 4 6 2 72 | 71 0 1 6 7 3 5 4 2 8 73 | 72 1 0 6 7 5 3 4 8 2 74 | 73 1 6 8 3 7 2 0 5 4 75 | 74 0 3 4 8 7 2 1 5 6 76 | 75 2 3 6 7 5 0 8 1 4 77 | 76 7 0 6 8 1 5 4 3 2 78 | 77 0 1 2 8 7 3 5 4 6 79 | 78 3 2 4 1 5 7 8 0 6 80 | 79 0 6 1 7 3 2 5 8 4 81 | 80 7 1 5 8 0 2 3 6 4 82 | 81 6 0 4 2 1 5 8 3 7 83 | 82 6 4 2 7 5 0 8 1 3 84 | 83 8 4 5 2 1 7 3 0 6 85 | 84 1 8 6 0 5 7 3 4 2 86 | 85 7 2 0 1 8 5 3 6 4 87 | 86 7 5 8 4 2 6 3 1 0 88 | 87 6 3 4 7 1 8 2 0 5 89 | 88 2 5 3 6 0 4 8 1 7 90 | 89 5 3 2 4 7 6 0 8 1 91 | 90 6 5 1 2 7 8 0 4 3 92 | 91 3 6 1 7 4 5 8 0 2 93 | 92 1 3 0 2 7 6 5 8 4 94 | 93 0 5 8 1 6 3 4 7 2 95 | 94 0 1 4 5 7 8 6 2 3 96 | 95 3 4 8 6 1 7 2 5 0 97 | 96 1 0 3 2 8 4 6 5 7 98 | 97 1 2 0 7 3 8 5 4 6 99 | 98 8 5 0 1 2 4 3 6 7 100 | 99 0 6 5 1 8 7 3 4 2 101 | -------------------------------------------------------------------------------- /1 Search/1 Blind Search/code/puzzle.py: -------------------------------------------------------------------------------- 1 | import sys 2 | import copy 3 | import numpy as np 4 | 5 | 6 | class Puzzle: 7 | goal8 = list(range(9)) 8 | def __init__(self, board=None, blank=-1): 9 | if not board: 10 | self.x = 3 11 | self.size = 9 12 | self.board = [i for i in range(0, self.size)] 13 | self.blank = 0 14 | else: 15 | self.board = board 16 | if len(self.board) == 9: 17 | self.x = 3 18 | self.size = 9 19 | else: 20 | print('puzzle size not supported') 21 | sys.exit(1) 22 | if blank == -1: 23 | self.blank = board.index(0) 24 | 25 | 26 | def __hash__(self): 27 | return hash(tuple(self.board)) 28 | 29 | def __eq__(self, other): 30 | return self.board == other.board 31 | 32 | def __repr__(self): 33 | def tostr(d): 34 | if d > 0: 35 | return "%2d" % (d) 36 | else: 37 | return " " 38 | s = '\n' 39 | for i in range(0, self.x): 40 | s += "|" 41 | s += "|".join([tostr(d) for d in self.board[i*self.x:i*self.x+self.x]]) 42 | s += "|\n" 43 | return s 44 | 45 | def successors(self): 46 | ''' 47 | Crea una lista de tuplas de la forma (estado, accion, costo) 48 | donde estado es el estado sucesor de self que se genera al ejecutar 49 | accion (un string) y costo (un numero real) es el costo de accion 50 | ''' 51 | def create_child(newblank): 52 | child = copy.deepcopy(self) 53 | child.blank = newblank 54 | child.board[child.blank] = 0 55 | child.board[self.blank] = self.board[newblank] 56 | return child 57 | 58 | succ = [] 59 | if self.blank > self.x - 1: 60 | c = create_child(self.blank-self.x) 61 | succ.append((c, 'down', 1)) 62 | if self.blank % self.x > 0: 63 | c = create_child(self.blank-1) 64 | succ.append((c, 'right', 1)) 65 | if self.blank % self.x < self.x - 1: 66 | c = create_child(self.blank+1) 67 | succ.append((c, 'left', 1)) 68 | if self.blank < self.size - self.x: 69 | c = create_child(self.blank+self.x) 70 | succ.append((c, 'up', 1)) 71 | return succ 72 | 73 | def is_goal(self): 74 | return Puzzle.goal8 == self.board 75 | -------------------------------------------------------------------------------- /1 Search/1 Blind Search/code/test_brfs_puzzle.py: -------------------------------------------------------------------------------- 1 | from puzzle import Puzzle 2 | from BrFS import BrFS 3 | from os.path import join 4 | 5 | def load_problems(problems): ## carga los problemas en memoria 6 | puzzles = list() 7 | with open('problems_r8.txt') as f: 8 | for line in f: 9 | puzzle = line.rstrip().split(' ', 1)[1] 10 | problems.append(Puzzle([int(x) for x in puzzle.split(' ')])) 11 | puzzles.append(puzzle) 12 | 13 | 14 | 15 | show_solutions = False # mostramos las soluciones? 16 | 17 | problems = [] 18 | load_problems(problems) 19 | 20 | total_time = 0 21 | total_cost = 0 22 | total_expansions = 0 23 | num_problems = 3 # len(problems) # cambiar si quieres ejecutar sobre todos los problemas 24 | 25 | 26 | print('prob\texp\tgenerated\t|sol|\ttiempo\n') 27 | 28 | for prob in range(0, num_problems): 29 | init = problems[prob] 30 | s = BrFS(init) # agregar un tercer parámetro una vez que lo hayas transformado en Weighted A* 31 | result = s.search() 32 | print('%5d%10d%10d%10d%10.2f' % (prob+1, s.expansions, len(s.generated), result.g, s.end_time-s.start_time )) 33 | total_time += s.end_time - s.start_time 34 | total_cost += result.g 35 | total_expansions += s.expansions 36 | 37 | if show_solutions: 38 | print(result.trace()) 39 | 40 | 41 | print('Tiempo total: %.2f'%(total_time)) 42 | print('Expansiones totales: %d'%(total_expansions)) 43 | print('Costo total: %d'%(total_cost)) 44 | -------------------------------------------------------------------------------- /1 Search/1 Blind Search/img/alg2.1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/matgreco/IntroAI/35ab1725bb4343b41f66957dbf0f2766da327a50/1 Search/1 Blind Search/img/alg2.1.png -------------------------------------------------------------------------------- /1 Search/1 Blind Search/img/alg2.3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/matgreco/IntroAI/35ab1725bb4343b41f66957dbf0f2766da327a50/1 Search/1 Blind Search/img/alg2.3.png -------------------------------------------------------------------------------- /1 Search/2 Informed Search/BrFS.py: -------------------------------------------------------------------------------- 1 | from node import Node 2 | import time 3 | from open_list import OpenList 4 | 5 | class BrFS: 6 | def __init__(self, initial_state): 7 | self.expansions = 0 8 | #self.generated = 0 # es la lista de estados generados OPEN U CLOSE 9 | self.initial_state = initial_state 10 | self.solution = None 11 | self.open = OpenList() 12 | self.generated = {} 13 | 14 | 15 | 16 | def search(self): 17 | self.start_time = time.process_time() 18 | 19 | #self.expansions = 0 20 | #self.solution = None 21 | initial_node = Node(self.initial_state) 22 | initial_node.g = 0 23 | initial_node.key = initial_node.g 24 | 25 | self.open.insert(initial_node) 26 | self.generated[self.initial_state] = initial_node # para cada estado alguna vez generado, generated almacena el Node object que le corresponde 27 | 28 | while not self.open.is_empty(): # Mientras la OPEN no esté vacia (ciclo de expansiones) 29 | n = self.open.extract() # extrae n de la open (el con menor key (en este caso profundidad)) 30 | 31 | if n.state.is_goal(): # Si el estado extraido es el estado objetivo (el problema resuelto) 32 | self.end_time = time.process_time() 33 | self.solution = n # Define el estado extraido como solución (para reconstruirlo luego) 34 | return n 35 | succ = n.state.successors() # Genera los sucesores 36 | self.expansions += 1 # Aumenta en 1 las expansiones 37 | for child_state, action, cost in succ: # Por cada uno de los estados sucesores 38 | child_node = self.generated.get(child_state) # Lo agrega a generados 39 | path_cost = n.g + cost # costo del camino encontrado hasta child_state 40 | if child_node is None : # si el estado no existe en OPEN U CLOSE 41 | child_node = Node(child_state, n) # creamos el nodo de child_state 42 | self.generated[child_state] = child_node # lo agregamos a generados 43 | child_node.action = action # definimos el nombre de la acción del nodo 44 | child_node.parent = n # definimos el padre 45 | child_node.g = path_cost # aumentamos el costo del camino con el costo de la accion 46 | child_node.key = child_node.g # actualizamos la key (que ordenará la OPEN LIST) 47 | self.open.insert(child_node) # agrega el nodo a la OPEN 48 | 49 | self.end_time = time.process_time() 50 | print("No solution found") # Si el ciclo de expansiones termina sin encontrar solución, no existe solución. 51 | return None 52 | 53 | 54 | -------------------------------------------------------------------------------- /1 Search/2 Informed Search/README.md: -------------------------------------------------------------------------------- 1 | # Algoritmo A* 2 | 3 | El material y pseudocodigo están en el archivo 2_A_.ipynb 4 | -------------------------------------------------------------------------------- /1 Search/2 Informed Search/__pycache__/BrFS.cpython-38.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/matgreco/IntroAI/35ab1725bb4343b41f66957dbf0f2766da327a50/1 Search/2 Informed Search/__pycache__/BrFS.cpython-38.pyc -------------------------------------------------------------------------------- /1 Search/2 Informed Search/__pycache__/node.cpython-38.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/matgreco/IntroAI/35ab1725bb4343b41f66957dbf0f2766da327a50/1 Search/2 Informed Search/__pycache__/node.cpython-38.pyc -------------------------------------------------------------------------------- /1 Search/2 Informed Search/__pycache__/open_list.cpython-38.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/matgreco/IntroAI/35ab1725bb4343b41f66957dbf0f2766da327a50/1 Search/2 Informed Search/__pycache__/open_list.cpython-38.pyc -------------------------------------------------------------------------------- /1 Search/2 Informed Search/__pycache__/puzzle.cpython-38.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/matgreco/IntroAI/35ab1725bb4343b41f66957dbf0f2766da327a50/1 Search/2 Informed Search/__pycache__/puzzle.cpython-38.pyc -------------------------------------------------------------------------------- /1 Search/2 Informed Search/node.py: -------------------------------------------------------------------------------- 1 | class Node: 2 | def __init__(self, search_state, parent=None, action=''): 3 | self.state = search_state 4 | self.parent = parent # Es el estado padre. 5 | if parent: # compatibilidad con DFS/BrFS 6 | self.depth = parent.depth + 1 7 | else: 8 | self.depth = 0 9 | self.action = action # es el nombre de la accion 10 | self.key = -1 # el el criterio de ordenamiento del nodo 11 | self.g = 0 # corresponde al costo del camino 12 | self.heap_index = 0 13 | 14 | def __repr__(self): 15 | return self.state.__repr__() 16 | 17 | def __gt__(self, other): 18 | if self.key > other.key: 19 | return True 20 | else : 21 | return False 22 | 23 | def __lt__(self, other): 24 | if self.key < other.key: 25 | return True 26 | else : 27 | return False 28 | 29 | def trace(self): 30 | s = '' 31 | if self.parent: 32 | s = self.parent.trace() 33 | s += '-' + self.action + '->' 34 | s += str(self.state) 35 | return s 36 | -------------------------------------------------------------------------------- /1 Search/2 Informed Search/open_list.py: -------------------------------------------------------------------------------- 1 | import heapq 2 | 3 | class OpenList: 4 | # Inicia una lista vacia 5 | def __init__(self): 6 | self.items = [] 7 | 8 | # La cantidad de elementos en el heap 9 | @staticmethod 10 | def size(self): 11 | return len(self.items) 12 | 13 | # Retorna el mejor elemento del heap 14 | def top(self): 15 | if self.size == 0: 16 | return None 17 | else: 18 | return self.items[0] 19 | # Retorna el mejor elemento del heap y lo elimina 20 | def extract(self): 21 | if len(self.items): 22 | return heapq.heappop(self.items) 23 | else : 24 | None 25 | 26 | # Inserta un elemento en el heap 27 | def insert(self, element): 28 | heapq.heappush(self.items, element) 29 | 30 | # Verifica si esta vacia 31 | def is_empty(self): 32 | return self.size == 0 33 | -------------------------------------------------------------------------------- /1 Search/2 Informed Search/problems_r8.txt: -------------------------------------------------------------------------------- 1 | 00 4 7 5 0 8 2 6 1 3 2 | 01 6 8 7 4 3 2 1 5 0 3 | 02 0 6 7 1 2 4 3 8 5 4 | 03 0 1 8 7 2 4 5 6 3 5 | 04 5 0 8 7 2 4 6 1 3 6 | 05 0 4 6 2 1 5 3 8 7 7 | 06 0 2 8 4 5 1 7 6 3 8 | 07 2 3 8 0 4 1 6 7 5 9 | 08 5 7 3 0 2 8 4 1 6 10 | 09 0 4 2 1 3 8 6 5 7 11 | 10 4 5 8 1 3 0 6 7 2 12 | 11 3 8 4 7 5 2 6 1 0 13 | 12 2 1 5 0 6 8 7 3 4 14 | 13 4 8 2 5 6 0 7 1 3 15 | 14 4 6 2 3 7 0 5 1 8 16 | 15 2 4 7 3 5 0 1 8 6 17 | 16 4 5 1 8 7 3 0 2 6 18 | 17 7 6 3 1 5 4 2 0 8 19 | 18 3 7 8 6 5 0 4 2 1 20 | 19 0 1 8 5 2 7 4 6 3 21 | 20 1 6 5 3 4 7 2 8 0 22 | 21 2 4 1 0 6 5 3 7 8 23 | 22 4 2 0 5 8 1 7 3 6 24 | 23 7 1 5 8 2 3 6 0 4 25 | 24 4 5 6 8 1 3 2 0 7 26 | 25 7 1 5 4 0 6 3 2 8 27 | 26 3 6 2 5 7 4 1 0 8 28 | 27 6 3 7 0 2 4 5 1 8 29 | 28 7 2 8 6 0 4 3 5 1 30 | 29 6 5 4 1 8 7 3 0 2 31 | 30 0 3 7 2 8 5 6 1 4 32 | 31 0 8 1 7 5 4 3 2 6 33 | 32 8 5 2 0 4 1 7 3 6 34 | 33 2 7 3 1 5 4 0 6 8 35 | 34 0 5 7 8 2 6 3 4 1 36 | 35 5 1 3 0 8 6 7 4 2 37 | 36 5 7 1 6 3 4 2 8 0 38 | 37 0 2 3 7 4 1 8 6 5 39 | 38 1 2 4 7 8 5 3 6 0 40 | 39 3 8 7 2 4 1 6 5 0 41 | 40 1 4 2 6 0 5 8 7 3 42 | 41 8 5 7 4 2 1 3 0 6 43 | 42 5 7 8 1 0 4 3 6 2 44 | 43 8 3 2 0 7 1 6 4 5 45 | 44 5 2 3 7 6 4 0 1 8 46 | 45 1 2 0 5 4 7 3 8 6 47 | 46 5 3 2 7 1 0 8 4 6 48 | 47 6 7 8 1 0 3 2 4 5 49 | 48 2 3 0 5 6 7 1 4 8 50 | 49 4 0 2 1 5 3 8 7 6 51 | 50 0 7 5 2 6 8 1 4 3 52 | 51 3 6 7 5 2 0 8 1 4 53 | 52 3 0 1 7 8 5 4 6 2 54 | 53 4 6 8 0 3 1 5 7 2 55 | 54 3 7 2 8 1 6 0 4 5 56 | 55 0 1 6 3 8 2 7 5 4 57 | 56 3 7 5 4 1 0 2 6 8 58 | 57 3 7 5 1 0 4 8 6 2 59 | 58 6 7 8 0 3 1 4 2 5 60 | 59 2 5 8 3 1 0 7 4 6 61 | 60 0 7 8 5 1 2 4 6 3 62 | 61 3 4 1 0 6 5 7 2 8 63 | 62 1 8 2 3 4 7 5 0 6 64 | 63 2 5 8 0 6 4 1 3 7 65 | 64 3 6 8 5 0 2 7 4 1 66 | 65 5 4 0 1 7 6 2 3 8 67 | 66 0 7 2 1 4 8 3 6 5 68 | 67 2 7 4 8 3 6 0 5 1 69 | 68 3 1 8 4 7 2 6 5 0 70 | 69 6 8 4 1 5 0 7 2 3 71 | 70 8 7 5 0 1 3 4 6 2 72 | 71 0 1 6 7 3 5 4 2 8 73 | 72 1 0 6 7 5 3 4 8 2 74 | 73 1 6 8 3 7 2 0 5 4 75 | 74 0 3 4 8 7 2 1 5 6 76 | 75 2 3 6 7 5 0 8 1 4 77 | 76 7 0 6 8 1 5 4 3 2 78 | 77 0 1 2 8 7 3 5 4 6 79 | 78 3 2 4 1 5 7 8 0 6 80 | 79 0 6 1 7 3 2 5 8 4 81 | 80 7 1 5 8 0 2 3 6 4 82 | 81 6 0 4 2 1 5 8 3 7 83 | 82 6 4 2 7 5 0 8 1 3 84 | 83 8 4 5 2 1 7 3 0 6 85 | 84 1 8 6 0 5 7 3 4 2 86 | 85 7 2 0 1 8 5 3 6 4 87 | 86 7 5 8 4 2 6 3 1 0 88 | 87 6 3 4 7 1 8 2 0 5 89 | 88 2 5 3 6 0 4 8 1 7 90 | 89 5 3 2 4 7 6 0 8 1 91 | 90 6 5 1 2 7 8 0 4 3 92 | 91 3 6 1 7 4 5 8 0 2 93 | 92 1 3 0 2 7 6 5 8 4 94 | 93 0 5 8 1 6 3 4 7 2 95 | 94 0 1 4 5 7 8 6 2 3 96 | 95 3 4 8 6 1 7 2 5 0 97 | 96 1 0 3 2 8 4 6 5 7 98 | 97 1 2 0 7 3 8 5 4 6 99 | 98 8 5 0 1 2 4 3 6 7 100 | 99 0 6 5 1 8 7 3 4 2 101 | -------------------------------------------------------------------------------- /1 Search/2 Informed Search/puzzle.py: -------------------------------------------------------------------------------- 1 | import sys 2 | import copy 3 | import numpy as np 4 | 5 | 6 | class Puzzle: 7 | goal8 = list(range(9)) 8 | def __init__(self, board=None, blank=-1): 9 | if not board: 10 | self.x = 3 11 | self.size = 9 12 | self.board = [i for i in range(0, self.size)] 13 | self.blank = 0 14 | else: 15 | self.board = board 16 | if len(self.board) == 9: 17 | self.x = 3 18 | self.size = 9 19 | else: 20 | print('puzzle size not supported') 21 | sys.exit(1) 22 | if blank == -1: 23 | self.blank = board.index(0) 24 | 25 | 26 | def __hash__(self): 27 | return hash(tuple(self.board)) 28 | 29 | def __eq__(self, other): 30 | return self.board == other.board 31 | 32 | def __repr__(self): 33 | def tostr(d): 34 | if d > 0: 35 | return "%2d" % (d) 36 | else: 37 | return " " 38 | s = '\n' 39 | for i in range(0, self.x): 40 | s += "|" 41 | s += "|".join([tostr(d) for d in self.board[i*self.x:i*self.x+self.x]]) 42 | s += "|\n" 43 | return s 44 | 45 | def successors(self): 46 | ''' 47 | Crea una lista de tuplas de la forma (estado, accion, costo) 48 | donde estado es el estado sucesor de self que se genera al ejecutar 49 | accion (un string) y costo (un numero real) es el costo de accion 50 | ''' 51 | def create_child(newblank): 52 | child = copy.deepcopy(self) 53 | child.blank = newblank 54 | child.board[child.blank] = 0 55 | child.board[self.blank] = self.board[newblank] 56 | return child 57 | 58 | succ = [] 59 | if self.blank > self.x - 1: 60 | c = create_child(self.blank-self.x) 61 | succ.append((c, 'down', 1)) 62 | if self.blank % self.x > 0: 63 | c = create_child(self.blank-1) 64 | succ.append((c, 'right', 1)) 65 | if self.blank % self.x < self.x - 1: 66 | c = create_child(self.blank+1) 67 | succ.append((c, 'left', 1)) 68 | if self.blank < self.size - self.x: 69 | c = create_child(self.blank+self.x) 70 | succ.append((c, 'up', 1)) 71 | return succ 72 | 73 | def is_goal(self): 74 | return Puzzle.goal8 == self.board 75 | -------------------------------------------------------------------------------- /1 Search/2 Informed Search/test_brfs_puzzle.py: -------------------------------------------------------------------------------- 1 | from puzzle import Puzzle 2 | from BrFS import BrFS 3 | from os.path import join 4 | 5 | def load_problems(problems): ## carga los problemas en memoria 6 | puzzles = list() 7 | with open('problems_r8.txt') as f: 8 | for line in f: 9 | puzzle = line.rstrip().split(' ', 1)[1] 10 | problems.append(Puzzle([int(x) for x in puzzle.split(' ')])) 11 | puzzles.append(puzzle) 12 | 13 | 14 | 15 | show_solutions = False # mostramos las soluciones? 16 | 17 | problems = [] 18 | load_problems(problems) 19 | 20 | total_time = 0 21 | total_cost = 0 22 | total_expansions = 0 23 | num_problems = 3 # len(problems) # cambiar si quieres ejecutar sobre todos los problemas 24 | 25 | 26 | print('prob\texp\tgenerated\t|sol|\ttiempo\n') 27 | 28 | for prob in range(0, num_problems): 29 | init = problems[prob] 30 | s = BrFS(init) # agregar un tercer parámetro una vez que lo hayas transformado en Weighted A* 31 | result = s.search() 32 | print('%5d%10d%10d%10d%10.2f' % (prob+1, s.expansions, len(s.generated), result.g, s.end_time-s.start_time )) 33 | total_time += s.end_time - s.start_time 34 | total_cost += result.g 35 | total_expansions += s.expansions 36 | 37 | if show_solutions: 38 | print(result.trace()) 39 | 40 | 41 | print('Tiempo total: %.2f'%(total_time)) 42 | print('Expansiones totales: %d'%(total_expansions)) 43 | print('Costo total: %d'%(total_cost)) 44 | -------------------------------------------------------------------------------- /2 Programacion Logica/1.swinb: -------------------------------------------------------------------------------- 1 |
2 | 3 |
4 | ### The SWISH hangout room 5 | 6 | You can add messages to this room from here or using the __Broadcast to hangout__ option from the __Send__ button on any other file. In the latter case the message is added to this room with a link to the files. 7 |
8 | 9 |
10 | % Hecho 11 | perro(fido). 12 | perro(firulais). 13 | perro(bob). 14 | 15 | gato(felix). 16 | 17 | padre(fido, firulais). 18 | padre(fido, bob). 19 | 20 | % Reglas 21 | %animal(_). %∀x animal(x) % no es correcto, todo es un animal 22 | 23 | animal(X):- perro(X) ; gato(X). %∀x perro(x) => animal(x) 24 | %animal(X):- gato(X). %∀x perro(x) => animal(x) 25 |
26 | 27 |
28 | perro(fido) 29 |
30 | 31 |
32 | padre(fido,X) 33 |
34 | 35 |
36 | animal(felix) 37 |
38 | 39 |
40 | # La ejecucicón de una consulta es la unificación sucesiva de la expresion de la consulta con cada linea del programa 41 |
42 | 43 |
44 | [A,B,C,D] = [1,2,3,4]. 45 |
46 | 47 |
48 | -------------------------------------------------------------------------------- /2 Programacion Logica/2.swinb: -------------------------------------------------------------------------------- 1 |
2 | 3 |
4 | :- dynamic numero/2. 5 | numero(1, "uno"). 6 | numero(2, "dos"). 7 | numero(3, "tres"). 8 | 9 | n(par) :- numero(2,_); numero(4,_). 10 | n(impar) :- numero(1,_);numero(3,_). 11 | 12 | preguntar_numeros :- 13 | write("Ingrese un numero"),nl, 14 | read(N), 15 | write("El numero ingresado es"),write(N), 16 | write("Ingrese el numero en palabras"), 17 | read(N2), 18 | write("En palabras es"), write(N2), 19 | retractall(numero(_,_)), 20 | asserta(numero(N, N2)), 21 | numero(5,P), 22 | write("Ingresado es: "),write(P), 23 | funcion2, 24 | n(PPP), 25 | write(PPP). 26 | 27 | funcion2 :- 28 | write("Es una nueva funcion"),nl,nl. 29 |
30 | 31 |
32 | preguntar_numeros. 33 |
34 | 35 |
36 | -------------------------------------------------------------------------------- /2 Programacion Logica/3.swinb: -------------------------------------------------------------------------------- 1 |
2 | 3 |
4 | :- dynamic numero/2. 5 | numero(1, uno). 6 | numero(2, dos). 7 | numero(3, tres). 8 | 9 | traductor:- 10 | write("ingrese un numero 1 2 o 3"), nl, 11 | read(Numero), 12 | numero(Numero,F), 13 | asserta(numero(10,"soy el 10")), 14 | numero(2,HH), 15 | nl,nl,write(HH),nl,nl, 16 | write(Numero),write(F), 17 | write("El numero traducido es"),nl, 18 | n(P), 19 | write(P). 20 | 21 | 22 | n(one) :- numero(1,_). 23 | n(two) :- numero(2,_). 24 | n(three):- numero(3,_). 25 |
26 | 27 |
28 | traductor. 29 |
30 | 31 |
32 | %:- dynamic numero/2. 33 | numero(1, uno). 34 | numero(2, dos). 35 | numero(3, tres). 36 | 37 | 38 | 39 | traductor2:- 40 | write("ingrese un numero 1 2 o 3"), nl, 41 | 42 | %numero(Numero,F), 43 | %retractall(numero(_,_)), 44 | read(Numero), 45 | numero(Numero,_), 46 | asserta(numero(Numero,_)), 47 | write("El numero traducido es"),nl, 48 | n(P), 49 | write(P). 50 | 51 | n(one) :- numero(1,_). 52 | n(two) :- numero(2,_). 53 | n(three):- numero(3,_). 54 |
55 | 56 |
57 | traductor2 58 |
59 | 60 |
61 | -------------------------------------------------------------------------------- /3 Machine Learning/1 regresion.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "nbformat": 4, 3 | "nbformat_minor": 0, 4 | "metadata": { 5 | "colab": { 6 | "provenance": [] 7 | }, 8 | "kernelspec": { 9 | "name": "python3", 10 | "display_name": "Python 3" 11 | }, 12 | "language_info": { 13 | "name": "python" 14 | } 15 | }, 16 | "cells": [ 17 | { 18 | "cell_type": "markdown", 19 | "source": [ 20 | "# shorturl.at/mqvyR" 21 | ], 22 | "metadata": { 23 | "id": "jLXrQemON4_Z" 24 | } 25 | }, 26 | { 27 | "cell_type": "code", 28 | "execution_count": null, 29 | "metadata": { 30 | "colab": { 31 | "base_uri": "https://localhost:8080/" 32 | }, 33 | "id": "KLtdTFJC_IQL", 34 | "outputId": "3a39d9b4-0995-49b6-88e6-5902b2affb6b" 35 | }, 36 | "outputs": [ 37 | { 38 | "output_type": "stream", 39 | "name": "stdout", 40 | "text": [ 41 | "El tamaño de los datos (569, 30)\n", 42 | "El tamaño de las etiquetas (569,)\n" 43 | ] 44 | } 45 | ], 46 | "source": [ 47 | "from sklearn.datasets import load_breast_cancer\n", 48 | "\n", 49 | "data = load_breast_cancer()\n", 50 | "\n", 51 | "print(\"El tamaño de los datos\", data.data.shape)\n", 52 | "print(\"El tamaño de las etiquetas\", data.target.shape)" 53 | ] 54 | }, 55 | { 56 | "cell_type": "code", 57 | "source": [ 58 | "from sklearn.model_selection import train_test_split\n", 59 | "\n", 60 | "x_train, x_test, y_train, y_test = train_test_split(data.data, data.target, test_size=0.25)\n", 61 | "\n", 62 | "print(\"Train size:\", x_train.shape)\n", 63 | "print(\"Test size:\", x_test.shape)\n", 64 | "print(\"Label train\", y_train.shape)\n", 65 | "print(\"Label test\", y_test.shape)" 66 | ], 67 | "metadata": { 68 | "colab": { 69 | "base_uri": "https://localhost:8080/" 70 | }, 71 | "id": "I2g4F8BaFHQk", 72 | "outputId": "ea9f2d1c-d3ae-4640-9f39-3f3c7b83932f" 73 | }, 74 | "execution_count": null, 75 | "outputs": [ 76 | { 77 | "output_type": "stream", 78 | "name": "stdout", 79 | "text": [ 80 | "Train size: (426, 30)\n", 81 | "Test size: (143, 30)\n", 82 | "Label train (426,)\n", 83 | "Label test (143,)\n" 84 | ] 85 | } 86 | ] 87 | }, 88 | { 89 | "cell_type": "code", 90 | "source": [ 91 | "from sklearn.linear_model import LogisticRegression\n", 92 | "\n", 93 | "classifier = LogisticRegression(max_iter = 5000)\n", 94 | "classifier.fit(x_train, y_train)" 95 | ], 96 | "metadata": { 97 | "colab": { 98 | "base_uri": "https://localhost:8080/" 99 | }, 100 | "id": "ava6C5XnG8-7", 101 | "outputId": "57de84b5-15e8-4554-89f4-d37fb2ca5943" 102 | }, 103 | "execution_count": null, 104 | "outputs": [ 105 | { 106 | "output_type": "execute_result", 107 | "data": { 108 | "text/plain": [ 109 | "LogisticRegression(max_iter=5000)" 110 | ] 111 | }, 112 | "metadata": {}, 113 | "execution_count": 52 114 | } 115 | ] 116 | }, 117 | { 118 | "cell_type": "code", 119 | "source": [ 120 | "predictions = classifier.predict(x_test)\n", 121 | "print(predictions)" 122 | ], 123 | "metadata": { 124 | "colab": { 125 | "base_uri": "https://localhost:8080/" 126 | }, 127 | "id": "QX8kyyTvHh-z", 128 | "outputId": "49ce7346-ed53-475b-a7b8-a43e1d30a7a6" 129 | }, 130 | "execution_count": null, 131 | "outputs": [ 132 | { 133 | "output_type": "stream", 134 | "name": "stdout", 135 | "text": [ 136 | "[1 1 0 1 1 1 1 0 0 1 1 0 1 1 1 1 0 0 1 0 0 1 1 0 1 0 0 0 0 0 1 1 1 0 1 0 1\n", 137 | " 1 1 0 1 0 0 0 1 1 0 1 1 0 1 1 0 0 0 1 1 1 1 1 1 1 0 0 1 1 0 1 1 1 1 0 1 1\n", 138 | " 1 1 0 1 1 1 1 0 1 1 1 0 0 1 1 0 1 1 1 0 0 1 1 1 1 1 1 0 0 0 1 1 1 0 0 0 0\n", 139 | " 1 1 1 1 1 1 1 0 0 0 1 0 1 0 1 1 1 0 0 1 1 0 0 0 1 1 1 0 1 1 1 1]\n" 140 | ] 141 | } 142 | ] 143 | }, 144 | { 145 | "cell_type": "code", 146 | "source": [ 147 | "# Para evaluar el modelo, utilizamos el accuracy (exactitud), es decir, el porcentaje\n", 148 | "# de veces que fue clasificado con la clase correcta.\n", 149 | "\n", 150 | "accuracy = classifier.score (x_test, y_test)\n", 151 | "print(accuracy)" 152 | ], 153 | "metadata": { 154 | "colab": { 155 | "base_uri": "https://localhost:8080/" 156 | }, 157 | "id": "jwce_gOdH2VS", 158 | "outputId": "0b2f11b7-f8a3-4b1a-a0fc-2481b7f4d94e" 159 | }, 160 | "execution_count": null, 161 | "outputs": [ 162 | { 163 | "output_type": "stream", 164 | "name": "stdout", 165 | "text": [ 166 | "0.972027972027972\n" 167 | ] 168 | } 169 | ] 170 | }, 171 | { 172 | "cell_type": "code", 173 | "source": [ 174 | "from sklearn import metrics\n", 175 | "\n", 176 | "cm = metrics.confusion_matrix(y_test, predictions)\n", 177 | "print(cm)\n", 178 | "#en 143 datos" 179 | ], 180 | "metadata": { 181 | "colab": { 182 | "base_uri": "https://localhost:8080/" 183 | }, 184 | "id": "LEx6a2uVLuiS", 185 | "outputId": "d28b2596-898d-4389-e16f-d0fb1066a76c" 186 | }, 187 | "execution_count": null, 188 | "outputs": [ 189 | { 190 | "output_type": "stream", 191 | "name": "stdout", 192 | "text": [ 193 | "[[53 3]\n", 194 | " [ 1 86]]\n" 195 | ] 196 | } 197 | ] 198 | }, 199 | { 200 | "cell_type": "markdown", 201 | "source": [ 202 | "#MNIST\n", 203 | "\n", 204 | "Construya un clasificador multiclase para el conjunto de datos MNIST" 205 | ], 206 | "metadata": { 207 | "id": "yEgsoE3lNCVy" 208 | } 209 | }, 210 | { 211 | "cell_type": "code", 212 | "source": [ 213 | "from sklearn.datasets import load_digits\n", 214 | "digits = load_digits()" 215 | ], 216 | "metadata": { 217 | "id": "J3AAyvRJNRUc" 218 | }, 219 | "execution_count": null, 220 | "outputs": [] 221 | }, 222 | { 223 | "cell_type": "code", 224 | "source": [ 225 | "import numpy as np \n", 226 | "import matplotlib.pyplot as plt\n", 227 | "plt.figure(figsize=(20,4))\n", 228 | "\n", 229 | "for index, (image, label) in enumerate(zip(digits.data[0:5], digits.target[0:5])):\n", 230 | " plt.subplot(1, 5, index + 1)\n", 231 | " plt.imshow(np.reshape(image, (8,8)), cmap=plt.cm.gray)\n", 232 | " plt.title('Training: %i\\n' % label, fontsize = 20)" 233 | ], 234 | "metadata": { 235 | "colab": { 236 | "base_uri": "https://localhost:8080/", 237 | "height": 258 238 | }, 239 | "id": "yCNDx0BZNdCb", 240 | "outputId": "10d3a65f-be64-47b8-d60f-8a6f8bb2a346" 241 | }, 242 | "execution_count": null, 243 | "outputs": [ 244 | { 245 | "output_type": "display_data", 246 | "data": { 247 | "text/plain": [ 248 | "
" 249 | ], 250 | "image/png": "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\n" 251 | }, 252 | "metadata": { 253 | "needs_background": "light" 254 | } 255 | } 256 | ] 257 | } 258 | ] 259 | } -------------------------------------------------------------------------------- /3 Machine Learning/3 clustering_Kmeans.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "nbformat": 4, 3 | "nbformat_minor": 0, 4 | "metadata": { 5 | "colab": { 6 | "provenance": [] 7 | }, 8 | "kernelspec": { 9 | "name": "python3", 10 | "display_name": "Python 3" 11 | }, 12 | "language_info": { 13 | "name": "python" 14 | } 15 | }, 16 | "cells": [ 17 | { 18 | "cell_type": "markdown", 19 | "source": [ 20 | "# shorturl.at/CXYZ4" 21 | ], 22 | "metadata": { 23 | "id": "uWUhSfng-w1Q" 24 | } 25 | }, 26 | { 27 | "cell_type": "code", 28 | "source": [ 29 | "import sys\n", 30 | "import sklearn\n", 31 | "import matplotlib\n", 32 | "import numpy as np" 33 | ], 34 | "metadata": { 35 | "id": "_GSrZpjPPFTy" 36 | }, 37 | "execution_count": null, 38 | "outputs": [] 39 | }, 40 | { 41 | "cell_type": "code", 42 | "source": [ 43 | "from keras.datasets import mnist\n", 44 | "\n", 45 | "(x_total, y_total), (_, _) = mnist.load_data()\n", 46 | "\n", 47 | "print('Training Data: {}'.format(x_total.shape))\n", 48 | "print('Training Labels: {}'.format(y_total.shape))" 49 | ], 50 | "metadata": { 51 | "colab": { 52 | "base_uri": "https://localhost:8080/" 53 | }, 54 | "id": "edtUY4C0PFOf", 55 | "outputId": "dec654a9-682c-4197-a741-49894b25f1bb" 56 | }, 57 | "execution_count": null, 58 | "outputs": [ 59 | { 60 | "output_type": "stream", 61 | "name": "stdout", 62 | "text": [ 63 | "Downloading data from https://storage.googleapis.com/tensorflow/tf-keras-datasets/mnist.npz\n", 64 | "11490434/11490434 [==============================] - 0s 0us/step\n", 65 | "Training Data: (60000, 28, 28)\n", 66 | "Training Labels: (60000,)\n" 67 | ] 68 | } 69 | ] 70 | }, 71 | { 72 | "cell_type": "code", 73 | "source": [ 74 | "import numpy as np\n", 75 | "from sklearn.model_selection import train_test_split\n", 76 | "#from sklearn.datasets import load_digits\n", 77 | "\n", 78 | "#digits = load_digits()\n", 79 | "\n", 80 | "x_train, x_restante, y_train, y_restante = train_test_split(x_total, y_total, test_size=0.35, random_state=1)\n", 81 | "x_test, x_valid, y_test, y_valid = train_test_split(x_restante, y_restante, test_size=0.4285, random_state=1)\n", 82 | "\n", 83 | "print(x_train.shape)\n", 84 | "print(x_test.shape)\n", 85 | "print(x_valid.shape)" 86 | ], 87 | "metadata": { 88 | "colab": { 89 | "base_uri": "https://localhost:8080/" 90 | }, 91 | "id": "3FfIjqRjRQCm", 92 | "outputId": "d693d5e1-a400-46b8-f75b-7acaa9c90a8e" 93 | }, 94 | "execution_count": null, 95 | "outputs": [ 96 | { 97 | "output_type": "stream", 98 | "name": "stdout", 99 | "text": [ 100 | "(39000, 28, 28)\n", 101 | "(12001, 28, 28)\n", 102 | "(8999, 28, 28)\n" 103 | ] 104 | } 105 | ] 106 | }, 107 | { 108 | "cell_type": "code", 109 | "source": [ 110 | "import matplotlib.pyplot as plt\n", 111 | "\n", 112 | "# python magic function\n", 113 | "%matplotlib inline" 114 | ], 115 | "metadata": { 116 | "id": "ceXJjXnCPFJL" 117 | }, 118 | "execution_count": null, 119 | "outputs": [] 120 | }, 121 | { 122 | "cell_type": "code", 123 | "source": [ 124 | "# create figure with 3x3 subplots using matplotlib.pyplot\n", 125 | "fig, axs = plt.subplots(3, 3, figsize = (12, 12))\n", 126 | "plt.gray()\n", 127 | "\n", 128 | "# loop through subplots and add mnist images\n", 129 | "for i, ax in enumerate(axs.flat):\n", 130 | " ax.imshow(x_train[i])\n", 131 | " ax.axis('off')\n", 132 | " ax.set_title('Number {}'.format(y_train[i]))\n", 133 | " \n", 134 | "# display the figure\n", 135 | "fig.show()\n" 136 | ], 137 | "metadata": { 138 | "colab": { 139 | "base_uri": "https://localhost:8080/", 140 | "height": 699 141 | }, 142 | "id": "txC8iqDSPFGe", 143 | "outputId": "59c03d44-72d4-4d92-b842-8b020a75ec23" 144 | }, 145 | "execution_count": null, 146 | "outputs": [ 147 | { 148 | "output_type": "display_data", 149 | "data": { 150 | "text/plain": [ 151 | "
" 152 | ], 153 | "image/png": "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qimmAABUQTEFAKAKiikAAFVQTAEAqMLY4V7AYG277bZpNm7cuI6u+cc//jHNHnnkkY6uCfQ4++yz02wkv/K+nS222GK4l/CyannlPd1vwoQJA57T7vtyN7zyvt1JBAsWLEizbn/lfSfcMQUAoAqKKQAAVVBMAQCogmIKAEAVFFMAAKqgmAIAUIWuPy6qnaZpOpp35513ptmsWbM6XQ4QEfPnzx/uJVRns802G+4lwGJz6KGHDvcSFpkTTjih5fghhxySzpk3b16abb311mn2v//7v/1fWBdxxxQAgCoopgAAVEExBQCgCoopAABVUEwBAKiCYgoAQBW6/rioO+64I83+9re/pdnYsfmHPnHixDR729ve1nL8lltuSefssssuabYolFLSrNMjtDrx2GOPpdnll1++2NZBXXbbbbc0O+mkk9LsueeeWxTLAfg/VlhhhTQ7/vjj02yfffYZ8PXaZcsss0yajVTumAIAUAXFFACAKiimAABUQTEFAKAKiikAAFVQTAEAqELXHxf105/+NM1uvvnmNNtmm23SbIsttkiziy66qOX4nDlz0jlrr712mi0KtRwXtWDBgjR74IEH0uy8885LsxNOOGFQa2LotPuanz9/fpptvfXWaXbIIYek2Wmnnda/hXWh9ddff0ivd+mllw7p9WAk2njjjdPsC1/4Qprtueeei2A1vMgdUwAAqqCYAgBQBcUUAIAqKKYAAFRBMQUAoAqKKQAAVSjtjg8qpSy+s4UWgcMOOyzNTj311MW4ksWrluOiOvX888+n2W9+85uW4295y1uGfB1N0+SfyErVsmePO+64NPvsZz/b0TWvvPLKNPvxj3+cZrfeemtHj9eJdnvv3HPPTbONNtpowI/1xBNPpNnrX//6NGt3VFu367Y9W8t+XRSWX375NPvFL36RZptvvnnL8aeeeiqdM2PGjP4vrI/NNtsszSZMmNDRNTtx7bXXptnuu++eZu2OZOwG2X51xxQAgCoopgAAVEExBQCgCoopAABVUEwBAKiCYgoAQBVG9HFRe+21V5qdd955abbkkksuiuW0dNttt6XZkUce2dE1x4zJf95YuHBhR9fsxIYbbphm06ZN6+iaTz75ZMvxlVZaqaPrtdNtR89E1LNnl1pqqTS78MIL06zd0Sjdrt0xaEsssUSaZfv54YcfTuesscYa/V/YCNJte7aW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mtVy/Nprrx3yx4KXeuyxx9Jsv/32W4wrWbxe//rXp9m+++6bZr/85S9bju+5557pnHnz5vV/YaOAO6YAAFRBMQUAoAqKKQAAVVBMAQCogmIKAEAVFFMAAKrguCiAAVhhhRXS7BOf+MSQP97s2bOH/JpAe1/72tfS7L777kuzU089teX4k08+Oeg1jRbumAIAUAXFFACAKiimAABUQTEFAKAKiikAAFXwqnyAATjllFPSbIsttujomjfccEOafeADH+jomkDEUkstlWYTJkxIs7lz56bZHXfckWaXXHJJ/xZGyh1TAACqoJgCAFAFxfgj4aQAABclSURBVBQAgCoopgAAVEExBQCgCoopAABV6Irjonbeeec0W3311Yf88e655540u/7664f88TpRSkmzMWMG/vNGu+vBaLPccsul2WabbTbkj3fCCSek2UMPPTTkjwejxate9ao0u/XWW9Psne98Z5otit7B/+OOKQAAVVBMAQCogmIKAEAVFFMAAKqgmAIAUAXFFACAKnTFcVEHHnhgmu2xxx5D/nhz5sxJs7vvvnvA1zvqqKPS7LHHHkuz7bffPs1e97rXpdnChQv7t7A+mqYZ8BwYqXbdddc023TTTTu65nPPPZdmTz/9dEfXBCJWW221NDvuuOPS7MQTT0yz6667Ls1eeOGFfq2LzrhjCgBAFRRTAACqoJgCAFAFxRQAgCoopgAAVEExBQCgCqXdMUGllCrOEJo0aVKa/elPfxryxxszJu/rnRzFVNM67r///pbj7373u9M5M2fO7Oixul3TNGW41zBQtezZbrD00kun2YwZM9Ks3VFt7fziF79Isx133LGja/L3um3P2q9D45Of/GSafeUrX0mzm2++Oc222267NGt39Bv9l+1Xd0wBAKiCYgoAQBUUUwAAqqCYAgBQBcUUAIAqKKYAAFRh7HAvoD9mzZqVZuuuu25H1zzwwAPTrN3RSeuvv35Hj1eLq666quX4aD0SitHrbW97W5p1eiTUvffem2YHHHBAR9cEIt7whjek2ec+97k0u/3229Os3TFtjoQaPu6YAgBQBcUUAIAqKKYAAFRBMQUAoAqKKQAAVVBMAQCoQmmaJg9LycMRrN0RVNttt92Ar3fiiSem2SqrrJJmY8bkPzd86UtfSrM//elPafbjH/+45fhf//rXdM5o1TRNGe41DNRo3bOd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\n" 154 | }, 155 | "metadata": { 156 | "needs_background": "light" 157 | } 158 | } 159 | ] 160 | }, 161 | { 162 | "cell_type": "code", 163 | "source": [ 164 | "# preprocessing the images\n", 165 | "\n", 166 | "# convert each image to 1 dimensional array\n", 167 | "X = x_train.reshape(len(x_train),-1)\n", 168 | "Y = y_train\n", 169 | "\n", 170 | "# normalize the data to 0 - 1\n", 171 | "X = X.astype(float) / 255.\n", 172 | "\n", 173 | "print(X.shape)\n", 174 | "print(X[0].shape)" 175 | ], 176 | "metadata": { 177 | "colab": { 178 | "base_uri": "https://localhost:8080/" 179 | }, 180 | "id": "EPwCPR5vQFOZ", 181 | "outputId": "520fbb0b-3288-4fed-8f5d-6051903bd742" 182 | }, 183 | "execution_count": null, 184 | "outputs": [ 185 | { 186 | "output_type": "stream", 187 | "name": "stdout", 188 | "text": [ 189 | "(39000, 784)\n", 190 | "(784,)\n" 191 | ] 192 | } 193 | ] 194 | }, 195 | { 196 | "cell_type": "code", 197 | "source": [ 198 | "X.shape" 199 | ], 200 | "metadata": { 201 | "id": "akRR_EDN1azv" 202 | }, 203 | "execution_count": null, 204 | "outputs": [] 205 | }, 206 | { 207 | "cell_type": "code", 208 | "source": [ 209 | "from sklearn.cluster import MiniBatchKMeans\n", 210 | "\n", 211 | "n_digits = len(np.unique(y_test))\n", 212 | "print(n_digits)\n", 213 | "\n", 214 | "# Initialize KMeans model\n", 215 | "kmeans = MiniBatchKMeans(n_clusters = 10, max_iter=100)\n", 216 | "\n", 217 | "# Fit the model to the training data\n", 218 | "kmeans.fit(X)" 219 | ], 220 | "metadata": { 221 | "colab": { 222 | "base_uri": "https://localhost:8080/" 223 | }, 224 | "id": "fbfytRGoQFLy", 225 | "outputId": "5f029181-f1ac-4c35-f738-0265884f32c4" 226 | }, 227 | "execution_count": null, 228 | "outputs": [ 229 | { 230 | "output_type": "stream", 231 | "name": "stdout", 232 | "text": [ 233 | "10\n" 234 | ] 235 | }, 236 | { 237 | "output_type": "execute_result", 238 | "data": { 239 | "text/plain": [ 240 | "MiniBatchKMeans(n_clusters=10)" 241 | ] 242 | }, 243 | "metadata": {}, 244 | "execution_count": 8 245 | } 246 | ] 247 | }, 248 | { 249 | "cell_type": "code", 250 | "source": [ 251 | "img 2 9 5 7 7\n", 252 | "clu 0 7 9 4 6" 253 | ], 254 | "metadata": { 255 | "id": "3LqCg6r6rR72" 256 | }, 257 | "execution_count": null, 258 | "outputs": [] 259 | }, 260 | { 261 | "cell_type": "code", 262 | "source": [ 263 | "print(kmeans.predict(X[293].reshape(1,-1) ))\n", 264 | "plt.imshow(X[293].reshape(28,28) )" 265 | ], 266 | "metadata": { 267 | "colab": { 268 | "base_uri": "https://localhost:8080/", 269 | "height": 300 270 | }, 271 | "id": "7m23hOAFp7lp", 272 | "outputId": "dc077b72-3a32-43af-aa58-a0c1270b3373" 273 | }, 274 | "execution_count": null, 275 | "outputs": [ 276 | { 277 | "output_type": "stream", 278 | "name": "stdout", 279 | "text": [ 280 | "[5]\n" 281 | ] 282 | }, 283 | { 284 | "output_type": "execute_result", 285 | "data": { 286 | "text/plain": [ 287 | "" 288 | ] 289 | }, 290 | "metadata": {}, 291 | "execution_count": 15 292 | }, 293 | { 294 | "output_type": "display_data", 295 | "data": { 296 | "text/plain": [ 297 | "
" 298 | ], 299 | "image/png": "iVBORw0KGgoAAAANSUhEUgAAAPsAAAD4CAYAAAAq5pAIAAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAALEgAACxIB0t1+/AAAADh0RVh0U29mdHdhcmUAbWF0cGxvdGxpYiB2ZXJzaW9uMy4yLjIsIGh0dHA6Ly9tYXRwbG90bGliLm9yZy+WH4yJAAANJUlEQVR4nO3db6hc9Z3H8c9nYyKaJho1hmDFpMUHltW1S5DFlcWltEThGotamsCaZYXbBwm0/mNjF21gCci6yT4QrdyiNCtZS1GLsYiNDWVdfVC8ihujbqsbE5pwTYhBcouQqPnugznpXpM7Z27OnDNnku/7BcPMnO+cc77MzSfnzDkz5+eIEIAz35+13QCAwSDsQBKEHUiCsANJEHYgibMGuTLbHPoHGhYRnm56X1t228tt/872+7bX9bMsAM1y1fPstmdJ+r2kb0raK+k1SSsj4p2SediyAw1rYst+jaT3I2JXRByV9DNJK/pYHoAG9RP2SyT9YcrzvcW0L7A9anvc9ngf6wLQp8YP0EXEmKQxid14oE39bNn3Sbp0yvMvF9MADKF+wv6apMttL7U9R9J3JW2tpy0Adau8Gx8Rn9leK+lXkmZJeiIi3q6tMwC1qnzqrdLK+MwONK6RL9UAOH0QdiAJwg4kQdiBJAg7kARhB5Ig7EAShB1IgrADSRB2IAnCDiRB2IEkCDuQxEAvJY3Tzw033FBa37RpU2n9yJEjXWtr164tnfeVV14prePUsGUHkiDsQBKEHUiCsANJEHYgCcIOJEHYgSS4uixKPfnkk6X1VatWVV724cOHS+sjIyOldc7DT4+rywLJEXYgCcIOJEHYgSQIO5AEYQeSIOxAEvyeHaUmJycbW/b8+fNL63fffXdpnfPsp6avsNveLWlS0ueSPouIZXU0BaB+dWzZ/zYiDtawHAAN4jM7kES/YQ9J22y/bnt0uhfYHrU9bnu8z3UB6EO/u/HXRcQ+2xdLesn2/0TEy1NfEBFjksYkfggDtKmvLXtE7CvuD0j6haRr6mgKQP0qh932XNvzjj+W9C1JO+tqDEC9Kv+e3fZX1NmaS52PA/8RERt6zMNu/Gnm/PPPL62vXLmytP7AAw90rV188cWVejru3HPPLa2XXbP+TNbt9+yVP7NHxC5Jf1G5IwADxak3IAnCDiRB2IEkCDuQBGEHkuBS0mjU+vXru9buv//+vpZ9++23l9a3bNnS1/JPV1xKGkiOsANJEHYgCcIOJEHYgSQIO5AEYQeS4FLSaI097engGXv11Vdr6iQHtuxAEoQdSIKwA0kQdiAJwg4kQdiBJAg7kATn2dGafq+lsHv37noaSYItO5AEYQeSIOxAEoQdSIKwA0kQdiAJwg4kwXl2NGpkZKTyvFu3bq2xE/Tcstt+wvYB2zunTLvA9ku23yvuFzTbJoB+zWQ3/qeSlp8wbZ2k7RFxuaTtxXMAQ6xn2CPiZUmHTpi8QtLm4vFmSTfX3BeAmlX9zL4oIiaKxx9KWtTthbZHJY1WXA+AmvR9gC4iomzAxogYkzQmMbAj0Kaqp972214sScX9gfpaAtCEqmHfKml18Xi1pOfqaQdAU3ruxtt+StL1ki6yvVfSjyQ9KOnntu+QtEfSd5psEsPrrLPK/wmdd955lZc9OTlZeV6crGfYI2Jll9I3au4FQIP4uiyQBGEHkiDsQBKEHUiCsANJ8BPXM8BVV13VtXbPPfeUznvhhReW1nsNq/zRRx+V1pcuXVpaL/PBBx9UnhcnY8sOJEHYgSQIO5AEYQeSIOxAEoQdSIKwA0lwnv00sG5d+fU877vvvq61efPm9bXuXufZ+xl2+ejRo6X1559/vvKycTK27EAShB1IgrADSRB2IAnCDiRB2IEkCDuQhPs5T3rKK2NEmGk99NBDpfU777yztN7rXHg/mjzPfujQiUMIftHChQsrLzuziJj2j8aWHUiCsANJEHYgCcIOJEHYgSQIO5AEYQeS4Dz7AMyfP7+0/vHHH5fWe/2Nyn4Xvm3bttJ5N27cWFq/6667SusjIyOl9TKcZ29G5fPstp+wfcD2zinT1tveZ/vN4nZjnc0CqN9MduN/Kmn5NNP/LSKuLm4v1NsWgLr1DHtEvCypfH8LwNDr5wDdWts7it38Bd1eZHvU9rjt8T7WBaBPVcP+Y0lflXS1pAlJXY/yRMRYRCyLiGUV1wWgBpXCHhH7I+LziDgm6SeSrqm3LQB1qxR224unPP22pJ3dXgtgOPS8brztpyRdL+ki23sl/UjS9bavlhSSdkv6XoM9nvZuueWWRpdfNgb7I4880tey16xZ09f8Zc4+++zS+mWXXVZa37NnT53tnPF6hj0iVk4z+fEGegHQIL4uCyRB2IEkCDuQBGEHkiDsQBIM2TwAt956a1/zHzx4sLT+9NNPV172kiVLSuu33XZbab2fn0jPnTu3tH7FFVeU1jn1dmrYsgNJEHYgCcIOJEHYgSQIO5AEYQeSIOxAEpxnH4CJiYnSeq9hkXft2lVa379//yn3dNyjjz5aWm9yOOherr322tL6iy++OKBOzgxs2YEkCDuQBGEHkiDsQBKEHUiCsANJEHYgCYZsHoDly6cbF/P/vfBC+biYn376aWl93bp1XWvLlpUPxNPrMtdz5swprTf576dsKGpJOueccxpb9+ms8pDNAM4MhB1IgrADSRB2IAnCDiRB2IEkCDuQBOfZh8CxY8dK64P8G53ok08+Ka1v2LChtL5+/fqutdmzZ1dp6U9mzZrV1/xnqsrn2W1favs3tt+x/bbt7xfTL7D9ku33ivsFdTcNoD4z2Y3/TNLdEfE1SX8laY3tr0laJ2l7RFwuaXvxHMCQ6hn2iJiIiDeKx5OS3pV0iaQVkjYXL9ss6eammgTQv1O6Bp3tJZK+Lum3khZFxPGLq30oaVGXeUYljVZvEUAdZnw03vaXJD0j6QcRcXhqLTpHkKY9ihQRYxGxLCLKf5EBoFEzCrvt2eoEfUtEPFtM3m97cVFfLOlAMy0CqEPP3Xh3riX8uKR3I2LTlNJWSaslPVjcP9dIhwns2LGjtH7llVc2tu4jR46U1u+9997S+mOPPVZaX7Cg+0maVatWlc67cePG0jpOzUw+s/+1pL+T9JbtN4tpP1Qn5D+3fYekPZK+00yLAOrQM+wR8YqkbiMFfKPedgA0ha/LAkkQdiAJwg4kQdiBJAg7kAQ/cR0CCxcuLK2PjY2V1m+66aautV7DGj/88MOldYZFPv1wKWkgOcIOJEHYgSQIO5AEYQeSIOxAEoQdSILz7MAZhvPsQHKEHUiCsANJEHYgCcIOJEHYgSQIO5AEYQeSIOxAEoQdSIKwA0kQdiAJwg4kQdiBJAg7kETPsNu+1PZvbL9j+23b3y+mr7e9z/abxe3G5tsFUFXPi1fYXixpcUS8YXuepNcl3azOeOx/jIh/nfHKuHgF0LhuF6+YyfjsE5ImiseTtt+VdEm97QFo2il9Zre9RNLXJf22mLTW9g7bT9he0GWeUdvjtsf76hRAX2Z8DTrbX5L0n5I2RMSzthdJOigpJP2zOrv6/9BjGezGAw3rths/o7Dbni3pl5J+FRGbpqkvkfTLiPjzHssh7EDDKl9w0rYlPS7p3alBLw7cHfdtSTv7bRJAc2ZyNP46Sf8l6S1Jx4rJP5S0UtLV6uzG75b0veJgXtmy2LIDDetrN74uhB1oHteNB5Ij7EAShB1IgrADSRB2IAnCDiRB2IEkCDuQBGEHkiDsQBKEHUiCsANJEHYgCcIOJNHzgpM1Oyhpz5TnFxXThtGw9jasfUn0VlWdvV3WrTDQ37OftHJ7PCKWtdZAiWHtbVj7kuitqkH1xm48kARhB5JoO+xjLa+/zLD2Nqx9SfRW1UB6a/UzO4DBaXvLDmBACDuQRCtht73c9u9sv297XRs9dGN7t+23imGoWx2frhhD74DtnVOmXWD7JdvvFffTjrHXUm9DMYx3yTDjrb53bQ9/PvDP7LZnSfq9pG9K2ivpNUkrI+KdgTbShe3dkpZFROtfwLD9N5L+KOnfjw+tZftfJB2KiAeL/ygXRMQ/Dklv63WKw3g31Fu3Ycb/Xi2+d3UOf15FG1v2ayS9HxG7IuKopJ9JWtFCH0MvIl6WdOiEySskbS4eb1bnH8vAdeltKETERES8UTyelHR8mPFW37uSvgaijbBfIukPU57v1XCN9x6Sttl+3fZo281MY9GUYbY+lLSozWam0XMY70E6YZjxoXnvqgx/3i8O0J3suoj4S0k3SFpT7K4Opeh8Bhumc6c/lvRVdcYAnJC0sc1mimHGn5H0g4g4PLXW5ns3TV8Ded/aCPs+SZdOef7lYtpQiIh9xf0BSb9Q52PHMNl/fATd4v5Ay/38SUTsj4jPI+KYpJ+oxfeuGGb8GUlbIuLZYnLr7910fQ3qfWsj7K9Jutz2UttzJH1X0tYW+jiJ7bnFgRPZnivpWxq+oai3SlpdPF4t6bkWe/mCYRnGu9sw42r5vWt9+POIGPhN0o3qHJH/X0n/1EYPXfr6iqT/Lm5vt92bpKfU2a37VJ1jG3dIulDSdknvSfq1pAuGqLcn1Rnae4c6wVrcUm/XqbOLvkPSm8Xtxrbfu5K+BvK+8XVZIAkO0AFJEHYgCcIOJEHYgSQIO5AEYQeSIOxAEv8HuAMws/IQEi8AAAAASUVORK5CYII=\n" 300 | }, 301 | "metadata": { 302 | "needs_background": "light" 303 | } 304 | } 305 | ] 306 | }, 307 | { 308 | "cell_type": "code", 309 | "source": [ 310 | "kmeans.__dict__" 311 | ], 312 | "metadata": { 313 | "id": "_tJB77gnxCRI" 314 | }, 315 | "execution_count": null, 316 | "outputs": [] 317 | }, 318 | { 319 | "cell_type": "code", 320 | "source": [ 321 | "print(kmeans.labels_)" 322 | ], 323 | "metadata": { 324 | "id": "LXXxWZCpQFJJ" 325 | }, 326 | "execution_count": null, 327 | "outputs": [] 328 | }, 329 | { 330 | "cell_type": "code", 331 | "source": [ 332 | "common_label = list()\n", 333 | "for i in range(10):\n", 334 | " common_label.append(np.zeros(10,dtype=int))\n", 335 | "\n", 336 | "print(common_label)" 337 | ], 338 | "metadata": { 339 | "id": "u3oQkXSK2mA9" 340 | }, 341 | "execution_count": null, 342 | "outputs": [] 343 | }, 344 | { 345 | "cell_type": "code", 346 | "source": [ 347 | "for data_img, data_label in zip(x_train, y_train):\n", 348 | " img = data_img.reshape(1,-1)/255\n", 349 | " res = kmeans.predict(img)\n", 350 | " #print(data_label, res)\n", 351 | " common_label[data_label][res] += 1" 352 | ], 353 | "metadata": { 354 | "id": "exhctaREzSPO" 355 | }, 356 | "execution_count": null, 357 | "outputs": [] 358 | }, 359 | { 360 | "cell_type": "code", 361 | "source": [ 362 | "common_label" 363 | ], 364 | "metadata": { 365 | "id": "rcjE7guxsJHX" 366 | }, 367 | "execution_count": null, 368 | "outputs": [] 369 | }, 370 | { 371 | "cell_type": "code", 372 | "source": [ 373 | "equivalencias = list()\n", 374 | "for i in range(10):\n", 375 | " equivalencias.append(common_label[i].argmax())" 376 | ], 377 | "metadata": { 378 | "id": "_QfJWNIq5Q_6" 379 | }, 380 | "execution_count": null, 381 | "outputs": [] 382 | }, 383 | { 384 | "cell_type": "code", 385 | "source": [ 386 | "equivalencias" 387 | ], 388 | "metadata": { 389 | "id": "3sP3uoF75wVV" 390 | }, 391 | "execution_count": null, 392 | "outputs": [] 393 | }, 394 | { 395 | "cell_type": "code", 396 | "source": [ 397 | "# test the infer_cluster_labels() and infer_data_labels() functions\n", 398 | "cluster_labels = infer_cluster_labels(kmeans, Y)\n", 399 | "X_clusters = kmeans.predict(X)\n", 400 | "predicted_labels = infer_data_labels(X_clusters, cluster_labels)\n", 401 | "print(predicted_labels[:20])\n", 402 | "print(Y[:20])" 403 | ], 404 | "metadata": { 405 | "id": "ueo5cjrYQFDq" 406 | }, 407 | "execution_count": null, 408 | "outputs": [] 409 | }, 410 | { 411 | "cell_type": "code", 412 | "source": [], 413 | "metadata": { 414 | "id": "hMsE4T5bQ54Y" 415 | }, 416 | "execution_count": null, 417 | "outputs": [] 418 | }, 419 | { 420 | "cell_type": "code", 421 | "source": [], 422 | "metadata": { 423 | "id": "BZt0DPpzQFAv" 424 | }, 425 | "execution_count": null, 426 | "outputs": [] 427 | }, 428 | { 429 | "cell_type": "code", 430 | "source": [], 431 | "metadata": { 432 | "id": "BDCy9TT6PFD6" 433 | }, 434 | "execution_count": null, 435 | "outputs": [] 436 | }, 437 | { 438 | "cell_type": "code", 439 | "source": [], 440 | "metadata": { 441 | "id": "eTAIOEhOPFBI" 442 | }, 443 | "execution_count": null, 444 | "outputs": [] 445 | }, 446 | { 447 | "cell_type": "markdown", 448 | "source": [ 449 | "# ejemplo de sklearn doc\n", 450 | "https://scikit-learn.org/stable/auto_examples/cluster/plot_kmeans_digits.html" 451 | ], 452 | "metadata": { 453 | "id": "od3oEarpPFvW" 454 | } 455 | }, 456 | { 457 | "cell_type": "code", 458 | "source": [], 459 | "metadata": { 460 | "id": "arpsIcc6PE4t" 461 | }, 462 | "execution_count": null, 463 | "outputs": [] 464 | }, 465 | { 466 | "cell_type": "code", 467 | "execution_count": null, 468 | "metadata": { 469 | "id": "nIqwjSbUAQUq" 470 | }, 471 | "outputs": [], 472 | "source": [ 473 | "import numpy as np\n", 474 | "from sklearn.datasets import load_digits\n", 475 | "\n", 476 | "data, labels = load_digits(return_X_y=True)\n", 477 | "(n_samples, n_features), n_digits = data.shape, np.unique(labels).size\n", 478 | "\n", 479 | "print(f\"# digits: {n_digits}; # samples: {n_samples}; # features {n_features}\")" 480 | ] 481 | }, 482 | { 483 | "cell_type": "code", 484 | "source": [ 485 | "from time import time\n", 486 | "from sklearn import metrics\n", 487 | "from sklearn.pipeline import make_pipeline\n", 488 | "from sklearn.preprocessing import StandardScaler\n", 489 | "\n", 490 | "\n", 491 | "def bench_k_means(kmeans, name, data, labels):\n", 492 | " \"\"\"Benchmark to evaluate the KMeans initialization methods.\n", 493 | "\n", 494 | " Parameters\n", 495 | " ----------\n", 496 | " kmeans : KMeans instance\n", 497 | " A :class:`~sklearn.cluster.KMeans` instance with the initialization\n", 498 | " already set.\n", 499 | " name : str\n", 500 | " Name given to the strategy. It will be used to show the results in a\n", 501 | " table.\n", 502 | " data : ndarray of shape (n_samples, n_features)\n", 503 | " The data to cluster.\n", 504 | " labels : ndarray of shape (n_samples,)\n", 505 | " The labels used to compute the clustering metrics which requires some\n", 506 | " supervision.\n", 507 | " \"\"\"\n", 508 | " t0 = time()\n", 509 | " estimator = make_pipeline(StandardScaler(), kmeans).fit(data)\n", 510 | " fit_time = time() - t0\n", 511 | " results = [name, fit_time, estimator[-1].inertia_]\n", 512 | "\n", 513 | " # Define the metrics which require only the true labels and estimator\n", 514 | " # labels\n", 515 | " clustering_metrics = [\n", 516 | " metrics.homogeneity_score,\n", 517 | " metrics.completeness_score,\n", 518 | " metrics.v_measure_score,\n", 519 | " metrics.adjusted_rand_score,\n", 520 | " metrics.adjusted_mutual_info_score,\n", 521 | " ]\n", 522 | " results += [m(labels, estimator[-1].labels_) for m in clustering_metrics]\n", 523 | "\n", 524 | " # The silhouette score requires the full dataset\n", 525 | " results += [\n", 526 | " metrics.silhouette_score(\n", 527 | " data,\n", 528 | " estimator[-1].labels_,\n", 529 | " metric=\"euclidean\",\n", 530 | " sample_size=300,\n", 531 | " )\n", 532 | " ]\n", 533 | "\n", 534 | " # Show the results\n", 535 | " formatter_result = (\n", 536 | " \"{:9s}\\t{:.3f}s\\t{:.0f}\\t{:.3f}\\t{:.3f}\\t{:.3f}\\t{:.3f}\\t{:.3f}\\t{:.3f}\"\n", 537 | " )\n", 538 | " print(formatter_result.format(*results))" 539 | ], 540 | "metadata": { 541 | "id": "r6c-iFivO4PE" 542 | }, 543 | "execution_count": null, 544 | "outputs": [] 545 | }, 546 | { 547 | "cell_type": "code", 548 | "source": [ 549 | "from sklearn.cluster import KMeans\n", 550 | "from sklearn.decomposition import PCA\n", 551 | "\n", 552 | "print(82 * \"_\")\n", 553 | "print(\"init\\t\\ttime\\tinertia\\thomo\\tcompl\\tv-meas\\tARI\\tAMI\\tsilhouette\")\n", 554 | "\n", 555 | "kmeans = KMeans(init=\"k-means++\", n_clusters=n_digits, n_init=4, random_state=0)\n", 556 | "bench_k_means(kmeans=kmeans, name=\"k-means++\", data=data, labels=labels)\n", 557 | "\n", 558 | "kmeans = KMeans(init=\"random\", n_clusters=n_digits, n_init=4, random_state=0)\n", 559 | "bench_k_means(kmeans=kmeans, name=\"random\", data=data, labels=labels)\n", 560 | "\n", 561 | "pca = PCA(n_components=n_digits).fit(data)\n", 562 | "kmeans = KMeans(init=pca.components_, n_clusters=n_digits, n_init=1)\n", 563 | "bench_k_means(kmeans=kmeans, name=\"PCA-based\", data=data, labels=labels)\n", 564 | "\n", 565 | "print(82 * \"_\")" 566 | ], 567 | "metadata": { 568 | "id": "CAUDrcr1O9sT" 569 | }, 570 | "execution_count": null, 571 | "outputs": [] 572 | }, 573 | { 574 | "cell_type": "code", 575 | "source": [ 576 | "import matplotlib.pyplot as plt\n", 577 | "\n", 578 | "reduced_data = PCA(n_components=2).fit_transform(data)\n", 579 | "kmeans = KMeans(init=\"k-means++\", n_clusters=n_digits, n_init=4)\n", 580 | "kmeans.fit(reduced_data)\n", 581 | "\n", 582 | "# Step size of the mesh. Decrease to increase the quality of the VQ.\n", 583 | "h = 0.02 # point in the mesh [x_min, x_max]x[y_min, y_max].\n", 584 | "\n", 585 | "# Plot the decision boundary. For that, we will assign a color to each\n", 586 | "x_min, x_max = reduced_data[:, 0].min() - 1, reduced_data[:, 0].max() + 1\n", 587 | "y_min, y_max = reduced_data[:, 1].min() - 1, reduced_data[:, 1].max() + 1\n", 588 | "xx, yy = np.meshgrid(np.arange(x_min, x_max, h), np.arange(y_min, y_max, h))\n", 589 | "\n", 590 | "# Obtain labels for each point in mesh. Use last trained model.\n", 591 | "Z = kmeans.predict(np.c_[xx.ravel(), yy.ravel()])\n", 592 | "\n", 593 | "# Put the result into a color plot\n", 594 | "Z = Z.reshape(xx.shape)\n", 595 | "plt.figure(1)\n", 596 | "plt.clf()\n", 597 | "plt.imshow(\n", 598 | " Z,\n", 599 | " interpolation=\"nearest\",\n", 600 | " extent=(xx.min(), xx.max(), yy.min(), yy.max()),\n", 601 | " cmap=plt.cm.Paired,\n", 602 | " aspect=\"auto\",\n", 603 | " origin=\"lower\",\n", 604 | ")\n", 605 | "\n", 606 | "plt.plot(reduced_data[:, 0], reduced_data[:, 1], \"k.\", markersize=2)\n", 607 | "# Plot the centroids as a white X\n", 608 | "centroids = kmeans.cluster_centers_\n", 609 | "plt.scatter(\n", 610 | " centroids[:, 0],\n", 611 | " centroids[:, 1],\n", 612 | " marker=\"x\",\n", 613 | " s=169,\n", 614 | " linewidths=3,\n", 615 | " color=\"w\",\n", 616 | " zorder=10,\n", 617 | ")\n", 618 | "plt.title(\n", 619 | " \"K-means clustering on the digits dataset (PCA-reduced data)\\n\"\n", 620 | " \"Centroids are marked with white cross\"\n", 621 | ")\n", 622 | "plt.xlim(x_min, x_max)\n", 623 | "plt.ylim(y_min, y_max)\n", 624 | "plt.xticks(())\n", 625 | "plt.yticks(())\n", 626 | "plt.show()\n" 627 | ], 628 | "metadata": { 629 | "id": "1LRQamlVPA8G" 630 | }, 631 | "execution_count": null, 632 | "outputs": [] 633 | } 634 | ] 635 | } -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # IntroAI --------------------------------------------------------------------------------