Adquisición de Textos

NLP - Analítica Estratégica de Datos


Fundación Universitaria Konrad Lorenz
Docente: Viviana Márquez vivianam.penama@konradlorenz.edu.co
Clase #2: Febrero 25, 2020

⌛ En la clase anterior

• Nos presentamos 🤗
• Introducción a NLP
• Python, GitHub, cuenta de desarrollador de Twitter

git push origin main (Cambió a raíz del movimiento de BLM, gracias Brayam por el dato!)

🚀 Hoy veremos...

• Repaso de Python
• Flujo de datos en un proyecto de NLP (pipeline)
• Métodos de adquisición de texto más comunes
• Taller #2

🐍 Python

Flujo de datos en un proyecto de NLP (pipeline)


Si en su empresa les piden desarrollar un proyecto, ¿cómo lo harían?

Normalmente, revisaríamos los requerimientos y dividiríamos el problema en diferentes pasos; para luego crear una estrategía para resolver cada paso.

Esto mismo se hace con los proyectos de machine learning y se le conoce como pipeline o flujo de datos. Aunque los detalles específicos varian de proyecto a proyecto, estos pasos son comunes y nos van a permitir comenzar cualquier proyecto de machine learning.

Flujo de datos en un proyecto de NLP (pipeline)


Paso 1: Adquisición de datos


Necesitamos adquirir datos relevantes a nuestro proyecto
😃 Eso es lo que haremos en la clase de hoy 😃

Flujo de datos en un proyecto de NLP (pipeline)


Paso 2 y 3: Limpieza de Texto y Pre-Procesamiento


Rara vez los datos están como los necesitamos, por lo tanto tenemos que hacer
limpieza y pre-procesamiento de estos para normalizarlos
(Siguientes clases)

Flujo de datos en un proyecto de NLP (pipeline)


Paso 4: Feature Engineering (Creación de Características)


Creamos indicadores que son los más adecuados para nuestro proyecto y los convertimos en un formato que sea entendido por nuestro modelo/algoritmo

Flujo de datos en un proyecto de NLP (pipeline)


Paso 5: Modelo


Usualmente se crean varios modelos para poder escoger el mejor

Flujo de datos en un proyecto de NLP (pipeline)


Paso 6: Evaluación del rendimiento del modelo


Las métricas de rendimiento nos permiten escoger el modelo más adecuado y ajustar sus parámetros para mejorarlo. De ser necesario, podemos regresar y optimizar los primeros pasos

Flujo de datos en un proyecto de NLP (pipeline)


Paso 7: Modelo en producción


Una vez tenemos un buen modelo, pasamos a ponerlo en producción o socializar resultados

Flujo de datos en un proyecto de NLP (pipeline)


Paso 8: Vigilancia y actualización


Es buena práctica monitorear regularmente el rendimiento del modelo y actualizarlo para que siga dando buenos resultados

👷🏽‍♀️ Adquisición de datos

¿Cuáles son los tipos de archivos de texto más comunes?

https://pollev.com/vivianamarqu288

- Datos abiertos
- txt, csv, json, zip
- Excel, Word
- (HTML) Web Scraping 
- PDFs e imágenes
- Aumento de datos

👷🏽‍♀️ Adquisición de datos: Un caso ideal


• Tenemos que identificar si es una consulta de servicio al cliente vs una consulta de venta

• Para esta tarea, nuestra empresa tiene miles (incluso millones) de datos

• Adicionalmente, cada uno de los datos están etiquetados

• Sin embargo, la mayoría de proyectos no tienen tanta suerte 🙁

👷🏽‍♀️ 1. Usar un conjunto de datos abiertos

👷🏽‍♀️ 3. Archivos más comunes

Archivos tipo .csv (Comma Separated Value)

