paint-brush
Ham vs Spam: Cómo identificar y clasificar el correo electrónico spampor@ramakadapala
Nueva Historia

Ham vs Spam: Cómo identificar y clasificar el correo electrónico spam

por Rama7m2025/03/08
Read on Terminal Reader

Demasiado Largo; Para Leer

En este proyecto, se utilizaron algunas de las herramientas de aprendizaje automático para ver cómo funcionan como clasificadores de correos electrónicos no deseados y de correo no deseado. Se presentan descripciones de los cálculos, así como una comparación de sus rendimientos.
featured image - Ham vs Spam: Cómo identificar y clasificar el correo electrónico spam
Rama HackerNoon profile picture

Abstracto

El correo electrónico es una herramienta vital para la comunicación en el mundo actual; sin embargo, los correos electrónicos no deseados se han convertido en un gran desafío. Estos mensajes no solicitados de fuentes desconocidas a menudo llenan las bandejas de entrada, lo que altera la comunicación y la productividad. Este artículo investiga el uso de varias técnicas de aprendizaje automático para clasificar los correos electrónicos como "spam" o "ham" (no spam).


Se evalúan modelos de clasificación como K-Nearest Neighbors (KNN), regresión logística, máquinas de vectores de soporte (SVM) y Naïve Bayes, y se compara su eficacia en la clasificación de correos electrónicos. El rendimiento de cada modelo se evalúa en función de métricas como exactitud, precisión, recuperación y puntuación F1 para determinar qué enfoque es el más adecuado para esta tarea.

Introducción

En 2023, se enviarán 347.300 millones de correos electrónicos cada día, de los cuales el 45 % del tráfico total corresponde a correos electrónicos no deseados. Estos correos electrónicos no deseados le cuestan a las empresas 20.500 millones de dólares cada año. Teniendo en cuenta esto, siempre será necesario garantizar que el correo no deseado se clasifique correctamente y no interfiera con el tráfico legítimo de correo electrónico. Esta es una forma útil de comprender el potencial y la aplicación del aprendizaje automático.


En el caso de la detección de spam, un usuario humano familiarizado con el correo electrónico puede determinar fácilmente si se trata de spam casi inmediatamente después de verlo. Como resultado, creo que este trabajo confirma que la identificación de spam es una aplicación útil para un clasificador de aprendizaje automático. Para clasificar un correo electrónico como spam o no deseado, hay muchos pasos de preprocesamiento involucrados: preparar los datos para que sean aceptables para un clasificador lineal, luego tokenizar y derivar cada línea para convertirla en una tabla TF-IDF (frecuencia de término – frecuencia inversa de documento).


Se seleccionó KNN con K=3 como modelo de referencia. También se probaron la regresión logística con regularización L1, el modelo Naïve Bayes y los modelos SVM antes de decidir el mejor modelo. Para el propósito de este proyecto, se ha utilizado un conjunto de datos de Kaggle, que tiene 2551 archivos de correo electrónico "ham" y 501 archivos de correo electrónico spam y el modelado se ha realizado utilizando el lenguaje de programación R.

Un primer plano de las palabras jamónUn primer plano de palabras spam Metodología seguida

El siguiente gráfico ayudará a comprender el flujo de los distintos pasos seguidos:

Figura que representa los pasos del proyecto

Pasos de preprocesamiento

