Home / Technology / Clasificación binaria: filtrado de spam – Wintellect

Clasificación binaria: filtrado de spam – Wintellect

Mi publicación anterior presentaba un modelo de aprendizaje automático que usaba regresión logística para predecir si la entrada de texto expresa un sentimiento positivo o negativo. Usamos la probabilidad de que el texto exprese un sentimiento positivo como una puntuación de sentimiento y vimos que expresiones como “Las largas colas y el mal servicio al cliente realmente me desaniman” tienen una puntuación cercana a 0.0, mientras que expresiones como “La comida fue excelente y el servicio excelente “puntaje cercano a 1.0. En esta publicación, crearemos un modelo de clasificación binario que clasifica los correos electrónicos como spam o no spam. Y usaremos un algoritmo de aprendizaje llamado bahías ingenuas para ajustar el modelo a los datos de entrenamiento.

No es casualidad que los filtros de spam modernos sean increíblemente buenos para identificar el spam. Prácticamente todos ellos dependen del aprendizaje automático. Estos modelos son difíciles de implementar algorítmicamente, porque un algoritmo que utiliza palabras clave como “crédito” y “puntuación” para determinar si un correo electrónico es spam se engaña fácilmente. El aprendizaje automático, por otro lado, analiza un cuerpo de correos electrónicos y usa lo que aprende para clasificar el siguiente correo electrónico. Estos modelos suelen alcanzar una precisión superior al 99%. Y se vuelven más inteligentes con el tiempo a medida que se capacitan con más y más correos electrónicos.

bahías ingenuas

Naïve Bayes es un algoritmo de clasificación basado en el teorema de Bayes, que proporciona un medio para calcular probabilidades condicionales. Matemáticamente, el teorema de Bayes se establece de esta manera:

Teorema de Bayes

Esto dice que la probabilidad de que A sea verdadero si B es verdadero es igual a la probabilidad de que B sea verdadero si A es verdadero multiplicado por la probabilidad de que A sea verdadero dividido por la probabilidad de que B sea verdadero. Esto es complicado y, aunque preciso, no explica por qué Naïve Bayes es tan útil para clasificar texto, o cómo aplica la ecuación a un montón de correos electrónicos para determinar cuáles son spam.

Resulta que si hace algunas suposiciones simples (ingenuas), que el orden de las palabras en un correo electrónico no importa y que cada palabra tiene el mismo peso, puede escribir la ecuación de esta manera para ordenar el texto:

En portugués simple, la probabilidad de que un mensaje sea spam es proporcional al producto de:

  • La probabilidad de que cualquier mensaje del conjunto de datos sea spam (PD))
  • La probabilidad de que cada palabra del mensaje aparezca en un mensaje de spam (P (palabra | S))

PD) se puede calcular con bastante facilidad; es solo la fracción de los mensajes en el conjunto de datos que son mensajes de spam. Si entrena un modelo de aprendizaje automático con 1000 mensajes y 500 de ellos son spam, entonces PD) = 0,5. Por una palabra dada, P (palabra | S) es simplemente la cantidad de veces que la palabra aparece en los mensajes de spam dividida por la cantidad de palabras en todos los mensajes de spam. Todo el problema se reduce al recuento de palabras. Lo que es realmente genial es que puede hacer un cálculo similar para calcular la probabilidad de que el mensaje sea no spam y luego use la mayor de las dos probabilidades para hacer una predicción.

Aquí hay un ejemplo que involucra cuatro correos electrónicos de ejemplo. Los correos electrónicos son:

Texto correo no deseado
Aumente su puntaje de crédito en minutos 1
Aquí están las actas de la reunión de ayer. 0
Reunión mañana para revisar las puntuaciones de ayer 0
Obtenga la medicina de mañana a los precios de ayer 1

Si elimina palabras superfluas, convierte caracteres a minúsculas y radicaliza las palabras para que “mañana” se convierta en “mañana”, tendrá lo siguiente:

Texto correo no deseado
aumentar la puntuación de crédito minuto 1
minuto ayer encuentro 0
reunión mañana revisión de puntuación ayer 0
la puntuación de mañana y el precio de ayer 1

Dado que dos de los cuatro mensajes son spam y dos no lo son, la probabilidad de que cualquier mensaje sea spam (PD)) es 0,5. Lo mismo ocurre con la probabilidad de que cualquier mensaje no sea spam (P (N) = 0,5). Además, los mensajes de spam contienen un total de 9 palabras, mientras que los mensajes que no son de spam contienen un total de 8.

