diff --git "a/Introducci\303\263n a Numpy y Matplotlib.ipynb" "b/Introducci\303\263n a Numpy y Matplotlib.ipynb"
new file mode 100644
index 0000000..c3a28ca
--- /dev/null
+++ "b/Introducci\303\263n a Numpy y Matplotlib.ipynb"
@@ -0,0 +1,1110 @@
+{
+ "cells": [
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "view-in-github",
+ "colab_type": "text"
+ },
+ "source": [
+ "
"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "frWQrOuEu5bz"
+ },
+ "source": [
+ "# Introducción a Numpy y Matplotlib\n",
+ "\n",
+ "**Curso Inteligencia Artificial 2025-1**"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "KDfRuLlwu5b0"
+ },
+ "source": [
+ "## Inicialización de una libreta"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "bEa-pBU4u5b1"
+ },
+ "source": [
+ "Vamos a introducir Numpy y Matplotlib, librerías para matemáticas y graficación, desde una libreta tipo *Jupyter*. Esta la puedes descargar y ejecutar en tu propia computadora, usando un editor de texto como VSCode, o inicializando Jupyter en linea de comando. Una opción muy popular es ejecutar la libreta en [Colaboratory](https://colab.google) de Google (que te permite ejecutar libretas en linea si cuantas con una cuenta de *Google*). Para ejecutar esta libreta en particular, lo puedes hacer [desde este enlace](https://colab.research.google.com/github/IA-UNISON/3-Aprendizaje/blob/main/Introducción%20a%20Numpy%20y%20Matplotlib.ipynb).\n",
+ "\n",
+ "Para inicializar la libreta y poderla utilizar con `numpy` y `matplotlib`, y asegurarse que los gráficos se presenten donde deben de estar es necesario ejecutar las siguientes instrucciones:"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 2,
+ "metadata": {
+ "id": "3shHq-Mmu5b1"
+ },
+ "outputs": [],
+ "source": [
+ "import numpy as np\n",
+ "import matplotlib.pyplot as plt\n",
+ "import random\n",
+ "\n",
+ "# Para insertar las gráficas dentro del entorno\n",
+ "%matplotlib inline"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "KbUaDcUlu5b1"
+ },
+ "source": [
+ "Recuerda que hay que ejecutar cada celda (cell) con *ctrl-enter* o con el simbolo de la flechita arriba de la libreta.\n",
+ "\n",
+ "La linea que empieza con `%` es un tipo de comando conocidos como *comandos mágicos*. En este comando le especificamos a la libreta que vamos a utilizar matplotlib para hacer gráficas y que queremos que las anexe dentro del documento. Existen muchos comandos mágicos, algunos muy útiles que vamos a ir viendo sobre la marcha. Para una explicacion completa está [esta libreta](http://nbviewer.ipython.org/github/ipython/ipython/blob/1.x/examples/notebooks/Cell%20Magics.ipynb).\n"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "SzR1VJYNu5b2"
+ },
+ "source": [
+ "En Jupyter existen varias funciones que se llaman *mágicas* las cuales empiezan siempre con %. La más común es `%matplotlib inline` para realizar gráficas dentro de la libreta y no que las genere en forma independiente. Otras muy usadas son %time Para calcular el tiempo que tarda en ejecitarse una celda, y %prun para hacer profile de la celda.\n",
+ "\n",
+ "Por ejemplo"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "metadata": {
+ "id": "W9PPGE9Wu5b2"
+ },
+ "outputs": [],
+ "source": [
+ "%time sum([x for x in range(100000)])"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "metadata": {
+ "id": "olPKszA0u5b2"
+ },
+ "outputs": [],
+ "source": [
+ "%prun sum([x for x in range(100000)])"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "G-xDfPKOu5b2"
+ },
+ "source": [
+ "En general los comandos mágicos se pueden consultar con otro comando mágico"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "metadata": {
+ "collapsed": true,
+ "id": "J_fAn5wfu5b3"
+ },
+ "outputs": [],
+ "source": [
+ "%quickref"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "4_wRjFYKu5b3"
+ },
+ "source": [
+ "## Inicializando variables en Numpy"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "F7BXwj-6u5b3"
+ },
+ "source": [
+ "Numpy agrega a python básicamente dos nuevos tipos o clases, de los cuales solo nos vamos a interesar por los arreglos multidimensionales o `ndarray`. La manera más sencilla de crear un array (vector o matriz) es utilizando `array` como:"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "metadata": {
+ "colab": {
+ "base_uri": "https://localhost:8080/"
+ },
+ "id": "eL-cK4CLu5b3",
+ "outputId": "1432750d-37cf-4242-bd8b-0ba5fbcd0033"
+ },
+ "outputs": [
+ {
+ "output_type": "stream",
+ "name": "stdout",
+ "text": [
+ "vector a = [ 1. 3.1416 40. 0. 2. 5. ]\n",
+ "matriz A = [[1 2]\n",
+ " [3 4]\n",
+ " [5 6]]\n"
+ ]
+ }
+ ],
+ "source": [
+ "# Crea un objeto vector\n",
+ "vector_a = np.array([1, 3.1416, 40, 0, 2, 5])\n",
+ "print(f\"vector a = {vector_a}\")\n",
+ "\n",
+ "# Crea una matriz\n",
+ "matriz_A = np.array([[1, 2], [3, 4], [5, 6]])\n",
+ "print(f\"matriz A = {matriz_A}\")"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "kc0CDsnDu5b4"
+ },
+ "source": [
+ "Esta es la manera más directa pero no la única (y en muchos casos la mas usada) para crear nuevos vectores multidimensionales. Existen otras maneras de generar arreglos como son las funciones:\n",
+ "\n",
+ "* `arange(ini=0, fin, inc=1)`: Devuelve un ndarray iniciando en `ini` y terminando en `fin`, con incrementos de inc\n",
+ "\n",
+ "* `zeros(dim)`: Devuelve un ndarray de dimensión `dim` (si es un escalar se considera un vector, si es una tupla de números entonces son las dimensiones del ndarray), con todas sus entradas en cero.\n",
+ " \n",
+ "* `ones(dim)`: Similar a `zeros()` pero con unos.\n",
+ " \n",
+ "* `eye(x, y=none)`: si solo se tiene el argumento `x` devuelve una matriz identidad de $x \\times x$. Si se encuentra `y`, entonces una matriz diagonal rectangular de dimensión x por y.\n",
+ " \n",
+ "* `zeros_like( x )`: Un ndarray de ceros de la misma dimensión que `x` (igual existe `ones_like`).\n",
+ " \n",
+ "* `linspace(inicial, final, elementos)`: Devuelve un ndarray de una dimensión iniciando en inicial, hasta final de\n",
+ "manera que existan elementos numeros igualmente espaciados. Muy útil para graficación principalmente.\n",
+ " \n",
+ "* `random.rand(dim1, dim2, ...)`: Devuelve un ndarray de dimensiones `dim1` por `dim2` por ... con números aleatorios\n",
+ "generados por una distribución uniforme entre 0 y 1.\n",
+ " \n",
+ "Veamos unos cuantos ejemplos:"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "metadata": {
+ "id": "z8EY2Jweu5b4"
+ },
+ "outputs": [],
+ "source": [
+ "vZ = np.zeros(5)\n",
+ "print(f\"Un vector de ceros con 5 valores \\n {vZ}\")"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "metadata": {
+ "id": "EDqYnU6Ru5b4"
+ },
+ "outputs": [],
+ "source": [
+ "mO = np.ones((3, 10))\n",
+ "print(f\"Una matriz de 3 x 10 de puron unos, \\n {mO}\")"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "metadata": {
+ "id": "P0il5wZ-u5b4"
+ },
+ "outputs": [],
+ "source": [
+ "va = np.arange(10)\n",
+ "print(f\"va = \\n {va}\")"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "metadata": {
+ "id": "oUcKESulu5b4"
+ },
+ "outputs": [],
+ "source": [
+ "vb = np.arange(20, -10, -5)\n",
+ "print(f\"vb = \\n {vb}\")"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "metadata": {
+ "id": "pk-m8sqmu5b4"
+ },
+ "outputs": [],
+ "source": [
+ "print(\"Y una matriz de ceros de las dimensiones de mO:\")\n",
+ "print(np.zeros_like(mO))"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "metadata": {
+ "id": "5QS-Scn_u5b4"
+ },
+ "outputs": [],
+ "source": [
+ "mA = np.random.rand(5, 12)\n",
+ "print(\"Y una matriz con números aleatorios bajo una distribución uniforme entre 0 y 1\")\n",
+ "print(mA)"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "KRQXmUGnu5b5"
+ },
+ "source": [
+ "### Primer problema a resolver :"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "otgxjRxau5b5"
+ },
+ "source": [
+ "En la siguiente celda (o puedes crear las que consideres convenientes) crea las siguientes matrices:\n",
+ "\n",
+ "* Una matriz de 4 por 6 con valores aleatorios de acuerdo a una distribución normal con media cero y varianza unitaria.\n",
+ " \n",
+ "* Un vector de 10 elementos con valores aleatorios de números enteros entre 4 y 100\n",
+ " \n",
+ "* Una matriz diagonal de 5 por 5 cuyos elementos de la diagonal sean (1, 2, 3, 4, 5)"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "metadata": {
+ "id": "J9FQiXZ7u5b5"
+ },
+ "outputs": [],
+ "source": [
+ "# 1)\n",
+ "a = [[random.randint(0, 9) for _ in range(4)] for _ in range(6)]\n",
+ "\n",
+ "# 2)\n",
+ "b = [random.randint(4, 100) for _ in range(10)]\n",
+ "\n",
+ "# 3)\n",
+ "c = np.diag([1, 2, 3, 4, 5])\n",
+ "\n",
+ "#Recuerda probar con el autocompletado de las celdas, así como la documentación en linea"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "source": [
+ "# Imprimir 1.1.\n",
+ "for fila in a:\n",
+ " print(fila)"
+ ],
+ "metadata": {
+ "colab": {
+ "base_uri": "https://localhost:8080/"
+ },
+ "id": "kL8jZUX0yWSM",
+ "outputId": "3729eed7-ece4-4ed2-a6a2-63d830712d8f"
+ },
+ "execution_count": null,
+ "outputs": [
+ {
+ "output_type": "stream",
+ "name": "stdout",
+ "text": [
+ "[9, 4, 9, 3]\n",
+ "[3, 9, 7, 9]\n",
+ "[0, 2, 8, 8]\n",
+ "[0, 8, 6, 6]\n",
+ "[7, 0, 7, 4]\n",
+ "[2, 9, 3, 9]\n"
+ ]
+ }
+ ]
+ },
+ {
+ "cell_type": "code",
+ "source": [
+ "print(b)"
+ ],
+ "metadata": {
+ "colab": {
+ "base_uri": "https://localhost:8080/"
+ },
+ "id": "ifaHJ_TTy7cH",
+ "outputId": "03b73bb6-bea9-437b-b4c9-96e661cfa0d7"
+ },
+ "execution_count": null,
+ "outputs": [
+ {
+ "output_type": "stream",
+ "name": "stdout",
+ "text": [
+ "[12, 31, 35, 18, 26, 36, 12, 69, 78, 48]\n"
+ ]
+ }
+ ]
+ },
+ {
+ "cell_type": "code",
+ "source": [
+ "print(c)"
+ ],
+ "metadata": {
+ "colab": {
+ "base_uri": "https://localhost:8080/"
+ },
+ "id": "lDHCVtGBy8nF",
+ "outputId": "73a1f38b-4d0d-4073-810d-600b893042b9"
+ },
+ "execution_count": null,
+ "outputs": [
+ {
+ "output_type": "stream",
+ "name": "stdout",
+ "text": [
+ "[[1 0 0 0 0]\n",
+ " [0 2 0 0 0]\n",
+ " [0 0 3 0 0]\n",
+ " [0 0 0 4 0]\n",
+ " [0 0 0 0 5]]\n"
+ ]
+ }
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "IGM4XASIu5b5"
+ },
+ "source": [
+ "## Operaciones básicas de los ndarray"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "NO4QjnQKu5b5"
+ },
+ "source": [
+ "La mayoría de las operaciones que se pueden aplicar en los ndarray se encuenran en el espacio de nombres de np, y las cuales son bastante directas tal como:\n",
+ "\n",
+ " b = np.sin(a)\n",
+ "\n",
+ "la cual devuelve en b un ndarray de las mismas dimensiones que a, cuyas entradas son el seno de las entradas de a (en radianes).\n",
+ "Así, parece inecesario explicar las funciones cos, tan, tanh, acos, asin, etc..\n",
+ "\n",
+ "Otras funciones muy útiles no son tan directas. Veamos algunas:\n",
+ "\n",
+ " c = a + b\n",
+ "\n",
+ "es la suma de dos ndarray, bastante obvio, lo que no lo es tanto es:\n",
+ "\n",
+ " c = a * b\n",
+ "\n",
+ "la cual es un ndarray resultante de la *multiplicación punto a punto* de los elementos de a y b, asumiendo que ambos tienen\n",
+ "las mismas diensiones. ¿Y para aplicar un producto matricial? Pues se utiliza el comando dot (o producto punto) el cual puede ser\n",
+ "expresado de tres formas:\n",
+ "\n",
+ " c = np.dot(a, b)\n",
+ " c = a.dot(b)\n",
+ " c = a @ b\n",
+ "\n",
+ "La suma de los elementos de un ndarray tambien es un método del objeto (como min, max, argmin, argmax, etc...) que tambien se pueden llamar de dos maneras diferentes (al menos):\n",
+ "\n",
+ " b = a.sum()\n",
+ " b = np.sum(a)\n",
+ "\n",
+ "es la suma de *todos los elementos del array* mientras que\n",
+ "\n",
+ " b = a.sum(axis=0)\n",
+ " b = np.sum(a, axis=0)\n",
+ "\n",
+ "es un ndarray con una dimensión menos que a, con la suma de las columnas. Veamos unos ejemplos:"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 3,
+ "metadata": {
+ "id": "MJ3VHXOeu5b5",
+ "colab": {
+ "base_uri": "https://localhost:8080/",
+ "height": 540
+ },
+ "outputId": "42a42152-bf81-4eaa-db02-a822150eb772"
+ },
+ "outputs": [
+ {
+ "output_type": "stream",
+ "name": "stdout",
+ "text": [
+ "a = [[1 2 3]\n",
+ " [4 5 6]]\n",
+ "b = [[0.93196622 0.1171058 0.39744099]\n",
+ " [0.88339038 0.19280126 0.51238716]]\n",
+ "Suma de todos los números de b = 3.0350918150394657\n",
+ "Media de cada columna de a = [2.5 3.5 4.5]\n",
+ "Transpuesta de a, forma larga \n",
+ " a.transpose()\n",
+ "Transpuesta de a, forma preferida \n",
+ " a.T\n",
+ "10 * b = [[9.31966218 1.17105795 3.97440994]\n",
+ " [8.83390384 1.92801263 5.1238716 ]]\n",
+ "a * b = [[0.93196622 0.23421159 1.19232298]\n",
+ " [3.53356154 0.96400632 3.07432296]]\n",
+ "2 elevado a la matriz a = [[ 2 4 8]\n",
+ " [16 32 64]]\n",
+ "a elevada al cuadrado (elemento a elemento)\n",
+ "[[ 1 4 9]\n",
+ " [16 25 36]]\n",
+ "a.dot(b.T) = [[2.35850079 2.80615439]\n",
+ " [6.69803982 7.57189081]]\n"
+ ]
+ },
+ {
+ "output_type": "error",
+ "ename": "ValueError",
+ "evalue": "shapes (2,3) and (2,3) not aligned: 3 (dim 1) != 2 (dim 0)",
+ "traceback": [
+ "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m",
+ "\u001b[0;31mValueError\u001b[0m Traceback (most recent call last)",
+ "\u001b[0;32m\u001b[0m in \u001b[0;36m\u001b[0;34m()\u001b[0m\n\u001b[1;32m 18\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 19\u001b[0m \u001b[0mprint\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34mf\"a.dot(b.T) = {a.dot(b.T)}\"\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m---> 20\u001b[0;31m \u001b[0mprint\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34mf\"a.dot(b) debería dar error {a.dot(b)}\"\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m",
+ "\u001b[0;31mValueError\u001b[0m: shapes (2,3) and (2,3) not aligned: 3 (dim 1) != 2 (dim 0)"
+ ]
+ }
+ ],
+ "source": [
+ "# Vamos a generar varios ndarrays\n",
+ "a = np.array([[1, 2, 3], [4, 5, 6]])\n",
+ "b = np.random.rand(2, 3)\n",
+ "\n",
+ "print(f\"a = {a}\")\n",
+ "print(f\"b = {b}\")\n",
+ "print(f\"Suma de todos los números de b = {b.sum()}\")\n",
+ "print(f\"Media de cada columna de a = {a.mean(axis=0)}\")\n",
+ "print(f\"Transpuesta de a, forma larga \\n a.transpose()\")\n",
+ "print(f\"Transpuesta de a, forma preferida \\n a.T\")\n",
+ "\n",
+ "print(f\"10 * b = {10 * b}\")\n",
+ "print(f\"a * b = {a * b}\")\n",
+ "\n",
+ "print(f\"2 elevado a la matriz a = {np.power(2, a)}\")\n",
+ "print(f\"a elevada al cuadrado (elemento a elemento)\")\n",
+ "print(np.power(a, 2))\n",
+ "\n",
+ "print(f\"a.dot(b.T) = {a.dot(b.T)}\")\n",
+ "print(f\"a.dot(b) debería dar error {a.dot(b)}\")"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "SbdAjabQu5b5"
+ },
+ "source": [
+ "Como vemos tenemos aqui una bateria completa de funciones, las cuales se aplican en un ndarray. ¿Pero que información tengo de un ndarray? ¿Como puedo componer un ndarray a partir de otros? Asumamos por ejemplo un ndarray de una dimensión:"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "metadata": {
+ "id": "x-7IEAExu5b5"
+ },
+ "outputs": [],
+ "source": [
+ "#Generamos el ndarray\n",
+ "a = np.arange(100)\n",
+ "\n",
+ "# Checamos algunas propiedades\n",
+ "print(f\"El número de dimensiones de a es: {a.ndim}\")\n",
+ "print(f\"Y su forma es {a.shape}\")\n",
+ "print(f\"Y tiene {a.size} elementos\")\n",
+ "\n",
+ "#Generamos algunos ndarrays a partir de a\n",
+ "b, c = a[:20], a[20:]\n",
+ "d, e = a[-1:-10:-1], a[10:11]\n",
+ "f = a[::-1]\n",
+ "g = a[a % 5 == 0]\n",
+ "h = f[[1, 15, 60]]\n",
+ "\n",
+ "# Ahora trata de inferir que es lo que debe contener cada array b, c, d, e, f, g, h sin hacer ninguna prueba.\n",
+ "\n",
+ "# Agrega ahora los print que consideres necesarios para verificar que valores tiene b, c, d, e, f, g, h"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "oQZ6xaVWu5b5"
+ },
+ "source": [
+ "A partir de una matriz (un ndarray de dos dimensiones) se pueden ejemplificar otras cosas, por ejemplo:"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "metadata": {
+ "id": "-PdL3POsu5b5"
+ },
+ "outputs": [],
+ "source": [
+ "#Generamos un arreglo con 100 valores equiespaciados del seno desde 0 a 2$\\pi$\n",
+ "a = np.sin(np.linspace(0, 2 * np.pi, 100))\n",
+ "\n",
+ "#Lo convertimos en una matriz de 10 por *lo que sea*, donde *lo que sea* es 10 en este caso,\n",
+ "b = a.reshape((10, -1))\n",
+ "print(\"b queda como: \",b)\n",
+ "print(f\"donde b tiene {b.ndim} dimensiones, con una forma {b.shape} y con {b.size} elementos.\")"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "metadata": {
+ "id": "IVaTCHZIu5b6"
+ },
+ "outputs": [],
+ "source": [
+ "#Si queremos convertir un ndarray a un array de una sola dimension (desenrrollar la matriz podría ser el término)\n",
+ "c = b.ravel()\n",
+ "\n",
+ "print(\"La diferencia de a y c sería\")\n",
+ "print((a - c).sum())"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "metadata": {
+ "id": "e9YICw3hu5b6"
+ },
+ "outputs": [],
+ "source": [
+ "# Si queremos hacer que un vector se comporte como un vector renglon\n",
+ "a = np.arange(30).reshape(1,-1)\n",
+ "print(f\"a es de forma {a.shape}\")\n",
+ "\n",
+ "# Y si queremos que sea un vector columna hacemos esto\n",
+ "b = np.linspace(30, 35, 30).reshape(-1,1)\n",
+ "print(f\"b es de forma {b.shape}\")\n",
+ "\n",
+ "# Y para hacer una concatenacion de columnas entonces utilizamps la forma especial np.c[]\n",
+ "c = np.c_[a.T, b]\n",
+ "print(f\"c es de forma {c.shape}\")\n",
+ "\n",
+ "#Y una concatenación de renglones es por lo tanto\n",
+ "d = np.r_[a, b.T]\n",
+ "print(f\"d es de forma {d.shape}\")"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "BA7it7lUu5b6"
+ },
+ "source": [
+ "### Segundo problema a resolver"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "trZHdjDhu5b6"
+ },
+ "source": [
+ "Realiza lo siguiente:\n",
+ "\n",
+ "* Genera una matriz de 100 por 5 de forma que en cada columna tengamos lo siguiente:\n",
+ " \n",
+ " - En la primer columna los valores entre -1 y 1, equiespaciados\n",
+ " - En la segunda columna el valor de seno para los valores de la primer columna\n",
+ " - En la tercer columna el valor de la función logística de los valores de la primer columna, la cual es $g(x) = \\frac{1}{1 + \\exp(-x)}$\n",
+ " - En la cuarta columna 1 si el valor de la segunda columna es mayor que cero y -1 en otro caso (revisa la función np.where)\n",
+ " - En la quinta columna valores aleatorios de acuerdo a una distribución gaussiana con media 1 y varianza 0.5\n",
+ " \n",
+ "* Encuentra un arreglo con todos los valores de la función logística, cuando el valor absoluto del seno de x es menor a 0.5\n",
+ " \n",
+ "* Convierte este arraglo en una matriz con 5 columnas y los renglones que sean necesarios.\n",
+ " "
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 6,
+ "metadata": {
+ "collapsed": true,
+ "id": "0wtyrw6_u5b6",
+ "colab": {
+ "base_uri": "https://localhost:8080/"
+ },
+ "outputId": "bf8666a8-48da-426c-c832-239ad193e7b4"
+ },
+ "outputs": [
+ {
+ "output_type": "stream",
+ "name": "stdout",
+ "text": [
+ "[[-1. -0.84147098 0.26894142 -1. 1.43398386]\n",
+ " [-0.97979798 -0.83038482 0.27293187 -1. 1.10960074]\n",
+ " [-0.95959596 -0.81895978 0.2769591 -1. 1.29053607]\n",
+ " [-0.93939394 -0.8072005 0.28102278 -1. 0.26511749]\n",
+ " [-0.91919192 -0.79511181 0.28512257 -1. 1.11054861]\n",
+ " [-0.8989899 -0.78269862 0.28925812 -1. 1.49345114]\n",
+ " [-0.87878788 -0.76996601 0.29342902 -1. 0.84931953]\n",
+ " [-0.85858586 -0.75691917 0.29763488 -1. 1.84263605]\n",
+ " [-0.83838384 -0.74356342 0.30187528 -1. 1.31253272]\n",
+ " [-0.81818182 -0.72990422 0.30614975 -1. 0.75413909]\n",
+ " [-0.7979798 -0.71594714 0.31045783 -1. 1.1459327 ]\n",
+ " [-0.77777778 -0.70169788 0.31479902 -1. 0.78420003]\n",
+ " [-0.75757576 -0.68716224 0.31917283 -1. 0.80757214]\n",
+ " [-0.73737374 -0.67234618 0.3235787 -1. 0.10171269]\n",
+ " [-0.71717172 -0.65725572 0.32801609 -1. 1.17623359]\n",
+ " [-0.6969697 -0.64189703 0.33248443 -1. 0.76908438]\n",
+ " [-0.67676768 -0.62627638 0.33698311 -1. 1.20194548]\n",
+ " [-0.65656566 -0.61040014 0.34151151 -1. 0.25947908]\n",
+ " [-0.63636364 -0.59427479 0.34606901 -1. 0.50712943]\n",
+ " [-0.61616162 -0.57790691 0.35065493 -1. 0.30805473]\n",
+ " [-0.5959596 -0.56130318 0.35526862 -1. 0.81230898]\n",
+ " [-0.57575758 -0.54447039 0.35990936 -1. 1.04842511]\n",
+ " [-0.55555556 -0.52741539 0.36457644 -1. 0.74708946]\n",
+ " [-0.53535354 -0.51014514 0.36926913 -1. 1.02087335]\n",
+ " [-0.51515152 -0.49266671 0.37398667 -1. 2.15475149]\n",
+ " [-0.49494949 -0.47498721 0.37872829 -1. 1.17154162]\n",
+ " [-0.47474747 -0.45711386 0.3834932 -1. 0.33183269]\n",
+ " [-0.45454545 -0.43905397 0.38828059 -1. -0.01596213]\n",
+ " [-0.43434343 -0.42081489 0.39308964 -1. 0.87240761]\n",
+ " [-0.41414141 -0.40240408 0.3979195 -1. 1.97370339]\n",
+ " [-0.39393939 -0.38382904 0.40276933 -1. 1.24946442]\n",
+ " [-0.37373737 -0.36509735 0.40763825 -1. 0.74409668]\n",
+ " [-0.35353535 -0.34621667 0.41252537 -1. 1.66999128]\n",
+ " [-0.33333333 -0.3271947 0.41742979 -1. 0.90228471]\n",
+ " [-0.31313131 -0.30803919 0.42235061 -1. 0.19138288]\n",
+ " [-0.29292929 -0.28875797 0.42728688 -1. 0.85085066]\n",
+ " [-0.27272727 -0.26935891 0.43223768 -1. 0.74277387]\n",
+ " [-0.25252525 -0.24984992 0.43720205 -1. 1.13881973]\n",
+ " [-0.23232323 -0.23023896 0.44217903 -1. 0.80138811]\n",
+ " [-0.21212121 -0.21053404 0.44716765 -1. 0.11903096]\n",
+ " [-0.19191919 -0.1907432 0.45216693 -1. 0.94451537]\n",
+ " [-0.17171717 -0.17087452 0.45717588 -1. 0.69423592]\n",
+ " [-0.15151515 -0.1509361 0.46219351 -1. 0.94773079]\n",
+ " [-0.13131313 -0.13093608 0.46721881 -1. 1.11747884]\n",
+ " [-0.11111111 -0.11088263 0.47225076 -1. 0.29288317]\n",
+ " [-0.09090909 -0.09078392 0.47728837 -1. 1.49883674]\n",
+ " [-0.07070707 -0.07064817 0.48233059 -1. 0.19394107]\n",
+ " [-0.05050505 -0.05048358 0.48737642 -1. 0.7914607 ]\n",
+ " [-0.03030303 -0.03029839 0.49242482 -1. 0.43661812]\n",
+ " [-0.01010101 -0.01010084 0.49747477 -1. 2.2237551 ]\n",
+ " [ 0.01010101 0.01010084 0.50252523 1. 1.73091518]\n",
+ " [ 0.03030303 0.03029839 0.50757518 1. 1.61137349]\n",
+ " [ 0.05050505 0.05048358 0.51262358 1. 0.61341465]\n",
+ " [ 0.07070707 0.07064817 0.51766941 1. 1.02521058]\n",
+ " [ 0.09090909 0.09078392 0.52271163 1. 0.64492015]\n",
+ " [ 0.11111111 0.11088263 0.52774924 1. 1.30349375]\n",
+ " [ 0.13131313 0.13093608 0.53278119 1. 0.54277661]\n",
+ " [ 0.15151515 0.1509361 0.53780649 1. 0.8537923 ]\n",
+ " [ 0.17171717 0.17087452 0.54282412 1. 0.67532121]\n",
+ " [ 0.19191919 0.1907432 0.54783307 1. 0.68436616]\n",
+ " [ 0.21212121 0.21053404 0.55283235 1. 1.56459827]\n",
+ " [ 0.23232323 0.23023896 0.55782097 1. 0.65389627]\n",
+ " [ 0.25252525 0.24984992 0.56279795 1. 0.45743574]\n",
+ " [ 0.27272727 0.26935891 0.56776232 1. 1.03401091]\n",
+ " [ 0.29292929 0.28875797 0.57271312 1. 0.97326399]\n",
+ " [ 0.31313131 0.30803919 0.57764939 1. 0.97843109]\n",
+ " [ 0.33333333 0.3271947 0.58257021 1. 0.82824127]\n",
+ " [ 0.35353535 0.34621667 0.58747463 1. 0.30752805]\n",
+ " [ 0.37373737 0.36509735 0.59236175 1. 0.49227885]\n",
+ " [ 0.39393939 0.38382904 0.59723067 1. 1.86753419]\n",
+ " [ 0.41414141 0.40240408 0.6020805 1. 0.80221374]\n",
+ " [ 0.43434343 0.42081489 0.60691036 1. 1.21221858]\n",
+ " [ 0.45454545 0.43905397 0.61171941 1. 0.39361959]\n",
+ " [ 0.47474747 0.45711386 0.6165068 1. 0.97676689]\n",
+ " [ 0.49494949 0.47498721 0.62127171 1. 0.94180217]\n",
+ " [ 0.51515152 0.49266671 0.62601333 1. 0.84362348]\n",
+ " [ 0.53535354 0.51014514 0.63073087 1. 0.44020363]\n",
+ " [ 0.55555556 0.52741539 0.63542356 1. 0.74662225]\n",
+ " [ 0.57575758 0.54447039 0.64009064 1. 0.27139223]\n",
+ " [ 0.5959596 0.56130318 0.64473138 1. 0.73111793]\n",
+ " [ 0.61616162 0.57790691 0.64934507 1. 1.03235483]\n",
+ " [ 0.63636364 0.59427479 0.65393099 1. 0.69062595]\n",
+ " [ 0.65656566 0.61040014 0.65848849 1. 0.77590386]\n",
+ " [ 0.67676768 0.62627638 0.66301689 1. 1.27010214]\n",
+ " [ 0.6969697 0.64189703 0.66751557 1. 0.64801934]\n",
+ " [ 0.71717172 0.65725572 0.67198391 1. 0.6423979 ]\n",
+ " [ 0.73737374 0.67234618 0.6764213 1. 0.12577142]\n",
+ " [ 0.75757576 0.68716224 0.68082717 1. 0.87598947]\n",
+ " [ 0.77777778 0.70169788 0.68520098 1. 1.08575358]\n",
+ " [ 0.7979798 0.71594714 0.68954217 1. 1.29447094]\n",
+ " [ 0.81818182 0.72990422 0.69385025 1. 1.05514667]\n",
+ " [ 0.83838384 0.74356342 0.69812472 1. 1.27240609]\n",
+ " [ 0.85858586 0.75691917 0.70236512 1. 0.84458684]\n",
+ " [ 0.87878788 0.76996601 0.70657098 1. 0.42258599]\n",
+ " [ 0.8989899 0.78269862 0.71074188 1. 0.53518801]\n",
+ " [ 0.91919192 0.79511181 0.71487743 1. 1.50128719]\n",
+ " [ 0.93939394 0.8072005 0.71897722 1. 0.71522486]\n",
+ " [ 0.95959596 0.81895978 0.7230409 1. 0.06112117]\n",
+ " [ 0.97979798 0.83038482 0.72706813 1. 1.17003692]\n",
+ " [ 1. 0.84147098 0.73105858 1. 1.11783232]]\n"
+ ]
+ }
+ ],
+ "source": [
+ "# 1)\n",
+ "a1 = np.linspace(-1, 1, 100)\n",
+ "b1 = np.sin(a1)\n",
+ "c1 = 1 / (1 + np.exp(-a1))\n",
+ "d1 = np.where(b1 > 0, 1, -1)\n",
+ "e1 = np.random.normal(1, 0.5, 100)\n",
+ "\n",
+ "a = np.c_[a1, b1, c1, d1, e1]\n",
+ "\n",
+ "# 2)\n",
+ "a2 = a[np.abs(a[:, 1]) < 0.5, 2]\n",
+ "b2 = a2.reshape(-1, 5)\n",
+ "\n",
+ "print(a)"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "qCOGN-tbu5b6"
+ },
+ "source": [
+ "Además de estas funciones, numpy cuenta con funciones del algebra lineal altamente optimizadas (aunque no paralelizadas), las cuales son (entre otras):\n",
+ "\n",
+ "* `np.linalg.inv(a)`: Inversa de a\n",
+ "* `np.linalg.pinv(a)`: Pseudoinversa de Ross-Penrose de a (muy útil para nosotros)\n",
+ "* `np.linalg.det(a)`: determinante de a\n",
+ "* `np.linalg.eig(a)`: eigenvalores y eigenvectores de a\n",
+ "* `np.linalg.svd(a)`: Valores singulares de a"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "_rDUW5Ntu5b6"
+ },
+ "source": [
+ "## Haciendo gráficas sencillas con Matplotlib"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "XHUSpDLVu5b6"
+ },
+ "source": [
+ "La mejor manera de mostrar como funcionan las facilidades que ofrece matplotlib, es mostrando directamente su uso más sencillo,\n",
+ "así que veamos un ejemplo muy simple. Es importante recordar que en la primer celda de esta libreta se definió la manera de realizar las gráficas (dentro del documento y no como figuras aparte), así como se cargo matplotlib en el espacio de nombres plt."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "metadata": {
+ "id": "-FRVcDOou5b6"
+ },
+ "outputs": [],
+ "source": [
+ "# Vamos a hacerlo pasito a pasito\n",
+ "\n",
+ "# Primero obtenemos un vector x\n",
+ "x = np.linspace(-np.pi, np.pi, 1000)\n",
+ "\n",
+ "# Luego obtenemos un vector y bastante trivial\n",
+ "y = np.sin(x)\n",
+ "\n",
+ "# Y ahora hacemos una gráfica bastante básica de x y y\n",
+ "plt.plot(x, y)\n",
+ "plt.xlabel(\"el eje de las x's\")\n",
+ "plt.ylabel(\"el eje de las y's\")\n",
+ "plt.title(\"Este es un plot bastante trivial y sin mucho chiste\")\n",
+ "\n",
+ "# Bueno como la gráfica no esta muy bien a lo mejor se ve mejor si modificamos los limites de los ejes\n",
+ "plt.axis([-3.1416, 3.1416, -1.1, 1.1])"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "gXUCitP1u5b-"
+ },
+ "source": [
+ "Aunque a veces queremos hacer unas gráficas más bien indicativas por lo que un estilo más informal podría ser útil:\n"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "metadata": {
+ "id": "X0vpHx3fu5b-"
+ },
+ "outputs": [],
+ "source": [
+ "with plt.xkcd():\n",
+ " plt.plot(x, y)\n",
+ " plt.xlabel(\"el eje de las x's\")\n",
+ " plt.ylabel(\"el eje de las y's\")\n",
+ " plt.title(\"Este es un plot bastante trivial y sin mucho chiste\")\n",
+ " plt.axis([-3.1416, 3.1416, -1.1, 1.1])"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "ewoiaTI3u5b-"
+ },
+ "source": [
+ "Hay que tener mucho cuidado, ya que si no se utiliza plt.xkcd() dentro de un with, entonces va a modificar todas las graficas que se realicen en la libreta (a veces es deseable, pero es una mejor práctica de programación hacerlo así)."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "metadata": {
+ "id": "G4O6TYvCu5b-"
+ },
+ "outputs": [],
+ "source": [
+ "with plt.style.context(('ggplot')):\n",
+ " plt.plot(x, y)\n",
+ " plt.xlabel(\"el eje de las x's\")\n",
+ " plt.ylabel(\"el eje de las y's\")\n",
+ " plt.title(\"Este es un plot bastante trivial y sin mucho chiste\")\n",
+ " plt.axis([-3.1416, 3.1416, -1.1, 1.1])"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "HaKh6D1iu5b-"
+ },
+ "source": [
+ "Ahora hagamos una gráfica con varios valores diferentes"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "metadata": {
+ "id": "hAgayTJAu5b_"
+ },
+ "outputs": [],
+ "source": [
+ "plt.plot(x, np.sin(x), label='seno')\n",
+ "\n",
+ "plt.plot(x, 1/(1 + np.exp(-x)), label=u\"logística\")\n",
+ "\n",
+ "plt.plot(x, (0.2 * x * x) - 0.5, label=r'$0.2 x^2 - 0.5$')\n",
+ "\n",
+ "plt.axis([-3.1416, 3.1416, -1.1, 1.4])\n",
+ "\n",
+ "plt.title(\"Tres funciones piteras juntas\")\n",
+ "plt.xlabel(r\"$\\theta$ (rad)\")\n",
+ "plt.ylabel(\"magnitud\")\n",
+ "\n",
+ "plt.legend(loc=0)"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "Mofwie-Vu5b_"
+ },
+ "source": [
+ "Hay muchos tipos de funciones, lo mejor para saber como ustilizar matplotlib es ver la galeria de ejemplo que se encuentran en la ayuda,\n",
+ "y pueden consultarse en http://matplotlib.org/gallery.html (al darle click a una imagen se puede ver el código que la genera).\n",
+ "\n",
+ "Por ejemplo si queremos una gráfica tipo pay:"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "metadata": {
+ "id": "St1CYZeiu5b_"
+ },
+ "outputs": [],
+ "source": [
+ "labels = 'Tortas', 'Taquitos', 'Burros', 'Ensaladas'\n",
+ "porcentajes = [15, 30, 45, 10]\n",
+ "colores = ['yellowgreen', 'gold', 'lightskyblue', 'lightcoral']\n",
+ "separa = (0, 0.1, 0, 0) # solo separa la segunda rebanada (i.e. 'Taquitos')\n",
+ "\n",
+ "plt.pie(\n",
+ " porcentajes, explode=separa, labels=labels, colors=colores,\n",
+ " autopct='%1.1f%%', shadow=True, startangle=90\n",
+ ")\n",
+ "plt.axis('equal') #Para que el pay se vea como un círculo\n",
+ "plt.xlabel(u'Lo que como cuando me quedo en la UNISON a mediodía')\n"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "t_k2UHcru5b_"
+ },
+ "source": [
+ "O si queremos una gráfica tipo contorno con todo y datos"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "metadata": {
+ "id": "xBwScPMau5b_"
+ },
+ "outputs": [],
+ "source": [
+ "import matplotlib.cm as cm\n",
+ "\n",
+ "delta = 0.025\n",
+ "x = np.arange(-3.0, 3.0, delta)\n",
+ "y = np.arange(-2.0, 2.0, delta)\n",
+ "X, Y = np.meshgrid(x, y)\n",
+ "Z1 = np.exp(-X**2 - Y**2)\n",
+ "Z2 = np.exp(-(X - 1)**2 - (Y - 1)**2)\n",
+ "Z = (Z1 - Z2) * 2\n",
+ "\n",
+ "CS = plt.contour(X, Y, Z)\n",
+ "plt.clabel(CS, fontsize=10)\n",
+ "plt.title('Grafica simple de contorno')\n",
+ "plt.show()"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "jBmUVXlMu5b_"
+ },
+ "source": [
+ "Por último, un detalle muy importante y que puede ser de mucha utilidad: La generación de subplots. Una figura puede contener varias subgraficas, para esto hay que especificar en cuantas gráficas vamos a dividir la figura en forma de renglones y columnas, y luego seleccionar la subgráfica en la que vamos a graficar. Por ejemplo\n",
+ "\n",
+ " plt.subplot(2,2,1)\n",
+ " \n",
+ "significa que la figura la vamos a dividir en 2 renglones y dos columnas (cuatro subgráficas) y vamos a escribir sobre la subgráfica 1. Lo mejor es ilustrarlo con un ejemplo muy simple."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "metadata": {
+ "id": "v2Jgaramu5b_"
+ },
+ "outputs": [],
+ "source": [
+ "x = np.linspace(0, 5, 1000)\n",
+ "y1 = np.exp(-0.2 * x) * np.cos(2 * np.pi * x)\n",
+ "y2 = np.cos(2 * np.pi * x)\n",
+ "y3 = np.exp(0.2 * x) * np.cos(2 * np.pi * x)\n",
+ "y4 = np.exp(-0.1 * x)\n",
+ "\n",
+ "plt.subplot(2, 2, 1)\n",
+ "plt.plot(x, y1)\n",
+ "plt.title('Estable subamortiguado')\n",
+ "\n",
+ "plt.subplot(2, 2, 2)\n",
+ "plt.plot(x, y2)\n",
+ "plt.title('Criticamente estable')\n",
+ "\n",
+ "plt.subplot(2, 2, 3)\n",
+ "plt.plot(x, y3)\n",
+ "plt.title('inestable')\n",
+ "\n",
+ "plt.subplot(2, 2, 4)\n",
+ "plt.plot(x, y4)\n",
+ "plt.title('Estable sobreamortiguado')\n",
+ "\n"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "1QpAfCNYu5cA"
+ },
+ "source": [
+ "### Ultimo trabajo"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "jqmfl5qyu5cA"
+ },
+ "source": [
+ "Realiza lo siguiente en varias celdas abajo de esta:\n",
+ "\n",
+ "* Genera un vector de 1000 datos aleatorios distribuidos de acuerdo a una gaussiana con media 3 y varianza .5, y otro vector con 1000 datos aleatorios distribuidos con una media 0 y una varianza unitaria. Al concatenar los dos vectores, estás generando una serie de datos proveniente de una distribución conocida como suma de gaussianas. Para ver como es esta distribución de datos, grafíca un histograma (con un número suficiente de bins).\n",
+ "\n",
+ "* Genera un vector de datos de entrada `x = np.linspace(0, 1, 1000)` y grafica $\\sin(2\\pi x)$, $\\sin(4\\pi x)$, $\\sin(8\\pi x)$. ¿Que conlusión puedes sacar al respecto? Realiza la gráfica con titulo, ejes, etiquetas y todo lo necesario para que sea publicable.\n",
+ "\n",
+ "* Grafíca la función $e^{-t}\\cos(2\\pi t)$ para $t \\in [0, 5]$. Asegurate que la gráfica sea una linea punteada de color rojo, que la gráfica tenga título, etiqueta en el eje de $t$ (tiempo), etiqueta en el eje de $y$ (voltaje en $\\mu$V), y una nota donde se escriba la ecuación simulada.\n",
+ "\n",
+ "* Copia el ejemplo de la galería de matplotlib http://matplotlib.org/examples/pylab_examples/shading_example.html y modificalo para que se grafique dentro de la libreta. Una vez funcionando, comenta *cada linea de código* dejando bien claro **en español y con tus palabras** que es lo que hace cada una de las lineas."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "metadata": {
+ "id": "lDFwWorLu5cA"
+ },
+ "outputs": [],
+ "source": [
+ "#Agrega aqui el primer problema y resualve cada problema en una celda independiente."
+ ]
+ }
+ ],
+ "metadata": {
+ "kernelspec": {
+ "display_name": "pandas",
+ "language": "python",
+ "name": "python3"
+ },
+ "language_info": {
+ "codemirror_mode": {
+ "name": "ipython",
+ "version": 3
+ },
+ "file_extension": ".py",
+ "mimetype": "text/x-python",
+ "name": "python",
+ "nbconvert_exporter": "python",
+ "pygments_lexer": "ipython3",
+ "version": "3.12.5"
+ },
+ "colab": {
+ "provenance": [],
+ "include_colab_link": true
+ }
+ },
+ "nbformat": 4,
+ "nbformat_minor": 0
+}
\ No newline at end of file
diff --git a/README.md b/README.md
index f29e96d..8910597 100644
--- a/README.md
+++ b/README.md
@@ -1,44 +1 @@
-
-# Desarrollo de entornos y agentes
-**Evaluación de competencias 1**
-
-## Desarrollo de entornos y agentes
-
-### Objetivo de la tarea
-
-Esta tarea tiene como objetivo revisar y dejar claro el desarrollo de las técnicas que se estudiarán en el curso como el desarrollo de programas de agentes racionales, y se revisará en forma superficial el desarrollo de agentes *reactivos* y *reactivos basados en modelo*, así como las peculiaridades de diferentes tipos de entornos.
-
-### Trabajo a realizar
-
-**Importante:** Todo el desarrollo que se realice para la tarea debe de ser incluido en el archivo `tarea_1.py`. Recuerda que los *commits* que hagas de tus avances son importantes para que como profesor pueda medir lo que vas haciendo.
-
-En esta tarea realiza las siguiente acciones:
-
-1. Desarrolla un entorno similar al de los dos cuartos (el cual se encuentra en el módulo `doscuartos_o.py` o el modulo `doscuartos_f.py`, como prefieras), pero con tres cuartos en el primer piso, tres cuartos en el segundo piso y tres cuartos en el tercer piso.
-
- El entorno se llamará `NueveCuartos`.
-
- Las acciones totales serán
-
- ```
- ["ir_Derecha", "ir_Izquierda", "subir", "bajar", "limpiar", "nada"]
- ```
-
- La acción de `"subir"` solo es legal en los primeros dos pisos, en los cuartos de la derecha, mientras que la acción de `"bajar"` solo es legal en los dos pisos de arriba de arriba y en el cuarto de la izquierda.
-
- Las acciones de subir y bajar son mas costosas en término de energía que ir a la derecha y a la izquierda, por lo que la función de desempeño debe de ser de tener limpios todos los cuartos, con el menor numero de acciones posibles, y minimizando subir y bajar en relación a ir a los lados. El costo de limpiar es menor a los costos de cualquier acción.
-
-2. Diseña un Agente reactivo basado en modelo para este entorno y compara su desempeño con un agente aleatorio después de 200 pasos de simulación.
-
-3. A este modelo de `NueveCuartos`, modifícalo de manera que el agente solo pueda saber en que cuarto se encuentra pero no sabe si está limpio o sucio. Utiliza la herencia entre clases para no escribir código redundante.
-
- A este nuevo entorno llámalo `NueveCuartosCiego`.
-
- Diseña un agente racional para este problema, pruébalo y compáralo con el agente aleatorio.
-
-4. Al modelo original de `NueveCuartos` modifícalo para que cuando el agente decida aspirar, el 80% de las veces limpie pero el 20% (aleatorio) deje sucio el cuarto. Igualmente, cuando el agente decida cambiar de cuarto, se cambie correctamente de cuarto el 80% de la veces, el 10% de la veces se queda en su lugar y el 10% de las veces realiza una acción legal aleatoria. Diseña un agente racional para este problema, pruébalo y compáralo con el agente aleatorio.
-
- A este entorno llámalo `NueveCuartosEstocástico`.
-
-**Todos los incisos tienen un valor de 25 puntos sobre la calificación de la tarea.**
-
+Repositorio de Francisco Javier Atondo Nubes para la clase de Inteligencia Artificial 2025-1
diff --git a/.DS_Store b/Tarea 1/.DS_Store
similarity index 100%
rename from .DS_Store
rename to Tarea 1/.DS_Store
diff --git a/.gitignore b/Tarea 1/.gitignore
similarity index 71%
rename from .gitignore
rename to Tarea 1/.gitignore
index 0c9092e..ccdcc0d 100644
--- a/.gitignore
+++ b/Tarea 1/.gitignore
@@ -3,4 +3,4 @@
.idea*
.idea/*
*.*~
-__pycache__/
\ No newline at end of file
+__pycache__/
diff --git a/.vscode/settings.json b/Tarea 1/.vscode/settings.json
similarity index 97%
rename from .vscode/settings.json
rename to Tarea 1/.vscode/settings.json
index 0d4d661..1462a9e 100644
--- a/.vscode/settings.json
+++ b/Tarea 1/.vscode/settings.json
@@ -1,3 +1,3 @@
{
"python.pythonPath": "/Users/juliowaissman/anaconda/bin/python"
-}
\ No newline at end of file
+}
diff --git a/Tarea 1/README.md b/Tarea 1/README.md
new file mode 100644
index 0000000..f29e96d
--- /dev/null
+++ b/Tarea 1/README.md
@@ -0,0 +1,44 @@
+
+# Desarrollo de entornos y agentes
+**Evaluación de competencias 1**
+
+## Desarrollo de entornos y agentes
+
+### Objetivo de la tarea
+
+Esta tarea tiene como objetivo revisar y dejar claro el desarrollo de las técnicas que se estudiarán en el curso como el desarrollo de programas de agentes racionales, y se revisará en forma superficial el desarrollo de agentes *reactivos* y *reactivos basados en modelo*, así como las peculiaridades de diferentes tipos de entornos.
+
+### Trabajo a realizar
+
+**Importante:** Todo el desarrollo que se realice para la tarea debe de ser incluido en el archivo `tarea_1.py`. Recuerda que los *commits* que hagas de tus avances son importantes para que como profesor pueda medir lo que vas haciendo.
+
+En esta tarea realiza las siguiente acciones:
+
+1. Desarrolla un entorno similar al de los dos cuartos (el cual se encuentra en el módulo `doscuartos_o.py` o el modulo `doscuartos_f.py`, como prefieras), pero con tres cuartos en el primer piso, tres cuartos en el segundo piso y tres cuartos en el tercer piso.
+
+ El entorno se llamará `NueveCuartos`.
+
+ Las acciones totales serán
+
+ ```
+ ["ir_Derecha", "ir_Izquierda", "subir", "bajar", "limpiar", "nada"]
+ ```
+
+ La acción de `"subir"` solo es legal en los primeros dos pisos, en los cuartos de la derecha, mientras que la acción de `"bajar"` solo es legal en los dos pisos de arriba de arriba y en el cuarto de la izquierda.
+
+ Las acciones de subir y bajar son mas costosas en término de energía que ir a la derecha y a la izquierda, por lo que la función de desempeño debe de ser de tener limpios todos los cuartos, con el menor numero de acciones posibles, y minimizando subir y bajar en relación a ir a los lados. El costo de limpiar es menor a los costos de cualquier acción.
+
+2. Diseña un Agente reactivo basado en modelo para este entorno y compara su desempeño con un agente aleatorio después de 200 pasos de simulación.
+
+3. A este modelo de `NueveCuartos`, modifícalo de manera que el agente solo pueda saber en que cuarto se encuentra pero no sabe si está limpio o sucio. Utiliza la herencia entre clases para no escribir código redundante.
+
+ A este nuevo entorno llámalo `NueveCuartosCiego`.
+
+ Diseña un agente racional para este problema, pruébalo y compáralo con el agente aleatorio.
+
+4. Al modelo original de `NueveCuartos` modifícalo para que cuando el agente decida aspirar, el 80% de las veces limpie pero el 20% (aleatorio) deje sucio el cuarto. Igualmente, cuando el agente decida cambiar de cuarto, se cambie correctamente de cuarto el 80% de la veces, el 10% de la veces se queda en su lugar y el 10% de las veces realiza una acción legal aleatoria. Diseña un agente racional para este problema, pruébalo y compáralo con el agente aleatorio.
+
+ A este entorno llámalo `NueveCuartosEstocástico`.
+
+**Todos los incisos tienen un valor de 25 puntos sobre la calificación de la tarea.**
+
diff --git a/doscuartos_f.py b/Tarea 1/doscuartos_f.py
similarity index 99%
rename from doscuartos_f.py
rename to Tarea 1/doscuartos_f.py
index 1e94298..c773f1d 100644
--- a/doscuartos_f.py
+++ b/Tarea 1/doscuartos_f.py
@@ -129,4 +129,4 @@ def test():
if __name__ == "__main__":
- test()
+ test()
\ No newline at end of file
diff --git a/doscuartos_o.py b/Tarea 1/doscuartos_o.py
similarity index 99%
rename from doscuartos_o.py
rename to Tarea 1/doscuartos_o.py
index faa9128..d3e8845 100644
--- a/doscuartos_o.py
+++ b/Tarea 1/doscuartos_o.py
@@ -188,4 +188,4 @@ def test():
if __name__ == "__main__":
- test()
+ test()
\ No newline at end of file
diff --git a/entornos_f.py b/Tarea 1/entornos_f.py
similarity index 99%
rename from entornos_f.py
rename to Tarea 1/entornos_f.py
index 1d29ebf..dc34ac2 100644
--- a/entornos_f.py
+++ b/Tarea 1/entornos_f.py
@@ -114,4 +114,3 @@ def imprime_simulacion(historial, s_0):
str(s_i).center(25) +
str(c_i).rjust(12))
print('_' * (10 + 40 + 25 + 15) + '\n\n')
-
diff --git a/entornos_o.py b/Tarea 1/entornos_o.py
similarity index 99%
rename from entornos_o.py
rename to Tarea 1/entornos_o.py
index 7345329..a1e1601 100644
--- a/entornos_o.py
+++ b/Tarea 1/entornos_o.py
@@ -122,4 +122,4 @@ def simulador(entorno, agente, pasos=10, verbose=True):
print('_' * (10 + 40 + 25 + 15) + '\n\n')
- return historial_estados, historial_acciones, historial_costo
+ return historial_estados, historial_acciones, historial_costo
\ No newline at end of file
diff --git a/ia.png b/Tarea 1/ia.png
similarity index 100%
rename from ia.png
rename to Tarea 1/ia.png
diff --git a/Tarea 1/tarea_1.py b/Tarea 1/tarea_1.py
new file mode 100755
index 0000000..7b5773c
--- /dev/null
+++ b/Tarea 1/tarea_1.py
@@ -0,0 +1,304 @@
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+"""
+tarea_1.py
+------------
+
+Revisa el archivo README.md con las instrucciones de la tarea.
+
+"""
+__author__ = 'escribe_tu_nombre'
+
+import entornos_f
+import entornos_o
+import random
+
+# Requiere el modulo entornos_f.py o entornos_o.py
+# Usa el modulo doscuartos_f.py para reutilizar código
+# Agrega los modulos que requieras de python
+
+# 1 - Definicion de NueveCuartos
+class NueveCuartos(entornos_o.Entorno):
+ """
+ Crea un entorno de nueve cuartos 3x3, osea:
+ A1|A2|A3
+ B1|B2|B3
+ C1|C2|C3
+
+ Metodo Orientado a Objetos
+ """
+ def __init__(self, x0=["A1", [["sucio", "sucio","sucio"], ["sucio", "sucio","sucio"], ["sucio", "sucio","sucio"]]]):
+ """
+ Por default inicialmente el robot está en A1 y todos los cuartos
+ están sucios.
+
+ """
+ super().__init__(x0)
+ self.costo = 0
+
+ def accion_legal(self, accion):
+ posicion, _ = self.x
+ piso, cuarto = posicion[0], int(posicion[1])
+
+ if accion == "subir":
+ return piso in "BC" and cuarto == 3
+ elif accion == "bajar":
+ return piso in "AB"
+ elif accion == "ir_Derecha":
+ return cuarto < 3
+ elif accion == "ir_Izquierda":
+ return cuarto > 1
+ elif accion in ("limpiar", "nada"):
+ return True
+ return False
+
+ def transicion(self, accion):
+ if not self.accion_legal(accion):
+ print(f"Acción ilegal: {accion}")
+ return "nada" # Si la acción no es legal, simplemente no hace nada
+ #raise ValueError(f"Acción '{accion}' no es legal en el estado actual.")
+
+ print(f"Estado actual: {self.x}, Acción: {accion}")
+ posicion, cuartos = self.x
+ piso, cuarto = posicion[0], int(posicion[1])
+
+ if accion == "limpiar":
+ cuartos["ABC".index(piso)][cuarto - 1] = "limpio"
+ self.costo += 1
+ elif accion == "ir_Derecha" and cuarto < 3:
+ self.x[0] = f"{piso}{cuarto + 1}"
+ self.costo += 2
+ elif accion == "ir_Izquierda" and cuarto > 1:
+ self.x[0] = f"{piso}{cuarto - 1}"
+ self.costo += 2
+ elif accion == "subir" and piso != "A":
+ self.x[0] = f"{chr(ord(piso) + 1)}{cuarto}"
+ self.costo += 3
+ elif accion == "bajar" and piso != "C":
+ self.x[0] = f"{chr(ord(piso) - 1)}{cuarto}"
+ self.costo += 3
+ elif accion == "nada":
+ pass
+
+ def percepcion(self):
+ posicion, cuartos = self.x
+ piso, cuarto = posicion[0], int(posicion[1])
+ if piso not in "ABC" or cuarto < 1 or cuarto > 3:
+ raise ValueError(f"Posición inválida: {posicion}. Estado: {self.x}")
+ return posicion, cuartos["ABC".index(piso)][cuarto - 1]
+
+# 2 - Agente Reactivo
+class AgenteReactivoNueveCuartos(entornos_o.Agente):
+ """
+ Agente reactivo para el entorno NueveCuartos.
+ """
+ def programa(self, percepcion):
+ posicion, estado_cuarto = percepcion
+ piso, cuarto = posicion[0], int(posicion[1]) # Dividimos la posición en piso y cuarto
+
+ if estado_cuarto == "sucio":
+ return "limpiar"
+ elif cuarto < 3: # Si no estamos en el último cuarto, ir a la derecha
+ #print(cuarto)
+ return "ir_Derecha"
+ elif cuarto == 1 and estado_cuarto == "limpio" and piso != "A": # Subir si estamos en el último cuarto de un piso y no estamos en C
+ return "subir"
+ elif cuarto == 3 and estado_cuarto == "limpio" and piso != "C": # Bajar si estamos en el primer cuarto de un piso y no estamos en A
+ return "bajar"
+ elif cuarto > 1: # Si no estamos en el primer cuarto, ir a la izquierda
+ return "ir_Izquierda"
+ else: # Si todo está limpio o no hay nada más que hacer, hacer nada
+ return "nada"
+
+
+
+
+class AgenteAleatorioNueveCuartos(entornos_o.Agente):
+ """
+ Agente Aleatorio para el entorno NueveCuartos.
+ """
+ def programa(self, percepcion):
+ posicion = percepcion
+ piso, cuarto = posicion[0], int(posicion[1])
+
+ num = random.randrange(6)
+
+ if num == 0:
+ return "limpiar"
+ elif num == 1 and cuarto < 3:
+ return "ir_Derecha"
+ elif num == 2 and piso != "A":
+ return "subir"
+ elif num == 3 and cuarto > 1:
+ return "ir_Izquierda"
+ elif num == 4 and piso != "C":
+ return "bajar"
+ elif num == 5:
+ return "nada"
+ else:
+ return "nada"
+
+# 3 - Nueve Cuartos Ciego
+class NueveCuartosCiego(NueveCuartos):
+ """
+ Funciona de forma identica a Nueve Cuartos, pero no verifica el estado de la habitacion.
+ """
+ def percepcion(self):
+ return []
+
+# 4 - Nueve Cuartos Estocastico
+class NueveCuartosEstocastico(NueveCuartos):
+
+ def transicion(self, accion):
+ if not self.accion_legal(accion):
+ print(f"Acción ilegal: {accion}")
+ return "nada" # Si la acción no es legal, simplemente no hace nada
+ #raise ValueError(f"Acción '{accion}' no es legal en el estado actual.")
+
+ print(f"Estado actual: {self.x}, Acción: {accion}")
+ posicion, cuartos = self.x
+ piso, cuarto = posicion[0], int(posicion[1])
+
+ num = random.randrange(10)
+
+ if accion == "limpiar":
+ if(num < 8):
+ cuartos["ABC".index(piso)][cuarto - 1] = "limpio"
+ self.costo += 1
+ else:
+ pass
+ elif accion == "ir_Derecha" and cuarto < 3:
+ if(num > 2):
+ self.x[0] = f"{piso}{cuarto + 1}"
+ self.costo += 2
+ elif(num == 1):
+ num = random.randrange(6)
+ if(num == 0):
+ cuartos["ABC".index(piso)][cuarto - 1] = "limpio"
+ self.costo += 1
+ elif(num == 1) == "ir_Derecha" and cuarto < 3:
+ self.x[0] = f"{piso}{cuarto + 1}"
+ self.costo += 2
+ elif(num == 2) == "ir_Izquierda" and cuarto > 1:
+ self.x[0] = f"{piso}{cuarto - 1}"
+ self.costo += 2
+ elif(num == 3) == "subir" and piso != "A":
+ self.x[0] = f"{chr(ord(piso) + 1)}{cuarto}"
+ self.costo += 3
+ elif(num == 4) == "bajar" and piso != "C":
+ self.x[0] = f"{chr(ord(piso) - 1)}{cuarto}"
+ self.costo += 3
+ elif(num == 5) == "nada":
+ pass
+ elif(num == 0):
+ pass
+
+
+ elif accion == "ir_Izquierda" and cuarto > 1:
+ if(num > 2):
+ self.x[0] = f"{piso}{cuarto - 1}"
+ self.costo += 2
+ elif(num == 1):
+ num = random.randrange(6)
+ if(num == 0):
+ cuartos["ABC".index(piso)][cuarto - 1] = "limpio"
+ self.costo += 1
+ elif(num == 1) == "ir_Derecha" and cuarto < 3:
+ self.x[0] = f"{piso}{cuarto + 1}"
+ self.costo += 2
+ elif(num == 2) == "ir_Izquierda" and cuarto > 1:
+ self.x[0] = f"{piso}{cuarto - 1}"
+ self.costo += 2
+ elif(num == 3) == "subir" and piso != "A":
+ self.x[0] = f"{chr(ord(piso) + 1)}{cuarto}"
+ self.costo += 3
+ elif(num == 4) == "bajar" and piso != "C":
+ self.x[0] = f"{chr(ord(piso) - 1)}{cuarto}"
+ self.costo += 3
+ elif(num == 5) == "nada":
+ pass
+ elif(num == 0):
+ pass
+ elif accion == "subir" and piso != "A":
+ if(num > 2):
+ self.x[0] = f"{chr(ord(piso) + 1)}{cuarto}"
+ self.costo += 3
+ elif(num == 1):
+ num = random.randrange(6)
+ if(num == 0):
+ cuartos["ABC".index(piso)][cuarto - 1] = "limpio"
+ self.costo += 1
+ elif(num == 1) == "ir_Derecha" and cuarto < 3:
+ self.x[0] = f"{piso}{cuarto + 1}"
+ self.costo += 2
+ elif(num == 2) == "ir_Izquierda" and cuarto > 1:
+ self.x[0] = f"{piso}{cuarto - 1}"
+ self.costo += 2
+ elif(num == 3) == "subir" and piso != "A":
+ self.x[0] = f"{chr(ord(piso) + 1)}{cuarto}"
+ self.costo += 3
+ elif(num == 4) == "bajar" and piso != "C":
+ self.x[0] = f"{chr(ord(piso) - 1)}{cuarto}"
+ self.costo += 3
+ elif(num == 5) == "nada":
+ pass
+ elif(num == 0):
+ pass
+ elif accion == "bajar" and piso != "C":
+ if(num > 2):
+ self.x[0] = f"{chr(ord(piso) - 1)}{cuarto}"
+ self.costo += 3
+ elif(num == 1):
+ num = random.randrange(6)
+ if(num == 0):
+ cuartos["ABC".index(piso)][cuarto - 1] = "limpio"
+ self.costo += 1
+ elif(num == 1) == "ir_Derecha" and cuarto < 3:
+ self.x[0] = f"{piso}{cuarto + 1}"
+ self.costo += 2
+ elif(num == 2) == "ir_Izquierda" and cuarto > 1:
+ self.x[0] = f"{piso}{cuarto - 1}"
+ self.costo += 2
+ elif(num == 3) == "subir" and piso != "A":
+ self.x[0] = f"{chr(ord(piso) + 1)}{cuarto}"
+ self.costo += 3
+ elif(num == 4) == "bajar" and piso != "C":
+ self.x[0] = f"{chr(ord(piso) - 1)}{cuarto}"
+ self.costo += 3
+ elif(num == 5) == "nada":
+ pass
+ elif(num == 0):
+ pass
+ elif accion == "nada":
+ if(num > 2):
+ pass
+ elif(num == 1):
+ num = random.randrange(6)
+ if(num == 0):
+ cuartos["ABC".index(piso)][cuarto - 1] = "limpio"
+ self.costo += 1
+ elif(num == 1) == "ir_Derecha" and cuarto < 3:
+ self.x[0] = f"{piso}{cuarto + 1}"
+ self.costo += 2
+ elif(num == 2) == "ir_Izquierda" and cuarto > 1:
+ self.x[0] = f"{piso}{cuarto - 1}"
+ self.costo += 2
+ elif(num == 3) == "subir" and piso != "A":
+ self.x[0] = f"{chr(ord(piso) + 1)}{cuarto}"
+ self.costo += 3
+ elif(num == 4) == "bajar" and piso != "C":
+ self.x[0] = f"{chr(ord(piso) - 1)}{cuarto}"
+ self.costo += 3
+ elif(num == 5) == "nada":
+ pass
+ elif(num == 0):
+ pass
+
+if __name__ == "__main__":
+ # Inicializa el entorno y el agente
+ entorno = NueveCuartos()
+ #agente = AgenteAleatorioNueveCuartos()
+ agente = AgenteReactivoNueveCuartos()
+
+ # Simula por 200 pasos
+ entornos_o.simulador(entorno, agente, pasos=200, verbose=True)
\ No newline at end of file
diff --git a/semana01.md b/semana01.md
new file mode 100644
index 0000000..8857111
--- /dev/null
+++ b/semana01.md
@@ -0,0 +1,34 @@
+# Semana 01
+
+## Historia de la Inteligencia Artificial
+
+La Inteligencia Artificial es el desarrollo de agentes que, al interactuar con un entorno, maximicen la esperanza de una utilidad futura.
+
+El termino "Inteligencia Aritificial" fue usado por primera vez por John McCartyh en 1956. Este titulo es considerado "desafortunado", debido a que da la idea de una maquina que piensa por si misma,
+cuando en realidad se trata de una herramienta generativa que responde segun los estimulos dados, por lo que "Inteligencia Generativa" es considerado un titulo mas apropiado.
+
+Un metodo de interacciones es la Razional, en la cual se intentara maximizar la utilidad obtenida con las mediciones, acciones y lo que se conoce del entorno(Desempeño, Caracteristicas, Actuadores y Sensores).
+
+Las caracteriscitas del entorno se pueden clasificar de la siguiente forma, junto a sus opuestos:
+
+* Discreto / Continuo
+* Estatico / Dinamico
+* Observable / Parcialmente Observable
+* Determinista / Estocastico
+* Conocido / Desconocido
+* Un Agente / Multi Agente
+* Episodico / Secuencial
+
+Un entorno se modela haciendo inventario de los conceptos presentes, las variables, espacio y caracteristicas de estado, percepciones y todas las acciones, tanto posibles como legales.
+
+## Agentes Inteligentes
+
+El Agente es el actor que interactua con el entorno, este puede ser un humano, robot, termostato, etcetera. Las funciones del agente se pueden definir como:
+
+f: p* -> A
+
+Los Programas Agentes corren en una arquitectura fisica para producir f.
+
+El Rendimiento Fijo mide y evalua las secuencias del entorno.
+
+Un Agente Racional escoge la opcion que maximize el valor esperado del Rendimiento Fijo dado la secuencia perceptual.
diff --git a/semana02.md b/semana02.md
new file mode 100644
index 0000000..3643070
--- /dev/null
+++ b/semana02.md
@@ -0,0 +1,25 @@
+### Metodos de Aprendizaje:
+* Modelos Descriptivos
+* Modelos lineales generalizados
+* Arboles de decision
+* Redes Neuronales
+* Metodos de ensemble
+
+
+
+
+## Jueves 23/01/2025
+
+y = w_1 x_1 + w_2 x_2 + b? --- x = (x_1, x_2) e R^2
+
+en(h) ≈ E_ost (h) -> M >> 10d_16 (H) ?
+
+### Arbol de Decision
+Es un algoritmo para generar aprendizaje.
+
+Hipotesis:
+* Cada nodo interno prueba un atributo.
+* Cada rama para cada posible atributo se puede expresar como x_i = v.
+* Cada hoja asigna una clase y.
+* Para clasificar una entrada x se traversa el arbol desde la raiz a la hoja, con una salida y.
+
diff --git a/semana03.md b/semana03.md
new file mode 100644
index 0000000..bf43079
--- /dev/null
+++ b/semana03.md
@@ -0,0 +1,50 @@
+# 27/01/2025 - Continuacion de Arboles de Decision.
+En Arboles Binarios se llega mas rapido a la profunidad.
+
+En Arboles Binarios, el limite de divisiones se puede definir como el numero de particiones del atributo X en el valor t, donde:
+- Una rama: Xt
+
+Ganancia de Informacion - Entropia? Es sobre separacion de datos. Ejemplo: se tienen dos grupos de (10|10|5) datos en grupos Xa y Xb,
+si se divide Xa en (8|10|4) y (2|0|1) y Xb en (7|7|0), (1|0|4) y (2|3|1), por el calculo:
+
+H(<10, 10, 5>) = - (10/25) ln_2 10/25 - (10/25) ln_2 10/25 - (5/25) ln_2 5/25
+
+Entropia si se separa por A:
+
+H(<10, 10, 5>|Xa) = 22/25[ -8/22 ln_2 8/22 - 10/22 ln_2 10/22 - 4/22 ln_2 4/22] + 3/25[ -2/3 ln_2 2/3 - 0 * ln_2 0 - 1/3 ln_2 1/3]
+
+H(<10, 10, 5>|Xb) = 14/25[ -1/2 ln 1/2 - 1/2 ln_2 1/2 - 0] + 5/25[ -1/5 ln_2 1/5 - 0 - 4/5 ln_2 4/5] + 6/25[ -1/3 ln_2 1/3 - 1/2 ln_2 1/2 - 1/6 ln_2 1/6]
+
+La mayor ganancia de informacion a escoger es como la menor Entropia restante.
+
+# 28/01/2025
+
+Pandas es una libreria de Python para el manejo de datos.
+
+Dataframe: Conjunto de Series que comparten un mismo Indice.
+
+# 29/01/2025 - Arboles de Particiones
+
+Ganancia de Informacion: medida utilizada en Arboles de Decision para seleccionar el mejor atributo para dividir un conjunto de datos en cada nodo.
+
+La Prediccion de Error varia segun la Complejidad del Modelo de forma que muy poca o mucha aumenta esta.
+
+Mediacion/Averaging se usa para reducir la varianza: Var(x) = Var(x)/(n)
+
+Hay muchas formas de hacer aprendisaje de ensamble, siendo algunos de estos:
+- Bagging: aplicando multiples datos a un nodo y clasificandolos.
+- Boosting: Se entrenan modelos de manera secuencial.
+- Stacking: Se combinan múltiples modelos base entrenados con diferentes algoritmos y sus predicciones se usan como entrada para un modelo final que aprende a combinar sus resultados de manera óptima.
+
+Un Arbol Aleatorio es un metodo de Ensamblamiento diseñado para clasificar arboles. Tienen la ventaja de ser completamente paralelisables.
+
+# 30/01/2025 - Sesgo Cognitivo
+
+El Aprendizaje Automatico tiene como esencia la existencia de un patron, la imposibilidad de establecerlo de forma analitica y la obtencion y generacion de datos.
+
+Algunas consideraciones a tomar respecto al Aprendizaje Automatico:
+* Esta presente en muchas areas profesionales, pero no puede remplazar el conocimiento experto.
+* Un riesgo en cuanto a reduccion de empleos no especializados.
+* Dependencia por evidencias.
+* Riesgo latente en los usos no eticos.
diff --git a/tarea_1.py b/tarea_1.py
deleted file mode 100755
index d43959f..0000000
--- a/tarea_1.py
+++ /dev/null
@@ -1,18 +0,0 @@
-#!/usr/bin/env python
-# -*- coding: utf-8 -*-
-"""
-tarea_1.py
-------------
-
-Revisa el archivo README.md con las instrucciones de la tarea.
-
-"""
-__author__ = 'escribe_tu_nombre'
-
-import entornos_f
-import entornos_o
-
-# Requiere el modulo entornos_f.py o entornos_o.py
-# Usa el modulo doscuartos_f.py para reutilizar código
-# Agrega los modulos que requieras de python
-
|