In [3]:
import pandas as pd
In [102]:
df = pd.read_csv("../archivos/iris.csv", sep=',')
In [103]:
df.head(5)
Out[103]:
sepal_length sepal_width petal_length petal_width species
0 5.1 3.5 1.4 0.2 setosa
1 4.9 3.0 1.4 0.2 setosa
2 4.7 3.2 1.3 0.2 setosa
3 4.6 3.1 1.5 0.2 setosa
4 5.0 3.6 1.4 0.2 setosa
In [17]:
pd.read_csv?
In [16]:
df.species.str.cat(sep=" **** ")
Out[16]:
'setosa **** setosa **** setosa **** setosa **** setosa **** setosa **** setosa **** setosa **** setosa **** setosa **** setosa **** setosa **** setosa **** setosa **** setosa **** setosa **** setosa **** setosa **** setosa **** setosa **** setosa **** setosa **** setosa **** setosa **** setosa **** setosa **** setosa **** setosa **** setosa **** setosa **** setosa **** setosa **** setosa **** setosa **** setosa **** setosa **** setosa **** setosa **** setosa **** setosa **** setosa **** setosa **** setosa **** setosa **** setosa **** setosa **** setosa **** setosa **** setosa **** setosa **** versicolor **** versicolor **** versicolor **** versicolor **** versicolor **** versicolor **** versicolor **** versicolor **** versicolor **** versicolor **** versicolor **** versicolor **** versicolor **** versicolor **** versicolor **** versicolor **** versicolor **** versicolor **** versicolor **** versicolor **** versicolor **** versicolor **** versicolor **** versicolor **** versicolor **** versicolor **** versicolor **** versicolor **** versicolor **** versicolor **** versicolor **** versicolor **** versicolor **** versicolor **** versicolor **** versicolor **** versicolor **** versicolor **** versicolor **** versicolor **** versicolor **** versicolor **** versicolor **** versicolor **** versicolor **** versicolor **** versicolor **** versicolor **** versicolor **** versicolor **** virginica **** virginica **** virginica **** virginica **** virginica **** virginica **** virginica **** virginica **** virginica **** virginica **** virginica **** virginica **** virginica **** virginica **** virginica **** virginica **** virginica **** virginica **** virginica **** virginica **** virginica **** virginica **** virginica **** virginica **** virginica **** virginica **** virginica **** virginica **** virginica **** virginica **** virginica **** virginica **** virginica **** virginica **** virginica **** virginica **** virginica **** virginica **** virginica **** virginica **** virginica **** virginica **** virginica **** virginica **** virginica **** virginica **** virginica **** virginica **** virginica **** virginica'

👷🏽‍♀️ 3. Archivos más comunes

Archivos tipo .txt

In [26]:
with open("../archivos/grabacion.txt", encoding='utf-8') as archivo:
    data = archivo.read()
In [27]:
print(data)
© - Derechos Reservados: La presente obra, y todos sus contenidos, se encuentran protegidos por la normativa nacional e internacional vigente sobre propiedad Intelectual, por lo tanto su utilización parcial o total, reproducción, comunicación pública, transformación, distribución, alquiler, préstamo público e importación, total o parcial, en todo o en parte, en formato impreso o digital y en cualquier formato conocido o por conocer, se encuentran prohibidos, y solo serán lícitos en la medida en que se cuente con la autorización previa y expresa por escrito de la Fundación Universitaria Konrad Lorenz. Así mismo, de acuerdo con la normativa referente al habeas data, la utilización de la imagen de las personas, docentes o estudiantes, sin su previa autorización está expresamente prohibida. En caso de incumplirse con lo mencionado, se procederá de conformidad con los reglamentos de la Institución, sin perjuicio de las demás acciones legales aplicables. 

👷🏽‍♀️ 3. Archivos más comunes

Archivos tipo .json

In [28]:
import json
In [29]:
with open ("../archivos/sistemas_operativos.json") as archivo:
    data = json.load(archivo)
In [32]:
data[-1]
Out[32]:
{'Name': 'Gentoo',
 'Version': 'Rolling Release',
 'Install': 'emerge',
 'Owner': 'Gentoo Foundation',
 'Kernel': '4.12'}
In [36]:
from pandas import json_normalize
json_normalize(data)
Out[36]:
Name Version Install Owner Kernel
0 Debian 9 apt SPI 4.9
1 Ubuntu 17.10 apt Canonical 4.13
2 Fedora 26 dnf Red Hat 4.13
3 CentOS 7 yum Red Hat 3.10
4 OpenSUSE 42.3 zypper Novell 4.4
5 Arch Linux Rolling Release pacman SPI 4.13
6 Gentoo Rolling Release emerge Gentoo Foundation 4.12

👷🏽‍♀️ 3. Archivos más comunes

Archivos tipo .zip (archivos anidados)

In [34]:
import os
from zipfile import ZipFile
In [35]:
direccion = '../archivos/astrok.zip'
In [39]:
# Descomprimir el archivo ZIP
with ZipFile(direccion) as archivo:
    archivo.extractall("../archivos/")
    
import shutil
shutil.rmtree('../archivos/__MACOSX')

Para ver el nombre de los archivos:

In [40]:
for archivo in os.walk("../archivos/astrok"):
    print(archivo)
('../archivos/astrok', [], ['Perseverance.txt', 'Conjución.txt', 'La muerte de las estrellas.txt'])
In [43]:
for raiz, dirs, archivos in os.walk("../archivos/astrok"):
    # print(raiz, dirs, archivos)
    for a in archivos: 
        print(a)
Perseverance.txt
Conjución.txt
La muerte de las estrellas.txt

👷🏽‍♀️ 4. Archivos de Office

Word

Instalar libreria: pip install python-docx

In [45]:
import docx
In [46]:
documento = docx.Document("../archivos/Colombia.docx")
In [54]:
[print(p.text) for p in documento.paragraphs] 
Colombia