El siguiente paso es crear la siguiente tabla de frecuencia de palabras. Tome la palabra “ayer” como ejemplo. Aparece una vez en un mensaje marcado como spam, por lo que P (ayer | S) es 1/9 o 0,111. Aparece dos veces en mensajes que no son spam, por lo que P (ayer | N) es 2/8 o 0,250.

Palabra P (palabra | S) P (palabra | N)
aumento 1/9 = 0,111 0/8 = 0,000
crédito 1/9 = 0,111 0/8 = 0,000
puntuación 2/9 = 0,222 1/8 = 0,125
minuto 1/9 = 0,111 1/8 = 0,125
ayer 1/9 = 0,111 2/8 = 0,250
cita 0/9 = 0,000 2/8 = 0,250
mañana 1/9 = 0,111 1/8 = 0,125
revisión 0/9 = 0,000 1/8 = 0,125
con 1/9 = 0,111 0/8 = 0,000
precio 1/9 = 0,111 0/8 = 0,000

Esto funciona hasta cierto punto, pero los ceros en la tabla son un problema. Supongamos que desea determinar si “Las puntuaciones deben revisarse antes de mañana” es spam. La eliminación de las palabras vacías le deja con “revisión de puntuación mañana”. Puede calcular la probabilidad de que el mensaje sea spam así:

El resultado es 0 porque “revisión” no aparece en un mensaje de spam y 0 veces cualquier valor es 0. El algoritmo simplemente no puede asignar una probabilidad de spam a “Las puntuaciones deben revisarse mañana”.

Una forma común de resolver esto es aplicar el suavizado de Laplace, también conocido como suavizado aditivo. Por lo general, esto implica agregar 1 a cada numerador y el número de palabras únicas en el conjunto de datos (en este caso 10) a cada denominador. Ahora, P (revisión | S) se evalúa como (0 + 1) / (9 + 10), lo que equivale a 0.053. No es mucho, pero es mejor que nada (literalmente). Aquí están las palabras frecuencias nuevamente, esta vez revisadas para usar el suavizado de Laplace:

Palabra P (palabra | S) P (palabra | N)
aumento (1 + 1) / (9 + 10) = 0,105 (0 + 1) / (8 + 10) = 0.056
crédito (1 + 1) / (9 + 10) = 0,105 (0 + 1) / (8 + 10) = 0.056
puntuación (2 + 1) / (9 + 10) = 0,158 (1 + 1) / (8 + 10) = 0,111
minuto (1 + 1) / (9 + 10) = 0,105 (1 + 1) / (8 + 10) = 0,111
ayer (1 + 1) / (9 + 10) = 0,105 (2 + 1) / (8 + 10) = 0,167
cita (0 + 1) / (9 + 10) = 0.053 (2 + 1) / (8 + 10) = 0,167
mañana (1 + 1) / (9 + 10) = 0,105 (1 + 1) / (8 + 10) = 0,111
revisión (0 + 1) / (9 + 10) = 0.053 (1 + 1) / (8 + 10) = 0,111
con (1 + 1) / (9 + 10) = 0,105 (0 + 1) / (8 + 10) = 0.056
precio (1 + 1) / (9 + 10) = 0,105 (0 + 1) / (8 + 10) = 0.056

Ahora puede determinar si “Las puntuaciones deben ser revisadas para mañana” es spam realizando dos cálculos simples:

Según esta medida, “Las puntuaciones deben revisarse mañana” probablemente no sea spam. Las probabilidades son relativas, pero puede normalizarlas y concluir que existe un 40% de probabilidad de que el mensaje sea spam y un 60% de probabilidad de que no se base en los correos electrónicos con los que se entrenó el modelo.

Afortunadamente, no es necesario que realice estos cálculos manualmente. Scikit-learn ofrece varias clases para ayudar, incluido el MultinomialNB clase, que funciona muy bien con tablas de recuento de palabras producidas por CountVectorizer. CountVectorizer se introdujo en la publicación anterior de esta serie e incluye la capacidad de eliminar palabras de ruptura, así como convertir texto a minúsculas y considerar No-gramas (grupos de No palabras consecutivas) en lugar de solo palabras individuales.

Entrenar a un clasificador de spam

Pongamos MultinomialDB y CountVectorizer para trabajar mediante la creación de una plantilla que examina un correo electrónico y nos dice si ese correo electrónico es spam, así como la probabilidad que es spam.

Hay varios conjuntos de datos de clasificación de spam disponibles en el dominio público. Cada uno contiene una colección de correos electrónicos de muestra marcados con 1 para spam y 0 para no spam. Usaremos un conjunto de datos relativamente pequeño que contiene 1000 muestras. Empiece por descargar el conjunto de datos y copiarlo en el subdirectorio “Datos” de sus cuadernos. Luego use el siguiente código para cargar los datos y mostrar las primeras cinco líneas:

