{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Estadistica: es real o es ruido\n",
    "\n",
    "Cuaderno de practica de la guia **Estadistica para analizar datos** de Miss Yera.\n",
    "Corre de arriba abajo. No necesitas instalar nada si lo abres en Google Colab.\n",
    "\n",
    "Los datos son ventas de una distribuidora peruana, con los defectos que traen\n",
    "los datos reales: fechas en dos formatos, la ciudad escrita de cuatro maneras,\n",
    "montos como texto, duplicados y tres tipos distintos de dato faltante.\n",
    "\n",
    "Guia completa: https://missyera.com/guias/estadistica-para-analizar-datos/"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "La unica pregunta que importa al mirar datos: **esta diferencia que veo es real o es variacion normal**. Aqui se responde con tus propios numeros."
   ]
  },
  {
   "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",
    "df = pd.read_csv(URL)\n",
    "\n",
    "print(df.shape)\n",
    "df.head()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "df[\"monto\"] = pd.to_numeric(df[\"monto\"].astype(str).str.replace(\",\", \".\", regex=False),\n",
    "                            errors=\"coerce\")\n",
    "df = df.drop_duplicates()\n",
    "ventas = df[df[\"monto\"] > 0].copy()\n",
    "print(len(ventas), \"ventas válidas\")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 1. La media miente y la mediana no\n",
    "\n",
    "Mira la diferencia entre las dos en una variable con cola larga. Esta es la decision mas comun y la que mas se equivoca."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "print(f\"media    S/{ventas['monto'].mean():,.2f}\")\n",
    "print(f\"mediana  S/{ventas['monto'].median():,.2f}\")\n",
    "print(f\"desviación estándar S/{ventas['monto'].std():,.2f}\")\n",
    "print()\n",
    "print(ventas[\"monto\"].describe())"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 2. La dispersion es la mitad que nadie mira\n",
    "\n",
    "Dos segmentos pueden tener promedios parecidos y no parecerse en nada."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "resumen = ventas.groupby(\"segmento\")[\"monto\"].agg(\n",
    "    n=\"count\", media=\"mean\", mediana=\"median\", desviacion=\"std\")\n",
    "resumen[\"coef_variacion\"] = resumen[\"desviacion\"] / resumen[\"media\"]\n",
    "resumen.round(2)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 3. La regla del 68 y el 95\n",
    "\n",
    "Si la distribucion se parece a una normal, dos de cada tres casos caen a una desviacion del promedio. Es el criterio mas rapido para decir si un valor es raro."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "m, s = ventas[\"monto\"].mean(), ventas[\"monto\"].std()\n",
    "for k in (1, 2, 3):\n",
    "    dentro = ventas[\"monto\"].between(m - k*s, m + k*s).mean()\n",
    "    print(f\"±{k} desviación: {dentro:.1%} de los casos\")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Si los porcentajes se alejan mucho de 68 / 95 / 99, tus datos **no** son normales y aplicar herramientas que lo asumen te va a dar conclusiones falsas."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 4. Prueba de hipotesis: dos canales, una diferencia\n",
    "\n",
    "La pregunta de negocio: vende mas la Web que la Tienda, o es casualidad."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from scipy import stats\n",
    "\n",
    "web = ventas[ventas[\"canal\"] == \"Web\"][\"monto\"]\n",
    "tienda = ventas[ventas[\"canal\"] == \"Tienda\"][\"monto\"]\n",
    "\n",
    "print(f\"Web    n={len(web):5}  media S/{web.mean():,.2f}\")\n",
    "print(f\"Tienda n={len(tienda):5}  media S/{tienda.mean():,.2f}\")\n",
    "print(f\"diferencia: S/{web.mean() - tienda.mean():,.2f}\")\n",
    "\n",
    "t, p = stats.ttest_ind(web, tienda, equal_var=False)\n",
    "print(f\"\\nt = {t:.3f}   valor p = {p:.4f}\")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "**Como se lee ese valor p.** NO es la probabilidad de que la Web venda mas. Es qué tan raro seria ver esta diferencia si en realidad los dos canales vendieran igual. Si sale alto, la diferencia que ves cabe dentro de la variacion normal y la reunion para explicarla sobra."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 5. El intervalo de confianza dice mas que el valor p\n",
    "\n",
    "En vez de \"hay diferencia\" o \"no hay\", da el rango honesto."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "dif = web.mean() - tienda.mean()\n",
    "ee = np.sqrt(web.var(ddof=1)/len(web) + tienda.var(ddof=1)/len(tienda))\n",
    "print(f\"diferencia S/{dif:,.2f}  IC 95%: [{dif - 1.96*ee:,.2f}, {dif + 1.96*ee:,.2f}]\")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Si el intervalo cruza el cero, no puedes afirmar que haya diferencia."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 6. Correlacion, y la frase que hay que decir en voz alta"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "num = ventas[[\"monto\", \"unidades\", \"descuento\", \"satisfaccion\"]]\n",
    "num.corr().round(3)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Toma el par con la correlacion mas alta y hazte la pregunta correcta: **que tercera variable podria estar moviendo a las dos**. La correlacion es una observacion; la causa requiere un experimento."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 7. Buscar hasta encontrar\n",
    "\n",
    "Esta celda muestra por que probar veinte cosas hasta que una salga significativa no es un hallazgo."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "rng = np.random.default_rng(7)\n",
    "significativos = 0\n",
    "for _ in range(20):\n",
    "    a = rng.normal(size=200)\n",
    "    b = rng.normal(size=200)          # dos series SIN ninguna relación real\n",
    "    if stats.ttest_ind(a, b).pvalue < 0.05:\n",
    "        significativos += 1\n",
    "print(f\"de 20 pruebas sobre datos sin relación, {significativos} salieron 'significativas'\")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Lo que te llevas\n",
    "\n",
    "Cuatro preguntas que valen por todo el cuaderno:\n",
    "\n",
    "1. La diferencia que reporto, esta dentro de la variacion normal.\n",
    "2. Estoy dando un promedio sin decir cuanto varia.\n",
    "3. Esta correlacion la estoy presentando como causa.\n",
    "4. Cuantas hipotesis probe antes de quedarme con esta."
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "name": "python",
   "version": "3.11"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}