Procesamiento de lenguaje natural para correos electrónicos

Pipeline de NLP de resumen en correos electrónicos usando Python

Durante mi función actual, es útil mantener un registro de todos los correos electrónicos enviados y recibidos, lo que puede ser extremadamente problemático de mantener y consume gran parte de mi energía y desvía mi atención de mis tareas principales. En este tutorial, lo guiaré a través de cómo usar NLP e IMAPlib para resúmenes y realizar un seguimiento de sus correos electrónicos.

La idea:

La idea en mente es construir un sistema que sea capaz de permitir que el usuario inicie sesión para acceder a los últimos correos electrónicos y actualizarlos en una hoja de Excel con los siguientes datos:

También te puede interesarAhora puede usar la búsqueda basada en Bing AI en Android e iOS

Podemos hacerlo usando la biblioteca IMAP, que significa Protocolo de acceso al correo de Internet. IMAP, que se propuso por primera vez en 1986, es un protocolo de recuperación de correo electrónico que tiene la capacidad de leer correos electrónicos y mostrarlos. Python tiene una biblioteca específica para esto llamada imaplib.

Luego, usando los comandos de python, podemos acceder fácilmente a todos los datos necesarios. Ahora, parte de la información útil para registrar es un resumen del cuerpo del correo electrónico. Para hacerlo con el mínimo esfuerzo, me referiré a la ayuda de la confiable plataforma Huggingface.

cara de abrazo es un excelente recurso para crear aplicaciones que utilizan aprendizaje automático, más específicamente aplicaciones que requieren el uso de Transformers. Su biblioteca de transformadores está diseñada para aplicaciones de procesamiento de lenguaje natural y su plataforma permite a los usuarios compartir conjuntos de datos y modelos de aprendizaje automático.

Comencemos instalando las bibliotecas necesarias para este proyecto:

También te puede interesarLos 5 mejores proyectos de ciencia de datos de principiantes a profesionales en PythonLos 5 mejores proyectos de ciencia de datos de principiantes a profesionales en Python
!pip install python-imap
!pip install transformers

Luego, avancemos e importemos todas las bibliotecas necesarias, quedará claro por qué necesitamos cada biblioteca a medida que avanzamos en el código.

import imaplib
import email
import codecs
import string
from transformers import AutoTokenizer, pipeline,

Primero, comenzaremos con “conectarnos” a nuestro correo electrónico. Esto se puede hacer creando una instancia de clase imap4_ssl. Si desea conectarse a una cuenta de gmail, entonces «imap.gmail.com» sería suficiente. Si Outlook, entonces «imap.outlook.com».

