nacho commited on
Commit
7bf61c5
1 Parent(s): 11dfe6d
.gitattributes CHANGED
@@ -1,35 +1,3 @@
1
- *.7z filter=lfs diff=lfs merge=lfs -text
2
- *.arrow filter=lfs diff=lfs merge=lfs -text
3
- *.bin filter=lfs diff=lfs merge=lfs -text
4
- *.bz2 filter=lfs diff=lfs merge=lfs -text
5
- *.ckpt filter=lfs diff=lfs merge=lfs -text
6
- *.ftz filter=lfs diff=lfs merge=lfs -text
7
- *.gz filter=lfs diff=lfs merge=lfs -text
8
- *.h5 filter=lfs diff=lfs merge=lfs -text
9
- *.joblib filter=lfs diff=lfs merge=lfs -text
10
- *.lfs.* filter=lfs diff=lfs merge=lfs -text
11
- *.mlmodel filter=lfs diff=lfs merge=lfs -text
12
- *.model filter=lfs diff=lfs merge=lfs -text
13
- *.msgpack filter=lfs diff=lfs merge=lfs -text
14
- *.npy filter=lfs diff=lfs merge=lfs -text
15
- *.npz filter=lfs diff=lfs merge=lfs -text
16
- *.onnx filter=lfs diff=lfs merge=lfs -text
17
- *.ot filter=lfs diff=lfs merge=lfs -text
18
- *.parquet filter=lfs diff=lfs merge=lfs -text
19
- *.pb filter=lfs diff=lfs merge=lfs -text
20
- *.pickle filter=lfs diff=lfs merge=lfs -text
21
  *.pkl filter=lfs diff=lfs merge=lfs -text
22
- *.pt filter=lfs diff=lfs merge=lfs -text
23
- *.pth filter=lfs diff=lfs merge=lfs -text
24
- *.rar filter=lfs diff=lfs merge=lfs -text
25
- *.safetensors filter=lfs diff=lfs merge=lfs -text
26
- saved_model/**/* filter=lfs diff=lfs merge=lfs -text
27
- *.tar.* filter=lfs diff=lfs merge=lfs -text
28
- *.tar filter=lfs diff=lfs merge=lfs -text
29
- *.tflite filter=lfs diff=lfs merge=lfs -text
30
- *.tgz filter=lfs diff=lfs merge=lfs -text
31
- *.wasm filter=lfs diff=lfs merge=lfs -text
32
- *.xz filter=lfs diff=lfs merge=lfs -text
33
- *.zip filter=lfs diff=lfs merge=lfs -text
34
- *.zst filter=lfs diff=lfs merge=lfs -text
35
- *tfevents* filter=lfs diff=lfs merge=lfs -text
 
1
+ .pkl filter=lfs diff=lfs merge=lfs -text
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2
  *.pkl filter=lfs diff=lfs merge=lfs -text
3
+ tfidf_vectorizador2.pkl filter=lfs diff=lfs merge=lfs -text
 
 
 
 
 
 
 
 
 
 
 
 
 
.idea/.gitignore ADDED
@@ -0,0 +1,8 @@
 
 
 
 
 
 
 
 
 
1
+ # Default ignored files
2
+ /shelf/
3
+ /workspace.xml
4
+ # Editor-based HTTP Client requests
5
+ /httpRequests/
6
+ # Datasource local storage ignored files
7
+ /dataSources/
8
+ /dataSources.local.xml
.idea/.name ADDED
@@ -0,0 +1 @@
 
 
1
+ TFG
.idea/TFG.iml ADDED
@@ -0,0 +1,10 @@
 
 
 
 
 
 
 
 
 
 
 
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <module type="PYTHON_MODULE" version="4">
3
+ <component name="NewModuleRootManager">
4
+ <content url="file://$MODULE_DIR$">
5
+ <excludeFolder url="file://$MODULE_DIR$/venv" />
6
+ </content>
7
+ <orderEntry type="inheritedJdk" />
8
+ <orderEntry type="sourceFolder" forTests="false" />
9
+ </component>
10
+ </module>
.idea/alertDetection.iml ADDED
@@ -0,0 +1,8 @@
 
 
 
 
 
 
 
 
 
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <module type="PYTHON_MODULE" version="4">
3
+ <component name="NewModuleRootManager">
4
+ <content url="file://$MODULE_DIR$" />
5
+ <orderEntry type="inheritedJdk" />
6
+ <orderEntry type="sourceFolder" forTests="false" />
7
+ </component>
8
+ </module>
.idea/inspectionProfiles/profiles_settings.xml ADDED
@@ -0,0 +1,6 @@
 
 
 
 
 
 
 
