Skip to content

feat(nlp): un modelo dedicado y entrenado con etiqueta humana para la señal de clickbait (#115) - #120

Merged
g-garciac2022 merged 1 commit into
devfrom
feat/115-stremie
Aug 26, 2026
Merged

feat(nlp): un modelo dedicado y entrenado con etiqueta humana para la señal de clickbait (#115)#120
g-garciac2022 merged 1 commit into
devfrom
feat/115-stremie

Conversation

@g-garciac2022

Copy link
Copy Markdown
Collaborator

Cierra #115.

detect_clickbait usaba facebook/bart-large-mnli, elegido en E3-02 por
eliminación
—era lo único que el serverless de HuggingFace servía— y nunca por
medida. El aplazamiento traía condición explícita, «si llega la infra», y la
infra llegó en la Épica 5 con LocalNLPClient. Nadie volvió a la nota durante
dos épicas
, porque nadie tenía motivo para releerla.

Medido en #109, aquel modelo acertaba el 63,7 %: la señal más floja de forma.

El sustituto obvio era el equivocado

E3-02 dejaba nombre: elozano/bert-base-cased-clickbait-news. Da 99,7 % en
Chakraborty dev y F1 0,185 en Webis-17, contra una mayoritaria del 69,0 %.
Memorización, no capacidad.

Eso obligó a buscar con criterios: licencia clara, procedencia de la etiqueta
(humana, no por-fuente) e independencia del par acoplado.

Y ahí salió el hallazgo que no se buscaba

39 datasets candidatos en el Hub; cinco en inglés con licencia permisiva. Los
cinco son Chakraborty reempaquetado
, medido por solapamiento de titulares: 100 %,
86 %, 86 %, 57 % y 56 %.

La variedad de corpus de clickbait es ilusoria: un dataset con cinco envoltorios.
Explica estructuralmente el caso de elozano —casi todo lo que hay arrastra las
mismas etiquetas por-fuente— y responde el bullet de #78 «búsqueda de corpus
adicionales» con un no medido en vez de con un «no encontré».

El elegido

Stremie/roberta-base-clickbait (Apache-2.0). Su README declara entrenamiento
sobre Webis-17 y postText — el mismo campo que tenemos vendorizado — con
~0,7 F1 en su test.

En su corpus Fuera
elozano 99,7 % (Chakraborty) F1 0,185 (Webis)
Stremie F1 0,631 (Webis) F1 0,946 (Chakraborty)

Alto fuera y más bajo dentro: el patrón inverso, que es el de generalizar.
Y ese 0,946 supera al 0,865 que el lineal saca dentro de su propio dominio
el argumento de #78, la palanca es la supervisión, medido desde el otro lado.

El voto vuelve, y no es marcha atrás

Tercera señal Acierto forma AMBIGUO de esa ambigüedad, error suyo
BART (antes) 63,7 % 37,0 % 78,4 %
Stremie 94,7 % 15,0 % 20,0 %

Cuatro de cada cinco ambigüedades pasan de ruido a discrepancia legítima. #109
declaró ese silencio condicional en la ficha —«placeholder pendiente de
#115»— precisamente para poder encontrarlo cuando llegara el momento.

dedicated.py: faltaba un módulo

Tres de las cinco señales tenían módulo propio (lexical, linear,
incoherence); ésta no, y llamaba al backend desde las dos fachadas. Por eso su
id y sus etiquetas acabaron duplicados (#116): no había dónde ponerlos.

El módulo nuevo contiene el id (leído de la ficha), el mapeo de etiquetas y la
normalización. El vocabulario del modelo no sale hacia fuera: la tool sigue
publicando clickbait/factual news, contrato leído por el LLM, así que el
próximo cambio de modelo no se propaga a quien consume la señal.

Y el mapeo falla en vez de dejar pasar una etiqueta desconocida. Si se
colara, el extractor la compararía con clickbait, no coincidiría, y todos los
titulares saldrían factuales sin levantar ninguna excepción
.

Auditoría de requisitos: R3.9 no se cumple, y el código decía que sí

Cambiar de modelo es la prueba de fuego de R3.9 («intercambiarlos por
configuración, sin cambios de código»). No se cumple: hizo falta tocar la tabla
de fichas, escribir un módulo y añadir un mapeo.

Lo llamativo es que el docstring de model_cards.py afirmaba lo contrario,
confundiendo nlp_backend —que decide dónde corre el modelo— con cuál es.
Llevaba dos épicas dándolo por cumplido, invisible porque hasta ahora nunca se
había cambiado un modelo. Corregido aquí; el hueco queda en #119, con la
tensión de fondo planteada: el id se configura fácil, el mapeo de etiquetas y el
modo de invocación no.

Del resto de lo auditado: R3.5 sale reforzado y R3.8 gana evidencia propia
a favor. R3.6 probablemente mejora al pasar de BART-large a roberta-base, pero
no se ha medido y no se apunta como mejora.

Lo que no arregla

Sigue siendo una señal opaca: forma gana acierto, no transparencia. Y su
independencia del par acoplado es desconocida, que no es lo mismo que buena
su único test honesto es Chakraborty, donde tres clasificadores competentes
coinciden por fuerza. Declarado así en la ficha. La segunda señal interpretable e
independiente sigue siendo #75.

Verificación

193 tests pasan, ruff y formato limpios. Además, verificación de humo con el
modelo real —los dobles sólo prueban lo que uno cree que devuelve el modelo—:
los cuatro casos correctos, etiquetas normalizadas al contrato, y el camino
completo de orchestrator.analyze resolviendo forma con las tres señales.

Un test se cayó y estuvo bien que lo hiciera: test_una_señal_que_revienta_no_tumba_a_las_demas
saboteaba zero_shot, y la señal ya no pasa por ahí. Ahora rompe sólo ese
modelo
, no el método, porque el tono comparte classify desde este cambio.

@g-garciac2022 g-garciac2022 changed the title feat(nlp): un modelo dedicado y entrenado con etiqueta humana para la senal de clickbait (#115) feat(nlp): un modelo dedicado y entrenado con etiqueta humana para la señal de clickbait (#115) Aug 26, 2026
@g-garciac2022
g-garciac2022 merged commit c0786db into dev Aug 26, 2026
1 check passed
@g-garciac2022
g-garciac2022 deleted the feat/115-stremie branch August 26, 2026 14:55
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant