---
name: correlation_ratio
kind: function
lang: py
domain: datascience
version: "1.0.0"
purity: pure
signature: "def correlation_ratio(categories: list, values: list) -> float"
description: "Correlation ratio eta (η): mide cuanto explica una variable categorica de la varianza de una variable numerica, en [0,1]. η²=varianza entre grupos/varianza total; devuelve η=sqrt(η²). Es la metrica num↔cat de una matriz de asociacion mixta (analoga a Cramer's V para cat↔cat o Pearson para num↔num). Descarta pares con categoria None o valor None/NaN/no-numerico. Si <2 grupos distintos o varianza total 0 devuelve 0.0 (float, nunca None ni excepcion)."
tags: [eda, correlation, association, categorical, numeric, statistics, datascience]
params:
  - name: categories
    desc: "Lista de etiquetas categoricas (cualquier hashable: str, int, etc.). Define los grupos. None en una posicion descarta ese par."
  - name: values
    desc: "Lista de valores numericos pareada con categories (mismo orden e indice). None, NaN o no-numerico descarta ese par."
output: "eta (η) en rango [0,1] como float. 1.0 = la categorica explica toda la varianza de la numerica (medias de grupo muy separadas); 0.0 = no la explica (medias de grupo iguales o datos degenerados). Nunca None ni excepcion."
uses_functions: []
uses_types: []
returns: []
returns_optional: false
error_type: ""
imports: []
tested: true
tests: ["test_high_eta_when_groups_separated", "test_low_eta_when_random", "test_single_group_returns_zero", "test_zero_total_variance_returns_zero", "test_skips_none_and_nan_pairs", "test_result_in_unit_range"]
test_file_path: "python/functions/datascience/correlation_ratio_test.py"
file_path: "python/functions/datascience/correlation_ratio.py"
---

## Ejemplo

```python
from datascience import correlation_ratio

# La categoria separa claramente los valores -> eta alto (cercano a 1)
categories = ["A", "A", "A", "B", "B", "B", "C", "C", "C"]
values     = [ 1,   2,   1,   10,  11,  10,  20,  21,  20 ]
print(round(correlation_ratio(categories, values), 3))  # ~0.997

# Categoria sin relacion con los valores -> eta bajo (cercano a 0)
import random
random.seed(0)
cats = [random.choice(["x", "y", "z"]) for _ in range(300)]
vals = [random.gauss(0, 1) for _ in range(300)]
print(round(correlation_ratio(cats, vals), 3))  # ~0.0 - 0.1
```

## Cuando usarla

Cuando quieras saber **si una variable categorica explica una numerica**: pais → salario,
ciudad → precio de vivienda, segmento de cliente → ticket medio. Es la celda num↔cat de una
matriz de asociacion mixta para EDA — combinala con Pearson/Spearman (num↔num) y Cramer's V
(cat↔cat). Un η alto indica que conocer el grupo reduce mucho la incertidumbre sobre el valor.

## Gotchas

Funcion pura, sin gotchas de efectos. Notas de comportamiento:
- η NO es simetrica: mide cat→num, no num→cat. No la uses al reves.
- η no distingue direccion ni linealidad: solo cuanta varianza separan los grupos.
- Pocos datos por grupo inflan η al alza (sobreajuste a medias ruidosas); con grupos de
  tamaño 1 cada grupo "explica" su punto. Interpretar con cautela en muestras pequeñas.
