{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Un vector no es una flecha, es una fila de tu tabla\n",
    "\n",
    "Qué es un vector de verdad en machine learning, por qué el dibujo de la flecha te va a estorbar, y la diferencia entre fila y columna.\n",
    "\n",
    "Cuaderno de práctica del capítulo 2 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-un-vector/\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: \"VHJ1ZQpUcnVl\",\n",
    "    2: \"MSAtPiA0NTQKMiAtPiA0MjYKMyAtPiA0NDcKNCAtPiA0NDkKNSAtPiA0NjI=\",\n",
    "    3: \"b3JpZ2luYWwgOiBbIDEwLiAgIDQ4MC4zNyAgIDQuICBdCmFsIHJldmVzIDogWyAgNC4gICA0ODAuMzcgIDEwLiAgXQ==\",\n",
    "}, lenguaje=\"python\")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Te tengo que quitar un dibujo de la cabeza 🌸"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Si en el colegio te enseñaron vectores, casi seguro te los enseñaron como\n",
    "una flecha. Una flecha con su origen, su dirección y su largo.\n",
    "\n",
    "Ese dibujo no está mal, pero te va a estorbar. Porque en machine learning\n",
    "un vector típico tiene cincuenta componentes, y una flecha en cincuenta\n",
    "dimensiones no se puede dibujar ni imaginar.\n",
    "\n",
    "Así que lo cambiamos por otro que sí escala: **un vector es una fila\n",
    "de tu tabla** 🐣"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Volvemos a abrir el archivo"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Cada capítulo arranca de cero, así que estas líneas se repiten. Son las\n",
    "mismas del capítulo 1 y las vas a ver en todos."
   ]
  },
  {
   "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",
    "for c in ('unidades', 'monto', 'satisfaccion'):\n",
    "    df[c] = pd.to_numeric(df[c], errors='coerce')\n",
    "X = df[['unidades', 'monto', 'satisfaccion']].dropna().to_numpy()\n",
    "print('X.shape:', X.shape)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Saca una fila y míralo"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "v = X[0]\n",
    "print('v       :', np.round(v, 2))\n",
    "print('v.shape :', v.shape, '| ndim:', v.ndim)\n",
    "print('len(v)  :', len(v))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Eso es un vector. Tres números en un orden que significa algo: primero las\n",
    "unidades, después el monto, después la satisfacción.\n",
    "\n",
    "Fíjate en `ndim: 1`. Una **dimensión**. La matriz\n",
    "del capítulo anterior tenía dos. Y la forma sale `(3,)`, con esa\n",
    "coma sola al final, que es la manera que tiene NumPy de decirte \"esto no es una\n",
    "tabla de 3 por algo, es una lista de 3\"."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## El orden es el vector"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Esto es lo que separa un vector de un montón de números sueltos.\n",
    "\n",
    "Si te doy `[10, 480.37, 4]` sabes que fueron 10 unidades por\n",
    "480.37 soles con satisfacción 4. Si te doy `[4, 10, 480.37]` son los\n",
    "mismos tres números y ya no significan nada, porque la posición es la que dice\n",
    "qué es cada uno."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "𝐯∈ℝd\n",
    "\n",
    "v es una lista de d números reales, y esa negrita es lo único que la distingue de un número suelto"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "La **d** es cuántas componentes tiene. Y la negrita de la\n",
    "**v** no es decorativa: en los papers es lo único que distingue un\n",
    "vector de un número suelto. Cuando veas una letra en negrita, es una lista."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "𝐯=(v1,v2,…,vd)\n",
    "\n",
    "un vector se escribe como sus componentes, una por cada cosa que mediste"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "| Símbolo | Qué es |\n",
    "|---|---|\n",
    "| **v** | el vector entero |\n",
    "| **v1** | su primera componente, en nuestro caso las unidades |\n",
    "| **d** | cuántas componentes tiene |"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Y ojo con algo que confunde a todo el mundo: en matemática las componentes\n",
    "se numeran desde 1, y en Python desde 0. Así que la v1\n",
    "del paper es `v[0]` en tu código. No hay forma de que eso deje de\n",
    "molestar, solo se acostumbra uno 🙂"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Una columna también es un vector"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "montos = X[:, 1]\n",
    "print('montos.shape :', montos.shape)\n",
    "print('primeros 3   :', np.round(montos[:3], 2))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "2.238 componentes. También es un vector, y también tiene un orden que\n",
    "significa algo: cada posición es una venta distinta.\n",
    "\n",
    "Y aquí está la idea que quiero que te lleves de este capítulo: la\n",
    "**misma tabla** te da dos familias de vectores según cómo la\n",
    "cortes. Por filas te da un vector por venta. Por columnas te da un vector por\n",
    "característica.\n",
    "\n",
    "Las dos se usan, y para cosas distintas. Cuando en machine learning se dice\n",
    "\"cada ejemplo es un punto en el espacio\", se está hablando de los de fila.\n",
    "Cuando se dice \"esta columna correlaciona con aquella\", de los de columna."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Fila o columna, que sí importa"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "En matemática un vector suele escribirse como columna, y eso a veces hay que\n",
    "decírselo a NumPy:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "fila = v.reshape(1, -1)\n",
    "col  = v.reshape(-1, 1)\n",
    "print('fila.shape', fila.shape, ' col.shape', col.shape)\n",
    "print(np.round(col, 2))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Los tres son el mismo vector con los mismos tres números. Lo que cambia es\n",
    "la forma: `(3,)`, `(1, 3)` y `(3, 1)`.\n",
    "\n",
    "El `-1` del `reshape` quiere decir \"calcula tú cuánto\n",
    "va aquí\". Es cómodo y es peligroso: si te equivocas de eje, NumPy no protesta,\n",
    "te devuelve algo con la forma que pediste y el error aparece tres funciones más\n",
    "allá.\n",
    "\n",
    "Cuándo importa: cuando multipliques. Ahí `(1, 3)` y\n",
    "`(3, 1)` dan resultados completamente distintos, y eso es el capítulo\n",
    "del producto punto."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Lo que te llevas"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "- Un vector es una lista ordenada de números. Olvídate de la flecha.\n",
    "\n",
    "- La **posición** es la que dice qué es cada número.\n",
    "\n",
    "- Forma `(3,)` con coma suelta quiere decir una dimensión.\n",
    "\n",
    "- Las filas y las columnas de tu tabla son las dos vectores, y se usan para\n",
    "cosas distintas.\n",
    "\n",
    "- Los papers numeran desde 1 y Python desde 0. Es así y ya."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Comprueba que se entendió"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Comprueba que lo tienes\n",
    "\n",
    "Sacas v = X[0] y te sale forma (3,). Después haces v.reshape(-1, 1). ¿Qué cambió?\n",
    "\n",
    "a) Solo la forma: los mismos tres números organizados como columna\n",
    "\n",
    "b) Los números, que ahora están al revés\n",
    "\n",
    "c) Nada, porque (3,) y (3, 1) son lo mismo\n",
    "\n",
    "d) Ahora hay tres vectores de un número cada uno"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Ejercicios"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 1. Fila contra columna\n",
    "\n",
    "Comprueba que las tres formas llevan los mismos números."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "%%revisa 1\n",
    "# tu turno"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 2. El vector de una columna concreta\n",
    "\n",
    "Saca las satisfacciones y mira cuántas hay de cada nota."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "%%revisa 2\n",
    "# tu turno"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 3. El orden importa, demuéstralo\n",
    "\n",
    "Desordena las componentes y mira si sigue significando lo\n",
    "mismo."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "%%revisa 3\n",
    "# tu turno"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Preguntas frecuentes"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "¿Qué es un vector?Una lista ordenada de números. En machine learning, una fila de tu tabla es un vector: un cliente son sus cinco números puestos en fila y en el mismo orden siempre.\n",
    "\n",
    "¿Qué son las componentes de un vector?Cada uno de los números de la lista. Si el vector es un cliente, sus componentes son unidades, monto, descuento y lo que hayas medido.\n",
    "\n",
    "¿Qué tipos de vectores hay?En el álgebra que hace falta acá, la distinción que importa es fila o columna, y es de forma y no de fondo. NumPy te lo va a recordar el día que dos formas no encajen.\n",
    "\n",
    "¿Cómo se suman dos vectores?Componente a componente: el primero con el primero, el segundo con el segundo. Solo se pueden sumar si tienen el mismo largo."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "---\n",
    "\n",
    "Ese era el capítulo 2 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-un-vector/\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
}