1
+ <component name="InspectionProjectProfileManager">
2
+ <settings>
3
+ <option name="USE_PROJECT_PROFILE" value="false" />
4
+ <version value="1.0" />
5
+ </settings>
6
+ </component>
.idea/misc.xml ADDED
@@ -0,0 +1,7 @@
 
 
 
 
 
 
 
 
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <project version="4">
3
+ <component name="Black">
4
+ <option name="sdkName" value="Python 3.9 (pythonProject1) (2)" />
5
+ </component>
6
+ <component name="ProjectRootManager" version="2" project-jdk-name="Python 3.9 (pythonProject1) (2)" project-jdk-type="Python SDK" />
7
+ </project>
.idea/modules.xml ADDED
@@ -0,0 +1,8 @@
 
 
 
 
 
 
 
 
 
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <project version="4">
3
+ <component name="ProjectModuleManager">
4
+ <modules>
5
+ <module fileurl="file://$PROJECT_DIR$/.idea/TFG.iml" filepath="$PROJECT_DIR$/.idea/TFG.iml" />
6
+ </modules>
7
+ </component>
8
+ </project>
.idea/vcs.xml ADDED
@@ -0,0 +1,6 @@
 
 
 
 
 
 
 
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <project version="4">
3
+ <component name="VcsDirectoryMappings">
4
+ <mapping directory="$PROJECT_DIR$" vcs="Git" />
5
+ </component>
6
+ </project>
imagenes/Captura1.PNG ADDED
imagenes/Captura2.PNG ADDED
imagenes/Captura3.PNG ADDED
imagenes/Captura4.PNG ADDED
imagenes/uoc.png ADDED
imagenes/uoc2.png ADDED
main.py ADDED
@@ -0,0 +1,90 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import streamlit as st
2
+ import nltk
3
+ from secciones.procesar_textos import procesar_textos # Asegúrate de que esta ruta sea correcta
4
+ from secciones.home_page import home_page
5
+ from secciones.info_page import info_page
6
+
7
+
8
+ def main():
9
+ """
10
+ Función principal que ejecuta la aplicación Streamlit.
11
+
12
+ Esta función se encarga de configurar la página, cargar el modelo y el vectorizador, y gestionar el menú de
13
+ navegación de la aplicación. Dependiendo de la opción seleccionada en el menú, renderiza diferentes vistas como
14
+ la página de inicio, la página de análisis de texto o la página de información.
15
+
16
+ :return: None. Ejecuta y mantiene activa la aplicación Streamlit.
17
+ """
18
+ # Configuración de la página
19
+ logo_log_bar = r'imagenes/Captura de pantalla 2024-01-06 a las 17.13.19.png'
20
+ st.set_page_config(page_title='Análisis sentimientos', page_icon=logo_log_bar, layout="wide")
21
+
22
+ # Descargar recursos de NLTK
23
+ @st.cache_data
24
+ def descargar_recursos_nltk():
25
+ """
26
+ Descarga los recursos necesarios de NLTK.
27
+
28
+ Esta función descarga los componentes 'punkt' y 'stopwords' de NLTK, que son necesarios para tokenizar y
29
+ preprocesar el texto en las funciones de análisis.
30
+
31
+ :return: None.
32
+ """
33
+ nltk.download('punkt')
34
+ nltk.download('stopwords')
35
+
36
+ descargar_recursos_nltk()
37
+
38
+ # Menú de opciones
39
+ with st.sidebar:
40
+ # Imagen y título del menú centrados
41
+ st.image("imagenes/uoc.png", width=290) # Tamaño más grande para el logo
42
+ st.markdown('<h1 style="text-align: center; color: black;">Menú de Navegación</h2>', unsafe_allow_html=True)
43
+
44
+ # Opciones del menú con emojis como iconos
45
+ opciones_menu = {
46
+ "Home": "🏠 Home",
47
+ "Analizar texto": "🔍 Analizar texto",
48
+ "Info": "ℹ️ Info"
49
+ }
50
+ # Valor predeterminado para 'selected'
51
+ if 'selected' not in st.session_state:
52
+ st.session_state['selected'] = "Home"
53
+
54
+ # Estilo personalizado para los botones
55
+ btn_style = """
56
+ <style>
57
+ .css-2trqyj {
58
+ display: flex;
59
+ justify-content: center;
60
+ align-items: center;
61
+ font-size: 18px;
62
+ font-weight: bold;
63
+ }
64
+ </style>
65
+ """
66
+ st.markdown(btn_style, unsafe_allow_html=True)
67
+
68
+ # Crear botones en la barra lateral para cada opción del menú
69
+ for opcion, etiqueta in opciones_menu.items():
70
+ if st.button(etiqueta, key=opcion, use_container_width=True):
71
+ st.session_state['selected'] = opcion
72
+
73
+ # Vista de información
74
+ if st.session_state['selected'] == "Home":
75
+ st.image("imagenes/uoc2.png", use_column_width=True)
76
+ home_page()
77
+
78
+ # Analizar texto
79
+ elif st.session_state['selected'] == "Analizar texto":
80
+ st.image("imagenes/uoc2.png", use_column_width=True)
81
+ procesar_textos()
82
+
83
+ # Info
84
+ elif st.session_state['selected'] == "Info":
85
+ st.image("imagenes/uoc2.png", use_column_width=True)
86
+ info_page()
87
+
88
+
89
+ if __name__ == "__main__":
90
+ main()
modelo_nn_g2.pkl ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:73c1fd2dd7ef4320ff37d6715da5be4b7d12a8074356271ba312267867b059f4
3
+ size 6107894
requirements.txt ADDED
Binary file (3.77 kB). View file
 
