{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Dos negocios con el mismo promedio\n",
    "\n",
    "Desviación estándar, rango intercuartílico y coeficiente de variación. Y el ddof que cambia el número sin que lo pidas.\n",
    "\n",
    "Cuaderno de práctica del capítulo 4 de **Estadística desde cero**, 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/estadistica-desde-cero/dispersion/\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\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: \"cmFuZ28gY29tcGxldG86ICAgICAgICA2NzM0LjQzCnNpbiBsYSBtYXlvciB5IGxhIG1lbm9yOiA2NTc1LjQ4CmVudHJlIGVsIDElIHkgZWwgOTklOiAgICAzMDIyLjk1\",\n",
    "    2: \"ICAgICAgICAgICAgIG1lYW4gICAgICBzdGQgICAgIGN2CmNpdWRhZAphcmVxdWlwYSAgODAxLjkxNyAgNzUyLjUxOSAgMC45MzgKY2hpY2xheW8gIDgxMy45MDggIDc2MC45NTMgIDAuOTM1CmN1c2NvICAgICA3ODAuNjk2ICA3MDUuMjM3ICAwLjkwMwpsaW1hICAgICAgNzkyLjczNyAgNzUyLjk1NCAgMC45NTAKcGl1cmEgICAgIDc5Mi4xNjEgIDcyNS4xMjUgIDAuOTE1CnRydWppbGxvICA4NDIuNjg4ICA4MTYuMzEyICAwLjk2OQ==\",\n",
    "    3: \"Y29uIHVuIGRhdG86ICAgbmFuCmNvbiBkb3MgZGF0b3M6IDAuMA==\",\n",
    "    4: \"bW9udG8gICAgICAgICBtZWRpYSAgODAzLjc2MSB8IGRlc3ZpYWNpb24gIDc1MS45ODkgfCBDViAwLjkzNTYKdW5pZGFkZXMgICAgICBtZWRpYSAgIDExLjYwMSB8IGRlc3ZpYWNpb24gICAgNS43NzUgfCBDViAwLjQ5NzgKZGVzY3VlbnRvICAgICBtZWRpYSAgICAwLjEyNSB8IGRlc3ZpYWNpb24gICAgMC4wNzIgfCBDViAwLjU3MzEKc2F0aXNmYWNjaW9uICBtZWRpYSAgICAzLjAxMCB8IGRlc3ZpYWNpb24gICAgMS40MjEgfCBDViAwLjQ3MjA=\",\n",
    "    5: \"ZGVzdmlhY2lvbiBjYWxjdWxhZGE6ICAwLjQ5NDAxMwpmb3JtdWxhIHNxcnQocCooMS1wKSk6IDAuNDkzOTMxCmNvbiBsYSBjb3JyZWNjaW9uIG4tMTogMC40OTQwMTM=\",\n",
    "    6: \"bW9udG86IG1lZGlhbmEgNTMzLjYzLCB5IGxhIG1pdGFkIGNlbnRyYWwgZW50cmUgMjUyLjY5IHkgMTA2OC42OAp1bmlkYWRlczogMTEuNjAgZGUgbWVkaWEsICsvLSA1Ljc3Cm1vbnRvIGVuIEJvZGVnYTogMTc4LjcwIGRlIG1lZGlhLCArLy0gNjkuNTk=\",\n",
    "    7: \"bW9udG8gICAgICAgICBkZXN2aWFjaW9uICAgNzUxLjk5ICAgSVFSICAgODE1Ljk5ICAgTUFEICAgMzI1LjY3CnVuaWRhZGVzICAgICAgZGVzdmlhY2lvbiAgICAgNS43NyAgIElRUiAgICAgOC4wMCAgIE1BRCAgICAgNC4wMApzYXRpc2ZhY2Npb24gIGRlc3ZpYWNpb24gICAgIDEuNDIgICBJUVIgICAgIDIuMDAgICBNQUQgICAgIDEuMDA=\",\n",
    "    8: \"Y29uIHRvZG86ICAgICAgICBkZXN2aWFjaW9uIDc1MS45OQpzaW4gZWwgMSUgZGUgYXJyaWJhOiBkZXN2aWFjaW9uIDcwNy40NwpzZSBmdWUgZWwgNS45JSBkZSBsYSBkaXNwZXJzaW9uIHF1aXRhbmRvIGVsIDEuMCUgZGUgbGFzIGZpbGFz\",\n",
    "}, lenguaje=\"python\")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Dos vendedores. Los dos venden 500 soles de promedio 💰\n",
    "\n",
    "Uno vende 500 todos los días como un reloj. El otro vende 50 un día y 950 al\n",
    "siguiente. El promedio no los distingue, y sin embargo son dos personas\n",
    "completamente distintas: al segundo no puedes prometerle a nadie que mañana\n",
    "factura 500.\n",
    "\n",
    "Eso es la dispersión, y por eso **un promedio sin su dispersión al lado\n",
    "es medio dato**."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "import pandas as pd\n",
    "import numpy as np\n",
    "\n",
    "URL = 'https://missyera.com/static/datasets/ventas-miss-yera.csv'\n",
    "\n",
    "\n",
    "def carga_limpia(url):\n",
    "    \"\"\"La misma del capítulo 2.\"\"\"\n",
    "    v = pd.read_csv(url).drop_duplicates()\n",
    "    v['ciudad'] = (v['ciudad'].str.strip().str.lower()\n",
    "                   .str.normalize('NFKD')\n",
    "                   .str.encode('ascii', 'ignore').str.decode('utf-8'))\n",
    "    v['monto'] = pd.to_numeric(v['monto'].str.replace(',', '.'))\n",
    "    for col in ['fecha', 'fecha_ultima_compra']:\n",
    "        f = pd.to_datetime(v[col], format='%Y-%m-%d', errors='coerce')\n",
    "        falta = f.isna() & v[col].notna()\n",
    "        f[falta] = pd.to_datetime(v.loc[falta, col], format='%d/%m/%Y',\n",
    "                                  errors='coerce')\n",
    "        v[col] = f\n",
    "    return v\n",
    "\n",
    "\n",
    "v = carga_limpia(URL)\n",
    "\n",
    "reloj = pd.Series([500, 510, 495, 505, 490, 500, 505, 495])\n",
    "montania = pd.Series([100, 900, 50, 950, 200, 800, 150, 850])\n",
    "\n",
    "print('el reloj:    media %.1f | desviacion %.2f' % (reloj.mean(), reloj.std()))\n",
    "print('la montaña:  media %.1f | desviacion %.2f' % (montania.mean(), montania.std()))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Mismo promedio, desviaciones de 6,55 y 405,32. Ahí sí se ven dos negocios\n",
    "distintos 👀\n",
    "\n",
    "Y una pregunta para que la lleves puesta: **¿tu negocio es más reloj o más montaña rusa?** Los dos pueden tener el mismo promedio, y se planifican de forma completamente distinta 📏"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Las cuatro medidas, de la peor a la mejor"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "**El rango** es lo primero que se le ocurre a cualquiera: el\n",
    "máximo menos el mínimo."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "print('rango: %.2f  (de %.2f a %.2f)'\n",
    "      % (v['monto'].max() - v['monto'].min(), v['monto'].min(), v['monto'].max()))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Y ya se ve el problema: ese número lo deciden **dos filas** de\n",
    "tres mil. Las otras 2.998 no opinan. Además una de las dos es una venta\n",
    "negativa, que ya sabemos que es rara y que miramos en el capítulo 6.\n",
    "\n",
    "**La varianza** es la media de las distancias al cuadrado. Se\n",
    "elevan al cuadrado para que las que están por debajo no cancelen a las que están\n",
    "por encima:"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "s2=1n−1∑i=1n(xi−x¯)2\n",
    "\n",
    "promedias las distancias al cuadrado de cada dato al centro, dividiendo entre n menos uno"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "print('varianza:  %.2f' % v['monto'].var())\n",
    "print('desviacion: %.2f' % v['monto'].std())\n",
    "print('la desviacion es la raiz de la varianza:',\n",
    "      round(np.sqrt(v['monto'].var()), 2) == round(v['monto'].std(), 2))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Y aquí está por qué la varianza casi nunca se reporta: **sus unidades\n",
    "son soles al cuadrado**. 565.487 soles cuadrados no significa nada para\n",
    "nadie 🤷 La desviación estándar deshace el cuadrado con la raíz y vuelve a\n",
    "soles, que sí se entienden: *\"las ventas se separan del promedio unos 752\n",
    "soles\"*."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## El ddof, o por qué numpy y pandas no coinciden"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Esto pilla a todo el mundo una vez, y luego ya no se olvida:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "print('pandas: %.6f' % v['monto'].std())\n",
    "print('numpy:  %.6f' % np.std(v['monto']))\n",
    "print('diferencia: %.6f' % (v['monto'].std() - np.std(v['monto'])))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Los dos calculan \"la desviación estándar\" de la misma columna y dan números\n",
    "distintos 😑\n",
    "\n",
    "La razón es el **ddof**, que decide si divides entre n o entre\n",
    "n-1. pandas divide entre n-1 por defecto y numpy entre n.\n",
    "\n",
    "Y no es un capricho. Se divide entre n-1 cuando tus datos son una\n",
    "**muestra** y quieres estimar la dispersión de la población entera.\n",
    "Una muestra siempre parece un poquito menos dispersa que la población de la que\n",
    "salió, así que se corrige haciendo el divisor más chico. Se divide entre n\n",
    "cuando tus datos **son** toda la población y no estimas nada.\n",
    "\n",
    "Con 3.000 filas la diferencia es de 12 céntimos y da igual. Pero mira lo que\n",
    "pasa con pocos datos:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "tres = pd.Series([9, 10, 11])\n",
    "print('con 3 datos -> pandas %.4f | numpy %.4f' % (tres.std(), np.std(tres)))\n",
    "print('diferencia relativa: %.1f%%'\n",
    "      % (100 * (tres.std() - np.std(tres)) / np.std(tres)))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "**22,5% de diferencia** por un parámetro que no pusiste 😳\n",
    "\n",
    "Si trabajas con grupos chicos, encuestas de 10 personas o resultados de 5\n",
    "sucursales, esto sí te cambia el número que llevas a la reunión. La regla\n",
    "práctica: en análisis de datos casi siempre tienes una muestra, así que\n",
    "**casi siempre quieres n-1**, o sea el de pandas. Si usas numpy,\n",
    "pídelo a mano con `np.std(x, ddof=1)`."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## El rango intercuartílico, que es el hermano robusto"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Igual que la mediana era la versión robusta de la media, el\n",
    "**IQR** es la versión robusta de la desviación. Se queda con el 50%\n",
    "central y descarta las dos puntas:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "q1 = v['monto'].quantile(0.25)\n",
    "q3 = v['monto'].quantile(0.75)\n",
    "\n",
    "print('Q1 (25%%): %.2f' % q1)\n",
    "print('Q3 (75%%): %.2f' % q3)\n",
    "print('IQR:      %.2f' % (q3 - q1))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Se lee así: **el 50% de las ventas está entre 252,69 y 1.068,68\n",
    "soles**. Y eso, para contárselo a alguien que no sabe estadística, es\n",
    "muchísimo más claro que \"la desviación estándar es 752\" 🗣️\n",
    "\n",
    "Ojo con la escala de los cuantiles, que se equivoca todo el mundo:"
   ]
  },
  {
   "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",
    "    v['monto'].quantile(1.5)\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: percentiles should all be in the interval [0, 1]\n",
    "```"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "En pandas los cuantiles van de 0 a 1, no de 0 a 100. El 75% es\n",
    "`0.75`. En numpy, en cambio, `np.percentile` va de 0 a 100.\n",
    "Es de las incoherencias más molestas que hay entre las dos librerías 🙃"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## El coeficiente de variación, y lo que encontró"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Última medida, y es la que más uso cuando comparo cosas distintas.\n",
    "\n",
    "Problema: ¿varían más las ventas de Bodega o las de Mayorista? La desviación\n",
    "no te sirve para contestar, porque una vende a 178 soles y la otra a 1.856. La\n",
    "grande va a tener una desviación más grande siempre, solo por ser grande.\n",
    "\n",
    "El **coeficiente de variación** arregla eso dividiendo la\n",
    "desviación entre la media. Queda un número sin unidades, o sea comparable:"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "CV=sx¯\n",
    "\n",
    "la dispersión medida en veces la media, que sale sin unidades y por eso se puede comparar entre cosas distintas"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "por_segmento = v.groupby('segmento')['monto'].agg(['mean', 'std'])\n",
    "por_segmento['cv'] = por_segmento['std'] / por_segmento['mean']\n",
    "\n",
    "print(por_segmento.round(3))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Esto me pareció precioso cuando salió 😍\n",
    "\n",
    "Las desviaciones van de **69,59 a 719,55**, o sea que una es diez\n",
    "veces la otra. Y los coeficientes de variación van de\n",
    "**0,358 a 0,389**: prácticamente el mismo número en los cuatro.\n",
    "\n",
    "Lo que eso dice del negocio es concreto y bonito: **los cuatro\n",
    "segmentos se comportan igual, solo que a escalas distintas**. Todos\n",
    "tienen ventas que se desvían alrededor de un 37% de su propio promedio. Un\n",
    "mayorista es una bodega multiplicada por diez, no un animal diferente.\n",
    "\n",
    "Y encaja con lo del capítulo 3, donde vimos que dentro de cada segmento la\n",
    "media y la mediana coincidían. Cuatro poblaciones con la misma forma y distinto\n",
    "tamaño 🪆"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## La regla del 68, 95 y 99 (y cuándo falla)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Seguro la has oído: en una distribución normal, el 68% de los datos cae a una\n",
    "desviación del promedio, el 95% a dos y el 99,7% a tres.\n",
    "\n",
    "Vamos a comprobarlo en tres columnas de este archivo:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "for col in ['monto', 'unidades', 'satisfaccion']:\n",
    "    s = v[col].dropna()\n",
    "    dentro = 100 * (abs(s - s.mean()) < s.std()).mean()\n",
    "    print('%-13s dentro de 1 desviacion: %.2f%%' % (col, dentro))\n",
    "\n",
    "print('lo que dice la teoria para una normal:  68.27%')"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Tres columnas del mismo archivo y tres respuestas: 81,80%, 68,70% y 59,44%.\n",
    "La teoría dice 68,27% 🎯\n",
    "\n",
    "- 📦 `unidades` da 68,70%, que es clavado. Esa columna sí tiene\n",
    "forma de campana.\n",
    "\n",
    "- 💰 `monto` da 81,80%, muy por encima. Se concentra más de lo que\n",
    "debería cerca del centro y tiene cola.\n",
    "\n",
    "- ⭐ `satisfaccion` da 59,44%, muy por debajo. Y tiene sentido:\n",
    "son cinco valores repartidos casi por igual, no una campana.\n",
    "\n",
    "**La regla del 68-95-99 solo vale si tus datos son normales**, y\n",
    "la mayoría no lo son. Aplicarla sin comprobar es de los errores más comunes que\n",
    "existen, y por eso el capítulo 5 va entero de eso: cómo saber si tienes una\n",
    "campana antes de usar las herramientas de la campana.\n",
    "\n",
    "Mientras tanto hay una regla que vale *siempre*, pase lo que pase con\n",
    "la forma. Se llama desigualdad de Chebyshev y dice que al menos el 75% de los\n",
    "datos está a menos de 2 desviaciones, y al menos el 88,9% a menos de 3:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "m, s = v['monto'].mean(), v['monto'].std()\n",
    "\n",
    "for k, cota in [(2, 75.0), (3, 88.89)]:\n",
    "    dentro = 100 * (abs(v['monto'] - m) < k * s).mean()\n",
    "    print('a menos de %d desviaciones: %.2f%%  (Chebyshev garantiza %.2f%%)'\n",
    "          % (k, dentro, cota))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Se cumple con holgura, como tenía que ser. Chebyshev es una garantía mínima,\n",
    "floja pero universal: no hay ninguna distribución en el mundo que la rompa 🛡️"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Y dos más, que salen justo con el rango intercuartílico"
   ]
  },
  {
   "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",
    "    np.percentile(m, [25, 110])\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: Percentiles must be in the range [0, 100]\n",
    "```"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Un percentil va de 0 a 100 y no hay un 110. Suena obvio hasta que mezclas las dos formas de escribirlo: `np.percentile` quiere 25 y `pandas.quantile` quiere 0,25. Las dos calculan lo mismo y se piden distinto."
   ]
  },
  {
   "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",
    "    np.std(v['ciudad'])\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",
    "TypeError: Cannot perform reduction 'std' with string dtype\n",
    "```"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "La desviación estándar mide cuánto se alejan los valores del promedio, y para eso hay que poder restar. A \"lima\" menos \"cusco\" no se le puede pedir eso. Es la misma frontera del capítulo 2: el tipo decide qué cálculo tiene sentido 📏"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Practica 💪"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 1. El rango es de cristal\n",
    "\n",
    "Quita la venta más grande y la más chica y vuelve a\n",
    "calcular el rango. Compara también con el rango entre el percentil 1 y el 99."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "%%revisa 1\n",
    "# tu turno"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 2. ¿Varían igual todas las ciudades?\n",
    "\n",
    "Saca media, desviación y coeficiente de variación por\n",
    "ciudad. ¿Se parece al resultado de los segmentos?"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "%%revisa 2\n",
    "# tu turno"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 3. La desviación de un solo dato\n",
    "\n",
    "Calcula la desviación estándar de una serie con un solo\n",
    "valor. Antes de correrlo, piensa qué debería salir."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "%%revisa 3\n",
    "# tu turno"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 4. Compara la variabilidad de cosas incomparables\n",
    "\n",
    "¿Qué varía más en este archivo: el monto, las unidades, el\n",
    "descuento o la satisfacción? Están en unidades distintas, así que la desviación\n",
    "no sirve."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "%%revisa 4\n",
    "# tu turno"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 5. La desviación de una proporción\n",
    "\n",
    "Calcula la desviación estándar de `compro`, que\n",
    "es 0/1. Luego comprueba que coincide con la fórmula de la proporción."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "%%revisa 5\n",
    "# tu turno"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 6. Un resumen honesto en una línea\n",
    "\n",
    "Escribe una función que resuma una columna con centro y\n",
    "dispersión, eligiendo las medidas según si hay cola o no."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "%%revisa 6\n",
    "# tu turno"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 7. Las tres medidas sobre tres columnas\n",
    "\n",
    "Saca desviación, rango intercuartílico y desviación absoluta mediana de tres columnas y compáralas."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "%%revisa 7\n",
    "# tu turno"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 8. Cuánto pesa el uno por ciento de arriba\n",
    "\n",
    "Quita el 1% de montos más altos y mira cuánta dispersión se va con ellos."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "%%revisa 8\n",
    "# tu turno"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## La columna más estable, que no lo era"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Y ahora una comparación que parece de sentido común y que no lo es. Mírala despacio, que es de las que se cuelan solas 📏"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### La trampa\n",
    "\n",
    "Miras qué columna es más estable para decidir cuál vigilar. Comparas las desviaciones y una es enorme y la otra chiquita.\n",
    "\n",
    "```\n",
    "for c in ['monto', 'unidades']:\n",
    "    print(c, round(v[c].std(), 2))\n",
    "\n",
    "# monto     751.99\n",
    "# unidades    5.78\n",
    "```\n",
    "\n",
    "**¿Qué está mal?** La respuesta está en el cuaderno de soluciones. Míralo tú primero."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Comprueba que lo tienes\n",
    "\n",
    "Los cuatro segmentos tienen desviaciones de 69,59 a 719,55 y todos un coeficiente de variación de 0,37. ¿Qué dice eso del negocio?\n",
    "\n",
    "a) Que son el mismo negocio a distinta escala\n",
    "\n",
    "b) Que Mayorista es mucho más impredecible que Bodega\n",
    "\n",
    "c) Que hay que analizarlos por separado siempre\n",
    "\n",
    "d) Que las desviaciones están mal calculadas"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Lo que te llevas"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "- 📏 Un promedio sin dispersión es medio dato. Dos vendedores de 500 soles con\n",
    "desviaciones de 6,55 y 405,32 son dos negocios distintos.\n",
    "\n",
    "- 🔢 `ddof`: pandas divide entre n-1 y numpy entre n. Con 3.000\n",
    "filas da igual; con 3 datos son 22,5% de diferencia.\n",
    "\n",
    "- 📦 El IQR se explica solo: el 50% de las ventas está entre 252,69 y\n",
    "1.068,68.\n",
    "\n",
    "- ⚖️ El coeficiente de variación compara escalas distintas. Los cuatro\n",
    "segmentos tienen desviaciones de 69 a 719 y todos el mismo CV de 0,37: son el\n",
    "mismo negocio a distinto tamaño.\n",
    "\n",
    "- 🧺 El CV por ciudad es 0,9 y por segmento 0,37. La dispersión depende de\n",
    "cómo agrupas, no solo de los datos.\n",
    "\n",
    "- 🔔 La regla del 68% solo vale si hay campana. Aquí dio 68,70% en unidades,\n",
    "81,80% en monto y 59,44% en satisfacción.\n",
    "\n",
    "- 🛡️ Chebyshev sí vale siempre: al menos el 75% a dos desviaciones, pase lo\n",
    "que pase con la forma.\n",
    "\n",
    "Y si de todo el capítulo te llevas una sola frase, que sea esta:"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Un promedio sin su dispersión al lado no describe nada. Describe la mitad."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Y si vienes de Excel, esto es la `DESVEST` que quizá ya usaste sin\n",
    "saber qué contaba. La [guía de Excel](https://missyera.com/guias/excel-desde-cero/) lo\n",
    "cuenta desde ese lado 📊"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Qué viene ahora"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Llevamos dos capítulos usando la palabra \"campana\" sin comprobar si la hay.\n",
    "En el capítulo 5 la miramos de frente: qué es la distribución normal, cómo se\n",
    "comprueba si tus datos la siguen, y qué se rompe cuando no 🔔"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Preguntas frecuentes"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "¿Cuál es la fórmula de la desviación estándar?Se resta la media a cada dato, se eleva al cuadrado cada resta, se promedian esos cuadrados y se saca la raíz. Ese promedio de cuadrados es la varianza, y la desviación estándar es su raíz.\n",
    "\n",
    "¿Qué es la desviación estándar, en una frase?Cuánto se aleja un dato típico de la media, medido en las mismas unidades que los datos. Si tus ventas están en soles, la desviación está en soles.\n",
    "\n",
    "¿Cómo se calcula la desviación estándar paso a paso?Calcula la media, resta la media a cada dato, eleva cada resta al cuadrado, súmalos, divide entre el número de datos y saca la raíz. En Python es una línea, y en este capítulo está corriendo.\n",
    "\n",
    "¿Qué diferencia hay entre varianza y desviación estándar?La varianza está en unidades al cuadrado, así que no se puede leer: soles al cuadrado no significa nada. La desviación estándar es su raíz y vuelve a las unidades originales, por eso es la que se reporta.\n",
    "\n",
    "¿Es lo mismo desviación estándar que desviación típica?Sí, son dos nombres para lo mismo. \"Típica\" se usa más en España y \"estándar\" en América Latina.\n",
    "\n",
    "¿Qué es el coeficiente de variación?La desviación estándar dividida entre la media, en porcentaje. Sirve para comparar la dispersión de dos cosas que no están en la misma escala, como el ticket de Lima contra el de Cusco.\n",
    "\n",
    "¿Qué es la varianza?El promedio de los cuadrados de las distancias a la media. Es el paso de en medio para llegar a la desviación estándar, y sola casi no se reporta porque sus unidades no se pueden leer.\n",
    "\n",
    "¿Cuál es la fórmula de la varianza?La suma de las diferencias al cuadrado respecto de la media, dividida entre el número de datos. Si es una muestra y no la población entera, se divide entre uno menos.\n",
    "\n",
    "¿Qué diferencia hay entre varianza poblacional y muestral?El divisor. La poblacional divide entre n y la muestral entre n menos uno, y esa resta existe para corregir que una muestra siempre se ve un poco menos dispersa de lo que es la población.\n",
    "\n",
    "¿Qué símbolo tiene la varianza?Sigma al cuadrado para la población y s al cuadrado para la muestra. La desviación estándar es la misma letra sin el cuadrado.\n",
    "\n",
    "¿Cómo se calcula la desviación estándar en Excel?Con DESVEST.M si tus datos son una muestra y DESVEST.P si son la población entera. Elegir mal cambia poco con muchos datos y cambia bastante con pocos.\n",
    "\n",
    "¿Cuáles son las medidas de dispersión?El rango, el rango intercuartílico, la varianza y la desviación estándar. Todas contestan lo mismo con distinta prudencia frente a los datos raros."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "---\n",
    "\n",
    "Ese era el capítulo 4 de **Estadística desde cero**. El texto completo, con las salidas de cada bloque, está en https://missyera.com/guias/estadistica-desde-cero/dispersion/\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
}
