Trabajo de Fin de Grado — Ingeniería del Software Nora Peñaloza Friqui · Universidad de Sevilla
Este proyecto investiga y construye un sistema de detección temprana de depresión e ideación suicida a partir de texto publicado en Reddit, comparando 5 modelos clásicos de Machine Learning frente a 6 arquitecturas de redes neuronales, combinadas con 7 técnicas distintas de representación textual (TF-IDF, Word2Vec, Word2Vec+TF-IDF, BERT, RoBERTa y SBERT, en sus variantes estándar y Long).
En total se evaluaron más de 60 configuraciones modelo–representación por tarea, con optimización de hiperparámetros, análisis de curvas de aprendizaje, matrices de confusión y comparación sistemática con el estado del arte publicado.
🎯 Los mejores modelos alcanzan F1 = 0.909 (suicidio) y F1 = 0.886 (depresión), superando de forma consistente los resultados reportados en la literatura comparable (Turcan & McKeown, Pirina & Çöltekin, Yeskuatov et al., Haque et al.).
Según la OMS, la depresión afecta a más de 300 millones de personas y el suicidio se cobró más de 700.000 vidas en 2021. Las redes sociales —Reddit en particular— se han convertido en espacios donde las personas expresan, a menudo sin ser plenamente conscientes de ello, su estado emocional. Este trabajo explora hasta qué punto ese contenido no estructurado puede aprovecharse con NLP y aprendizaje automático para apoyar la detección temprana, fuera del ámbito clínico tradicional.
Se combinaron dos estrategias: la reutilización de datasets públicos previamente estudiados (Basyouni et al., Haque et al., Reddit C-SSRS, Mafi et al., Naseem et al., Reddit Mental Health Dataset) y la extracción propia mediante la API de Reddit. El resultado son dos conjuntos de datos independientes, cada uno balanceado frente a una clase neutra (NonClassified) construida a partir de subreddits no relacionados:
| Dataset | Publicaciones totales | Clase positiva | Clase neutra |
|---|---|---|---|
| DepressDataset | 88.585 | 44.825 (Depression) | 43.760 (NonClassified) |
| SuicideDataset | 73.729 | 36.833 (Suicide) | 36.896 (NonClassified) |
Se optó deliberadamente por dos modelos independientes en lugar de uno multiclase, para reducir el ruido y la ambigüedad entre expresiones lingüísticamente próximas de depresión y suicidio.
Preprocesamiento aplicado: normalización de repeticiones de caracteres, tokenización (NLTK), eliminación de puntuación, eliminación de entidades nombradas (spaCy NER), eliminación de stopwords preservando negaciones, expansión de contracciones, lematización con POS tagging, filtrado de publicaciones muy cortas (<10 palabras) y verificación de idioma (langdetect).
- TF-IDF — línea base dispersa de alta dimensionalidad
- Word2Vec — embeddings estáticos entrenados sobre el corpus
- Word2Vec ponderado con TF-IDF
- BERT — variantes CLS, Mean-pooling y Long (documentos largos)
- RoBERTa — estándar y Long
- Sentence-BERT (SBERT) — estándar y Long
Modelos tradicionales (baseline): SVM, Regresión Logística, Naive Bayes, KNN, Random Forest — con optimización de hiperparámetros vía búsqueda en rejilla/Optuna.
Redes neuronales: Perceptrón Simple, MLP, RNN, LSTM/BiLSTM, GRU/BiGRU, CNN — implementadas y evaluadas sobre las 7 representaciones anteriores, con early stopping y análisis de sobreajuste.
| Tarea | Mejor tradicional | F1 | Mejor red neuronal | F1 |
|---|---|---|---|---|
| Suicidio | SVM + TF-IDF | 0.909 | CNN + BERT | 0.900 |
| Depresión | Reg. Logística / SVM + TF-IDF | 0.886 | BiGRU + Word2Vec | 0.886 |
TF-IDF con clasificadores lineales resultó ser un baseline sorprendentemente sólido y difícil de batir, mientras que las arquitecturas neuronales con embeddings contextuales (BERT) ofrecen un mejor equilibrio precisión/recall, criterio clave en un contexto de detección de riesgo.
| Referencia | Tarea comparada | Resultado publicado | Resultado de este TFG |
|---|---|---|---|
| Turcan & McKeown | Estrés en Reddit (BERT-base) | F1 = 0.807 | F1 = 0.900 (suicidio, CNN+BERT) |
| Pirina & Çöltekin | Depresión, SVM+TF-IDF | F1 = 0.55–0.64 | F1 = 0.886 |
| Yeskuatov et al. | Ideación suicida, SVM+TF-IDF | Acc = 0.787 / F1 = 0.523 | Acc = 0.905 / F1 = 0.904 |
| Haque et al. (SDCNL) | Dep. vs. suicidio, SVM+TF-IDF | F1 ≈ 0.71 | F1 = 0.909 (sui.) / 0.886 (dep.) |
(comparaciones no siempre estrictamente equivalentes por diferencias de tarea/corpus — el detalle metodológico está en la memoria, capítulo 8).
La elección final no se basó solo en el F1, sino en un criterio conjunto de estabilidad de entrenamiento, control del sobreajuste, equilibrio precisión/recall y minimización de falsos negativos (críticos en este dominio):
- Suicidio: CNN + BERT, GRU + BERT, BiGRU + Word2Vec
- Depresión: BiGRU + Word2Vec, CNN + Word2Vec, BiGRU + BERT
- TF-IDF + clasificadores lineales establece un baseline muy competitivo, difícil de superar incluso con arquitecturas profundas.
- Las representaciones contextuales (BERT) tienden a producir modelos más equilibrados; Word2Vec muestra sesgo sistemático hacia mayor sensibilidad (recall).
- Un F1 alto en test no garantiza fiabilidad: se detectaron modelos con métricas excelentes pero sobreajuste progresivo o inestabilidad en las curvas de validación, descartados en favor de configuraciones más robustas.
- Trabajo futuro: soporte multilingüe (mBERT/XLM-RoBERTa), validación clínica de los modelos, datasets más heterogéneos más allá de Reddit, y seguimiento longitudinal del estado emocional.
Python 3.11 · Pandas / NumPy · scikit-learn · Optuna · NLTK · spaCy · Gensim (Word2Vec) · Hugging Face Transformers (BERT, RoBERTa, SBERT)
tfg_detectarMH
│
├── BaseDatos_CSV # Datasets etiquetados: Depression, Suicide, Others
├── scrapy # Scripts de recolección de posts de Reddit
├── pre-procesado # Limpieza de texto y análisis de longitud
├── Caracteristicas
│ ├── contextualizedWordEmbedding # BERT, SBERT, RoBERTa
│ ├── embeddingTokens # Embeddings a nivel de token
│ └── staticWordEmbedding # Word2Vec
├── modelos_clasicos # SVM, Regresión Logística, Random Forest, Naive Bayes, KNN
└── modelo_redes_neuronales # MLP, RNN, CNN, LSTM, GRU, Perceptrón
Los modelos seleccionados se integraron en SocialMindScan, una aplicación web que permite a cualquier persona introducir texto y obtener un nivel de riesgo orientativo (bajo/medio/alto), con seguimiento del progreso y un chatbot de apoyo emocional. Este README se centra deliberadamente en la investigación y la implementación de los modelos; el código fuente completo de la aplicación está disponible aquí:
👉 [URL_APP]
This project investigates and builds a system for early detection of depression and suicidal ideation from Reddit posts, benchmarking 5 classical Machine Learning models against 6 neural network architectures, combined with 7 different text representation techniques (TF-IDF, Word2Vec, Word2Vec+TF-IDF, BERT, RoBERTa and SBERT, in their standard and Long variants).
Over 60 model–representation configurations per task were evaluated, including hyperparameter optimization, learning-curve analysis, confusion matrices, and a systematic comparison against published state-of-the-art work.
🎯 The best models reach F1 = 0.909 (suicide) and F1 = 0.886 (depression), consistently outperforming comparable results reported in the literature (Turcan & McKeown, Pirina & Çöltekin, Yeskuatov et al., Haque et al.).
According to the WHO, depression affects over 300 million people worldwide, and suicide claimed more than 700,000 lives in 2021. Social media — Reddit in particular — has become a space where people express, often without fully realizing it, their emotional state. This project explores how far that unstructured content can be leveraged with NLP and machine learning to support early detection outside traditional clinical settings.
Two strategies were combined: reuse of previously published public datasets (Basyouni et al., Haque et al., Reddit C-SSRS, Mafi et al., Naseem et al., Reddit Mental Health Dataset) and direct extraction via the Reddit API. The result is two independent, balanced datasets, each contrasted against a neutral class (NonClassified) built from unrelated subreddits:
| Dataset | Total posts | Positive class | Neutral class |
|---|---|---|---|
| DepressDataset | 88,585 | 44,825 (Depression) | 43,760 (NonClassified) |
| SuicideDataset | 73,729 | 36,833 (Suicide) | 36,896 (NonClassified) |
Two independent models were used instead of a single multiclass one, to reduce noise and ambiguity between linguistically close depression- and suicide-related expressions.
Preprocessing pipeline: repeated-character normalization, tokenization (NLTK), punctuation removal, named-entity removal (spaCy NER), stopword removal while preserving negations, contraction expansion, POS-aware lemmatization, filtering of very short posts (<10 words), and language verification (langdetect).
- TF-IDF — sparse, high-dimensional baseline
- Word2Vec — static embeddings trained on the corpus
- TF-IDF-weighted Word2Vec
- BERT — CLS, Mean-pooling and Long (long-document) variants
- RoBERTa — standard and Long
- Sentence-BERT (SBERT) — standard and Long
Classical baseline: SVM, Logistic Regression, Naive Bayes, KNN, Random Forest — with hyperparameter optimization via grid search/Optuna.
Neural networks: Simple Perceptron, MLP, RNN, LSTM/BiLSTM, GRU/BiGRU, CNN — evaluated across all seven representations, with early stopping and overfitting analysis.
| Task | Best classical | F1 | Best neural | F1 |
|---|---|---|---|---|
| Suicide | SVM + TF-IDF | 0.909 | CNN + BERT | 0.900 |
| Depression | Logistic Reg. / SVM + TF-IDF | 0.886 | BiGRU + Word2Vec | 0.886 |
TF-IDF with linear classifiers proved a surprisingly strong and hard-to-beat baseline, while neural architectures with contextual embeddings (BERT) offer a better precision/recall balance — a key criterion for a risk-detection system.
| Reference | Compared task | Published result | This work's result |
|---|---|---|---|
| Turcan & McKeown | Reddit stress detection (BERT-base) | F1 = 0.807 | F1 = 0.900 (suicide, CNN+BERT) |
| Pirina & Çöltekin | Depression, SVM+TF-IDF | F1 = 0.55–0.64 | F1 = 0.886 |
| Yeskuatov et al. | Suicidal ideation, SVM+TF-IDF | Acc = 0.787 / F1 = 0.523 | Acc = 0.905 / F1 = 0.904 |
| Haque et al. (SDCNL) | Depression vs. suicide, SVM+TF-IDF | F1 ≈ 0.71 | F1 = 0.909 (suicide) / 0.886 (depression) |
(comparisons are not always strictly equivalent due to task/corpus differences — full methodological detail is in the thesis, Chapter 8).
Model selection wasn't based on F1 alone, but on a joint criterion of training stability, overfitting control, precision/recall balance, and minimization of false negatives (critical in this domain):
- Suicide: CNN + BERT, GRU + BERT, BiGRU + Word2Vec
- Depression: BiGRU + Word2Vec, CNN + Word2Vec, BiGRU + BERT
- TF-IDF + linear classifiers set a highly competitive baseline, hard to beat even with deep architectures.
- Contextual representations (BERT) tend to produce more balanced models; Word2Vec shows a systematic bias toward higher sensitivity (recall).
- High test F1 doesn't guarantee reliability: some models had excellent metrics but progressive overfitting or unstable validation curves, and were discarded in favor of more robust configurations.
- Future work: multilingual support (mBERT/XLM-RoBERTa), clinical validation of the models, more heterogeneous datasets beyond Reddit, and longitudinal tracking of emotional state over time.
Python 3.11 · Pandas / NumPy · scikit-learn · Optuna · NLTK · spaCy · Gensim (Word2Vec) · Hugging Face Transformers (BERT, RoBERTa, SBERT)
tfg_detectarMH
│
├── BaseDatos_CSV # Labeled datasets: Depression, Suicide, Others
├── scrapy # Reddit post collection scripts
├── pre-procesado # Text cleaning and length analysis
├── Caracteristicas
│ ├── contextualizedWordEmbedding # BERT, SBERT, RoBERTa
│ ├── embeddingTokens # Token-level embeddings
│ └── staticWordEmbedding # Word2Vec
├── modelos_clasicos # SVM, Logistic Regression, Random Forest, Naive Bayes, KNN
└── modelo_redes_neuronales # MLP, RNN, CNN, LSTM, GRU, Perceptron
The selected models were integrated into SocialMindScan, a web application that lets anyone enter text and get an indicative risk level (low/medium/high), with progress tracking and an emotional-support chatbot. This README intentionally focuses on the research and model implementation side; the full application source code lives here:
👉 [URL_APP]
⭐ Si este proyecto te resulta útil o interesante, ¡una estrella es muy bienvenida! · If you find this project useful or interesting, a star is always welcome! ⭐