Después de establecer una conexión, necesitamos autenticarnos e iniciar sesión. Reemplace «user_email» y «password» con sus credenciales. Es importante tener en cuenta que para que esto funcione, deberá realizar pasos adicionales:

  • Habilite IMAP en su cuenta de gmail:
  • 2. Cree su propia contraseña de aplicación, ya que será su credencial de inicio de sesión:

    También te puede interesarChatGPT vs BARD: La batalla de los asistentes de IA
    summarizer = pipeline("summarization", model="knkarthick/MEETING_SUMMARY")

    # create an IMAP4_SSL class instance
    imap = imaplib.IMAP4_SSL("imap.gmail.com")

    # login with your Gmail account credentials
    user_email= "youremail@gmail.com"
    password = "APP_PASSWORD" #
    imap.login(user_email, password)

    A continuación, usamos el imap.list() método para recuperar una lista de todos los buzones en la cuenta de Gmail del usuario autenticado. El primer índice de la lista contiene «ok», mientras que el segundo índice es una tupla que contiene el nombre del buzón, delimitador (para separar la jerarquía en los nombres de los buzones), y atributos (propiedades del buzón, como la disponibilidad de nuevos mensajes).

    # loop through the tuple of imap.list, and print all mailboxes available.
    for i in imap.list()[1]:
    l = i.decode().split(' "/" ')
    print(l[0] + " = " + l[1])
    (HasNoChildren) = "INBOX"
    (HasChildren Noselect) = "[Gmail]"
    (All HasNoChildren) = "[Gmail]/All Mail"
    (HasNoChildren Trash) = "[Gmail]/Bin"
    (Drafts HasNoChildren) = "[Gmail]/Drafts"
    (HasNoChildren Important) = "[Gmail]/Important"
    (HasNoChildren Sent) = "[Gmail]/Sent Mail"
    (HasNoChildren Junk) = "[Gmail]/Spam"
    (Flagged HasNoChildren) = "[Gmail]/Starred"

    Ahora, como me gustaría revisar mi bandeja de entrada, seleccionaré «INBOX» de la lista anterior para recorrer y recuperar datos, más específicamente mis mensajes no leídos usando el método imap.fetch.

    También te puede interesarEliminación de comentarios de spam con el algoritmo Naïve Bayes de Bernoulli

    Note que en el código imap.fetch(num, "(RFC822)")el (RFC822) El parámetro se escribe para especificar el formato en el que se recupera el mensaje de correo electrónico. Este formato es útil ya que permite la extracción de elementos de encabezado en el correo electrónico, como la fecha y el asunto.

    Usando la biblioteca de correo electrónico de python, el email.message_from_bytes() El método ayuda a analizar un mensaje de correo electrónico con formato RFC 822 que se ha codificado como una cadena de bytes que devuelve un objeto del correo electrónico con toda su información de encabezado («Para», «De», «Asunto» y «Fecha», archivos adjuntos) y cuerpo .

    #select a mailbox (folder) to read messages from
    imap.select('"INBOX"')
    status, messages = imap.search(None, 'UNSEEN')
    # iterate over the messages and retrieve their contents
    for num in messages[0].split():
    _, msg = imap.fetch(num, "(RFC822)")
    message = email.message_from_bytes(msg[0][1])

    # print the message details
    print("Subject:", message["Subject"])
    print("From:", message["From"])
    print("Date:", message["Date"])

    Ahora viene la parte divertida…. extraer el cuerpo, para realizar resúmenes sobre el mismo.

    Sin embargo… para hacerlo, se debe realizar un paso adicional después de «message_from_bytes». Usamos «get_payload» para devolver el mensaje completo como una cadena. Para asegurarnos de que todo el procedimiento transcurra sin problemas, verificamos si el correo electrónico tiene varias partes. Los correos electrónicos de varias partes son, como su nombre lo indica, correos electrónicos que contienen varias partes, cada una de las cuales puede tener su propio tipo de contenido, codificación y otros atributos, como texto sin formato y uno o más archivos adjuntos.

    Entonces, primero, verifiquemos si hay varias partes, y si es Verdadero:

    Si es Falso, entonces la recuperación (usando get_payload) del texto sin formato solo mediante la verificación usando la función get_content_type().

    #select a mailbox (folder) to read messages from
    imap.select('"INBOX"')
    status, messages = imap.search(None, 'UNSEEN')

    # iterate over the messages and retrieve their contents
    for num in messages[0].split():
    _, msg = imap.fetch(num, "(RFC822)")
    message = email.message_from_bytes(msg[0][1])
    if message.is_multipart():
    for part in message.walk():
    if part.get_content_type() == "text/plain":
    content = part.get_payload(decode=True)
    body=content.decode("utf-8")
    break
    else:
    # if no text/plain part was found, use the first part as the body
    content = message.get_payload(0).get_payload(decode=True)
    body=content.decode("utf-8")
    else:
    # if the message is not multipart, just use the message body
    content = message.get_payload(decode=True)
    body=content.decode("utf-8")

    # print the message details
    print("Subject:", message["Subject"])
    print("From:", message["From"])
    print("Date:", message["Date"])
    print("Body:",body)

    Mientras codificaba, algunos asuntos de correo electrónico se recuperaron incorrectamente y en un formato ilegible, por lo tanto, importé la biblioteca email.reader para decodificar el asunto usando los siguientes cambios:

    import email.header

    summaryofsentemails=list()

    imap.select('"INBOX"')
    status, messages = imap.search(None, 'UNSEEN')

    # # search for all unread messages in the mailbox
    # _, messages = imap.search(None, "UNSEEN")

    # iterate over the messages and retrieve their contents
    for num in messages[0].split():
    _, msg = imap.fetch(num, "(RFC822)")
    message = email.message_from_bytes(msg[0][1])
    if message.is_multipart():
    for part in message.walk():
    if part.get_content_type() == "text/plain":
    content = part.get_payload(decode=True)
    body=content.decode("utf-8")
    break
    else:
    if message.get_content_type() == "text/plain":
    content = part.get_payload(decode=True)
    body=content.decode("utf-8")
    break

    # print the message details
    subject_header = message['Subject']
    decoded_subject = email.header.decode_header(subject_header)
    subject = decoded_subject[0][0]
    print("Subject:", subject)
    print("From:", message["From"])
    print("Date:", message["Date"])

    Después de extraer el cuerpo del correo electrónico en formato de texto sin formato, lo enviaremos a través de una canalización de resumen. En este tutorial, utilizaremos la biblioteca HuggingFace para la tarea de resumen del procesamiento del lenguaje natural.

    El modelo utilizado en este tutorial es «knkarthick/MEETING_SUMMARY» y el tokenizador utilizado es AutoTokenizer del mismo modelo. Al referirnos a la tarjeta modelo, vemos que podemos usar este modelo de la siguiente manera:

    from transformers import pipeline
    summarizer = pipeline("summarization", model="knkarthick/MEETING_SUMMARY")
    text = '''The tower is 324 metres (1,063 ft) tall, about the same height as an 81-storey building, and the tallest structure in Paris. Its base is square, measuring 125 metres (410 ft) on each side. During its construction, the Eiffel Tower surpassed the Washington Monument to become the tallest man-made structure in the world, a title it held for 41 years until the Chrysler Building in New York City was finished in 1930. It was the first structure to reach a height of 300 metres. Due to the addition of a broadcasting aerial at the top of the tower in 1957, it is now taller than the Chrysler Building by 5.2 metres (17 ft). Excluding transmitters, the Eiffel Tower is the second tallest free-standing structure in France after the Millau Viaduct.
    '''
    summarizer(text)

    Para generar el resumen, se pasa como parámetro al resumen el contenido a resumir junto con algunos otros parámetros de configuración como la longitud máxima y mínima del resumen y si se trunca o no el texto.

    summarizer = pipeline("summarization", model="knkarthick/MEETING_SUMMARY", tokenizer=AutoTokenizer.from_pretrained("knkarthick/MEETING_SUMMARY"))
    # Generate the summary
    content_summarised = summarizer(body, max_length=100,
    min_length=10, truncation=True, padding=True)[0]['summary_text']
    print(content_summarised)
    summary={"Subject": subject,"From":str(message["From"]),
    "Date": str(message["Date"]),
    "Email ":content_summarised}
    summaryofsentemails.append(summary)

    ¿Por qué especificar la longitud máxima, la longitud mínima, el relleno y el truncamiento?

    Bueno, las entradas por lotes para modelos preentrenados deben ser de cierto tamaño. Por lo tanto, debemos asegurarnos de que la entrada para el modelo de resumen se convierta en tensores de tamaño fijo similares a los del modelo en el que se entrenó originalmente… esto se hace de la siguiente manera:

    Una vez que se completa el proceso de resumen, el texto de resumen se extrae de la salida del resumen y se almacena en una variable llamada content_summarised.

    Finalmente, se crea un diccionario con todos los datos requeridos (asunto, remitente y fecha del correo electrónico, junto con el texto de resumen generado). Este diccionario se adjunta a una lista llamada resumen de correos enviados, que se puede usar para realizar un seguimiento de todos los correos electrónicos que se han resumido hasta ahora para guardarlos en un marco de datos separado.

    summarizer = pipeline("summarization", model="knkarthick/MEETING_SUMMARY", tokenizer=AutoTokenizer.from_pretrained("knkarthick/MEETING_SUMMARY"))
    # Generate the summary
    content_summarised = summarizer(body, max_length=100,
    min_length=10, truncation=True)[0]['summary_text']
    print(content_summarised)
    summary={"Subject": subject,"From":str(message["From"]), "Date": str(message["Date"]),
    "Email ":content_summarised}
    summaryofsentemails.append(summary)

    Scroll al inicio