---
name: effect_size_cohens_d
kind: function
lang: py
domain: datascience
version: "1.0.0"
purity: pure
signature: "def effect_size_cohens_d(group_a: list, group_b: list) -> dict"
description: "Tamano del efecto (effect size) entre dos grupos numericos: Cohen's d (diferencia de medias estandarizada por la desviacion tipica combinada, varianzas muestrales ddof=1), Hedges' g (d corregido por el sesgo al alza con muestras pequenas via el factor J) e interpretacion cualitativa de la magnitud segun los umbrales clasicos de Cohen (negligible/small/medium/large). El p-valor dice si hay diferencia; el effect size dice como de grande, de forma adimensional e independiente del N. Pura, sin dependencias externas; nunca lanza: los casos degenerados (varianza cero, N<2, listas vacias) devuelven NaN + una clave note."
tags: [papers, statistics, effect-size, cohens-d, hedges-g, python]
params:
  - name: group_a
    desc: "primera muestra (lista de numeros). Necesita >=2 observaciones para que exista la varianza muestral (ddof=1)."
  - name: group_b
    desc: "segunda muestra (lista de numeros). Necesita >=2 observaciones. El signo de cohens_d es positivo cuando mean_a > mean_b."
output: "dict {cohens_d: float (diferencia de medias estandarizada, puede ser NaN), hedges_g: float (cohens_d * factor de correccion J, puede ser NaN), interpretation: str ('negligible'|'small'|'medium'|'large', o 'undefined' en casos degenerados), n_a: int, n_b: int, mean_a: float, mean_b: float, pooled_sd: float (desviacion tipica combinada)}. Casos degenerados (varianza cero en ambos grupos, N<2 en algun grupo, o listas vacias) anaden clave note. Nunca None ni excepcion."
uses_functions: []
uses_types: []
returns: []
returns_optional: false
error_type: ""
imports: [math]
tested: true
tests: ["test_golden_large_effect", "test_hedges_g_menor_en_magnitud_que_cohens_d", "test_interpretation_thresholds", "test_signo_positivo_cuando_a_mayor_que_b", "test_varianza_cero_no_lanza", "test_n_insuficiente_no_lanza", "test_listas_vacias_no_lanza", "test_un_grupo_vacio_no_lanza"]
test_file_path: "python/functions/datascience/effect_size_cohens_d_test.py"
file_path: "python/functions/datascience/effect_size_cohens_d.py"
---

## Ejemplo

```python
from datascience import effect_size_cohens_d

# Dos grupos desplazados 2 unidades, misma dispersion.
a = [1, 2, 3, 4, 5]   # media 3, varianza muestral 2.5
b = [3, 4, 5, 6, 7]   # media 5, varianza muestral 2.5

out = effect_size_cohens_d(a, b)
print(out["cohens_d"])        # -> -1.264911...  (a esta 1.26 SD por debajo de b)
print(out["hedges_g"])        # -> -1.142500...  (|g| < |d|: correccion N pequeno)
print(out["interpretation"])  # -> "large"       (|d| >= 0.8)
print(out["pooled_sd"])       # -> 1.581138...

# Caso degenerado: varianza cero -> no lanza, NaN + note.
deg = effect_size_cohens_d([5, 5, 5], [5, 5, 5])
print(deg["interpretation"])  # -> "undefined"
print(deg["note"])            # -> "varianza cero, effect size indefinido"
```

## Cuando usarla

Cuando ya sepas que dos grupos difieren (o quieras cuantificar su diferencia)
y necesites una medida **de magnitud, no de significancia**: comparar el antes
y el despues de una intervencion, el grupo control frente al tratamiento, o dos
cohortes. Reportala junto al p-valor para responder "¿como de grande es la
diferencia?" — un p-valor minusculo con N enorme puede esconder un efecto
trivial. Es adimensional (en unidades de desviaciones tipicas), asi que hace
comparables resultados entre estudios y alimenta meta-analisis. Usa **Hedges' g**
en lugar de Cohen's d cuando los grupos sean pequenos (decenas o menos): d
sobreestima el efecto y g lo corrige.

## Gotchas

- Pura y sin dependencias externas (solo `math` de la stdlib).
- Usa **varianza muestral** (ddof=1), no poblacional. Por eso cada grupo
  necesita al menos 2 observaciones; con N=1 la varianza muestral no existe y la
  funcion devuelve NaN + `note`.
- **Nunca lanza excepcion**. Los casos degenerados devuelven `cohens_d` y
  `hedges_g` a `float('nan')`, `interpretation="undefined"` y una clave `note`:
  varianza cero en ambos grupos (`pooled_sd == 0`), N<2 en algun grupo, o listas
  vacias. Comprueba con `math.isnan(out["cohens_d"])` o la presencia de `note`
  antes de usar el resultado.
- El **signo** de `cohens_d` depende del orden de los argumentos: positivo si
  `mean_a > mean_b`, negativo en caso contrario. La `interpretation` usa `|d|`,
  asi que no depende del orden.
- `pooled_sd` asume varianzas comparables entre grupos (homogeneidad). Si las
  dispersiones son muy distintas, Cohen's d clasico pierde precision; considera
  variantes (Glass's delta) fuera del alcance de esta funcion.
- Los umbrales de Cohen (0.2 / 0.5 / 0.8) son convencion, no ley: interpretalos
  segun el dominio.
