---
name: detect_corpus_language
kind: function
lang: py
domain: datascience
version: "1.0.0"
purity: pure
signature: "def detect_corpus_language(texts, top_k=10, sample_max=1000) -> dict"
description: "Estima la distribucion de idiomas de un corpus de textos con la libreria langdetect (import perezoso). Funcion pura y defensiva del grupo eda: filtra documentos None/no-str/vacios, muestrea hasta sample_max docs, clasifica cada uno con detect() ignorando los que langdetect no puede resolver (LangDetectException), y devuelve la distribucion top_k por frecuencia mas el idioma dominante. Si langdetect no esta instalada o algo falla, degrada a {available: False, ...} y NUNCA lanza (dict-no-throw). Seed fija (DetectorFactory.seed=0) para deteccion determinista."
tags: [eda, datascience, text, nlp, language-detection, langdetect, pure, python]
params:
  - name: texts
    desc: "Lista de strings (documentos). Los elementos None, no-str o vacios tras strip se descartan antes de clasificar."
  - name: top_k
    desc: "Numero maximo de idiomas a devolver en distribution, ordenados por count descendente (desempate por codigo ISO ascendente). Default 10."
  - name: sample_max
    desc: "Numero maximo de documentos a clasificar (se toman los primeros del corpus) para acotar el coste. Default 1000."
output: >
  Dict con forma fija (dict-no-throw, nunca lanza):
  {"available": bool, "n_detected": int,
   "distribution": [{"lang": str, "count": int, "pct": float}, ...],
   "dominant": str|None}.
  available=True si langdetect es importable; lang son codigos ISO 639-1 ("es","en","fr",...);
  pct = count/n_detected*100 redondeado a 2 decimales; n_detected = docs clasificados con exito;
  dominant = idioma mas frecuente (None si no hubo detecciones). Corpus vacio con langdetect
  presente -> available True, n_detected 0, distribution [], dominant None. Sin langdetect (o
  fallo global) -> available False y el resto de campos a su valor vacio.
uses_functions: []
uses_types: []
returns: []
returns_optional: false
error_type: ""
imports: [langdetect]
tested: true
tests: ["test_mixto_es_en", "test_vacio", "test_degradacion"]
test_file_path: "python/functions/datascience/detect_corpus_language_test.py"
file_path: "python/functions/datascience/detect_corpus_language.py"
---

## Ejemplo

```python
import sys, os
sys.path.insert(0, os.path.join("python", "functions"))
from datascience.detect_corpus_language import detect_corpus_language

corpus = [
    "este es un texto bastante largo en español para detectar el idioma correctamente",
    "la inteligencia artificial transforma la manera en que trabajamos cada dia",
    "this is a fairly long english text to detect the language correctly without issues",
]
out = detect_corpus_language(corpus)
# {"available": True, "n_detected": 3,
#  "distribution": [{"lang": "es", "count": 2, "pct": 66.67},
#                   {"lang": "en", "count": 1, "pct": 33.33}],
#  "dominant": "es"}
```

## Cuando usarla

Cuando perfiles una columna o corpus de texto en un EDA y necesites saber en
que idioma(s) esta escrito antes de elegir tokenizadores, stopwords, modelos
NLP o stemmers. Util tambien como check de calidad: detectar corpus mezclados
o un idioma inesperado. Llamala con la lista de textos crudos; la funcion
limpia, muestrea y resume sola.

## Gotchas

- `langdetect` es **opcional**: si no esta instalada, la funcion no lanza —
  devuelve `{"available": False, "n_detected": 0, "distribution": [], "dominant": None}`.
  Comprueba `out["available"]` antes de usar la distribucion.
- **Textos cortos** (pocas palabras o sin features lingüisticas) pueden no
  detectarse: langdetect lanza `LangDetectException`, que se ignora y el doc no
  cuenta en `n_detected`. Pasa frases razonablemente largas para resultados fiables.
- **Determinismo**: se fija `DetectorFactory.seed = 0` en cada llamada para que la
  deteccion sea reproducible; sin esa semilla langdetect puede dar resultados
  ligeramente distintos entre ejecuciones.
- `distribution` esta truncada a `top_k`; si el corpus tiene mas idiomas que
  `top_k`, la suma de los `count` mostrados puede ser menor que `n_detected`
  (pero `dominant` siempre refleja el idioma mas frecuente del corpus completo).
