Python para PNL: Introducci贸n a la biblioteca de patrones

    Este es el octavo art铆culo de mi serie de art铆culos sobre Python para PNL. En mi art铆culo anterior, expliqu茅 c贸mo se puede usar la biblioteca TextBlob de Python para realizar una variedad de tareas de PNL que van desde la tokenizaci贸n hasta el etiquetado de POS, y la clasificaci贸n de texto al an谩lisis de opiniones. En este art铆culo, exploraremos la biblioteca de patrones de Python , que es otra biblioteca de procesamiento de lenguaje natural extremadamente 煤til.

    La biblioteca de patrones es una biblioteca multiprop贸sito capaz de manejar las siguientes tareas:

    • Procesamiento de lenguaje natural: Realizaci贸n de tareas como tokenizaci贸n, derivaci贸n, etiquetado POS, an谩lisis de sentimientos, etc.
    • Miner铆a de datos: contiene API para extraer datos de sitios como Twitter, Facebook, Wikipedia, etc.
    • Machine Learning: contiene modelos de Machine Learning como SVM, KNN y perceptron, que se pueden usar para tareas de clasificaci贸n, regresi贸n y agrupaci贸n en cl煤steres.

    En este art铆culo, veremos las dos primeras aplicaciones de la biblioteca de patrones de la lista anterior. Exploraremos el uso de la biblioteca de patrones para PNL realizando tareas como tokenizaci贸n, derivaci贸n y an谩lisis de sentimientos. Tambi茅n veremos c贸mo se puede usar la biblioteca de patrones para la miner铆a web.

    Instalaci贸n de la biblioteca

    Para instalar la biblioteca, puede usar el siguiente comando pip:

    $ pip install pattern
    

    De lo contrario, si est谩 usando la distribuci贸n Anaconda de Python, puede usar el siguiente comando Anaconda para descargar la biblioteca:

    $ conda install -c asmeurer pattern
    

    Funciones de biblioteca de patrones para PNL

    En esta secci贸n, veremos algunas de las aplicaciones de PNL de la biblioteca de patrones.

    Tokenizaci贸n, etiquetado de POS y fragmentaci贸n

    En las bibliotecas NLTK y spaCy, tenemos una funci贸n separada para tokenizar, etiquetar POS y encontrar frases nominales en documentos de texto. Por otro lado, en la biblioteca de patrones existe el parsem茅todo todo en uno que toma una cadena de texto como par谩metro de entrada y devuelve los tokens correspondientes en la cadena, junto con la etiqueta POS.

    El parsem茅todo tambi茅n nos dice si un token es un sintagma nominal o verbo, sujeto u objeto. Tambi茅n puede recuperar tokens lematizados configurando el lemmatapar谩metro en True. La sintaxis del parsem茅todo junto con los valores predeterminados para diferentes par谩metros es la siguiente:

    parse(string,
        tokenize=True,      # Split punctuation marks from words?
        tags=True,          # Parse part-of-speech tags? (NN, JJ, ...)
        chunks=True,        # Parse chunks? (NP, VP, PNP, ...)
        relations=False,    # Parse chunk relations? (-SBJ, -OBJ, ...)
        lemmata=False,      # Parse lemmata? (ate => eat)
        encoding='utf-8',   # Input string encoding.
        tagset=None         # Penn Treebank II (default) or UNIVERSAL.
    )
    

    Veamos el parsem茅todo en acci贸n:

    from pattern.en import parse
    from pattern.en import pprint
    
    pprint(parse('I drove my car to the hospital yesterday', relations=True, lemmata=True))
    

    Para utilizar el parsem茅todo, debe importar el enm贸dulo de la patternbiblioteca. El enm贸dulo contiene funciones de PNL en ingl茅s. Si usa el pprintm茅todo para imprimir la salida del parsem茅todo en la consola, deber铆a ver la siguiente salida:

             WORD   TAG    CHUNK   ROLE   ID     PNP    LEMMA
    
                 I   PRP    NP      SBJ    1      -      i
             drove   VBD    VP      -      1      -      drive
                my   PRP$   NP      OBJ    1      -      my
               car   NN     NP ^    OBJ    1      -      car
                to   TO     -       -      -      -      to
               the   DT     NP      -      -      -      the
          hospital   NN     NP ^    -      -      -      hospital
         yesterday   NN     NP ^    -      -      -      yesterday
    

    En la salida, puede ver las palabras tokenizadas junto con su etiqueta POS, el fragmento al que pertenecen los tokens y la funci贸n. Tambi茅n puede ver la forma lematizada de los tokens.

    Si llama al splitm茅todo en el objeto devuelto por el parsem茅todo, la salida ser谩 una lista de oraciones, donde cada oraci贸n es una lista de tokens y cada token es una lista de palabras, junto con las etiquetas asociadas con las palabras.

    Por ejemplo, mire el siguiente gui贸n:

    from pattern.en import parse
    from pattern.en import pprint
    
    print(parse('I drove my car to the hospital yesterday', relations=True, lemmata=True).split())
    

    La salida del script anterior se ve as铆:

    [[['I', 'PRP', 'B-NP', 'O', 'NP-SBJ-1', 'i'], ['drove', 'VBD', 'B-VP', 'O', 'VP-1', 'drive'], ['my', 'PRP$', 'B-NP', 'O', 'NP-OBJ-1', 'my'], ['car', 'NN', 'I-NP', 'O', 'NP-OBJ-1', 'car'], ['to', 'TO', 'O', 'O', 'O', 'to'], ['the', 'DT', 'B-NP', 'O', 'O', 'the'], ['hospital', 'NN', 'I-NP', 'O', 'O', 'hospital'], ['yesterday', 'NN', 'I-NP', 'O', 'O', 'yesterday']]]
    

    Pluralizaci贸n y singularizaci贸n de las fichas

    Los m茅todos pluralizey singularizese utilizan para convertir palabras singulares en plurales y viceversa, respectivamente.

    from pattern.en import pluralize, singularize
    
    print(pluralize('leaf'))
    print(singularize('theives'))
    

    La salida se ve as铆:

    leaves
    theif
    

    Conversi贸n de adjetivos en grados comparativos y superlativos

    Puede recuperar grados comparativos y superlativos de un adjetivo usando comparativey superlativefunciones. Por ejemplo, el grado comparativo de bien es mejor y el grado superlativo de bien es mejor. Veamos esto en acci贸n:

    from pattern.en import comparative, superlative
    
    print(comparative('good'))
    print(superlative('good'))
    

    Salida:

    better
    best
    

    Encontrar N-gramos

    N-gramos se refiere a “n” combinaciones de palabras en una oraci贸n. Por ejemplo, para la oraci贸n “Va al hospital”, 2 gramos ser铆an (Va), (Va a) y (Al hospital). N-Grams puede desempe帽ar un papel crucial en la clasificaci贸n de textos y el modelado del lenguaje.

    En la biblioteca de patrones, el ngramm茅todo se usa para encontrar todos los n-gramas en una cadena de texto. El primer par谩metro del ngramm茅todo es la cadena de texto. El n煤mero de n-gramos se pasa al npar谩metro del m茅todo. Mira el siguiente ejemplo:

    from pattern.en import ngrams
    
    print(ngrams("He goes to hospital", n=2))
    

    Salida:

    [('He', 'goes'), ('goes', 'to'), ('to', 'hospital')]
    

    Encontrar sentimientos

    El sentimiento se refiere a una opini贸n o sentimiento hacia una determinada cosa. La biblioteca de patrones ofrece funcionalidad para encontrar opiniones a partir de una cadena de texto.

    En Pattern, el sentimentobjeto se usa para encontrar la polaridad (positividad o negatividad) de un texto junto con su subjetividad.

    Dependiendo de los adjetivos positivos (bueno, mejor, excelente, etc.) y negativos (malo, horrible, pat茅tico, etc.) que ocurren con m谩s frecuencia, se asigna al texto una puntuaci贸n de sentimiento entre 1 y -1. Esta puntuaci贸n de sentimiento tambi茅n se llama polaridad.

    Adem谩s de la puntuaci贸n de sentimiento, tambi茅n se devuelve la subjetividad. El valor de subjetividad puede estar entre 0 y 1. La subjetividad cuantifica la cantidad de opini贸n personal e informaci贸n f谩ctica contenida en el texto. La subjetividad m谩s alta significa que el texto contiene opiniones personales en lugar de informaci贸n f谩ctica.

    from pattern.en import sentiment
    
    print(sentiment("This is an excellent movie to watch. I really love it"))
    

    Cuando ejecute el script anterior, deber铆a ver el siguiente resultado:

    (0.75, 0.8)
    

    La frase “Esta es una pel铆cula excelente para ver. Me encanta” tiene un sentimiento de 0,75, lo que demuestra que es muy positiva. De igual forma, la subjetividad de 0.8 se refiere al hecho de que la oraci贸n es una opini贸n personal del usuario.

    Verificar si una declaraci贸n es un hecho

    La modalityfunci贸n de la biblioteca de patrones se puede utilizar para encontrar el grado de certeza en la cadena de texto. La modalityfunci贸n devuelve un valor entre -1 y 1. En el caso de los hechos, la modalityfunci贸n devuelve un valor mayor que 0,5.

    Aqu铆 hay un ejemplo en acci贸n:

    from pattern.en import parse, Sentence
    from pattern.en import modality
    
    text = "Paris is the capital of France"
    sent = parse(text, lemmata=True)
    sent = Sentence(sent)
    
    print(modality(sent))
    
    1.0
    

    En el script anterior, primero importamos el parsem茅todo junto con la Sentenceclase. En la segunda l铆nea, importamos la modalityfunci贸n. El parsem茅todo toma texto como entrada y devuelve una forma tokenizada del texto, que luego se pasa al Sentenceconstructor de la clase. El modalitym茅todo toma el Sentenceobjeto de la clase y devuelve la modalidad de la oraci贸n.

    Dado que la cadena de texto “Par铆s es la capital de Francia” es un hecho, en la salida ver谩 un valor de 1.

    De manera similar, para una oraci贸n que no es segura, el valor devuelto por el modalitym茅todo es alrededor de 0.0. Mira el siguiente gui贸n:

    text = "I think we can complete this task"
    sent = parse(text, lemmata=True)
    sent = Sentence(sent)
    
    print(modality(sent))
    
    0.25
    

    Dado que la cadena en el ejemplo anterior no es muy segura, la modalidad de la cadena anterior ser谩 0,25.

    Correcciones ortogr谩ficas

    El suggestm茅todo se puede utilizar para averiguar si una palabra est谩 escrita correctamente o no. El suggestm茅todo devuelve 1 si una palabra est谩 escrita correctamente al 100%. De lo contrario, el suggestm茅todo devuelve las posibles correcciones de la palabra junto con su probabilidad de correcci贸n.

    Mira el siguiente ejemplo:

    from pattern.en import suggest
    
    print(suggest("Whitle"))
    

    En el gui贸n de arriba tenemos una palabra Whitleque est谩 mal escrita. En la salida, ver谩 posibles sugerencias para esta palabra.

    [('While', 0.6459209419680404), ('White', 0.2968881412952061), ('Title', 0.03280067283431455), ('Whistle', 0.023549201009251473), ('Chile', 0.0008410428931875525)]
    

    Seg煤n el suggestm茅todo, hay una probabilidad de 0,64 de que la palabra sea “Mientras”, de manera similar, hay una probabilidad de 0,29 de que la palabra sea “Blanca”, y as铆 sucesivamente.

    Ahora deletreemos una palabra correctamente:

    from pattern.en import suggest
    print(suggest("Fracture"))
    

    Salida:

    [('Fracture', 1.0)]
    

    En el resultado, puede ver que hay un 100% de probabilidad de que la palabra est茅 escrita correctamente.

    Trabajar con n煤meros

    La biblioteca de patrones contiene funciones que se pueden usar para convertir n煤meros en forma de cadenas de texto en sus contrapartes num茅ricas y viceversa. Para convertir de texto a representaci贸n num茅rica numberse utiliza la funci贸n. De manera similar, para volver a convertir de n煤meros a su representaci贸n de texto correspondiente numerals, se utiliza la funci贸n. Mira el siguiente gui贸n:

    from pattern.en import number, numerals
    
    print(number("one hundred and twenty two"))
    print(numerals(256.390, round=2))
    

    Salida:

    122
    two hundred and fifty-six point thirty-nine
    

    En el resultado, ver谩 122 que es la representaci贸n num茅rica del texto “ciento veintid贸s”. De manera similar, deber铆a ver “doscientos cincuenta y seis coma treinta y nueve”, que es la representaci贸n de texto del n煤mero 256.390.

    Recuerde, para la numeralsfunci贸n tenemos que proporcionar el valor entero al que queremos que se redondee nuestro n煤mero.

    La quantifyfunci贸n se utiliza para obtener una estimaci贸n del recuento de palabras de los elementos de la lista, que proporciona una frase para referirse al grupo. Si una lista tiene 3-8 elementos similares, la quantifyfunci贸n lo cuantificar谩 en “varios”. Dos elementos se cuantifican en un “par”.

    from pattern.en import quantify
    
    print(quantify(['apple', 'apple', 'apple', 'banana', 'banana', 'banana', 'mango', 'mango']))
    

    En la lista, tenemos tres manzanas, tres pl谩tanos y dos mangos. La salida de la quantifyfunci贸n para esta lista se ve as铆:

    several bananas, several apples and a pair of mangoes
    

    De manera similar, el siguiente ejemplo demuestra las otras estimaciones de recuento de palabras.

    from pattern.en import quantify
    
    print(quantify({'strawberry': 200, 'peach': 15}))
    print(quantify('orange', amount=1200))
    

    Salida:

    hundreds of strawberries and a number of peaches
    thousands of oranges
    

    Funciones de biblioteca de patrones para miner铆a de datos

    En la secci贸n anterior, vimos algunas de las funciones m谩s utilizadas de la biblioteca de patrones para PNL. En esta secci贸n, veremos c贸mo se puede usar la biblioteca de patrones para realizar una variedad de tareas de miner铆a de datos.

    El webm贸dulo de la biblioteca de patrones se utiliza para tareas de miner铆a web.

    Acceso a p谩ginas web

    El URLobjeto se utiliza para recuperar contenido de las p谩ginas web. Tiene varios m茅todos que se pueden utilizar para abrir una p谩gina web, descargar el contenido de una p谩gina web y leer una p谩gina web.

    Puede utilizar directamente el downloadm茅todo para descargar el contenido HTML de cualquier p谩gina web. El siguiente script descarga el c贸digo fuente HTML del art铆culo de Wikipedia sobre inteligencia artificial.

    from pattern.web import download
    
    page_html = download('https://en.wikipedia.org/wiki/Artificial_intelligence', unicode=True)
    

    Tambi茅n puede descargar archivos de p谩ginas web, por ejemplo, im谩genes utilizando el m茅todo URL:

    from pattern.web import URL, extension
    
    page_url = URL('https://upload.wikimedia.org/wikipedia/commons/f/f1/RougeOr_football.jpg')
    file = open('football' + extension(page_url.page), 'wb')
    file.write(page_url.download())
    file.close()
    

    En el script de arriba, primero hacemos una conexi贸n con la p谩gina web usando el URLm茅todo. A continuaci贸n, llamamos al extensionm茅todo en la p谩gina abierta, que devuelve la extensi贸n del archivo. La extensi贸n del archivo se agrega al final de la cadena “f煤tbol”. Se llama al m茅todo abierto para leer esta ruta y, finalmente, el download()m茅todo descarga la imagen y la escribe en la ruta de ejecuci贸n predeterminada.

    Encontrar URL dentro del texto

    Puede utilizar el findurlm茅todo para extraer URL de cadenas de texto. Aqu铆 hay un ejemplo:

    from pattern.web import find_urls
    
    print(find_urls('To search anything, go to www.google.com', unique=True))
    

    En el resultado, ver谩 la URL del sitio web de Google como se muestra a continuaci贸n:

    ['www.google.com']
    

    Realizaci贸n de solicitudes asincr贸nicas para p谩ginas web

    Las p谩ginas web pueden ser muy grandes y puede llevar bastante tiempo descargar el contenido completo de la p谩gina web, lo que puede impedir que un usuario realice cualquier otra tarea en la aplicaci贸n hasta que se descargue la p谩gina web completa. Sin embargo, el webm贸dulo de la biblioteca de patrones contiene una funci贸n asynchronousque descarga el contenido de una p谩gina web de manera paralela. El asynchronousm茅todo se ejecuta en segundo plano para que el usuario pueda interactuar con la aplicaci贸n mientras se descarga la p谩gina web.

    Tomemos un ejemplo muy simple del asynchronousm茅todo:

    from pattern.web import asynchronous, time, Google
    
    asyn_req = asynchronous(Google().search, 'artificial intelligence', timeout=4)
    while not asyn_req.done:
        time.sleep(0.1)
        print('searching...')
    
    print(asyn_req.value)
    
    print(find_urls(asyn_req.value, unique=True))
    

    En el script anterior, recuperamos el resultado de b煤squeda de Google de la p谩gina 1 para la consulta de b煤squeda “inteligencia artificial”, puede ver que mientras la p谩gina se descarga ejecutamos un ciclo while en paralelo. Finalmente, los resultados recuperados por la consulta se imprimen utilizando el valueatributo del objeto devuelto por el asynchronousm贸dulo. A continuaci贸n, extraemos las URL de la b煤squeda, que luego se imprimen en la pantalla.

    Obtener resultados de motores de b煤squeda con API

    La biblioteca de patrones contiene SearchEngineclases derivadas de las clases que se pueden utilizar para conectarse a API de llamada de diferentes motores de b煤squeda y sitios web como Google, Bing, Facebook, Wikipedia, Twitter, etc. La SearchEngineconstrucci贸n del objeto acepta tres par谩metros:

    • license: La clave de licencia de desarrollador para el motor de b煤squeda o sitio web correspondiente
    • throttle: Corresponde a la diferencia de tiempo entre solicitudes sucesivas al servidor
    • langauge: Especifica el idioma de los resultados

    El searchm茅todo de la SearchEngineclase se utiliza para realizar una solicitud al motor de b煤squeda para cierta consulta de b煤squeda. El searchm茅todo puede tomar los siguientes par谩metros:

    • query: La cadena de b煤squeda
    • type:El tipo de datos que desea buscar, puede tomar tres valores: SEARCH, NEWSy IMAGE.
    • start: La p谩gina desde la que desea iniciar la b煤squeda
    • count: El n煤mero de resultados por p谩gina.

    Las clases del motor de b煤squeda que heredan la SearchEngineclase junto con su searchm茅todo son: Google, Bing, Twitter, Facebook, Wikipedia, y Flickr.

    La consulta de b煤squeda devuelve objetos para cada elemento. El resultobjeto se puede utilizar para recuperar la informaci贸n sobre el resultado buscado. Los atributos del resultobjeto son url, title, text, language, author, date.

    Ahora veamos un ejemplo muy simple de c贸mo podemos buscar algo en Google a trav茅s de la biblioteca de patrones. Recuerde, para que este ejemplo funcione, deber谩 utilizar su clave de licencia de desarrollador para la API de Google.

    from pattern.web import Google
    
    google = Google(license=None)
    for search_result in google.search('artificial intelligence'):
        print(search_result.url)
        print(search_result.text)
    

    En el script de arriba, creamos un objeto de la clase de Google. En el constructor de Google, pase su propia clave de licencia al licensepar谩metro. A continuaci贸n, pasamos la cadena artificial intelligenceal searchm茅todo. De forma predeterminada, se devolver谩n los primeros 10 resultados de la primera p谩gina, que luego se iterar谩n, y la URL y el texto de cada resultado se mostrar谩n en la pantalla.

    El proceso es similar para el motor de b煤squeda Bing, solo tiene que reemplazar la Bingclase Googleen el script anterior.

    Busquemos ahora en Twitter los tres 煤ltimos tweets que contienen el texto “inteligencia artificial”. Ejecute el siguiente script:

    from pattern.web import Twitter
    
    twitter = Twitter()
    index = None
    for j in range(3):
        for tweet in twitter.search('artificial intelligence', start=index, count=3):
            print(tweet.text)
            index = tweet.id
    

    En el script anterior, primero importamos la Twitterclase del pattern.webm贸dulo. A continuaci贸n, iteramos sobre los tweets devueltos por la Twitterclase y mostramos el texto del tweet en la consola. No necesita ninguna clave de licencia para ejecutar el script anterior.

    Conversi贸n de datos HTML a texto sin formato

    El downloadm茅todo de la URLclase devuelve datos en forma de HTML. Sin embargo, si desea hacer un an谩lisis sem谩ntico del texto, por ejemplo, la clasificaci贸n de opiniones, necesita datos limpiados sin etiquetas HTML. Puede limpiar los datos con el plaintextm茅todo. El m茅todo toma como par谩metro el contenido HTML devuelto por el downloadm茅todo y devuelve texto limpio.

    Mira el siguiente gui贸n:

    from pattern.web import URL, plaintext
    
    html_content = URL('https://Pharos.sh.com/python-for-nlp-introduction-to-the-textblob-library/').download()
    cleaned_page = plaintext(html_content.decode('utf-8'))
    print(cleaned_page)
    

    En el resultado, deber铆a ver el texto limpio de la p谩gina web:

    https://Pharos.sh.com/python-for-nlp-introduction-to-the-textblob-library/.

    Es importante recordar que si est谩 utilizando Python 3, necesitar谩 llamar al decode('utf-8')m茅todo para convertir los datos de byte a formato de cadena.

    An谩lisis de documentos PDF

    La biblioteca de patrones contiene un objeto PDF que se puede utilizar para analizar un documento PDF. PDF (Portable Document Format) es un archivo multiplataforma que contiene im谩genes, textos y fuentes en un documento independiente.

    Veamos c贸mo se puede analizar un documento PDF con el objeto PDF:

    from pattern.web import URL, PDF
    
    pdf_doc = URL('https://demo.clab.cs.cmu.edu/NLP/syllabus_f18.pdf').download()
    print(PDF(pdf_doc.decode('utf-8')))
    

    En el script descargamos un documento usando la downloadfunci贸n. A continuaci贸n, el documento HTML descargado se pasa a la clase PDF que finalmente lo imprime en la consola.

    Limpiar la cach茅

    Los resultados devueltos por los m茅todos como SearchEngine.search()y URL.download()se almacenan, de forma predeterminada, en la cach茅 local. Para borrar el cach茅 despu茅s de descargar un documento HTML, podemos usar el clearm茅todo de la clase de cach茅, como se muestra a continuaci贸n:

    from pattern.web import cache
    
    cache.clear()
    

    Conclusi贸n

    La biblioteca de patrones es una de las bibliotecas de procesamiento de lenguaje natural m谩s 煤tiles en Python. Aunque no es tan conocido como spaCy o NLTK, contiene funcionalidades como encontrar superlativos y comparativos, y detecci贸n de hechos y opiniones que lo distingue de las otras bibliotecas NLP.

    En este art铆culo, estudiamos la aplicaci贸n de la biblioteca de patrones para el procesamiento del lenguaje natural, miner铆a de datos y raspado web. Vimos c贸mo realizar tareas b谩sicas de PNL como tokenizaci贸n, lematizaci贸n y an谩lisis de sentimientos con la biblioteca de patrones. Finalmente, tambi茅n vimos c贸mo usar Pattern para realizar consultas en motores de b煤squeda, extraer tweets en l铆nea y limpiar documentos HTML.

     

    Etiquetas:

    Deja una respuesta

    Tu direcci贸n de correo electr贸nico no ser谩 publicada. Los campos obligatorios est谩n marcados con *