import pandas as pd

df = pd.read_csv('Data/ham-spam.csv')
df.head()

Ahora verifique si hay filas duplicadas en el conjunto de datos:

df.groupby('IsSpam').describe()

El conjunto de datos contiene una fila duplicada. Eliminémoslo y revisemos el saldo:

df = df.drop_duplicates()
df.groupby('IsSpam').describe()

El conjunto de datos ahora contiene 499 muestras que no son spam y 500 que sí lo son. El siguiente paso es usar CountVectorizer para vectorizar los correos electrónicos. Por si acaso, permitamos CountVectorizer considere pares de palabras así como palabras individuales y elimine las palabras vacías utilizando el diccionario integrado de Scikit con más de 300 palabras vacías en inglés:

from sklearn.feature_extraction.text import CountVectorizer

vectorizer = CountVectorizer(ngram_range=(1, 2), stop_words="english")
x = vectorizer.fit_transform(df['Text'])
y = df['IsSpam']

Divida el conjunto de datos para que el 80% se pueda usar para entrenamiento y el 20% para pruebas:

from sklearn.model_selection import train_test_split

x_train, x_test, y_train, y_test = train_test_split(x, y, test_size=0.2, random_state=0) 

El siguiente paso es entrenar a un clasificador Naïve Bayes. Usaremos Scikit’s MultinomialDB clase, que es ideal para conjuntos de datos vectorizados por CountVectorizer:

from sklearn.naive_bayes import MultinomialNB

model = MultinomialNB()
model.fit(x_train, y_train)

Valide el modelo entrenado con el 20% del conjunto de datos reservado para pruebas y muestre una matriz de confusión:

%matplotlib inline
from sklearn.metrics import plot_confusion_matrix

plot_confusion_matrix(model, x_test, y_test, display_labels=['Not Spam', 'Spam'], cmap='Blues', xticks_rotation='vertical')

El modelo identificó correctamente 101 de 102 correos electrónicos legítimos como no spam y 95 de 98 correos electrónicos no deseados como spam.

Matriz de confusión

Utilizar el puntuación método para obtener una medida aproximada de la precisión del modelo:

model.score(x_test, y_test)

Ahora calcule el área bajo la curva de la característica de funcionamiento del receptor (ROC) para medir mejor la precisión del modelo:

from sklearn.metrics import roc_auc_score

probabilities = model.predict_proba(x_test)
roc_auc_score(y_test, probabilities[:, 1])

Los resultados son alentadores. Capacitado con solo 999 muestras, el modelo tiene una precisión de más del 99,9% al clasificar correos electrónicos como spam o no spam. Veamos cómo la plantilla clasifica algunos correos electrónicos que no ha visto antes, comenzando por uno que no sea spam. De modelo predecir El método proporciona una clase: 0 para no spam o 1 para spam.

message = vectorizer.transform(['Can you attend a code review on Tuesday? Need to make sure the logic is rock solid.'])
model.predict(message)[0]

El modelo dice que este mensaje no es spam, pero ¿cuál es la probabilidad de que no sea spam? puedes conseguirlo de Predict_proba, que devuelve una matriz que contiene dos valores: la probabilidad de que la clase predicha sea 0 y la probabilidad de que la clase predicha sea 1, en ese orden.

model.predict_proba(message)[0][0]

Ahora pruebe la plantilla con un mensaje de spam:

message = vectorizer.transform(['Why pay more for expensive meds when you can order them online and save $$$?'])
model.predict(message)[0]

¿Cuál es la probabilidad de que el mensaje no sea spam?

model.predict_proba(message)[0][0]

¿Cuál es la probabilidad de que el mensaje Es ¿Correo no deseado?

model.predict_proba(message)[0][1]

Mira eso predecir y Predict_proba aceptar una serie de entradas. En base a eso, podría ordenar una gran cantidad de correos electrónicos con una llamada a predecir o Predict_proba? ¿Cómo obtendría los resultados de cada correo electrónico?

obtener el código

Puede descargar un cuaderno de Jupyter que contenga este ejemplo del repositorio de aprendizaje automático que mantengo en GitHub. Siéntase libre de revisar los otros cuadernos en el repositorio mientras hace esto. También asegúrese de revisar de vez en cuando, ya que constantemente estoy cargando nuevos ejemplos y actualizando los existentes.

About admin

Check Also

Con calificaciones * Resultados de segundo año intermedio AP en 2021 Nombre y conocimiento universitario

Con Marks * AP Intermediate, los resultados del segundo año 2021 se pueden verificar en …

Leave a Reply

Your email address will not be published. Required fields are marked *