Colombia, oficialmente República de Colombia, es un país soberano situado en la región noroccidental de América del Sur, que se constituye en un estado unitario, social y democrático d
e derecho cuya forma de gobierno es presidencialista. Es una república organizada políticamente en 32 departamentos descentralizados y el Distrito Capital de Bogotá, sede del Gobierno Nacional.



Out[54]:
[None, None, None, None, None, None, None]

Para poder leer tablas dentro del archivo

In [58]:
tabla = documento.tables[0]
tabla
Out[58]:
<docx.table.Table at 0x7fcc803d5d50>
In [76]:
data = []

for i, fila in enumerate(tabla.rows):
    f = [celda.text for celda in fila.cells]
    data.append(f)
    
df = pd.DataFrame(data)

df.columns = df.loc[0].values

df
Out[76]:
REGION DEPARTAMENTO MUNICIPIO
0 REGION DEPARTAMENTO MUNICIPIO
1 Región Eje Cafetero - Antioquia Antioquia Medellín
2 Región Eje Cafetero - Antioquia Antioquia Abejorral
3 Región Eje Cafetero - Antioquia Antioquia Abriaquí
4 Región Eje Cafetero - Antioquia Antioquia Alejandría
5 Región Eje Cafetero - Antioquia Antioquia Amagá
6 Región Eje Cafetero - Antioquia Antioquia Amalfi
7 Región Eje Cafetero - Antioquia Antioquia Andes
8 Región Eje Cafetero - Antioquia Antioquia Angelópolis
9 Región Eje Cafetero - Antioquia Antioquia Angostura
10 Región Eje Cafetero - Antioquia Antioquia Anorí

👷🏽‍♀️ 4. Archivos de Office

Excel

In [77]:
import pandas as pd
In [78]:
data = pd.read_excel("../archivos/hoja.xlsx")
In [79]:
data.head()
Out[79]:
OrderDate Region Rep Item Units Unit Cost Total
0 2019-01-06 East Jones Pencil 95 1.99 189.05
1 2019-01-23 Central Kivell Binder 50 19.99 999.50
2 2019-02-09 Central Jardine Pencil 36 4.99 179.64
3 2019-02-26 Central Gill Pen 27 19.99 539.73
4 2019-03-15 West Sorvino Pencil 56 2.99 167.44

¿Y la segunda hoja?

In [82]:
data2 = pd.read_excel("../archivos/hoja.xlsx", sheet_name=1)
In [83]:
data2
Out[83]:
Hoja 2 Unnamed: 1
0 Días Número
1 Lunes 1
2 Martes 2
3 Miércoles 3
4 Jueves 4
5 Viernes 5
6 Sábado 6
7 Domingo 7

👷🏽‍♀️ 4. Archivos de Office

Excel (Directamente desde Google Sheets)

In [84]:
url = "https://docs.google.com/spreadsheets/d/1O8k9ZBaHSPbw_8IgE-jxmVE8FkMWimr6dZPuKhAT2hM/edit#gid=0"
In [90]:
new_url = url.rsplit("/",1)[0] + "/gviz/tq?tqx=out:csv"
new_url
Out[90]:
'https://docs.google.com/spreadsheets/d/1O8k9ZBaHSPbw_8IgE-jxmVE8FkMWimr6dZPuKhAT2hM/gviz/tq?tqx=out:csv'
In [91]:
data = pd.read_csv(new_url)

data
Out[91]:
Español English
0 Lunes Monday
1 Martes Tuesday
2 Miércoles Wednesday
3 Jueves Thursday
4 Viernes Friday

👷🏽‍♀️ 5. Archivos PDF

Instalar libreria: pip install PyMuPDF

Créditos: Angela Cristina Villate Moreno, ejemplo