Dado que se utiliza un gran volumen de datos de texto, fue necesario preprocesar los datos para limpiarlos y obtener un formato que pueda ser utilizado por los modelos de clasificación. A continuación, se explicará el proceso paso a paso que se siguió como parte del preprocesamiento de datos:

  • Los datos de texto deben ser aceptables para un clasificador lineal. Esto significa que el conjunto de datos debe transformarse mediante métodos de extracción de características de texto en características numéricas.

  • En primer lugar, cada línea del texto se convierte en un símbolo y se le asigna la siguiente forma. El proceso de derivación acorta las palabras eliminando las terminaciones flexivas. Por ejemplo, workers se convierte en worker en el siguiente ejemplo.

    Palabras y sus derivaciones

  • A continuación, los datos tokenizados se convierten en una tabla TF-IDF (frecuencia de término - frecuencia inversa de documento). TF-IDF es un enfoque de análisis de texto que establece cada n-grama de un documento en términos de su frecuencia de término-frecuencia inversa de documento. La frecuencia de término es simplemente la frecuencia de un término determinado dentro de un documento (en este caso, un correo electrónico). La frecuencia inversa de documento generalmente se establece como:

    log ((Número total de documentos/Número de documentos con plazo)


Esto sirve para dar más peso a los términos significativos que a los términos muy frecuentes y, por tanto, menos importantes.

  • A continuación, se reducen los términos seleccionando únicamente aquellos que han aparecido en al menos el 2 por ciento de los documentos, pero no en más del 95 por ciento. Este proceso evita el sobreajuste al garantizar que se eliminen los términos que son demasiado únicos o demasiado frecuentes en el conjunto de entrenamiento.


  • Esto produce un total de 1.130 términos en el conjunto de datos de entrenamiento.


Es importante tener en cuenta que la estrategia para utilizar TF-IDF con el conjunto de prueba será realizar únicamente el entrenamiento del modelo en el TF-IDF de entrenamiento y, luego, volver a calcular el TF-IDF con los datos completos para probar la precisión. Esto es necesario porque el TF-IDF depende de la frecuencia en todo el conjunto de datos de un término determinado y también para no incorporar los datos de prueba durante el entrenamiento.


Finalmente, solo se seleccionan los 1000 términos principales por frecuencia general de términos en el conjunto de entrenamiento.


tabla tf-idf

Código para los pasos de preprocesamiento -

 #tokenize word_tokens <- complete_tbl %>% unnest_tokens(word,content) #stemming word_tokens<-word_tokens %>% mutate(word_stem=SnowballC::wordStem(word)) #remove any words with numbers word_tokens <- word_tokens[-grep('^\\d+$', word_tokens$word_stem),] #remove any words with . word_tokens <- word_tokens[-grep('[.]', word_tokens$word_stem),] #remove any single character words word_tokens <- word_tokens[-grep('.\\b[az]\\b.', word_tokens$word_stem),] #remove tokens which match stop words word_tokens <- word_tokens %>% filter(!word %in% stopWords) word_tokens <- word_tokens %>% filter(!word_stem %in% stopWords) #split into training and test word_tokens_train <- word_tokens %>% filter(document %in% ind) #create tfidf for training and then a complete tfidf for testing tfidf_train<-word_tokens_train %>% count(document,word_stem,sort=TRUE) %>% bind_tf_idf(word_stem,document,n) tfidf_complete<-word_tokens %>% count(document,word_stem,sort=TRUE) %>% bind_tf_idf(word_stem,document,n)

Modelos utilizados

  1. K-Vecinos más cercanos (KNN): el modelo de referencia

El modelo logra una especificidad razonable pero una sensibilidad extremadamente baja, lo que significa que muchos correos electrónicos falsos se predicen erróneamente como spam. Tenga en cuenta que en cada uno de los resultados siguientes, la clase positiva es "radioaficionado". Este es realmente el peor resultado posible para un usuario, ya que se perderían muchos correos electrónicos reales que se clasifican como spam.


Matriz de confusión para KNN con K=3
Código para el modelo KNN -

 ##train a model library(e1071) library(caret) library(class) library(LiblineaR) ##remove document number since this is indicative of spam or ham wide_feat_train<-subset(wide_feat_train, select=-c(document)) wide_feat_test<-subset(wide_feat_test,select=-c(document)) #Base model is a knn attempt knn_pred<-knn(train=wide_feat_train,test=wide_feat_test,cl=labels_train$label,k=3) knn_results<-confusionMatrix(knn_pred,labels_test$label) knn_results knn_results$byClass["F1"] knn_results$byClass["Precision"] knn_results$byClass["Recall"]
  1. Regresión logística

Después de obtener malos resultados del modelo KNN, el siguiente modelo utilizado fue la regresión logística.


Para los fines de este escenario,

Las fórmulas de probabilidades para el correo basura y el spam

Se aplicó la regresión logística con los siguientes hiperparámetros:

  • pérdida =” L1”
  • costo = 2
  • épsilon = 0,1


Este modelo proporciona los siguientes resultados en el conjunto de datos de prueba, lo que ya supone una mejora significativa respecto del modelo KNN. La precisión general es bastante alta, pero la especificidad muestra que todavía hay margen de mejora. Un usuario de este modelo descubriría que algunos radioaficionados se predicen como spam.
Matriz de confusión para regresión logística Código para el modelo de regresión logística -

 #Next is a logistic regression usin the below hyperparameters grid_logit <- expand.grid(loss="L1",cost=2,epsilon=0.1) lr <- train(x=wide_feat_train,y=labels_train$label,method="regLogistic",tuneGrid=grid_logit) lr_results<-confusionMatrix(as.factor(predict(lr,wide_feat_test)),labels_test$label) lr_results p_lr = predict(lr,wide_feat_test) prednum_lr<-ifelse(p_lr=="spam",0,1) roc_lr<-roc(labels_test$label,prednum_lr) plot(roc_lr) roc_lr$auc p1_lr<- prediction(as.numeric(p_lr),as.numeric(labels_test$label)) pr_lr <- performance(p1_lr, "prec", "rec") plot(pr_lr) lr_results$byClass["F1"] lr_results$byClass["Precision"] lr_results$byClass["Recall"]
  1. Modelo Bayesiano Ingenuo

El siguiente modelo que se probó fue el modelo Naive Bayes. Para este modelo, se realizó una validación cruzada para encontrar los hiperparámetros óptimos con un enfoque quíntuple. Esto da como resultado los siguientes parámetros para Naive-Bayes:


  • Laplace = 0
  • usekernel = FALSO
  • ajustar = 1


Este modelo también consigue buenos resultados tanto en especificidad como en sensibilidad.

Matriz de confusión para el modelo Naïve Bayes Código para el modelo Naive Bayes -

 ##naive bayes main model nb_cv <- train( x=wide_feat_train, y=labels_train$label, method = "naive_bayes", trControl = train_control, tuneGrid = grid ) nb <- naiveBayes(wide_feat_train,labels_train$label,adjust=1,laplace=0,usekernel=FALSE) nb_results<-confusionMatrix(as.factor(predict(nb,wide_feat_test)),labels_test$label) nb_results p = predict(nb,wide_feat_test) prednum<-ifelse(p=="spam",0,1) roc_nb<-roc(labels_test$label,prednum) plot(roc_nb) roc_nb$auc p1<- prediction(as.numeric(p),as.numeric(labels_test$label)) pr <- performance(p1, "prec", "rec") plot(pr) nb_results$byClass["F1"] nb_results$byClass["Precision"] nb_results$byClass["Recall"]


4. Máquina de vectores de soporte (SVM)

El modelo final es una validación cruzada de SVM con un núcleo lineal. Las máquinas de vectores de soporte intentan encontrar de forma óptima el hiperplano de separación máxima para separar los datos entre dos clases.


Aquí se realiza un CV de 5 pasos utilizando la biblioteca R caret para identificar los hiperparámetros óptimos. Estos hiperparámetros se muestran a continuación:

  • costo = 1
  • pérdida = L2
  • peso = 3


Los resultados de este modelo cuando se aplica al conjunto de datos de prueba retenido se muestran a continuación:

Matriz de confusión para SVM

Código para SVM -

 #svm train_control <- trainControl( method = "cv", number = 5 ) svm <- train(x=wide_feat_train,y=labels_train$label,method="svmLinearWeights2",trControl=train_control) svm$bestTune svm_results<-confusionMatrix(as.factor(predict(svm,wide_feat_test)),labels_test$label) svm_results p_svm = predict(svm,wide_feat_test) prednum_svm<-ifelse(p_svm=="spam",0,1) roc_svm<-roc(labels_test$label,prednum_svm) plot(roc_svm,colorize=T,lwd=3, main=" ROC curve for SVM model") roc_svm$auc p1_svm<- prediction(as.numeric(p_svm),as.numeric(labels_test$label)) pr <- performance(p1_svm, "prec", "rec") plot(pr) svm_results$byClass["F1"] svm_results$byClass["Precision"] svm_results$byClass["Recall"]

Resultados

La siguiente tabla resume las medidas que se consideraron para seleccionar el mejor modelo:

Modelo

Exactitud

Puntuación F1

Precisión

Recordar

KNN

0,252

0,2293

0,8947

0,1315

Regresión logística

0,9624

0,9781

0,9591

0,998

Bayes ingenuo

0,9722

0,9834

0,9882

0,9787

SVM

0,9885

0,9932

0,9886

1

De la tabla anterior se puede ver que SVM tiene el mejor rendimiento en comparación con los otros modelos.


Para confirmar aún más, se trazaron curvas ROC y se calcularon los valores de AUC.

Modelo

KNN

Regresión logística

Bayes ingenuo

SVM

AUC

.5232

.882

.9574

.9628

Fig.: Valores AUC para los 4 modelos

A partir de las métricas anteriores, se puede concluir que el SVM con validación cruzada de 5 pasos tiene el mejor rendimiento en el conjunto de datos al clasificar los correos electrónicos como spam y correo no deseado.

Conclusión

El filtrado de spam siempre será un campo en continua evolución, ya que los spammers encuentran constantemente métodos nuevos e innovadores para enviar mensajes de spam. Es posible que ninguna solución antispam sea la correcta. En este proyecto, se utilizaron algunas de las herramientas de aprendizaje automático para ver cómo funcionan como clasificadores de correos electrónicos de spam y de correo no deseado. Se presentan descripciones de los cálculos, así como una comparación de sus rendimientos.


De los cuatro modelos de aprendizaje automático que se han probado, se ha comprobado que SVM es el mejor en términos de rendimiento. Los modelos de regresión logística y Naïve Bayes también muestran resultados prometedores.