Clúster & Regresión Logística para la Evaluación del nivel de satisfacción del Correo Institucional de la UNALM - IMPLEMENTACIÓN EN PYTHON
INTRODUCCIÓN
El correo institucional en la Universidad Nacional Agraria La Molina (UNALM) es un recurso esencial para la comunicación de estudiantes, docentes y personal administrativo. Sin embargo, en los últimos años, con el aumento en el uso de servicios tecnológicos y la creciente dependencia de plataformas en la nube, han surgido diversas percepciones respecto a su efectividad. Una de las principales preocupaciones recientes es la reducción del espacio de almacenamiento, que anteriormente era “ilimitado” y ahora está restringido a solo 5 GB, lo que ha generado inquietudes entre los usuarios. Además, hay otras áreas clave que afectan la experiencia con el servicio, como la gestión de correos no deseados, la organización interna de los correos y la calidad del soporte técnico. A esto se suman dudas sobre la utilidad de los beneficios adicionales asociados al correo institucional, como el acceso a servicios premium.
Este trabajo tiene como objetivo evaluar el nivel de satisfacción del correo institucional de la UNALM mediante la creación de un conjunto de datos basado en una encuesta realizada en Google Forms. Se utilizó una encuesta estructurada para capturar las opiniones de los usuarios sobre el correo institucional, cuyos resultados fueron procesados usando técnicas de machine learning, incluyendo un modelo de clustering para segmentar los niveles de satisfacción y un modelo de regresión logística para predecir las categorías de satisfacción de los usuarios.
METODOLOGÍA
El cuestionario incluyó preguntas enfocadas en evaluar ocho dimensiones clave relacionadas con la experiencia de uso del correo institucional, entre las que destacan:
P_1: ¿Cómo calificas la cantidad de espacio de almacenamiento disponible en tu correo institucional?
P_2: ¿Qué tan satisfecho estás con la gestión del spam administrativo?
P_3: ¿Cómo valoras la facilidad para organizar y gestionar tus correos importantes?
P_4: ¿Cómo calificas la capacidad de sincronización con Google Drive?
P_5: ¿Qué tan satisfecho estás con las notificaciones del correo institucional?
P_6: ¿Cómo valoras la atención y soporte técnico ofrecido?
P_7: ¿Qué tan satisfecho estás con las alternativas para almacenar información fuera del correo?
P_8: ¿Qué tan satisfecho estás con los beneficios adicionales?
Las respuestas a estas preguntas fueron registradas en una escala Likert de 1 a 5, donde 1 representa una total insatisfacción y 5 una completa satisfacción.
El enfoque metodológico incluye dos etapas principales:
Análisis de Clustering en R, que permitió agrupar a los usuarios en diferentes niveles de satisfacción, basados en las respuestas obtenidas.
Regresión Logística implementada en Python, la cual sirvió para predecir el nivel de satisfacción en función de las respuestas del usuario, utilizando las categorías previamente obtenidas mediante clustering.
PRIMERA PARTE EN R - Obtencion de la Variable Respuesta
El conjunto de datos con las respuestas fue procesado para obtener la variable dependiente (nivel de satisfacción) a través de un análisis de clustering. La primera etapa del análisis consistió en agrupar a los usuarios en diferentes categorías de satisfacción mediante un algoritmo de clustering K-means en R. Este análisis permitió segmentar los niveles de satisfacción en tres categorías: Satisfacción Baja, Satisfacción Media y Satisfacción Alta.
Se realizó la suma de las puntuaciones obtenidas en cada pregunta para cada usuario. Esta suma reflejaba el nivel de satisfacción acumulado de cada usuario en función de todas las dimensiones evaluadas.
Lectura de datos - Encuesta de Satisfacción del Correo Institucional de la UNALM
La encuesta diseñada en Google Forms, abarcan diferentes aspectos del servicio de correo institucional de la UNALM. Las respuestas fueron recolectadas en una escala de Likert (1 a 5), donde 1 representa la menor satisfacción y 5 la mayor. Se obtuvieron 72 respuestas.
Estructura del conjunto de datos
## tibble [72 × 12] (S3: tbl_df/tbl/data.frame)
## $ Marca temporal : chr [1:72] "09/25/2024 15:58:08" "09/25/2024 16:00:22" "09/25/2024 16:02:42" "09/25/2024 16:44:30" ...
## $ Código universitario : num [1:72] 20200310 20200323 20210824 20171126 20180994 ...
## $ Sexo : chr [1:72] "Femenino" "Femenino" "Maculino" "Maculino" ...
## $ Edad : num [1:72] 23 23 21 27 25 26 25 23 21 23 ...
## $ ¿Cómo calificas la cantidad de espacio de almacenamiento disponible en tu correo institucional? : num [1:72] 1 1 1 2 2 1 1 2 2 2 ...
## $ ¿Qué tan satisfecho estás con la gestión del spam administrativo (correos masivos de la universidad)? : num [1:72] 2 2 3 2 2 1 2 3 3 2 ...
## $ ¿Cómo valoras la facilidad para organizar y gestionar tus correos importantes dentro del espacio limitado? : num [1:72] 2 2 2 2 2 2 1 4 3 3 ...
## $ ¿Cómo calificas la capacidad de sincronización entre el correo y el espacio de Google Drive para gestionar archivos de estudio? : num [1:72] 1 1 1 2 1 2 1 2 3 3 ...
## $ ¿Qué tan satisfecho estás con las notificaciones del correo institucional para alertarte sobre correos importantes o urgentes? : num [1:72] 1 1 3 2 2 3 2 2 3 3 ...
## $ ¿Cómo valoras la atención y soporte técnico ofrecido por la universidad para resolver problemas con el correo institucional? : num [1:72] 3 1 1 3 1 4 2 3 3 3 ...
## $ ¿Qué tan satisfecho estás con las alternativas que te proporciona la universidad para almacenar información fuera del correo (por ejemplo, otros servicios en la nube)?: num [1:72] 4 4 3 3 3 2 4 3 4 4 ...
## $ ¿Qué tan satisfecho estás con los beneficios adicionales que ofrece el correo institucional, como acceso a cuentas premium (por ejemplo, Office 365, Canva Pro, etc.)? : num [1:72] 3 3 3 4 3 5 3 4 5 4 ...
Suma de las puntuaciones
Se realizó la suma de las puntuaciones obtenidas en cada pregunta para cada usuario. Esta suma reflejaba el nivel de satisfacción acumulado de cada usuario en función de todas las dimensiones evaluadas.
Clustering
El modelo de clustering se implementó utilizando el algoritmo K-means con tres grupos para segmentar a los usuarios en diferentes niveles de satisfacción. Con la suma de las respuestas, se aplicó el algoritmo de K-means
Clasificación de los niveles de satisfacción
Una vez identificados los clústeres, se asignaron estos grupos a las categorías de satisfacción, diferenciando entre usuarios con “Satisfacción Baja”, “Satisfacción Media” y “Satisfacción Alta”, según la media de las respuestas de cada clúster. Este proceso se realizó mediante la agregación y ordenación de los clústeres con base en su valor promedio
# Asignación de los clústeres a las categorías de satisfacción
DATA_SATISF$cluster <- kmeans_result$cluster
# Ordenar los clústeres por la media de las respuestas
cluster_media <- aggregate(DATA_SATISF$SUMA, by=list(DATA_SATISF$cluster), FUN=mean)
cluster_media <- cluster_media[order(cluster_media$x),]
cluster_media
## Group.1 x
## 2 2 14.00000
## 3 3 17.68750
## 1 1 21.54545
Posteriormente, se reasignaron las categorías de satisfacción a los usuarios. El resultado de este proceso permitió dividir a los usuarios en tres grupos de satisfacción: “Satisfacción Baja”, “Satisfacción Media” y “Satisfacción Alta”
# Reasignar las categorías de satisfacción
DATA_SATISF$NIVEL_SATISFACCION <- factor(DATA_SATISF$cluster,
levels = cluster_media$Group.1,
labels = c("SATISFACCIÓN BAJA", "SATISFACCIÓN MEDIA", "SATISFACCIÓN ALTA"))
# Visualización del resultado
table(DATA_SATISF$NIVEL_SATISFACCION)
##
## SATISFACCIÓN BAJA SATISFACCIÓN MEDIA SATISFACCIÓN ALTA
## 7 32 33
Interpretablidad del conjunto de datos
Después del análisis de clustering. Para hacer este dataset más interpretable, fue importante asignar nombres descriptivos a cada una de las columnas. Esto facilitó la interoperabilidad del dataset con otras herramientas y lenguajes, como Python, donde se llevaría a cabo el análisis de Regresión Logística.
Exportación del conjunto de datos consolidado
El archivo DATA_SATISFACCIÓN_COMP.xlsx es ahora el conjunto de datos consolidado, el cual contiene toda la información recolectada, procesada y categorizada a través del análisis de clustering.
SEGUNDA PARTE EN PYTHON - Implementación del Modelo de Regresión Logística
En esta sección se detalla el proceso de implementación del modelo de regresión logística utilizando Python, con el objetivo de predecir el nivel de satisfacción del correo institucional de la UNALM basado en las respuestas obtenidas del cuestionario. El conjunto de datos utilizado proviene del archivo DATA_SATISFACCIÓN_COMP.xlsx, que contiene las respuestas a las preguntas y el nivel de satisfacción previamente calculado mediante un análisis de clustering.
## Warning: package 'reticulate' was built under R version 4.4.1
Instalación de librerías
#!pip install pandas
#!pip install numpy
#!pip install openpyxl
#!pip install pickle
#!pip install streamlit
#!pip install streamlit_option_menu
#!pip install -U scikit-learn scipy matplotlib
# Librerias para el desarrollo del proyecto
import pandas as pd # Para la manipulación de datos
import numpy as np # Para operaciones numéricas
import matplotlib.pyplot as plt # matplotlib para visualización
import seaborn as sns # seaborn para visualización estadística
import streamlit # Para crear aplicaciones web interactivas
import pickle # Para serializar y deserializar objetos de Python
from sklearn.linear_model import LogisticRegression # Modelo de regresión logística de sklearn
from sklearn.model_selection import train_test_split # Para dividir los datos en conjuntos de entrenamiento y prueba
Carga y Exploración del conjunto de datos
Una vez que el entorno está listo, se procede a cargar el conjunto de datos desde el archivo Excel creado en la primera parte del proyecto. Se utiliza la librería pandas para leer el archivo. A continuación, se verifica la forma del dataset y se revisan los valores nulos.
## Marca_Temporal ID Sexo ... SUMA CLUSTER NIVEL_SATISFACCION
## 0 09/25/2024 15:58:08 20200310 Femenino ... 17 3 SATISFACCIÓN MEDIA
## 1 09/25/2024 16:00:22 20200323 Femenino ... 15 2 SATISFACCIÓN BAJA
## 2 09/25/2024 16:02:42 20210824 Maculino ... 17 3 SATISFACCIÓN MEDIA
## 3 09/25/2024 16:44:30 20171126 Maculino ... 20 1 SATISFACCIÓN ALTA
## 4 09/25/2024 16:57:01 20180994 Maculino ... 16 3 SATISFACCIÓN MEDIA
## .. ... ... ... ... ... ... ...
## 67 10/04/2024 12:07:14 20210831 Femenino ... 19 3 SATISFACCIÓN MEDIA
## 68 10/04/2024 12:10:31 20211777 Maculino ... 17 3 SATISFACCIÓN MEDIA
## 69 45569.532407407409 20210839 Maculino ... 22 1 SATISFACCIÓN ALTA
## 70 45569.602141203701 20201411 Femenino ... 21 1 SATISFACCIÓN ALTA
## 71 45569.772858796299 20210810 Maculino ... 21 1 SATISFACCIÓN ALTA
##
## [72 rows x 15 columns]
se crea un nuevo dataframe llamado data que contiene solo las columnas relevantes para nuestro análisis: las respuestas a las preguntas (P_1 a P_8) y el nivel de satisfacción (NIVEL_SATISFACCION). Esta selección nos permitirá enfocarnos en las variables de interés.
data = df[['P_1', 'P_2', 'P_3', 'P_4', 'P_5', 'P_6', 'P_7', 'P_8', 'NIVEL_SATISFACCION']] # Seleccionar columnas relevantes
print(data)
## P_1 P_2 P_3 P_4 P_5 P_6 P_7 P_8 NIVEL_SATISFACCION
## 0 1 2 2 1 1 3 4 3 SATISFACCIÓN MEDIA
## 1 1 2 2 1 1 1 4 3 SATISFACCIÓN BAJA
## 2 1 3 2 1 3 1 3 3 SATISFACCIÓN MEDIA
## 3 2 2 2 2 2 3 3 4 SATISFACCIÓN ALTA
## 4 2 2 2 1 2 1 3 3 SATISFACCIÓN MEDIA
## .. ... ... ... ... ... ... ... ... ...
## 67 1 2 1 1 2 4 3 5 SATISFACCIÓN MEDIA
## 68 1 2 1 2 3 2 4 2 SATISFACCIÓN MEDIA
## 69 2 3 2 3 3 4 3 2 SATISFACCIÓN ALTA
## 70 2 2 2 3 3 2 3 4 SATISFACCIÓN ALTA
## 71 2 2 3 2 2 3 2 5 SATISFACCIÓN ALTA
##
## [72 rows x 9 columns]
Para obtener una visión general del conjunto de datos, se utiliza data.shape, que proporciona las dimensiones, indicando cuántas filas y columnas contiene. Además, data.isnull().sum() para identificar y contar los valores nulos en cada columna.
## (72, 9)
## P_1 0
## P_2 0
## P_3 0
## P_4 0
## P_5 0
## P_6 0
## P_7 0
## P_8 0
## NIVEL_SATISFACCION 0
## dtype: int64
Agrupar el nivel de satisfacción por cada clase
Para obtener una idea inicial sobre la distribución de las respuestas en relación al nivel de satisfacción, se agrupan los datos según las categorías de satisfacción:
## NIVEL_SATISFACCION
## SATISFACCIÓN ALTA 33
## SATISFACCIÓN BAJA 7
## SATISFACCIÓN MEDIA 32
## dtype: int64
# Definir el orden de las categorías
orden_satisfaccion = ['SATISFACCIÓN BAJA', 'SATISFACCIÓN MEDIA', 'SATISFACCIÓN ALTA']
data['NIVEL_SATISFACCION'] = pd.Categorical(data['NIVEL_SATISFACCION'],
categories=orden_satisfaccion, ordered=True)
plt.figure(figsize=(10, 6)) # Ajustar el tamaño de la figura
ax = sns.countplot(data=data, x='NIVEL_SATISFACCION', palette='viridis') # Crear un gráfico de barras
for p in ax.patches:
ax.annotate(f'{round(p.get_height())}', # Redondear a 0 decimales
(p.get_x() + p.get_width() / 2., p.get_height()),
ha='center',
va='bottom',
fontsize=12)
plt.title('Distribución del Nivel de Satisfacción') # Título del gráfico
plt.xlabel('Nivel de Satisfacción') # Etiqueta del eje x
plt.ylabel('Cantidad de Respuestas') # Etiqueta del eje y
plt.xticks(rotation=0) # Rotar las etiquetas del eje x para mayor claridad
# Visualización de las respuestas a las preguntas (P_1 a P_8)
plt.figure(figsize=(15, 8)) # Ajustar el tamaño de la figura
sns.boxplot(data=data[['P_1', 'P_2', 'P_3', 'P_4', 'P_5', 'P_6', 'P_7', 'P_8']],
palette='Set2') # Crear un boxplot para las preguntas
plt.title('Distribución de Respuestas a las Preguntas') # Título del gráfico
plt.xlabel('Preguntas') # Etiqueta del eje x
plt.ylabel('Puntuaciones') # Etiqueta del eje y
plt.xticks(rotation=0) # Rotar las etiquetas del eje x para mayor claridad
Preparación de los Datos para el Modelo
Se separan las características (variables predictoras) y la variable respuesta (nivel de satisfacción) para el modelo de Regresión Logística. Se define el conjunto de características como las respuestas a las preguntas del cuestionario, y la variable objetivo como el nivel de satisfacción categorizado.
División del conjunto de datos
Se divide el conjunto de datos en un conjunto de entrenamiento y un conjunto de prueba, utilizando un 80% de los datos para el entrenamiento y un 20% para la validación del modelo.
# Particionando la data en 0.8 para entrenar y 0.2 para validar
X_trainset, X_testset, y_trainset, y_testset = train_test_split(X,Y, test_size=0.2, random_state=4)
print(X_trainset.shape, y_trainset.shape) # Imprime las dimensiones del conjunto de entrenamiento
## (57, 8) (57,)
## (15, 8) (15,)
Entrenamiento del Modelo de Regresión Logística
Una vez que los datos están preparados, se entrenó el modelo de Regresión Logística. Se especifica que no se aplique penalización en el modelo, y se establece un número máximo de iteraciones para la convergencia.
#entrenando modelo de regresion logistica
modelorl = LogisticRegression(penalty= None, max_iter=250)
rendimientorl = modelorl.fit(X_trainset, y_trainset)
print("Accuracy de entrenamiento:", rendimientorl.score(X, Y))
## Accuracy de entrenamiento: 0.9583333333333334
El accuracy (exactitud) del modelo es aproximadamente 0.8194, o 81.94%.
Predicción y Almacenamiento del Modelo
Una vez entrenado el modelo, se realizan predicciones sobre el conjunto de prueba y se guarda el modelo entrenado en un archivo utilizando la biblioteca pickle para su posterior implementación en una interfaz.
Ejemplo de Predicciones
Se puede realizar predicciones utilizando nuevos ejemplos de datos para comprobar el funcionamiento del modelo. A continuación, se presentan ejemplos de cómo utilizar el modelo para hacer predicciones basadas en nuevas entradas.
## 'SATISFACCIÓN ALTA'
## 'SATISFACCIÓN BAJA'
Universidad Nacional Agraria La Molina, 20200317@lamolina.edu.pe↩︎
Universidad Nacional Agraria La Molina, 20200335@lamolina.edu.pe↩︎
Universidad Nacional Agraria La Molina, 20200339@lamolina.edu.pe↩︎
Universidad Nacional Agraria La Molina, 20200342@lamolina.edu.pe↩︎