Documentos de Académico
Documentos de Profesional
Documentos de Cultura
Curso:
Técnicas avanzadas de minería de datos
Profesor
Sebastián Raveau
Clase Nº2:
Minería de texto y web scraping
Tabla de contenidos
Contenido
1. Resultado de aprendizaje de la clase u objetivos 3
2. Introducción 3
3. Minería de texto 3
3.1. Estructurando datos no estructurados 3
3.1.1. Corpus 5
3.1.2. Vocabulario 5
3.1.3. Bolsa de palabras 5
3.2. Limpieza y procesamiento 6
3.2.1. Tokenización 6
3.2.2. Normalización 6
3.2.3. Palabras vacías 6
3.2.4. Lematización 6
3.2.5. Stemming 6
3.3. Ejemplo de aplicación: análisis de sentimientos 7
4. Web scraping 11
4.1. Tipos de sitios web 12
4.2. Ejemplo de aplicación de web scraping 12
4.2.1. Paso 1 - Familiarizarse con el sitio web 13
4.2.2. Paso 2 - Descargar el código HTML 13
4.2.3. Paso 3 - Extraer la información de interés 14
5. Conclusión 15
6. Referencias bibliográficas 15
© Sebastián Raveau
1. Resultado de aprendizaje de la clase u objetivos
En esta clase discutiremos dos temas relacionados con el tratamiento de bases de datos, en particular de
datos no estructurados: minería de texto y web scraping. Comenzaremos describiendo los procesos
necesarios para trabajar con información procedente de texto, para luego describir los procesos necesarios
para extraer información de sitios web. Todo lo aprendido será implementado en Python mediante ejemplos
que permitan ilustrar ambas técnicas.
2. Introducción
Hoy en día, existe una gran cantidad de información disponible en línea y en otros medios, por lo que resulta
muy valiosa la capacidad de procesar y aprovechar dicha información para extraer datos relevantes. La
minería de texto y el web scraping son dos técnicas que permiten extraer información valiosa de datos de
texto no estructurados y sitios web, respectivamente.
La minería de texto es un conjunto de técnicas y herramientas que nos permiten extraer información valiosa
y conocimientos a partir de grandes cantidades de datos de texto no estructurados. En esta clase,
exploraremos los conceptos fundamentales de la minería de texto, incluyendo el preprocesamiento de texto,
la representación de documentos, la extracción de características y la clasificación de texto. También
veremos una de las aplicaciones más populares de la minería de texto: el análisis de sentimientos.
Web scraping es el proceso de extracción de datos de sitios web de forma automatizada utilizando
herramientas especialmente desarrolladas para dichos fines. La información que se puede extraer de sitios
web es diversa: texto, imágenes, tablas u otros datos. Una vez obtenida la información relevante, podemos
aplicar diversas técnicas de minería de datos.
3. Minería de texto
La minería de texto es un conjunto de técnicas y herramientas que se utilizan para extraer información útil
y conocimientos a partir de grandes cantidades de datos de texto no estructurados. Estos datos pueden ser
cualquier tipo de texto escrito, como artículos de noticias, correos electrónicos, mensajes de redes sociales,
informes financieros, entre otros.
La minería de texto se basa en la idea de que el texto contiene información valiosa que puede ser extraída
mediante el uso de algoritmos y técnicas de análisis de datos. Algunas de los análisis más habituales que se
pueden realizar mediante minería de texto incluyen la extracción de temas y tendencias, la clasificación de
documentos, el análisis de sentimientos, la identificación de entidades nombradas y la detección de spam,
entre otras.
Un primer desafío de la minería de texto consiste en que la información no está estructurada. En general, las
bases de datos con las que trabajamos al aplicar técnicas de minería de datos corresponden a dataframes
donde las filas corresponden a observaciones y las columnas a atributos que permiten caracterizar las
© Sebastián Raveau
observaciones. De esta manera, las bases con las que estamos acostumbrados a trabajar se ven de la
siguiente forma:
⋮ ⋮ ⋮ ⋮ ⋮ ⋮ ⋱
Pero los documentos con los que trabajamos al realizar minería de texto se ven de la siguiente forma:
Por lo tanto, necesitamos representar documentos en forma estructurada para poder aplicar técnicas de
minería de datos, como análisis de regresión, métodos de clasificación o clustering. Debemos recordar que
algunos de los algoritmos de minería de datos asociados a estas técnicas requieren una representación
numérica de los datos, por lo que eso es lo que obtendremos a partir de nuestros documentos de texto.
© Sebastián Raveau
3.1.1.Corpus
3.1.2.Vocabulario
Un vocabulario corresponde a una secuencia ordenada de palabras presentes en un corpus, cada una de ellas
con un identificador único. Las palabras del vocabulario pueden ser el equivalente a los atributos de una base
de datos estructurada, como la presentada en la Figura 1. En nuestro ejemplo, el vocabulario es:
id palabra
1 amarillo
2 auto
3 globo
4 plátano
5 rojo
6 tomate
7 un
8 verde
9 y
3.1.3.Bolsa de palabras
Finalmente, podemos representar cada documento como una bolsa de palabras en forma matricial, donde
los documentos corresponderán a las filas y las palabras corresponderán a las columnas. En nuestro ejemplo,
la bolsa de palabras es:
Doc. 1 2 3 4 5 6 7 8 9
1 0 1 0 0 1 0 1 0 0
2 0 0 1 0 2 1 2 0 1
3 1 0 0 1 0 1 2 1 1
© Sebastián Raveau
La bolsa de palabras obtenida puede ser utilizada directamente como un dataframe de datos estructurados
(notar que su estructura es exactamente igual que el ejemplo de la Figura 1). Sin embargo, en general la
cantidad de palabras (columnas) será muy grande y ampliamente superior a la cantidad de filas
(documentos). Es por esto que es necesario limpiar y procesar la bolsa de palabras antes de proceder con la
aplicación de técnicas de minería de datos, y realizar filtros en función de la frecuencia de aparición de las
distintas palabras dentro del corpus.
El proceso de limpieza y procesamiento de la bolsa de palabras obtenida a partir de los documentos de texto
consiste en eliminar aquello que no aporte información sobre su temática, estructura o contenido. No existe
una única forma de hacerlo, depende en gran medida de la finalidad del análisis y de la procedencia del texto.
Describamos algunos de los procesos más habituales que se pueden llevar a cabo:
3.2.1.Tokenización
Tokenizar un texto consiste en dividir el texto (frases, oraciones, párrafos, o documentos completos) en las
unidades de interés que lo conforman. Los elementos más sencillos a partir de los cuales se realizará el
análisis de minería de datos se llaman tokens. Los tokens habitualmente pueden corresponder a palabras
(como en el ejemplo desarrollado anteriormente), pero también pueden ser sílabas, representación fonética,
letras, etc.
3.2.2.Normalización
La normalización consiste en transformar un token en su forma base. Este proceso puede incluir el
tratamiento de mayúsculas y minúsculas (para que, por ejemplo, “Casa”, “casa” y “CASA” no sean
considerados tres tokens distintos), el tratamiento de acentos, la eliminación de símbolos, etc.
3.2.3.Palabras vacías
Las palabras vacías (stop-words en inglés) son palabras ampliamente utilizadas en un determinado lenguaje,
pero que no aportan información valiosa al análisis de texto al no poseer significado. Ejemplos de palabras
vacías son artículos, preposiciones, pronombres, etc.
3.2.4.Lematización
La lematización consiste en obtener las formas flexionadas de las palabras (femeninos y masculinos,
conjugaciones, plurales, etc.). Para llevar a cabo una lematización es necesario contar con una base de datos
léxica a partir de la cual relacionar las palabras.
3.2.5.Stemming
El stemming (proveniente de la palabra stem que en inglés significa tallo o tronco) es similar a la lematización,
pero no se basa en las estructuras lexicales, sino que realiza una aproximación, quedándose con las primeras
© Sebastián Raveau
letras (i.e. podando) de la palabra. Por ejemplo, de las palabras “programar”, “programador” y
“programación” podemos obtener y utilizar en el análisis la raíz “programa”.
Desarrollemos un ejemplo de minería de texto en Python. Trabajaremos con una base de datos de reseñas
de películas del sitio Rotten Tomatoes desarrollada por la Universidad de Stanford. La base de datos contiene
evaluaciones de películas de 0 a 4, en una estala semántica de cinco niveles: 0 = “muy mala”, 1 = “mala”, 2 =
“neutra”, 3 = “buena” y 4 = “muy buena”. Cada evaluación va acompañada de una breve reseña textual.
A partir del texto de las reseñas, realizaremos análisis de sentimientos para entender y predecir las
evaluaciones.
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
from sklearn.feature_extraction.text import CountVectorizer
La base de datos consta de 8.529 evaluaciones y reseñas. La columna Phrase contiene la reseña textual y la
columna Sentiment contiene la evaluación numérica.
coleccion = reviews.Phrase
© Sebastián Raveau
Podemos realizar un análisis visual general de las reseñas, obteniendo frecuencias de palabras y/o
obteniendo una nube de palabras.
plt.imshow(wordcloud)
plt.axis("off")
plt.show()
Procedamos con el procesamiento del corpus para realizar análisis de sentimientos. Haremos el
procesamiento paso a paso para ir ilustrando y analizando los efectos de llevar a cabo distintos procesos.
Los tokens en nuestra aplicación serán las palabras de las reseñas. Como paso inicial, simplemente
eliminemos los acentos (dado que la base de datos está en inglés, probablemente este paso no es necesario,
pero es bueno saber cómo se haría si estuviésemos trabajando con una base de datos en español).
Obtenemos una bolsa de palabras con 16.864 columnas. La bolsa de palabras tiene 8.529 × 16.864 =
143.833.056 celdas, de las cuales apenas 129.783 no poseen valor 0. Esto representa menos de un 0,1% del
total de las celdas. Esto se debe a que en cada uno de los documentos sólo aparece una cantidad pequeña
de todas las palabras posibles.
© Sebastián Raveau
Normalicemos los documentos, pasando todas las palabras a minúsculas para evitar múltiples conteos. El
tamaño de la bolsa de palabras decrece a 15.165 columnas.
Eliminamos las palabras vacías, y el tamaño de la bolsa de palabras decrece a 14.880 columnas.
Trabajar con 14.880 atributos al aplicar técnicas de minería de datos no es conveniente. La mayoría de las
palabras aparecen en pocos documentos, por lo que no serán de gran ayuda al identificar patrones que
permitan entender y predecir el sentimiento (i.e. evaluación en escala de 0 a 4) de cada reseña. Por lo tanto,
podemos filtrar y considerar aquellas palabras del diccionario que posean una frecuencia de ocurrencia
mínima. En este ejemplo, sólo consideraremos aquellas palabras que aparecen en al menos 40 de los 8.529
documentos (un filtro poco estricto, pues corresponde a menos del 0,5% de los documentos). El tamaño de
la bolsa de palabras decrece considerablemente a 228 columnas.
Transformamos la bolsa de palabras obtenida en un dataframe, con el cual podríamos aplicar distintas
técnicas de minería de datos.
df = pd.DataFrame(coleccion.todense())
df.columns = vectorizer.get_feature_names_out()
df
© Sebastián Raveau
actually
american
amusing
acting
action
actors
writer
...
works
world
worst
worth
years
young
year
age
art
0 0 0 0 0 0 0 0 0 ... 0 0 0 0 0 0 0 0
1 0 0 0 0 0 0 0 0 ... 0 0 0 1 0 0 0 0
2 0 0 0 0 0 0 0 0 ... 0 0 0 0 0 0 0 0
3 0 0 0 0 0 0 0 0 ... 0 0 0 0 0 0 0 0
4 0 0 0 0 0 0 0 0 ... 0 0 0 0 0 0 0 0
... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ...
8524 0 0 0 0 0 0 0 0 ... 0 0 0 0 0 0 0 0
8525 0 0 0 0 1 0 0 0 ... 0 0 0 0 0 0 0 0
8526 0 0 0 0 0 0 0 0 ... 0 0 0 0 0 0 0 0
8527 0 0 0 0 0 0 0 0 ... 0 0 0 0 0 0 0 0
8528 0 0 0 0 0 0 0 0 ... 0 0 0 0 0 0 0 0
Procederemos a entrenar un árbol de clasificación para poder predecir la evaluación en función del texto de
las reseñas.
dectree = tree.DecisionTreeClassifier()
x, y = df, reviews.Sentiment
arbol = dectree.fit(x, y)
plt.figure(figsize=(10,5), dpi=100)
tree.plot_tree(arbol,
max_depth = 3,
feature_names = vectorizer.get_feature_names_out(),
class_names = ['Muy Mala','Mala','Neutra','Buena','Muy Buena'],
impurity = False,
label = 'none',
fontsize = 6)
plt.show()
© Sebastián Raveau
Figura 4: Árbol de clasificación para análisis de sentimientos
Fuente: Elaboración propia
4. Web scraping
Los procesos de web scraping implican acceder a un sitio web y extrae información relevante de manera
automática a partir del código fuente HTML. Esos procesos requieren cierto dominio básico de HTML para
localizar la información relevante dentro del código fuente. Aprender a programar en HTML está fuera de los
alcances de este curso, por lo que sólo nos enfocaremos en los procesos básicos para llevar a cabo web
scraping en Python.
El web scraping posee diversas aplicaciones, siendo utilizada comúnmente en áreas como el marketing, la
investigación de mercado, el análisis de datos, el periodismo de datos o el monitoreo de precios. Por ejemplo,
una empresa puede utilizar web scraping para recopilar información de los precios de sus competidores en
línea y ajustar su estrategia de precios en consecuencia. Es importante tener en cuenta que el web scraping
© Sebastián Raveau
debe hacerse de manera ética y legal. La extracción de datos de sitios web puede ser ilegal si viola los
términos de servicio de un sitio web o la propiedad intelectual de una empresa.
Al igual que la minería de texto, el web scraping busca transformar el contenido no estructurado de un sitio
web en datos estructurados los que pueden ser almacenados en una base datos estructurada para ser
utilizada.
Al hacer web scrapping es importante distinguir cómo está construida y alojada la información. Esta puede
estar contenida directamente en el HTML (estática) o puede ser generada por alguna incrustación dinámica
dentro del HTML como un javaScript (dinámica).
La información estática es de más fácil acceso ya se encuentra contenida directamente en el código HTML
del sitio web. Para realizar web scrapping en sitios estáticos se recomienda el uso de la librería BeatifulSoup
de Python. Este es el tipo de web scraping en el que profundizaremos mediante un ejemplo.
Para trabajar con sitios web dinámicos es recomendable utilizar la librería Selenium de Python. Esta permite
simular un usuario que interactúa en un sitio web donde se permite la recolección de datos.
Supongamos que se requiere desarrollar una aplicación que permita conocer el valor en pesos chilenos de la
Unidad Tributaria Mensual (UTM) en todo momento. Dicho valor está disponible en diversos sitios web. En
este ejemplo utilizaremos la web prensaDigital, que publica el valor de la UTM aquí:
Es recomendable utilizar el navegador Google Chrome para acceder al sitio web. Una vez abierto, debemos
seleccionar el valor de la UTM y con clic secundario seleccionar "inspeccionar elemento". Ahora podrán ver
el código HTML del sitio web, para familiarizarse con su estructura.
Ahora utilizaremos la librería urllib de Python para simular un navegador y descargar el código fuente del
sitio web.
class WebDownloader:
def getHtmlAsString(self):
headers = {'User-Agent':self.user_agent}
request = net.Request(self.url,None,headers)
gcontext = ssl.SSLContext()
response = net.urlopen(request,context=gcontext)
return response.read().decode('utf-8')
wd = WebDownloader('https://www.prensadigital.cl/valor-utm-unidad-tributaria-mensual.html')
sourceCode = wd.getHtmlAsString()
Ahora tenemos acceso al código fuente del sitio web, a partir del cual podemos extraer toda la información
que sea interés. Al revisar el código fuente, es posible notar que el valor de la UTM se encuentra dentro del
archivo (en formato string) que acabamos de descargar. Podríamos procesar el string descargado para poder
obtener el valor buscado, pero veremos una manera más directa y fácil para extraer la información de interés.
print(sourceCode)
© Sebastián Raveau
Figura 6: Código HTML del sitio web
Fuente: Elaboración propia
Si luego de la inspección de elemento en Google Chrome seleccionamos el valor buscado, podemos ver el
nodo del código HTML en el que está contenido. En este caso encontramos el valor de la UTM en el nodo:
<td>61.769</td>
Los nodos <td> definen las celdas de una tabla en HTML. Accederemos a todos los nodos <td> dentro del
código HTML y para esto utilizaremos la librearía BeatifulSoup.
import bs4
info = []
soup = bs4.BeautifulSoup(sourceCode)
print(info)
['1', ' 61.769', '5', ' 308.845', '10', ' 617.690',
'50', ' 3.088.450', '100', ' 6.176.900', '1.000', ' 61.769.000',
'2.000', ' 123.538.000', '3.000', ' 185.307.000', '4.000', ' 247.076.000',
'5.000', ' 308.845.000', '10.000', ' 617.690.000',
'61.769 ', ' 1,00', '50.000 ', ' 0,81', '100.000 ', ' 1,62',
'200.000 ', ' 3,24', '500.000 ', ' 8,09', '1.000.000 ', ' 16,19',
'2.000.000 ', ' 32,38', '3.000.000 ', ' 48,57', '4.000.000 ', ' 64,76',
'5.000.000 ', ' 80,95', '10.000.000 ', ' 161,89']
Podemos ver que la información corresponde a la tabla de guía de conversión de UTM a pesos y de pesos a
UTM, de la Figura 5. Basta extraer el segundo elemento, que corresponde al valor de 1 UTM en pesos.
© Sebastián Raveau
En general, los procesos de web scraping deben desarrollarse a la medida de las necesidades y en función de
la estructura de los sitios web a utilizar. Documentarse correctamente es fundamental. En este ejemplo, sólo
extrajimos información de los nodos que definen una tabla en HTML. Una exhaustiva lista de los distintos
nodos en HTLM puede ser encontrada en el sitio web: www.w3schools.com/tags/
5. Conclusión
En esta clase hemos aprendido cómo extraer información relevante y útil a partir de grandes cantidades de
datos no estructurados.
Por un lado, hemos explorado los conceptos fundamentales de la minería de texto, desde el
preprocesamiento del texto, para obtener bolsas de palabras, hasta su uso en enfoques de minería de texto.
Ilustramos estos conceptos con una aplicación en Python de análisis de sentimientos. ¡Fuimos capaces de
entrenar un algoritmo de clasificación para que predijera la evaluación de distintas películas a partir de
reseñas!
Por otro lado, hemos aprendido los fundamentos básicos sobre web scraping, una poderosa técnica para
extraer datos de sitios web de forma automatizada. Nos hemos enfocado en el web scraping de sitios
estáticos, obteniendo información a partir del código HTML del sitio. Ilustramos estos fundamentos mediante
un sencillo ejemplo en Python para obtener el valor diario de la UTM. Podríamos utilizar el código
diariamente para generar automáticamente un registro en el tiempo.
6. Referencias bibliográficas
Géron, A. (2022). Hands-on machine learning with Scikit-Learn, Keras, and TensorFlow. O'Reilly Media, Inc.
Feldman, R., and Sanger, J. (2007). The text mining handbook: advanced approaches in analyzing
unstructured data. Cambridge University Press.
Mitchell, R. (2018). Web scraping with Python: Collecting more data from the modern web. O'Reilly Media,
Inc.
© Sebastián Raveau