secciones/home_page.py ADDED
@@ -0,0 +1,67 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import streamlit as st
2
+
3
+
4
+ def home_page():
5
+ """
6
+ Muestra la página principal de la aplicación Streamlit.
7
+
8
+ Esta función se encarga de renderizar la página de inicio de la aplicación de detección temprana de riesgo
9
+ de suicidio.
10
+ Incluye secciones que explican el propósito del proyecto, sus objetivos principales y cómo utilizar la herramienta.
11
+ Cada sección está claramente definida y contiene información detallada y relevante para el usuario.
12
+
13
+ La página de inicio se estructura en varias secciones, que incluyen:
14
+ - Una introducción al proyecto y su relevancia.
15
+ - Los objetivos principales del proyecto.
16
+ - Instrucciones detalladas sobre cómo utilizar la herramienta.
17
+
18
+ Las secciones están diseñadas para proporcionar a los usuarios una comprensión clara del propósito y
19
+ la funcionalidad de la herramienta, así como guiarlos en su uso efectivo.
20
+
21
+ :return: None. Renderiza los componentes de la página de inicio en la interfaz de usuario de Streamlit.
22
+ """
23
+ st.title("TFG: Detección Temprana de Riesgo de Suicidio Mediante Análisis de mensajes de texto")
24
+ with st.container():
25
+ st.write("""
26
+ Este proyecto emplea técnicas avanzadas de Procesamiento de Lenguaje Natural (PLN) y análisis de datos para
27
+ explorar y detectar señales de comportamientos autolesivos en mensajes publicados en redes sociales.
28
+ La iniciativa busca abordar una de las principales causas de preocupación en la salud mental global,
29
+ ofreciendo una herramienta innovadora y valiosa para la identificación temprana de riesgos de suicidio.
30
+ """)
31
+ with st.container(border=True):
32
+ st.header("Objetivos Principales")
33
+ st.write("""
34
+ - **Análisis Profundo de Comunicaciones Digitales**: Implementación de algoritmos de PLN para analizar
35
+ textos y detectar patrones de riesgo en comportamientos y estados emocionales.
36
+ - **Prevención de Comportamientos de Riesgo**: Utilización de la herramienta como un medio para identificar
37
+ señales tempranas de crisis emocionales, proporcionando una base sólida para intervenciones oportunas y
38
+ medidas preventivas.
39
+ - **Evaluación y Mejora de Estrategias de Prevención Actuales**: Contribución a la investigación y mejora de
40
+ estrategias de prevención del suicidio mediante la incorporación de tecnologías avanzadas de análisis de
41
+ datos.
42
+ """)
43
+ with st.container(border=True):
44
+ st.header("Cómo Utilizar la Herramienta")
45
+ st.write("""
46
+ 1. **Acceso a la herramienta de análisis**: Para acceder a esta propiedad tan solo hay que dirigirse
47
+ al botón 'Analizar texto' que se encuentra en el menú de navegación.
48
+ """)
49
+ st.image("imagenes/Captura1.PNG", use_column_width="auto")
50
+ st.write("""
51
+ 2. **Ingreso y procesamiento del texto**: Para llevar a cabo nuestro análisis tan solo se debe introducir
52
+ en el cuadro respectivo el texto a analizar. Haga clic en el botón 'Procesar texto' para que la herramienta
53
+ procese el texto. La herramienta utiliza modelos de PLN para analizar el contenido y la tonalidad
54
+ emocional del texto.
55
+ """)
56
+ st.write("""
57
+ **Importante: Por ahora no esta permitido ingresar archivos de texto**
58
+ """)
59
+ st.image("imagenes/Captura2.PNG")
60
+ st.image("imagenes/Captura3.PNG")
61
+ st.write("""
62
+ 4. **Interpretación de resultados y acciones sugeridas**: Los resultados proporcionan insights
63
+ sobre el estado emocional del texto y posibles señales de riesgo. Estos incluyen análisis de sentimientos,
64
+ emociones y una evaluación de riesgo de suicidio. Basado en el nivel de riesgo detectado,
65
+ la herramienta ofrece recomendaciones sobre posibles pasos a seguir.
66
+ """)
67
+ st.image("imagenes/Captura4.PNG")
secciones/info_page.py ADDED
@@ -0,0 +1,34 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import streamlit as st
2
+
3
+
4
+ def info_page():
5
+
6
+ with st.container():
7
+ st.markdown("""
8
+ <style>
9
+
10
+ .logo {
11
+ display: inline-block;
12
+ margin-right: 5px;
13
+ width: 20px; /* Ajusta el tamaño del logo aquí */
14
+ }
15
+ .about-container{
16
+ text-align: center;
17
+ }
18
+ </style>
19
+ <div class="about-container" >
20
+ <h1 >Acerca de este TFG</h1>
21
+ <p>
22
+ <h2>Ignacio Macías Martínez</h2><br>
23
+ <strong>Grado de ciencia de datos aplicada</strong>: Trabajo final de grado 22.536.<br>
24
+ <strong>Tutora TFG</strong>: Teresa Divorra Vallhonrat.<br>
25
+ <strong>Profesor responsable de la asignatura</strong>: David Merino Arranz.<br>
26
+ <strong>Contacto</strong>: /
27
+ <a href="https://github.com/imaciasm"><img class="logo"
28
+ src="https://github.githubassets.com/images/modules/logos_page/GitHub-Mark.png"/>GitHub</a> \\ /
29
+ <a href="https://www.linkedin.com/in/imaciasm/"><img class="logo"
30
+ src="https://upload.wikimedia.org/wikipedia/commons/c/ca/LinkedIn_logo_initials.png"/>LinkedIn</a>
31
+ \\
32
+ </p>
33
+ </div>
34
+ """, unsafe_allow_html=True)
secciones/model_utils.py ADDED
@@ -0,0 +1,10 @@
 
 
 
 
 
 
 
 
 
 
 
