{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Tus datos ya eran una matriz y nadie te lo había dicho\n",
    "\n",
    "Qué es una matriz, qué es una fila, qué es una columna, y por qué el archivo de ventas que abres todos los días ya es una.\n",
    "\n",
    "Cuaderno de práctica del capítulo 1 de **Matemática para machine learning**, de Miss Yera.\n",
    "\n",
    "Corre de arriba abajo. Si lo abres en Google Colab no necesitas instalar nada.\n",
    "\n",
    "Capítulo completo: https://missyera.com/guias/matematica-para-machine-learning/que-es-una-matriz/\n",
    "\n",
    "Los ejercicios están al final y traen una celda vacía debajo de cada uno. Las\n",
    "respuestas viven en el cuaderno de soluciones, y merece la pena pelearse un\n",
    "rato antes de abrirlo 💛"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Antes de empezar"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "import urllib.request\n",
    "\n",
    "# Este capitulo abre el archivo por su nombre, sin URL, que es lo que se hace\n",
    "# cuando lo tienes al lado. Aqui se baja primero para que exista.\n",
    "for nombre in ['ventas-miss-yera.csv']:\n",
    "    urllib.request.urlretrieve(f\"https://missyera.com/static/datasets/{nombre}\", nombre)\n",
    "    print(nombre, \"lista\")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Antes de empezar\n",
    "\n",
    "Esta celda baja el ayudante que corrige tus ejercicios. Después, en cada\n",
    "ejercicio que se pueda corregir solo, vas a ver `%%revisa` arriba de la celda:\n",
    "escribe tu respuesta debajo, ejecuta, y te digo si te salió 💛"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "import urllib.request\n",
    "\n",
    "# El ayudante de los cuadernos. Trae la corrección de los ejercicios y, en los\n",
    "# capítulos de consola, la celda mágica que ejecuta los comandos. Se baja en\n",
    "# vez de venir pegado aquí para que siempre sea el último.\n",
    "urllib.request.urlretrieve(\n",
    "    \"https://missyera.com/static/cuadernos/revisa.py\", \"revisa.py\")\n",
    "import revisa\n",
    "revisa.carga({\n",
    "    1: \"WCAgICAgICA6ICgyMjM4LCAzKQpYLlQgICAgIDogKDMsIDIyMzgpClhbMF0gICAgOiAoMywpClhbOiwgMV0gOiAoMjIzOCwp\",\n",
    "    2: \"VHJ1ZQ==\",\n",
    "    3: \"dWx0aW1hIGZpbGEgICA6IFsgMTcuICAgOTkzLjU3ICAgNC4gIF0KbG8gbWlzbW8sIGZlbyA6IFsgMTcuICAgOTkzLjU3ICAgNC4gIF0=\",\n",
    "    4: \"SW5kZXhFcnJvcjogaW5kZXggNyBpcyBvdXQgb2YgYm91bmRzIGZvciBheGlzIDEgd2l0aCBzaXplIDM=\",\n",
    "}, lenguaje=\"python\")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Hola! Empezamos por lo que ya sabes 🌸"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Te voy a hacer una promesa antes de nada: en este libro no hay ni un ejemplo\n",
    "de peras y manzanas. Todo sale del mismo archivo de ventas que usamos en los\n",
    "otros libros, porque lo que quiero es que veas que **la matemática ya\n",
    "estaba ahí**, metida en lo que haces todos los días, y nadie te lo había\n",
    "dicho con ese nombre.\n",
    "\n",
    "Vamos a abrirlo."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Abre el archivo y mira la forma"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "import pandas as pd\n",
    "import numpy as np\n",
    "\n",
    "df = pd.read_csv('ventas-miss-yera.csv')\n",
    "print('shape:', df.shape)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Ese `(3037, 14)` es lo primero que quiero que mires. Son\n",
    "**3.037 filas y 14 columnas**. Y eso, dicho en el idioma de este\n",
    "libro, es una matriz de 3.037 por 14.\n",
    "\n",
    "Ya está. Ese es el concepto entero. Una matriz es una tabla de números con\n",
    "filas y columnas 🙂"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Nos quedamos con los números"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Digo \"de números\" a propósito, porque tu archivo tiene columnas de texto\n",
    "como la ciudad y el canal. Una matriz de verdad es solo números, así que nos\n",
    "quedamos con tres columnas:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "for c in ('unidades', 'monto', 'satisfaccion'):\n",
    "    df[c] = pd.to_numeric(df[c], errors='coerce')\n",
    "\n",
    "X = df[['unidades', 'monto', 'satisfaccion']].dropna().to_numpy()\n",
    "print('shape:', X.shape, '| dtype:', X.dtype, '| ndim:', X.ndim)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Fíjate en el `to_numeric`. Sin esa línea el `monto`\n",
    "llega como texto, porque el archivo trae suciedad a propósito, y entonces\n",
    "`dtype` sale `object` en vez de `float64`. Eso\n",
    "lo trabajamos entero en el capítulo de auditoría de tipos del libro de machine\n",
    "learning; acá solo lo arreglamos para poder seguir.\n",
    "\n",
    "El `ndim: 2` es la palabra técnica: una matriz tiene\n",
    "**dos dimensiones**. Una sola columna sería de una dimensión y se\n",
    "llama vector, que es el capítulo que viene. Tres dimensiones sería un tensor, y\n",
    "eso lo vas a ver cuando llegues a las imágenes en Deep learning."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Cómo se escribe esto en un paper"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Cuando abras cualquier libro de machine learning te vas a topar con esto:"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "X∈ℝn×d\n",
    "\n",
    "X es una tabla de n filas por d columnas, y todo lo que hay dentro son números reales"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Y ahora ya lo puedes leer. La **X** es tu tabla. La\n",
    "**n** son tus 2.238 ventas. La **d** son tus 3\n",
    "columnas. Lo de **ℝ** solo dice que dentro hay números reales, o\n",
    "sea números con decimales, no palabras."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "| Símbolo | Qué es |\n",
    "|---|---|\n",
    "| **X** | la matriz entera, tu tabla de datos |\n",
    "| **n** | cuántas filas tiene, o sea cuántos ejemplos |\n",
    "| **d** | cuántas columnas tiene, o sea cuántas características |\n",
    "| **xij** | un número suelto: el de la fila i, columna j |"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Y una cosa que a mí me costó y por eso te la digo: en machine learning\n",
    "**casi siempre** las filas son los ejemplos y las columnas son las\n",
    "características. No es una ley del universo, es un acuerdo. Pero si te\n",
    "encuentras un paper donde está al revés, te lo va a decir."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Sacar un pedazo, que es lo que vas a hacer todo el tiempo"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "print('una venta entera  X[0]   :', np.round(X[0], 2))\n",
    "print('todos los montos  X[:,1] :', np.round(X[:5, 1], 2), '...')\n",
    "print('un solo numero    X[0,1] :', X[0, 1])"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Tres formas de meter la mano en la misma tabla:\n",
    "\n",
    "- `X[0]` te da la **fila** completa. Una venta: 10\n",
    "unidades, 480.37 soles, satisfacción 4.\n",
    "\n",
    "- `X[:, 1]` te da la **columna** completa. Los dos\n",
    "puntos quieren decir \"todas las filas\".\n",
    "\n",
    "- `X[0, 1]` te da **un número**. Fila 0, columna 1."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "xij=el valor de la fila i en la columna j\n",
    "\n",
    "el elemento que está en el cruce: primero se dice la fila, después la columna, siempre en ese orden"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "El orden importa y es el que se te va a olvidar: **primero la fila,\n",
    "después la columna**. Siempre. Si alguna vez tu código explota con un\n",
    "\"index out of bounds\", nueve de cada diez veces es que los cambiaste de sitio."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Cuánto es una matriz, de verdad"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "print('filas x columnas =', X.shape[0], 'x', X.shape[1], '=', X.size, 'numeros')\n",
    "print('cuanto ocupa en memoria:', X.nbytes, 'bytes')"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "6.714 números. 53 kilobytes. Nada.\n",
    "\n",
    "Te pongo el dato porque cuando llegues a Deep learning vas a ver matrices de\n",
    "otro tamaño, y quiero que tengas con qué comparar. Una imagen de 224 por 224 en\n",
    "color son 150.528 números *por foto*. Un lote de 32 fotos son casi cinco\n",
    "millones. Ahí es donde empieza a importar que esto sean matrices y no bucles 🐣"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## La traspuesta, que es mirarla al revés"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "print('X.T shape:', X.T.shape)\n",
    "print('X.T[1][:5]:', np.round(X.T[1][:5], 2))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "La traspuesta gira la tabla: lo que era una columna pasa a ser una fila. Se\n",
    "escribe con esa T pequeñita arriba:"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "(X⊤)ij=xji\n",
    "\n",
    "la traspuesta cambia filas por columnas, así que el elemento que estaba en la fila 2 columna 5 pasa a estar en la fila 5 columna 2"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Y no es un truco de programador, es una operación con nombre propio que vas\n",
    "a ver constantemente. Cuando en Deep learning veas W⊤,\n",
    "ya sabes qué está pasando: alguien necesitaba que las dimensiones encajaran para\n",
    "poder multiplicar, y eso lo vemos en el capítulo de multiplicación de\n",
    "matrices."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Tres matrices que vas a ver por todos lados"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Hay tres formas de matriz con nombre propio. Te las presento ahora porque\n",
    "cuando aparezcan en un capítulo más adelante quiero que ya las reconozcas."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "print(np.eye(3))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Esa es la **identidad**. Unos en la diagonal y ceros en todo lo\n",
    "demás. Es el 1 de las matrices: multiplicar por ella no cambia nada. Cuando\n",
    "llegues al capítulo de la inversa la vas a necesitar, porque la inversa se\n",
    "define justo como \"la que multiplicada por la original te da la identidad\"."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "print(np.zeros((2, 3)))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "La de **ceros**. Parece inútil y no lo es: así es como se\n",
    "arranca casi cualquier acumulador, y así empiezan los pesos de algunas capas en\n",
    "deep learning."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "print(np.diag([2., 0.5, 10.]))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Una **diagonal**. Solo tiene números en la diagonal. Esta la vas\n",
    "a ver en el capítulo de autovalores, y también es lo que hay por debajo cuando\n",
    "escalas cada columna por un número distinto."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Operar con toda la tabla de una vez"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Esto es lo que hace que NumPy valga la pena, y es donde mucha gente que viene\n",
    "de Excel dice \"ah, ya\"."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "print(np.round(X[:2], 2))\n",
    "print(np.round(X[:2] * 2, 2))\n",
    "print(np.round(X[:2] + 100, 2))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Sin un solo bucle. Escribes `X * 2` y se multiplica cada número de\n",
    "la tabla. Eso se llama **operación elemento a elemento**, y es lo\n",
    "que hace que entrenar una red sobre millones de números sea posible.\n",
    "\n",
    "Y ojo con esto, que es la trampa del capítulo que viene:\n",
    "`X * 2` **no es** multiplicar matrices. Es otra cosa\n",
    "completamente distinta y tiene otro símbolo. Lo vemos en su momento 🐣"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## El eje, que es lo que más se confunde"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Cuando resumes una tabla tienes que decir en qué dirección. Y aquí es donde\n",
    "todo el mundo se equivoca al menos una vez:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "print('media de cada COLUMNA (axis=0):', np.round(X.mean(axis=0), 2))\n",
    "print('media de cada FILA    (axis=1):', np.round(X.mean(axis=1)[:5], 2), '...')\n",
    "print('sin axis (todo junto)         :', round(X.mean(), 2))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Mira los tres resultados y cuál tiene sentido:\n",
    "\n",
    "- **axis=0** da tres números, uno por columna. La venta media es\n",
    "de 11.68 unidades y 803.39 soles, con satisfacción media de 3.02. Esto\n",
    "*significa* algo.\n",
    "\n",
    "- **axis=1** da un número por venta, y es el promedio de mezclar\n",
    "unidades con soles y con satisfacción. Eso no significa nada. Sumar soles con\n",
    "estrellas no es una cantidad de nada.\n",
    "\n",
    "- **sin axis** promedia los 6.714 números juntos. Peor todavía.\n",
    "\n",
    "La regla para acordarte: **axis=0 recorre las filas hacia abajo**\n",
    "y te deja un número por columna. Es el que vas a querer el 90% de las veces,\n",
    "porque las columnas son las que tienen unidades comparables."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## El error de forma, que te va a pasar"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Te lo enseño ahora para que cuando te salga ya sepas leerlo:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "a = X[:, :2]\n",
    "b = X[:, :3]\n",
    "print('a.shape', a.shape, ' b.shape', b.shape)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Y ahora las sumas:"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "**Esto revienta a propósito.** Se ejecuta dentro de un `try` para que puedas seguir con \"ejecutar todo\" y aun así ver la queja."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "try:\n",
    "    a + b\n",
    "except Exception as e:\n",
    "    print(f'{type(e).__name__}: {e}')"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Y la queja que tiene que salir es esta:\n",
    "\n",
    "```\n",
    "ValueError: operands could not be broadcast together with shapes (2238,2) (2238,3)\n",
    "```"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Dos tablas con distinto número de columnas no se pueden sumar. Obvio dicho\n",
    "así, pero cuando llevas cuarenta líneas de código y una de ellas cambió la forma\n",
    "sin que te dieras cuenta, este error aparece muy lejos de donde estuvo la\n",
    "culpa.\n",
    "\n",
    "El hábito que te va a salvar horas: cuando algo no cuadre,\n",
    "**imprime los `.shape`** antes de tocar nada más. En mi\n",
    "experiencia, la mitad de los errores de un proyecto de machine learning son de\n",
    "forma, no de matemática."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Lo que te llevas"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "- Una matriz es una tabla de números. Tu archivo de ventas ya lo era.\n",
    "\n",
    "- Se escribe **X**, tiene **n** filas y\n",
    "**d** columnas, y en machine learning las filas son los ejemplos.\n",
    "\n",
    "- `X[fila, columna]`, en ese orden y no al revés.\n",
    "\n",
    "- `.shape` te dice la forma y es lo primero que hay que mirar\n",
    "cuando algo no cuadra.\n",
    "\n",
    "- La traspuesta X⊤ cambia filas por columnas."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Comprueba que se entendió"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Comprueba que lo tienes\n",
    "\n",
    "Tienes X con forma (2238, 3) y escribes X.mean(axis=0). ¿Cuántos números te salen y qué es cada uno?\n",
    "\n",
    "a) Tres números: el promedio de cada columna\n",
    "\n",
    "b) 2.238 números: el promedio de cada venta\n",
    "\n",
    "c) Un solo número: el promedio de toda la tabla\n",
    "\n",
    "d) Depende de si la matriz tiene decimales"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Ejercicios"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 1. La forma antes que nada\n",
    "\n",
    "Antes de hacer ninguna cuenta, mira la forma. Es el hábito\n",
    "que más errores te va a ahorrar."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "%%revisa 1\n",
    "# tu turno"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 2. Traspón dos veces y mira qué pasa\n",
    "\n",
    "Sin correrlo, ¿qué crees que sale? Después córrelo."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "%%revisa 2\n",
    "# tu turno"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 3. Saca la última fila sin saber cuántas hay\n",
    "\n",
    "Los índices negativos cuentan desde el final."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "%%revisa 3\n",
    "# tu turno"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 4. El error que vas a cometer\n",
    "\n",
    "Pide una columna que no existe y lee el error entero, que\n",
    "para eso está."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "%%revisa 4\n",
    "# tu turno"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Preguntas frecuentes"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "¿Qué es una matriz?Una tabla de números con filas y columnas. Tu archivo de ventas ya es una: cada fila es una venta y cada columna una cosa medida.\n",
    "\n",
    "¿Qué son las filas y las columnas de una matriz?Las filas son los casos y las columnas las variables. Cuando alguien dice que una matriz es \"de 3037 por 14\", el primer número son las filas y el segundo las columnas, siempre en ese orden.\n",
    "\n",
    "¿Qué es la matriz identidad?La que tiene unos en la diagonal y ceros en todo lo demás. Multiplicar por ella no cambia nada, igual que multiplicar por uno, y sirve para comprobar si una inversa está bien calculada.\n",
    "\n",
    "¿Qué es la transpuesta de una matriz?La misma matriz con las filas puestas como columnas. Se usa mucho más de lo que parece, porque es lo que hace que dos formas encajen para poder multiplicarlas."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Ya sabes qué pasa por debajo. Ahora que corra"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Sabes qué mide una derivada, hacia dónde apunta un gradiente y por qué la regla de la cadena es lo que hace que una red aprenda. Eso no lo tiene la mayoría de la gente que entrena modelos 🎓\n",
    "\n",
    "Lo que la matemática no te da es lo que pasa después: que el sistema corra solo, que alguien se entere cuando empiece a fallar y que puedas demostrar con números que sirve. Eso es [el curso de ingeniería de IA en producción](https://missyera.com/cursos/ingenieria-de-ia/).\n",
    "\n",
    "Son cuatro semanas y sales con un sistema tuyo, sobre un proceso real de tu trabajo. Con lo que acabas de leer vas a entender por qué se toma cada decisión en vez de copiarla.\n",
    "\n",
    "Y si por ahora te quedas con la teoría, tranqui: el capítulo de referencias te deja por dónde seguir sola 🌸"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "---\n",
    "\n",
    "Ese era el capítulo 1 de **Matemática para machine learning**. El texto completo, con las salidas de cada bloque, está en https://missyera.com/guias/matematica-para-machine-learning/que-es-una-matriz/\n",
    "\n",
    "Que tengas lindo día! 🌸"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "name": "python",
   "version": "3.11"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}
