Análisis de Spam en Mensajes de Texto: Implementación de Aprendizaje Automático para su Detección.

Análisis de Spam en Mensajes de Texto: Implementación de Aprendizaje Automático para su Detección.

·

12 min read

Introducción


Este es un corpus de texto de más de 5,500 mensajes SMS en inglés con aproximadamente el 13% etiquetados como spam.

El archivo de texto contiene un mensaje por línea con dos columnas: la etiqueta ("ham" o "spam") y el texto crudo del mensaje. Los mensajes etiquetados como "ham" son mensajes no spam que se pueden considerar legítimos.

Fuente del conjunto de datos. Este corpus fue creado por Tiago A. Almeida y José María Gómez Hidalgo.

Almeida, T.A., Gómez Hidalgo, J.M., Yamakami, A. Contribuciones al Estudio del Filtrado de SMS Spam: Nueva Colección y Resultados. Actas del Simposio ACM de 2011 sobre Ingeniería de Documentos (DOCENG'11), Mountain View, CA, EE.UU., 2011.

Gómez Hidalgo, J.M., Almeida, T.A., Yamakami, A. Sobre la Validez de una Nueva Colección de SMS Spam. Actas de la 11ª Conferencia Internacional IEEE sobre Aprendizaje Automático y Aplicaciones (ICMLA'12), Boca Raton, FL, EE.UU., 2012.

Almeida, T.A., Gómez Hidalgo, J.M., Silva, T.P. Hacia el Filtrado de SMS Spam: Resultados bajo un Nuevo Conjunto de Datos. Revista Internacional de Ciencia de la Seguridad de la Información (IJISS), 2(1), 1-18, 2013.

Objetivos

  • 🗺️ Explorar: ¿Cuáles son las palabras más comunes en los mensajes de spam frente a los mensajes normales?

  • 📊 Visualizar: Crea una nube de palabras que visualice las palabras más comunes en el conjunto de datos.

  • 🔎 Analizar: ¿Qué palabra tiene más probabilidades de indicar que un mensaje es spam?

Contexto

Una empresa de telecomunicaciones que está lanzando una nueva aplicación de mensajería. Desafortunadamente, los filtros de spam anteriores que han utilizado están desactualizados y ya no son efectivos. Te han preguntado si puedes usar los nuevos datos que han proporcionado para distinguir con precisión entre mensajes de spam y mensajes regulares. También te han dicho que es esencial que los mensajes regulares rara vez, o nunca, se categoricen como spam.

prepara un informe que sea accesible para una audiencia amplia. Debe esbozar tu motivación, pasos, hallazgos y conclusiones.

Metodología

Datos

variableclasedescripción
0StringCadena de texto que identifica si el mensaje es 'ham' o 'spam'.
1StringCadena de texto que representa el mensaje.

Exploración Inicial


Tenemos un conjunto de 5,500 mensajes y en los primeros 10 mensajes no obtenemos información relevante pero surgen una preguntas.

IndexTYPEMSG
0hamGo until jurong point, crazy.. Available only ...
1hamOk lar... Joking wif u oni...
2spamFree entry in 2 a wkly comp to win FA Cup fina...
3hamU dun say so early hor... U c already then say...
4hamNah I don't think he goes to usf, he lives aro...
5spamFreeMsg Hey there darling it's been 3 week's n...
6hamEven my brother is not like to speak with me. ...
7hamAs per your request 'Melle Melle (Oru Minnamin...
8spamWINNER!! As a valued network customer you have...
9spamHad your mobile 11 months or more? U R entitle...

¿Existe una relacion en el tamaño de los mensajes y su clasificacion?

Estamos analizando la longitud de los mensajes (en número de caracteres) para observar si existe un patrón distintivo entre mensajes de spam y mensajes legítimos (ham).

Esto nos puede ayudar a entender e identificar diferencias en el tamaño de los mensajes puede ayudar a entender cómo los mensajes de spam se diseñan para llamar la atención o contener más información engañosa.

Como se muestra en el grafico solo se visualizan mensajes de “spam” y “ham” entre el rango de 100 a 300. Esto nos ayuda a centrarnos en la distribución mas importante sin incluir valores extremos. Esta grafica nos ayuda a visualizar lo siguiente.

  • La curva de spam (SPAM LENGTH) presenta un pico significativo entre 150 y 200 caracteres, lo que sugiere que los mensajes de spam tienden a ser más largos y suelen incluir más contenido.

  • la curva de ham (HAM LENGTH) está más concentrada en longitudes cortas, particularmente por debajo de 50 caracteres, lo que indica que los mensajes legítimos tienden a ser más breves.

  • Aunque existe cierta superposición entre las longitudes de los mensajes spam y ham, se nota una clara tendencia de separación

  • !! Este comportamiento puede ser clave para modelos de clasificación, ya que la longitud de un mensaje podría ser una característica relevante para distinguir entre ambas categorías.

¿Cuantos registros tenemos por etiqueta (ham, spam)?

Esta informacion nos puede ayudar para identificar si existe un balance adecuado entre ambas categorías o si el dataset está desequilibrado, lo cual podría afectar el rendimiento de modelos de clasificación.

El grafico de pastel (Pie Chart) generado podemos observar que la mayoría de los mensajes pertenecen a la categoría “ham”, con un 86.6% del total, mientras que los mensajes de spam constituyen solo el 13.4%. Eso nos indica que nuestro dataset se encuetra desequilibrado esto trae consigo ciertos problemas como por ejemplo:

  • Podría sesgar un modelo de clasificación, ya que el modelo podría aprender a favorecer la categoría predominante. En este caso, si los mensajes “ham” son mayoría, el modelo podría clasificar incorrectamente los mensajes spam.

!!! Esta información nos permite tomar decisiones informadas, como aplicar técnicas de balanceo de datos (submuestreo o sobremuestreo) para mejorar la calidad del análisis o el entrenamiento del modelo.

Preprocesamiento de Datos


El preprocesamiento es una etapa fundamental en el análisis de mensajes de texto, ya que permite transformar el contenido textual en una forma que los modelos de aprendizaje automático puedan interpretar y analizar de manera efectiva. En este caso, trabajamos con mensajes de “spam” y “ham”, por lo que es crucial limpiar y estructurar los datos textuales para garantizar un análisis satisfactorio.

Eliminación de caracteres especiales

Podemos utilizar expresiones regulares y librerías de Python y aplicarlo sobre los mensajes de la siguiente manera.

import re
# Eliminacion de caracteres especiales (@, #, %, $, etc.).
# Definir el patrón de expresión regular
pattern = r'[^a-zA-Z0-9\s]'

# Aplicar la limpieza a cada mensaje en la columna 'MSG'
msgs.loc[:, 'CLEAN_MSG'] = msgs['MSG'].apply(lambda msg: re.sub(pattern, "", msg))

Eliminacion de stopwords (English)

Podemos realizar esto mediante la librería "nltk" para análisis de texto, de la siguiente manera.

from nltk.corpus import stopwords
#import nltk
# Eliminacion de de palabras que no aportan informacion como [I, la, will, etc.] este depende el idioma
# En ingles ocupamos descargar el paquete
# Si no esta descargado el paquete de palabras
#nltk.download('stopwords')
# 
# Recurso
# https://www.geeksforgeeks.org/removing-stop-words-nltk-python/#removing-stop-words-with-sklearn
stop_words = set(stopwords.words('english'))


msgs['CLEAN_MSG'] = msgs['CLEAN_MSG'].apply(
    lambda msg: ' '.join(
      [word for word in msg.split() if word.lower() not in stop_words]
        )
    )

Lematizacion

Este proceso implica reducir las palabras a su forma base o raíz. Por ejemplo, convertimos "corriendo" a "correr" para evitar redundancia y simplificar el procesamiento.

para comprender mejor como se realiza podemos consultas en datacamp. Para comprender mejor esto.

Mediante el uso del algoritmo "PorterStemmer" realizamos la lemmatizacion para palabras en ingles.

# Algoritmo Porter stemme
from nltk.stem import PorterStemmer
# Initialize Python porter stemmer
ps = PorterStemmer()

msgs['CLEAN_MSG'] = msgs['CLEAN_MSG'].apply(
    lambda msg: ' '.join(
        [ps.stem(word) for word in msg.split()]
        )
    )

Análisis Exploratorio de Datos (EDA)


¿Cuales son las palabras mas comunes en los mensajes de spam y no spam?

Top Words in Ham

WORDFREQUENCY
u985
im461
go417
get360
come295
call289
dont276
ltgt276
ok273
ur246

Top Words in Spam

WORDFREQUENCY
call366
free216
txt163
u147
ur144
text138
mobil135
claim115
stop115
repli109

La identificación de las palabras más comunes en mensajes de spam y ham usando la biblioteca Counter es una excelente manera de entender el lenguaje característico de cada tipo de mensaje. Este análisis permite descubrir patrones importantes que diferencian los mensajes personales (ham) de los promocionales o no deseados (spam).

Patrones en Mensajes Ham En los mensajes ham, observamos un lenguaje informal y característico de conversaciones personales:

  • Palabras comunes: "u", "im", "go", "get" reflejan la naturaleza relajada y amistosa de los mensajes.

  • Interacciones cotidianas: Palabras como "call", "dont", "ok" sugieren actividades diarias, como hacer planes o confirmar algo.

!!! Este tipo de mensajes tiende a ser espontáneo, directo y natural, sin indicios de intenciones comerciales.

Patrones en Mensajes Spam En los mensajes spam, predominan palabras que buscan captar la atención o incitar una acción específica:

  • romociones y ofertas: "call", "free", "claim" son términos que indican contenido persuasivo relacionado con incentivos.

  • Interacción directa: "txt", "text", "stop", "repli" sugieren tácticas para motivar al usuario a responder o interactuar.

  • Personalización: "mobil", "ur" se utilizan para dar un toque personalizado al mensaje, lo que es común en campañas de marketing.

!! Los mensajes spam están diseñados para ser llamativos, directos y persuasivos, utilizando estrategias de lenguaje específicas para atraer la atención del receptor.

Comparaciones Clave Términos compartidos: Palabras como "u", "call", "ur" aparecen en ambos tipos de mensajes, pero con diferentes propósitos:

  • En ham, "call" suele estar relacionado con una invitación o comunicación personal.

  • En spam, "call" se utiliza principalmente para solicitudes comerciales o promocionales.

!!! Diferencias principales: Los mensajes spam están dominados por términos asociados al marketing ("free", "claim", "txt"), mientras que los ham son más naturales y espontáneos.

Nube de palabras

La nube de palabras es una herramienta visual que facilita la identificación de palabras dominantes en un conjunto de datos, destacando su frecuencia mediante el tamaño relativo de cada palabra. Esto permite interpretar rápidamente patrones importantes de un texto.

En este análisis, utilizamos las bibliotecas wordcloud y matplotlib para crear y visualizar las nubes de palabras correspondientes a los mensajes ham y spam. Limitamos la visualización a las principales 500 palabras más frecuentes, lo que nos permite enfocar la atención en los términos más relevantes.

!!! Solo se tomaron las principales 500 palabras con mayor frecuencia.

!!! Si quiere mas información se pude visitar DataCamp para mas información.

¿Cuál es la probabilidad de que una palabra indique que un mensaje sea Spam o no?

Para calcular la probabilidad de que una palabra pertenezca a un mensaje de spam, no podemos usar la típica probabilidad de Laplace:

$$P = \frac{\text{Casos Favorables}}{\text{Casos Posibles}}$$

Esto se debe a que hablamos de dos posibles conjuntos a los que puede pertenecer la palabra: ham y spam. Por lo tanto, debemos emplear el cálculo de la probabilidad condicional mediante la siguiente fórmula:

$$P(A \mid B) = \frac{P(A \cap B)}{P(B)}$$

Definiciones:

  • A: El mensaje es spam (Spam).

  • B: La palabra aparece en el mensaje (Word).

  • P(A | B): La probabilidad de que el mensaje sea spam y contenga la palabra.

  • P(B) : La probabilidad de que la palabra aparezca en cualquier mensaje.


Desafíos del cálculo:

  1. Falta de acceso al universo completo: No siempre contamos con datos representativos de todos los mensajes posibles.

  2. Ambigüedad en eventos conjuntos: Puede ser difícil identificar qué mensajes contienen una palabra específica y a qué clase pertenecen.

  3. Distribución desequilibrada: En nuestro dataset hay más mensajes ham que spam, lo que podría sesgar las probabilidades hacia la clase mayoritaria.


Solución práctica:

En lugar de calcular P(A | B) y P(B) directamente, trabajamos con frecuencias relativas específicas para cada clase (spam y ham) en el conjunto de datos. Esto nos lleva a una fórmula simplificada:

$$P(\text{Spam} \mid \text{Word}) = \frac{\text{frecuenciaSpam}}{\text{frecuenciaSpam} + \text{frecuenciaHam}}$$


Ajuste Laplaciano (Suavizado):

Para evitar problemas cuando una palabra solo aparece en una de las clases (por ejemplo, frecuencia 0 en ham o spam), aplicamos un ajuste laplaciano, que añade un pequeño valor constante para evitar divisiones problemáticas. La fórmula ajustada es:

$$P(\text{Spam} \mid \text{Word}) = \frac{\text{frecuenciaSpam} + 1}{\text{frecuenciaSpam} + \text{frecuenciaHam} + 2}$$


Resultados:

Sin ajuste Laplaciano:

WordFREQUENCY_HAMFREQUENCY_SPAMPROBABILITY
abl26.00.00.00000
abt26.00.00.00000
access0.08.01.00000
account24.019.00.44186
activ0.07.01.00000

Con ajuste Laplaciano:

WordFREQUENCY_HAMFREQUENCY_SPAMPROBABILITY
abl26.00.00.035714
abt26.00.00.035714
access0.08.00.900000
account24.019.00.444444
activ0.07.00.888889

Importancia:

El ajuste Laplaciano garantiza que las probabilidades sean más robustas frente a la ausencia de datos, evitando resultados extremos (como probabilidades de 0 o 1). Esto mejora la confiabilidad del análisis, especialmente cuando se utiliza en algoritmos de clasificación.

Modelo de Machine Learning


Para aplicar un modelo de machine learning de manera efectiva, es fundamental seguir algunos pasos clave en el proceso.

  1. División de los Datos Es importante dividir el conjunto de datos en dos partes:

    • 80% de los datos serán utilizados para entrenar el modelo.

    • 20% de los datos se utilizarán para probar la efectividad del modelo.

Esta división ayuda a evitar el sobreajuste y garantiza que el modelo tenga capacidad para generalizar.

Para entrenar nuestro modelo de Machine Learning y poder saber si está funcionando bien, alguien dijo: Separemos el conjunto de datos inicial en 2: conjunto de entrenamiento (train) y conjunto de Pruebas (test). Por lo general se divide haciendo “80-20”. Y se toman muestras aleatorias -no en secuencia, si no, mezclado.

# Divide el dataset en 80% entrenamiento y 20% prueba
train_size = int(msgs.shape[0] * 0.80)  # Asegúrate de convertir a entero
test_size = msgs.shape[0] - train_size  # El resto será el tamaño de prueba

msgs_train = msgs.sample(n=train_size, random_state=42)  # Conjunto de entrenamiento
msgs_test = msgs.drop(spam_train.index)  # El resto será el conjunto de prueba

Conversión a Vectores Numéricos (TF-IDF) El modelo de machine learning no puede trabajar directamente con texto. Por lo tanto, necesitamos convertirlo en una representación numérica. Para ello, utilizaremos el algoritmo TF-IDF (Term Frequency - Inverse Document Frequency).

# Función para codificar las categorías
def encode_category(cat):
    return 1 if cat in ["spam", 1] else 0

# Preprocesamiento y vectorización
msgs_train['TYPE'] = msgs_train['TYPE'].apply(encode_category)

vectorizer = TfidfVectorizer(encoding="latin-1")
tfidf_features = vectorizer.fit_transform(msgs_train['CLEAN_MSG'])

# División en conjuntos de entrenamiento y prueba
X_train, X_test, y_train, y_test = train_test_split(
    tfidf_features, msgs_train['TYPE'], stratify=msgs_train['TYPE'], 
    test_size=0.2, random_state=42
)

Con una división del conjunto en entrenamiento y su vectorización de los mensajes podemos proceder a implementar distintos modelo de machine learning. En este análisis se seleccionaron distintos modelos los cuales son: Naive Bayes, Random Forest, SVM.

Conclusiones


Aunque todos los modelos tienen un buen rendimiento, SVM se destaca por su mayor capacidad para detectar mensajes spam correctamente, dado que tiene el mejor recall para la clase spam. Esto es particularmente importante en aplicaciones de clasificación de spam, ya que es preferible capturar la mayoría de los mensajes spam, aunque algunos mensajes no spam puedan ser etiquetados incorrectamente como spam (falsos positivos).