1
+ import joblib
2
+ import streamlit as st
3
+
4
+
5
+ # Cargar el modelo y el vectorizador
6
+ @st.cache_data
7
+ def cargar_modelo_y_vectorizador():
8
+ modelo = joblib.load('modelo_nn_g2.pkl')
9
+ tfidf_vectorizador = joblib.load('tfidf_vectorizador2.pkl')
10
+ return modelo, tfidf_vectorizador
secciones/procesar_textos.py ADDED
@@ -0,0 +1,245 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import streamlit as st
2
+ import pandas as pd
3
+ import re
4
+ import nltk
5
+ import numpy as np
6
+ from nltk.tokenize import word_tokenize
7
+ from nltk.corpus import stopwords
8
+ from nltk.stem import SnowballStemmer
9
+ from transformers import pipeline
10
+ from secciones.model_utils import cargar_modelo_y_vectorizador
11
+
12
+ # Descargar recursos de NLTK
13
+ nltk.download('punkt')
14
+ nltk.download('stopwords')
15
+
16
+
17
+ # Función de limpieza y preprocesamiento de texto
18
+ def clean_text_stemming(text):
19
+ """
20
+ Realiza la limpieza y preprocesamiento de un texto. Convierte el texto a minúsculas,
21
+ elimina caracteres no alfabéticos, tokeniza, remueve stopwords y aplica stemming.
22
+
23
+ :param text: El texto a limpiar y preprocesar.
24
+ :return: Texto procesado y limpio.
25
+ """
26
+ text = text.lower()
27
+ text = re.sub(r'[^a-zñáéíóú]', ' ', text)
28
+ words = word_tokenize(text)
29
+ stop_words = set(stopwords.words('spanish'))
30
+ stemmer = SnowballStemmer('spanish')
31
+ stemmed_text = ' '.join([stemmer.stem(word) for word in words if word not in stop_words])
32
+ return stemmed_text
33
+
34
+
35
+ # Cargar modelos de Hugging Face para análisis de sentimientos y emociones
36
+ clasificador_sentimiento = pipeline('sentiment-analysis',
37
+ model='citizenlab/twitter-xlm-roberta-base-sentiment-finetunned')
38
+ clasificador_emociones = pipeline("text-classification",
39
+ model="maxpe/bertin-roberta-base-spanish_sem_eval_2018_task_1")
40
+
41
+
42
+ # Funciones para analizar sentimiento y emociones
43
+ def analizar_sentimiento(texto):
44
+ """
45
+ Analiza el sentimiento de un texto dado utilizando un modelo preentrenado de Hugging Face.
46
+
47
+ :param texto: El texto a analizar.
48
+ :return: La etiqueta del sentimiento detectado (ej. "Positive", "Negative", "Neutral").
49
+ Retorna None si ocurre un error.
50
+ """
51
+ try:
52
+ results = clasificador_sentimiento(texto, truncation=True, max_length=512)
53
+ top_result = max(results, key=lambda x: x['score'])
54
+ return top_result['label']
55
+ except Exception as e:
56
+ print(f"Error al procesar el texto: {e}")
57
+ return None
58
+
59
+
60
+ def analizar_emociones(texto):
61
+ """
62
+ Analiza las emociones presentes en un texto utilizando un modelo preentrenado de Hugging Face.
63
+
64
+ :param texto: El texto a analizar.
65
+ :return: La etiqueta de la emoción detectada (ej. "alegría", "tristeza").
66
+ Retorna None si ocurre un error.
67
+ """
68
+ try:
69
+ results = clasificador_emociones(texto, truncation=True, max_length=512)
70
+ top_result = max(results, key=lambda x: x['score'])
71
+ return top_result['label']
72
+ except Exception as e:
73
+ print(f"Error al procesar el texto: {e}")
74
+ return None
75
+
76
+
77
+ # Normalización de la longitud del texto
78
+ def normalizar_longitud(texto):
79
+ """
80
+ Normaliza la longitud de un texto dividiendo la longitud del texto por una longitud máxima observada.
81
+
82
+ :param texto: El texto cuya longitud se va a normalizar.
83
+ :return: Longitud normalizada del texto.
84
+ """
85
+ longitud_maxima_observada = 53352
86
+ return len(texto) / longitud_maxima_observada
87
+
88
+
89
+ # Obtener características de polaridad y emociones
90
+ def obtener_caracteristicas_polaridad(texto):
91
+ """
92
+ Obtiene características de polaridad (positiva, negativa, neutral) de un texto analizando su sentimiento.
93
+
94
+ :param texto: El texto a analizar.
95
+ :return: Un diccionario con las características de polaridad en formato binario.
96
+ """
97
+ polaridad = analizar_sentimiento(texto)
98
+ return {
99
+ "polarity_Negative": 1 if polaridad == "Negative" else 0,
100
+ "polarity_Neutral": 1 if polaridad == "Neutral" else 0,
101
+ "polarity_Positive": 1 if polaridad == "Positive" else 0
102
+ }
103
+
104
+
105
+ def obtener_caracteristicas_emociones(texto):
106
+ """
107
+ Obtiene características de emociones (ira, anticipación, miedo, alegría, tristeza) de un texto.
108
+
109
+ :param texto: El texto a analizar.
110
+ :return: Un diccionario con las características de emociones en formato binario.
111
+ """
112
+ emocion = analizar_emociones(texto)
113
+ categorias = ["anger", "anticipation", "fear", "joy", "sadness"]
114
+ return {f"emotions_{cat}": 1 if emocion == cat else 0 for cat in categorias}
115
+
116
+
117
+ # Función para realizar predicciones con información adicional
118
+ def predecir_suicidio_con_info(texto, modelo, tfidf_vectorizador):
119
+ """
120
+ Realiza la predicción de comportamiento suicida en un texto dado, utilizando un modelo
121
+ de machine learning y un vectorizador TF-IDF. Incluye características adicionales
122
+ como longitud del texto, polaridad y emociones.
123
+
124
+ :param texto: Texto a analizar.
125
+ :param modelo: Modelo de machine learning para realizar la predicción.
126
+ :param tfidf_vectorizador: Vectorizador TF-IDF para procesar el texto.
127
+ :return: Un diccionario con los resultados de la clasificación y análisis.
128
+ """
129
+ texto_limpio = clean_text_stemming(texto)
130
+
131
+ # Obtener características
132
+ longitud_normalizada = normalizar_longitud(texto)
133
+ caracteristicas_polaridad = obtener_caracteristicas_polaridad(texto)
134
+ caracteristicas_emociones = obtener_caracteristicas_emociones(texto)
135
+ polaridad = analizar_sentimiento(texto)
136
+ emocion = analizar_emociones(texto)
137
+
138
+ # Vectorizar texto y combinar características
139
+ texto_tfidf = tfidf_vectorizador.transform([texto_limpio]).toarray()
140
+ caracteristicas_adicionales = np.array(
141
+ [longitud_normalizada] + list(caracteristicas_polaridad.values()) + list(caracteristicas_emociones.values()))
142
+ features = np.hstack((texto_tfidf, caracteristicas_adicionales.reshape(1, -1)))
143
+
144
+ # Asegúrate de que el DataFrame tenga los mismos nombres de columnas que se usaron durante el entrenamiento
145
+ column_names = tfidf_vectorizador.get_feature_names_out().tolist() + ['text_length', 'polarity_Negative',
146
+ 'polarity_Neutral', 'polarity_Positive',
147
+ 'emotions_anger', 'emotions_anticipation',
148
+ 'emotions_fear', 'emotions_joy',
149
+ 'emotions_sadness']
150
+ features_df = pd.DataFrame(features, columns=column_names)
151
+
152
+ # Realizar la predicción
153
+ pred = modelo.predict(features_df)
154
+ pred_proba = modelo.predict_proba(features_df)[0]
155
+
156
+ # Confianza y nivel de riesgo
157
+ confianza = abs(pred_proba[1] - pred_proba[0])
158
+ nivel_riesgo = 'alto' if pred_proba[1] > 0.75 else 'moderado' if pred_proba[1] > 0.5 else 'bajo'
159
+ accion = 'Se recomienda buscar ayuda profesional inmediatamente.' if nivel_riesgo == 'alto' \
160
+ else 'Se sugiere monitorear los sentimientos y considerar hablar con un profesional.' \
161
+ if nivel_riesgo == 'moderado' \
162
+ else 'Probablemente no hay riesgo inmediato, pero mantén una actitud positiva.'
163
+
164
+ # Traducciones de las etiquetas de polaridad y emociones al español
165
+ traducciones_polaridad = {
166
+ "Negative": "Negativa",
167
+ "Neutral": "Neutral",
168
+ "Positive": "Positiva"
169
+ }
170
+ traducciones_emociones = {
171
+ "anger": "ira",
172
+ "anticipation": "Anticipación",
173
+ "fear": "Miedo",
174
+ "joy": "Alegría",
175
+ "sadness": "Tristeza"
176
+ }
177
+
178
+ # Traducir polaridad y emociones
179
+ polaridad_traducida = traducciones_polaridad.get(polaridad, polaridad)
180
+ emocion_traducida = traducciones_emociones.get(emocion, emocion)
181
+
182
+ return {
183
+ "clasificacion": 'suicidio' if pred[0] == 1 else 'no suicidio',
184
+ "probabilidad_suicidio": pred_proba[1],
185
+ "confianza": confianza,
186
+ "nivel_riesgo": nivel_riesgo,
187
+ "sugerencia_accion": accion,
188
+ "polaridad": polaridad_traducida,
189
+ "emocion": emocion_traducida
190
+ }
191
+
192
+
193
+ def procesar_textos():
194
+
195
+ """
196
+ Función principal para procesar textos en la aplicación Streamlit. Permite al usuario
197
+ ingresar o subir un texto, y luego utiliza el modelo y el vectorizador para analizarlo.
198
+
199
+ :param modelo: Modelo de machine learning para la predicción.
200
+ :param tfidf_vectorizador: Vectorizador TF-IDF utilizado en el modelo.
201
+ """
202
+ st.title("Analizar Texto")
203
+ modelo, tfidf_vectorizador = cargar_modelo_y_vectorizador()
204
+ # Opción para ingresar texto manualmente
205
+ text_input = st.text_area("Ingrese su texto aquí:")
206
+
207
+ # Opción para subir un archivo
208
+ uploaded_file = st.file_uploader("O suba un archivo de texto:", type=["txt"])
209
+
210
+ # Botón para procesar el texto
211
+ if st.button("Procesar Texto"):
212
+ text_to_process = ""
213
+ if uploaded_file is not None:
214
+ # Leer el archivo subido y almacenar su contenido
215
+ text_to_process = uploaded_file.read().decode("utf-8")
216
+ elif text_input:
217
+ # Utilizar el texto ingresado manualmente
218
+ text_to_process = text_input
219
+
220
+ if text_to_process:
221
+ # Llamar a la función de predicción con el texto procesado
222
+ resultado = predecir_suicidio_con_info(text_to_process, modelo, tfidf_vectorizador)
223
+
224
+ # Estilos personalizados según el nivel de riesgo
225
+ if resultado['nivel_riesgo'] == 'alto':
226
+ color = "red"
227
+ elif resultado['nivel_riesgo'] == 'moderado':
228
+ color = "orange"
229
+ else:
230
+ color = "green"
231
+
232
+ # Mostrar los resultados con estilos
233
+ st.markdown(f"<h2 style='color: {color};'>Resultado del Análisis:</h2>", unsafe_allow_html=True)
234
+ st.markdown(f"<b>Nivel de Riesgo:</b> <span style='color: {color};'>{resultado['nivel_riesgo']}</span>",
235
+ unsafe_allow_html=True)
236
+ st.markdown(f"<b>Polaridad:</b> {resultado['polaridad']}", unsafe_allow_html=True)
237
+ st.markdown(f"<b>Emoción:</b> {resultado['emocion']}", unsafe_allow_html=True)
238
+ st.markdown(f"<b>Clasificación:</b> {resultado['clasificacion']}", unsafe_allow_html=True)
239
+ st.markdown(f"<b>Probabilidad de Suicidio:</b> {resultado['probabilidad_suicidio']:.4f}",
240
+ unsafe_allow_html=True)
241
+ st.markdown(f"<b>Confianza:</b> {resultado['confianza']:.4f}", unsafe_allow_html=True)
242
+
243
+ st.markdown(f"<b>Sugerencia de Acción:</b> {resultado['sugerencia_accion']}", unsafe_allow_html=True)
244
+ else:
245
+ st.warning("Por favor, ingrese texto o suba un archivo.")
tfidf_vectorizador2.pkl ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:247005faccbe8acea43dccbcef558063a46250f489bd7e2ec4dc1ce59961612e
3
+ size 238915493