{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# De dónde salen los datos que estás mirando\n",
    "\n",
    "Muestreo aleatorio, de conveniencia y estratificado, medidos sobre la misma población. Y por qué más datos no arreglan una muestra torcida.\n",
    "\n",
    "Cuaderno de soluciones del capítulo 9 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/de-donde-salen-los-datos/\n",
    "\n",
    "Este es el cuaderno de **soluciones**. Trae el código de cada ejercicio, la\n",
    "explicación de la trampa y la respuesta del quiz. Si vienes del cuaderno de\n",
    "práctica sin haberlo intentado, vuelve 🙂"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Los ocho capítulos anteriores dan por hecho una cosa que nadie comprueba: que\n",
    "los datos que tienes delante representan a lo que quieres saber 🎯\n",
    "\n",
    "Y ese supuesto es el que más veces se cae. Un promedio bien calculado sobre\n",
    "una muestra torcida es un número perfecto de algo que no te interesa.\n",
    "\n",
    "Aquí tenemos una ventaja que en la vida real no vas a tener nunca:\n",
    "**conocemos la población entera**. Son 3.000 pedidos y podemos\n",
    "mirarlos todos. Así que podemos sacar muestras de tres maneras distintas y\n",
    "comparar cada una contra la verdad."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "import numpy as np\n",
    "import pandas as pd\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).dropna(subset=['monto'])\n",
    "POBLACION = v['monto'].mean()\n",
    "\n",
    "print('pedidos en total: %d' % len(v))\n",
    "print('ticket promedio de TODOS: %.2f' % POBLACION)\n",
    "print()\n",
    "print(v.groupby('segmento')['monto'].agg(['count', 'mean']).round(2)\n",
    "      .sort_values('mean').to_string())"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Guárdate esa tabla, que es el motor de todo lo que viene 🔑\n",
    "\n",
    "Un mayorista compra **diez veces** lo que una bodega: 1.856,34\n",
    "contra 178,70. Cuando dentro de tu población hay grupos así de distintos, a quién\n",
    "metes en la muestra deja de ser un detalle administrativo.\n",
    "\n",
    "Y antes de seguir, contéstate esto: **¿hacia dónde se te iría el número\n",
    "si preguntaras solo a los clientes que tienes más a mano?** 🐣"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Lo que pasa cuando se saca bien"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Muestreo aleatorio simple: cada pedido tiene exactamente la misma probabilidad\n",
    "de entrar. Lo sacamos 500 veces para no juzgar por una sola:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "def promedios(sacar, veces=500):\n",
    "    \"\"\"El ticket promedio de `veces` muestras sacadas con `sacar`.\"\"\"\n",
    "    return np.array([sacar(s)['monto'].mean() for s in range(veces)])\n",
    "\n",
    "\n",
    "al_azar = promedios(lambda s: v.sample(200, random_state=s))\n",
    "print('poblacion:              %.2f' % POBLACION)\n",
    "print('promedio de 500 muestras: %.2f' % al_azar.mean())\n",
    "print('sesgo:                    %+.2f' % (al_azar.mean() - POBLACION))\n",
    "print('cuanto varian entre si:   %.2f' % al_azar.std())"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Cuarenta y nueve céntimos de sesgo sobre 803 soles. Eso es cero 💚\n",
    "\n",
    "Y fíjate en que hay **dos números distintos** y no uno, porque\n",
    "son dos problemas distintos:\n",
    "\n",
    "- 📍 El **sesgo** es si le apuntas al sitio correcto. Aquí, sí.\n",
    "\n",
    "- 📏 La **variación** es lo que se mueve una muestra de otra.\n",
    "Cincuenta soles, que no es poco.\n",
    "\n",
    "La variación se arregla con más datos, y eso ya lo sabías por el capítulo\n",
    "10. El sesgo no. Y esa diferencia es el capítulo\n",
    "entero."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Y ahora una muestra como se saca de verdad"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Nadie encuesta al azar. Se encuesta a quien contesta, a quien pasa por la\n",
    "tienda, a quien el vendedor visita. Y el vendedor no visita a todos igual:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "VISIBILIDAD = {'Bodega': 1, 'Minimarket': 2, 'Horeca': 4, 'Mayorista': 8}\n",
    "peso = v['segmento'].map(VISIBILIDAD)\n",
    "\n",
    "conveniencia = promedios(\n",
    "    lambda s: v.sample(200, weights=peso, replace=True, random_state=s))\n",
    "\n",
    "print('lo que el vendedor visita, por cada bodega:')\n",
    "for seg, cuantas in VISIBILIDAD.items():\n",
    "    print('   %-11s %d' % (seg, cuantas))\n",
    "print()\n",
    "print('poblacion:                 %.2f' % POBLACION)\n",
    "print('lo que mide la encuesta:   %.2f' % conveniencia.mean())\n",
    "print('sesgo:                     %+.2f soles' % (conveniencia.mean() - POBLACION))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Cuatrocientos cincuenta y cinco soles 😱\n",
    "\n",
    "El ticket real es 803,76 y la encuesta dice 1.258,98. Un **57% de\n",
    "más**, y ni una sola línea del cálculo está mal: el promedio está bien\n",
    "hecho, la muestra tiene 200 pedidos de verdad, todo corre. Lo que está mal es\n",
    "quién entró.\n",
    "\n",
    "Y no hace falta que nadie mienta ni haga trampa. Basta con que el vendedor\n",
    "pase más por donde le compran más, que es lo que hace cualquier vendedor\n",
    "sensato."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## La tabla que hay que enseñarle a quien pide \"más datos\""
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Cuando un número no cuadra, lo primero que dice todo el mundo es \"hay que\n",
    "recoger más\". Vamos a ver si eso arregla algo:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "print('%8s %12s %10s %12s' % ('n', 'promedio', 'sesgo', 'variacion'))\n",
    "for n in [100, 400, 1600, 6400]:\n",
    "    m = promedios(lambda s: v.sample(n, weights=peso, replace=True, random_state=s), 200)\n",
    "    print('%8d %12.2f %+10.2f %12.2f' % (n, m.mean(), m.mean() - POBLACION, m.std()))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Léela de arriba abajo dos veces 😬\n",
    "\n",
    "La columna de la derecha baja bien: de 86 a 11. Con 6.400 encuestas tu número\n",
    "es **ocho veces más estable** que con 100.\n",
    "\n",
    "Y la del medio no se mueve. 453, 451, 450, 452. Sesenta y cuatro veces más\n",
    "datos y el error sigue ahí entero.\n",
    "\n",
    "O sea que recoger más datos de la misma manera torcida te deja\n",
    "**más seguro de un número equivocado**. Que es peor que estar\n",
    "inseguro, porque ahora lo defiendes en la reunión con un intervalo estrecho al\n",
    "lado."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Más datos arreglan la variación y no arreglan el sesgo. Una muestra torcida con muchas filas es una muestra torcida con un intervalo estrecho."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Cómo se arregla, que es más fácil de lo que parece"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Si el problema es que unos grupos entran de más y otros de menos, la solución\n",
    "es sacar de cada grupo lo que le toca. Eso se llama **muestreo\n",
    "estratificado**:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "reparto = v['segmento'].value_counts(normalize=True)\n",
    "print('como es el negocio de verdad:')\n",
    "print((reparto * 100).round(1).to_string())\n",
    "\n",
    "\n",
    "def estratificada(s):\n",
    "    trozos = [v[v['segmento'] == seg].sample(int(round(200 * w)), random_state=s)\n",
    "              for seg, w in reparto.items()]\n",
    "    return pd.concat(trozos)\n",
    "\n",
    "\n",
    "estrato = promedios(estratificada)\n",
    "print()\n",
    "print('%-22s %10s %10s %10s' % ('como se saca', 'promedio', 'sesgo', 'variacion'))\n",
    "for nombre, m in [('al azar', al_azar), ('por conveniencia', conveniencia),\n",
    "                  ('estratificada', estrato)]:\n",
    "    print('%-22s %10.2f %+10.2f %10.2f' % (nombre, m.mean(), m.mean() - POBLACION, m.std()))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Mira la última fila entera, que tiene dos buenas noticias 💜\n",
    "\n",
    "El sesgo se fue, como era de esperar. Pero además **la variación baja de\n",
    "50,10 a 28,62**, un 43% menos, con exactamente el mismo número de\n",
    "encuestas.\n",
    "\n",
    "Eso no es magia: al forzar que cada segmento aparezca en su proporción, quitas\n",
    "de en medio la lotería de cuántos mayoristas te tocaron esta vez. Estratificar no\n",
    "solo corrige, también **afina gratis**, y por eso es lo que hacen\n",
    "las encuestas serias.\n",
    "\n",
    "La condición para poder hacerlo es una y hay que decirla: tienes que\n",
    "**conocer el reparto real de la población**. Aquí lo conocemos\n",
    "porque tenemos la base entera. En una encuesta de calle se saca del censo, del\n",
    "padrón de clientes o de lo que haya, y si no lo tienes, no puedes estratificar."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## El error que sale al inventarse los pesos"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Y este sale el primer día que alguien decide pesar por algo:"
   ]
  },
  {
   "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.sample(200, weights=v['monto'] - POBLACION, random_state=0)\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: weight vector many not include negative values\n",
    "```"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Pesar por \"cuánto se aleja del promedio\" suena razonable hasta que lo escribes:\n",
    "la mitad de los pedidos están por debajo, así que la mitad de los pesos salen\n",
    "negativos. Y un peso negativo no significa nada, porque no puedes meter a alguien\n",
    "*menos* de cero veces 🚩\n",
    "\n",
    "Lo de *many* en vez de *may* es una errata de pandas, no mía. La\n",
    "dejo tal cual porque es lo que vas a ver en tu pantalla."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Los cuatro muestreos que se usan, en una tabla"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "| Cómo se saca | Cuándo | Qué le pasa |\n",
    "|---|---|---|\n",
    "| **Aleatorio simple** | Cuando tienes la lista completa de clientes | Sin sesgo. Es el patrón contra el que se compara todo |\n",
    "| **Estratificado** | Cuando hay grupos muy distintos y sabes su peso real | Sin sesgo y con menos variación. El mejor si puedes |\n",
    "| **Por conglomerados** | Cuando visitar cuesta: eliges 3 ciudades y encuestas todo dentro | Barato, y con más variación. Vale si eliges los conglomerados al azar |\n",
    "| **Por conveniencia** | Cuando preguntas a quien está a mano, que es lo que pasa casi siempre | Sesgo desconocido. Lo medido aquí: +455 soles |"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "La cuarta fila es la que de verdad usas, y no pasa nada por usarla: lo que no\n",
    "puedes es olvidarte de que la usaste. **Una encuesta de conveniencia se\n",
    "reporta diciendo a quién se preguntó**, y entonces quien lee decide cuánto\n",
    "se lo cree 🔍\n",
    "\n",
    "Y hay un quinto caso que no es un método sino una avería: la **no\n",
    "respuesta**. Mandas la encuesta al azar, bien sacada, y contesta el 12%.\n",
    "Ese 12% ya no es una muestra aleatoria, es una muestra de conveniencia de la\n",
    "gente a la que le apetece contestar. El sesgo entra por ahí aunque el diseño\n",
    "fuera perfecto.\n",
    "\n",
    "Si quieres el detalle formal, el\n",
    "[INEI](https://www.inei.gob.pe/) publica las fichas técnicas de sus\n",
    "encuestas con el diseño muestral entero, y son de lo mejor que hay para ver esto\n",
    "escrito en serio y sobre el Perú 📄"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### La trampa\n",
    "\n",
    "Un equipo quiere una encuesta estratificada y escribe los pesos a mano. La muestra sale, el código no se queja, y el ticket promedio les da 547,81 cuando el real es 803,76.\n",
    "\n",
    "```\n",
    "PESOS = {'Bodega': 1, 'Minimarket': 2, 'Horeca': 4}\n",
    "peso = v['segmento'].map(PESOS)\n",
    "\n",
    "muestra = v.sample(200, weights=peso, replace=True, random_state=0)\n",
    "print(muestra['monto'].mean())    # 547.81\n",
    "```\n",
    "\n",
    "**Qué está mal**\n",
    "\n",
    "Falta **Mayorista** en el diccionario. Al mapear, esas 750 filas se quedan en `NaN`, y pandas trata un peso ausente como un cero: el segmento que más factura, 1.856,34 de ticket, queda excluido de la muestra **sin un solo aviso**. Por eso el promedio se cae a 547,81. Esto es peor que el sesgo de conveniencia del capítulo, porque allí al menos sabías que estabas preguntando a quien tenías a mano. La comprobación que lo caza cabe en una línea y hay que hacerla siempre después de muestrear: `muestra[\"segmento\"].value_counts()`. Si falta una categoría que existe en la población, ahí está el problema."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Ejercicios"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Seis. El 1 es la trampa de arriba ejecutada, y el 4 es el que te va a servir\n",
    "en el trabajo 💛"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 1. Olvídate de un segmento a propósito\n",
    "\n",
    "Quita `Mayorista` del diccionario de pesos y mira\n",
    "qué sale."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "PESOS = {'Bodega': 1, 'Minimarket': 2, 'Horeca': 4}\n",
    "mala = v.sample(200, weights=v['segmento'].map(PESOS), replace=True, random_state=0)\n",
    "print('promedio:', round(mala['monto'].mean(), 2))\n",
    "print(mala['segmento'].value_counts().to_string())\n",
    "La segunda línea es la que hay que interiorizar: después de sacar una muestra,\n",
    "cuenta siempre qué hay dentro. Es donde se ve lo que no está."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 2. Cambia lo que el vendedor visita\n",
    "\n",
    "Prueba con `VISIBILIDAD` al revés, o sea que\n",
    "visite ocho veces más a las bodegas."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "El sesgo tiene que darse la vuelta y salir negativo. Y eso enseña algo que no\n",
    "es obvio: **el sesgo no siempre exagera**. Una encuesta mal sacada\n",
    "puede hacerte creer que vendes menos de lo que vendes, y ese error nadie lo\n",
    "sospecha porque las malas noticias se creen antes."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 3. Estratifica por ciudad en vez de por segmento\n",
    "\n",
    "Repite el estratificado usando `ciudad` y compara\n",
    "la variación con la del estratificado por segmento."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Va a bajar mucho menos. La razón es la tabla del principio: las ciudades se\n",
    "parecen entre sí (de 780 a 842) y los segmentos no (de 178 a 1.856). Estratificar\n",
    "sirve cuando **los grupos son distintos entre ellos y parecidos por\n",
    "dentro**, y si eliges la columna equivocada no aporta nada."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 4. La comprobación que se hace en el trabajo\n",
    "\n",
    "Escríbela como función y déjala puesta: comparar el reparto\n",
    "de tu muestra contra el de la población."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "def cuadra(muestra, columna='segmento'):\n",
    "    tabla = pd.DataFrame({\n",
    "        'poblacion': v[columna].value_counts(normalize=True),\n",
    "        'muestra': muestra[columna].value_counts(normalize=True),\n",
    "    })\n",
    "    tabla['diferencia'] = (tabla['muestra'] - tabla['poblacion']) * 100\n",
    "    return tabla.round(3)\n",
    "\n",
    "print(cuadra(v.sample(200, weights=peso, replace=True, random_state=0)))\n",
    "Esta es la que de verdad vas a usar. No te dice si tu muestra es buena, que\n",
    "eso no se puede saber del todo, pero te dice si está torcida **en las\n",
    "columnas que sí puedes mirar**, y eso ya caza casi todo."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 5. La no respuesta, simulada\n",
    "\n",
    "Saca una muestra aleatoria bien hecha de 500 y después quita\n",
    "al azar el 88%, pero con más probabilidad de quedarse los mayoristas."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "El diseño era perfecto y el resultado sale torcido igual. Es lo que pasa en\n",
    "toda encuesta de verdad, y por eso las fichas técnicas serias reportan la tasa de\n",
    "respuesta: sin ese número no se puede juzgar nada."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 6. Cuánto cuesta el sesgo en soles\n",
    "\n",
    "Si tomaras una decisión de compra de inventario con el\n",
    "promedio de la encuesta de conveniencia en vez del real, ¿de cuánto sería el\n",
    "error para 10.000 pedidos previstos?"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Son 455,21 por 10.000. Escríbelo en soles y ponlo en la primera línea del\n",
    "informe, que es donde la gente sí lo lee. Esa traducción a dinero es la misma que\n",
    "hace el capítulo 19 💰"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 7. Cuánto se aleja una muestra según su tamaño\n",
    "\n",
    "Saca trescientas muestras de cada tamaño y mide, en soles, a qué distancia queda su promedio del promedio real."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "for cuantas in [30, 100, 300, 1000]:\n",
    "    lejos = np.abs(promedios(lambda s: v.sample(cuantas, random_state=s),\n",
    "                             veces=300) - POBLACION)\n",
    "    print('con %4d filas: se aleja %6.2f soles de media, y hasta %7.2f'\n",
    "          % (cuantas, lejos.mean(), lejos.max()))\n",
    "con   30 filas: se aleja 110.81 soles de media, y hasta  393.56\n",
    "con  100 filas: se aleja  58.20 soles de media, y hasta  209.94\n",
    "con  300 filas: se aleja  32.93 soles de media, y hasta  113.40\n",
    "con 1000 filas: se aleja  14.60 soles de media, y hasta   53.62\n",
    "Mira la última columna, que es la que asusta 😨\n",
    "\n",
    "Con treinta filas hubo una muestra que se fue 393 soles del promedio real, o sea casi la mitad del promedio entero. Y no era una muestra mala ni mal sacada: era al azar, como debe ser.\n",
    "\n",
    "**El tamaño no cambia si aciertas, cambia cuánto te puedes equivocar sin darte cuenta.** Y fíjate en que pasar de 30 a 1000 filas, que es multiplicar por treinta y tres, solo divide el error entre siete y medio. Por eso conseguir datos cuesta tanto 💸"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 8. Al azar y estratificada, una al lado de la otra\n",
    "\n",
    "Saca 120 filas de las dos maneras y compara el reparto de segmentos de cada una contra el reparto real."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "reparto = v['segmento'].value_counts(normalize=True).sort_index()\n",
    "una = v.sample(120, random_state=3)['segmento'].value_counts(normalize=True).sort_index()\n",
    "otra = estratificada(120)['segmento'].value_counts(normalize=True).sort_index()\n",
    "print('%-12s %9s %9s %9s' % ('segmento', 'real', 'al azar', 'estrat.'))\n",
    "for seg in reparto.index:\n",
    "    print('%-12s %9.3f %9.3f %9.3f'\n",
    "          % (seg, reparto[seg], una.get(seg, 0), otra.get(seg, 0)))\n",
    "segmento          real   al azar   estrat.\n",
    "Bodega           0.236     0.300     0.236\n",
    "Horeca           0.247     0.200     0.246\n",
    "Mayorista        0.250     0.258     0.251\n",
    "Minimarket       0.267     0.242     0.266\n",
    "La tercera columna clava el reparto hasta el tercer decimal 🎯\n",
    "\n",
    "Y la del medio no: sacó 30 por ciento de bodegas cuando en realidad son 23,6 por ciento, y se quedó corta de horeca. Con 120 filas eso pasa sin que nadie haga nada mal.\n",
    "\n",
    "Acuérdate de lo que separa el segmento en estos datos, que lo viste en 1: **si la columna que más separa te sale descuadrada en la muestra, el promedio que calcules encima ya nace torcido**. Estratificar cuesta una línea y quita ese riesgo 🧺"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Comprueba que lo tienes\n",
    "\n",
    "Tu encuesta a 6.000 clientes dice que el ticket promedio es 1.250 soles, y la contabilidad dice 800. ¿Qué miras primero?\n",
    "\n",
    "a) A quién se le preguntó, y si ese reparto se parece al de tus clientes\n",
    "\n",
    "b) Si 6.000 son suficientes\n",
    "\n",
    "c) Si hay atípicos que estén subiendo el promedio\n",
    "\n",
    "d) Si la encuesta se hizo en un mes raro\n",
    "\n",
    "---\n",
    "\n",
    "**La correcta es la a.**\n",
    "\n",
    "*b)* Seis mil son un montón. Y el capítulo mide que con 6.400 el error sigue entero: el tamaño no era el problema.\n",
    "\n",
    "*c)* Vale la pena mirarlo y no explica una diferencia del 57%. Además, la contabilidad tiene los mismos atípicos y le sale 800.\n",
    "\n",
    "*d)* Puede influir, y es un efecto chico al lado de este. Empieza por lo que explica 450 soles y no 20.\n",
    "\n",
    "Cuando un número de encuesta y uno de sistema no cuadran, casi siempre el problema está en quién entró y no en cuántos."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Lo que te llevas"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "- 🎯 Sesgo y variación son dos cosas distintas. Sesgo es apuntar mal, variación\n",
    "es que te tiemble el pulso.\n",
    "\n",
    "- 📈 Más datos arreglan la variación (de 86 a 11) y no tocan el sesgo (453 y\n",
    "sigue en 452 con 64 veces más filas).\n",
    "\n",
    "- 🚪 Una muestra de conveniencia da 1.258,98 donde la verdad es 803,76, y todo\n",
    "el cálculo está bien hecho.\n",
    "\n",
    "- 🧱 Estratificar quita el sesgo y además baja la variación un 43% con el mismo\n",
    "número de encuestas, si conoces el reparto real.\n",
    "\n",
    "- 🔍 Después de muestrear, cuenta siempre qué hay dentro de la muestra. Ahí se\n",
    "ve lo que falta.\n",
    "\n",
    "El capítulo 10 le pone un intervalo a lo que\n",
    "mediste, y ahora ya sabes que ese intervalo solo vale si la muestra estaba bien\n",
    "sacada. El sesgo no entra en ningún intervalo.\n",
    "\n",
    "Y si quieres el vocabulario suelto de todo esto, está definido en dos líneas\n",
    "por término en el [glosario de IA](https://missyera.com/glosario-ia/) 📖\n",
    "\n",
    "Que tengas lindo día! 🌸"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "---\n",
    "\n",
    "Ese era el capítulo 9 de **Estadística desde cero**. El texto completo, con las salidas de cada bloque, está en https://missyera.com/guias/estadistica-desde-cero/de-donde-salen-los-datos/\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
}