In [95]:
import fitz
In [96]:
documento = fitz.open('../archivos/cien.pdf')
In [99]:
print("Número de páginas: ", documento.pageCount)
print("Metados: ", documento.metadata)
Número de páginas:  1
Metados:  {'format': 'PDF 1.3', 'title': 'cien', 'author': '', 'subject': '', 'keywords': '', 'creator': 'Pages', 'producer': 'macOS Version 10.15.6 (Build 19G2021) Quartz PDFContext', 'creationDate': "D:20200822062639Z00'00'", 'modDate': "D:20200822062639Z00'00'", 'trapped': '', 'encryption': None}
In [100]:
pagina = documento.loadPage(0)
texto = pagina.getText("text")
print(texto)
Cien años de soledad 
Muchos años después, frente al pelotón de fusilamiento, el coronel Aureliano Buendía había de 
recordar aquella tarde remota en que su padre lo llevó a conocer el hielo. Macondo era entonces 
una aldea de veinte casas de barro y cañabrava construidas a la orilla de un río de aguas diáfanas 
que se precipitaban por un lecho de piedras pulidas, blancas y enormes como huevos 
prehistóricos. El mundo era tan reciente, que muchas cosas carecían de nombre, y para 
mencionarlas había que señalarías con el dedo. Todos los años, por el mes de marzo, una familia 
de gitanos desarrapados plantaba su carpa cerca de la aldea, y con un grande alboroto de pitos y 
timbales daban a conocer los nuevos inventos. Primero llevaron el imán. Un gitano corpulento, de 
barba montaraz y manos de gorrión, que se presentó con el nombre de Melquiades, hizo una 
truculenta demostración pública de lo que él mismo llamaba la octava maravilla de los sabios 
alquimistas de Macedonia. Fue de casa en casa arrastrando dos lingotes metálicos, y todo el 
mundo se espantó al ver que los calderos, las pailas, las tenazas y los anafes se caían de su sitio, y 
las maderas crujían por la desesperación de los clavos y los tornillos tratando de desenclavarse, y 
aun los objetos perdidos desde hacía mucho tiempo aparecían por donde más se les había buscado, 
y se arrastraban en desbandada turbulenta detrás de los fierros mágicos de Melquíades. «Las 
cosas, tienen vida propia -pregonaba el gitano con áspero acento-, todo es cuestión de despertarles 
el ánima.» José Arcadio Buendía, cuya desaforada imaginación iba siempre más lejos que el 
ingenio de la naturaleza, y aun más allá del milagro y la magia, pensó que era posible servirse de 
aquella invención inútil para desentrañar el oro de la tierra. Melquíades, que era un hombre 
honrado, le previno: «Para eso no sirve.» Pero José Arcadio Buendía no creía en aquel tiempo en la 
honradez de los gitanos, así que cambió su mulo y una partida de chivos por los dos lingotes 
imantados. Úrsula Iguarán, su mujer, que contaba con aquellos animales para ensanchar el 
desmedrado patrimonio doméstico, no consiguió disuadirlo. «Muy pronto ha de sobrarnos oro 
para empedrar la casa», replicó su marido. Durante varios meses se empeñó en demostrar el 
acierto de sus conjeturas. Exploró palmo a palmo la región, inclusive el fondo del río, arrastrando 
los dos lingotes de hierro y recitando en voz alta el conjuro de Melquíades. Lo único que logró 
desenterrar fue una armadura del siglo xv con todas sus partes soldadas por un cascote de óxido, 
cuyo interior tenía la resonancia hueca de un enorme calabazo lleno de piedras. Cuando José 
Arcadio Buendía y los cuatro hombres de su expedición lograron desarticular la armadura, 
encontraron dentro un esqueleto calcificado que llevaba colgado en el cuello un relicario de cobre 
con un rizo de mujer.  

👷🏽‍♀️ 5. Archivos de imagen

Instalar:

In [ ]:
import pytesseract
from pytesseract import image_to_string
from PIL import Image
In [ ]:
Image.open("demo.png")
In [ ]:
# pytesseract.pytesseract.tesseract_cmd = "C:\\Program Files\\Tesseract-OCR\\tesseract.exe"
texto = image_to_string(Image.open("demo.png")) 
print(texto)

👷🏽‍♀️ 6. Aumentación de datos


• Estrategia utilizada frecuentemente en machine learning cuando no se tienen suficiente datos.

👷🏽‍♀️ 6. Aumentación de datos


• Estrategia utilizada frecuentemente en machine learning cuando no se tienen suficiente datos.

👷🏽‍♀️ 6. Aumentación de datos


• Estrategia utilizada frecuentemente en machine learning cuando no se tienen suficiente datos.

👷🏽‍♀️ 6. Aumentación de datos


• Estrategia utilizada frecuentemente en machine learning cuando no se tienen suficiente datos.

👷🏽‍♀️ 6. Aumentación de datos


• ¿Con textos?

  • Reemplazo de sinónimos
  • Traducción de ida y vuelta
  • Reemplazar entidades
  • Agregar "ruido" al texto

Libreria nlpaug: https://github.com/makcedward/nlpaug

Más info: Libreria de nlpaug: https://github.com/makcedward/nlpaug

🤓 Recapitulando: Hoy aprendímos...

  • Los diferentes pasos en un proyecto de machine learning/NLP (flujo de datos/pipeline)
  • Métodos de adquisición de texto más comunes
    • Usar un conjunto de datos abiertos
    • Archivos más comunes: .csv, .txt, .json, .zip
    • Archivos Office: Word, Excel, Google Sheets
    • PDFs e imágenes
    • Aumentación de datos

¡Tiempo de taller!

Taller # 2: Adquisición de datos de NLP.

Fecha de entrega: Marzo 4, 2020. (Antes del inicio de la próxima clase)

Proxima clase: Web scraping, extracción, pre-procesamiento y normalización de textos