Introducción

Esta pagina tiene como proposito mostrar las bases de datos, metodología, proceso de pensamiento y explicar el uso de los scripts utilizados. Si el interés es mejor explorar el desarrollo de los scripts se recomienda abrirlos directamente con un editor de texto pues vienen comentados.

Reto

Los clientes de Infosel necesitan acceder a la información de los Fondos de Inversión de BBVA Bancomer Gestión S.A de C.V, Sociedad Operadora de Fondos de Inversión. Para eso, la información solicitada por los clientes se puede localizar en: - El prospecto de colocación del fondo - Información de Mercado del fondo - Información de las carteras de inversión de los fondos

Por favor proporcione los datos de una muestra de cinco fondos de la operadora de fondos de BBVA con sus correspondientes series. La información solcitiada deberá corresponder a la más actual en los documentos y fuentes oficiales de información.

Metodología

Investigación inicial

En primer lugar se optó por investigar las paginas mencionadas en la descripción del reto así como de la Sociedad Operadora:

  • BMV
  • Valmer
  • BBVA

Sin embargo se notó que solo se encontraba información muy general. Por lo que se decidió hacer una busqueda más especifica dentro de la pagina de la Sociedad Operadora.

Definición de estrategia

Se encontró que la SO pública informes y reportes relacionados con el desempeño, normatividad y demás información relevante para el inversionista de cada bono y de los bonos de la SO en general. Por ello, con base en dichos documentos se decidió optar por dos estrategias con base en dos documentos distintos.

  • En primer lugar, una extracción de datos general del reporte diario acerca de todos los fondos de la Sociedad Operadora.

“Anaquel con Rendimientos Históricos del Día Actual”

  • En segundo lugar, una vez identificado algún fondo en particular, se procede a realizar una extracción direccionada con base en el documento DICI que emite la SO para cada fondo.

“Documento con información clave para la inversión”

Para estas tareas se desarrollaron 2 scripts de bash para la extracción y limpieza inicial y 2 de R para acomodar los datos. Los 4 scripts son automaticos, replicables y altamente funcionales. De esta manera se elaborarán dos bases de datos:

  • fondos_generales.csv que contiene información de los fondos mostrados en el reporte diario de BBVA (aunque por lo pronto solo se desarrollo el script para scrappear de manera diaria y completamente replicable solo la primera parte “Fondos de Deuda C.P P.F” aunque se podría trabajar posteriormente, con más tiempo, para adecuarlo de tal manera que se pueda extraer el contenido completo)

  • fondos_particulares.csv que contiene información de cada fondo ad hoc que gustemos agregar

Como comentario final, algunas variables no se extrajeron debido a que implicaría hacer 2 códigos adicionales para cada tipo de docuemnto nuevo. De esta manera, debido al tiempo otorgado (y debido a que tengo actividades) se decidió eficientizar esfuerzos en los dos tipos de documentos más ricos en contenido.

Mining general

Requisitos

Para la replicabilidad del mining se necesitan las siguientes cosas:

Todo esto se pude poner en un contenedor de docker para asegurar la replicabilidad o bien instalarse de manera local, dependiendo el expertise y comodidad del usuario.

Extracción de datos

El siguiente scrpt en bash extrae el contenido en texto del pdf

chmod +x general_extraction.zh
./general_extraction.zh
##   % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
##                                  Dload  Upload   Total   Spent    Left  Speed
## 
  0     0    0     0    0     0      0      0 --:--:-- --:--:-- --:--:--     0
100  182k  100  182k    0     0   394k      0 --:--:-- --:--:-- --:--:--  394k
## 1% Converting input to HTML...
## InputFormatPlugin: PDF Input running
## on /Users/marcoyel21/github/extraction_example_inf/sourcedoc.pdf
## pdftohtml log:
## Page-1
## Page-2
## Page-3
## Page-4
## Page-5
## Page-6
## Page-7
## Page-8
## Page-9
## Page-10
## Page-11
## Page-12
## Parsing all content...
## Generating default TOC from spine...
## 34% Running transforms on e-book...
## Merging user specified metadata...
## Detecting structure...
## Auto generated TOC with 0 entries.
## Flattening CSS and remapping font sizes...
## Source base font size is 12.00000pt
## Removing fake margins...
## Cleaning up manifest...
## Trimming unused files from manifest...
## Creating TXT Output...
## 67% Running TXT Output plugin
## Converting XHTML to TXT...
## TXT output written to /Users/marcoyel21/github/extraction_example_inf/file.txt
## Output saved to   /Users/marcoyel21/github/extraction_example_inf/file.txt

Limpieza

El siguiente script, acomoda la información extraída de tal manera que crea la base de datos de nombre fondos_generales.csv

source("general_cleaning.R")
## 
## Attaching package: 'dplyr'
## The following object is masked from 'package:kableExtra':
## 
##     group_rows
## The following objects are masked from 'package:stats':
## 
##     filter, lag
## The following objects are masked from 'package:base':
## 
##     intersect, setdiff, setequal, union
datatable(data, options = list(scrollX = TRUE))

Conclusión

De esta manera obtuvimos una base de datos que se actualiza al día con la más reciente información proporcionada por BBVA.

Mining direccionado

Requisitos

Para la replicabilidad del mining se necesitan las siguientes cosas:

  • contar con las url de los reportes DICI de cada fondo de los que se tenga interes (puede ser 1, 5 o 1000, no importa, el código es muy funcional). Estos se optienen de buscar el nombre del fondo en la pagina de BBVA, una vez ahí, vamos a documentación y encontraremos la URL del documento de interés
  • contar con calibre instalado
  • contar con R instalado (y los paquetes dplyr y readr)

Todo esto se pude poner en un contenedor de docker para asegurar la replicabilidad o bien instalarse de manera local, dependiendo el expertise y comodidad del usuario.

Extracción de datos

El siguiente script extrae de cada documento DICI información de manera muy direccionada. Para probar la replicabilidad de los scripts, hemos extraido información puntual de 10 fondos.

chmod +x particular_extraction.zh
./particular_extraction.zh
## ./particular_extraction.zh: line 34: 00009662: command not found
##   % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
##                                  Dload  Upload   Total   Spent    Left  Speed
## 
  0     0    0     0    0     0      0      0 --:--:-- --:--:-- --:--:--     0
  0     0    0     0    0     0      0      0 --:--:-- --:--:-- --:--:--     0
100  120k  100  120k    0     0   434k      0 --:--:-- --:--:-- --:--:--  432k
## 1% Converting input to HTML...
## InputFormatPlugin: PDF Input running
## on /Users/marcoyel21/github/extraction_example_inf/sourcedoc.pdf
## pdftohtml log:
## Page-1
## Page-2
## Page-3
## Page-4
## Parsing all content...
## Generating default TOC from spine...
## 34% Running transforms on e-book...
## Merging user specified metadata...
## Detecting structure...
## Auto generated TOC with 0 entries.
## Flattening CSS and remapping font sizes...
## Source base font size is 12.00000pt
## Removing fake margins...
## Cleaning up manifest...
## Trimming unused files from manifest...
## Creating TXT Output...
## 67% Running TXT Output plugin
## Converting XHTML to TXT...
## TXT output written to /Users/marcoyel21/github/extraction_example_inf/file.txt
## Output saved to   /Users/marcoyel21/github/extraction_example_inf/file.txt
##   % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
##                                  Dload  Upload   Total   Spent    Left  Speed
## 
  0     0    0     0    0     0      0      0 --:--:-- --:--:-- --:--:--     0
100  401k  100  401k    0     0   625k      0 --:--:-- --:--:-- --:--:--  625k
## 1% Converting input to HTML...
## InputFormatPlugin: PDF Input running
## on /Users/marcoyel21/github/extraction_example_inf/sourcedoc.pdf
## pdftohtml log:
## Page-1
## Page-2
## Page-3
## Page-4
## Page-5
## Page-6
## Page-7
## Page-8
## Page-9
## Page-10
## Page-11
## Page-12
## Page-13
## Page-14
## Page-15
## Page-16
## Page-17
## Page-18
## Page-19
## Page-20
## Page-21
## Page-22
## Page-23
## Page-24
## Page-25
## Page-26
## Page-27
## Page-28
## Parsing all content...
## Generating default TOC from spine...
## 34% Running transforms on e-book...
## Merging user specified metadata...
## Detecting structure...
## Auto generated TOC with 0 entries.
## Flattening CSS and remapping font sizes...
## Source base font size is 12.00000pt
## Removing fake margins...
## Cleaning up manifest...
## Trimming unused files from manifest...
## Creating TXT Output...
## 67% Running TXT Output plugin
## Converting XHTML to TXT...
## TXT output written to /Users/marcoyel21/github/extraction_example_inf/file.txt
## Output saved to   /Users/marcoyel21/github/extraction_example_inf/file.txt
##   % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
##                                  Dload  Upload   Total   Spent    Left  Speed
## 
  0     0    0     0    0     0      0      0 --:--:-- --:--:-- --:--:--     0
100  262k  100  262k    0     0   784k      0 --:--:-- --:--:-- --:--:--  784k
## 1% Converting input to HTML...
## InputFormatPlugin: PDF Input running
## on /Users/marcoyel21/github/extraction_example_inf/sourcedoc.pdf
## pdftohtml log:
## Page-1
## Page-2
## Page-3
## Page-4
## Page-5
## Page-6
## Page-7
## Page-8
## Page-9
## Page-10
## Page-11
## Page-12
## Page-13
## Page-14
## Page-15
## Page-16
## Parsing all content...
## Generating default TOC from spine...
## 34% Running transforms on e-book...
## Merging user specified metadata...
## Detecting structure...
## Auto generated TOC with 0 entries.
## Flattening CSS and remapping font sizes...
## Source base font size is 12.00000pt
## Removing fake margins...
## Cleaning up manifest...
## Trimming unused files from manifest...
## Creating TXT Output...
## 67% Running TXT Output plugin
## Converting XHTML to TXT...
## TXT output written to /Users/marcoyel21/github/extraction_example_inf/file.txt
## Output saved to   /Users/marcoyel21/github/extraction_example_inf/file.txt
##   % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
##                                  Dload  Upload   Total   Spent    Left  Speed
## 
  0     0    0     0    0     0      0      0 --:--:-- --:--:-- --:--:--     0
  0     0    0     0    0     0      0      0 --:--:-- --:--:-- --:--:--     0
100  353k  100  353k    0     0   319k      0  0:00:01  0:00:01 --:--:--  319k
## 1% Converting input to HTML...
## InputFormatPlugin: PDF Input running
## on /Users/marcoyel21/github/extraction_example_inf/sourcedoc.pdf
## pdftohtml log:
## Page-1
## Page-2
## Page-3
## Page-4
## Page-5
## Page-6
## Page-7
## Page-8
## Page-9
## Page-10
## Page-11
## Page-12
## Page-13
## Page-14
## Page-15
## Page-16
## Page-17
## Page-18
## Page-19
## Page-20
## Page-21
## Page-22
## Page-23
## Page-24
## Parsing all content...
## Generating default TOC from spine...
## 34% Running transforms on e-book...
## Merging user specified metadata...
## Detecting structure...
## Auto generated TOC with 0 entries.
## Flattening CSS and remapping font sizes...
## Source base font size is 12.00000pt
## Removing fake margins...
## Cleaning up manifest...
## Trimming unused files from manifest...
## Creating TXT Output...
## 67% Running TXT Output plugin
## Converting XHTML to TXT...
## TXT output written to /Users/marcoyel21/github/extraction_example_inf/file.txt
## Output saved to   /Users/marcoyel21/github/extraction_example_inf/file.txt
##   % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
##                                  Dload  Upload   Total   Spent    Left  Speed
## 
  0     0    0     0    0     0      0      0 --:--:-- --:--:-- --:--:--     0
 64  395k   64  256k    0     0   492k      0 --:--:-- --:--:-- --:--:--  491k
100  395k  100  395k    0     0   638k      0 --:--:-- --:--:-- --:--:--  637k
## 1% Converting input to HTML...
## InputFormatPlugin: PDF Input running
## on /Users/marcoyel21/github/extraction_example_inf/sourcedoc.pdf
## pdftohtml log:
## Page-1
## Page-2
## Page-3
## Page-4
## Page-5
## Page-6
## Page-7
## Page-8
## Page-9
## Page-10
## Page-11
## Page-12
## Page-13
## Page-14
## Page-15
## Page-16
## Page-17
## Page-18
## Page-19
## Page-20
## Page-21
## Page-22
## Page-23
## Page-24
## Page-25
## Page-26
## Parsing all content...
## Generating default TOC from spine...
## 34% Running transforms on e-book...
## Merging user specified metadata...
## Detecting structure...
## Auto generated TOC with 0 entries.
## Flattening CSS and remapping font sizes...
## Source base font size is 12.00000pt
## Removing fake margins...
## Cleaning up manifest...
## Trimming unused files from manifest...
## Creating TXT Output...
## 67% Running TXT Output plugin
## Converting XHTML to TXT...
## TXT output written to /Users/marcoyel21/github/extraction_example_inf/file.txt
## Output saved to   /Users/marcoyel21/github/extraction_example_inf/file.txt
##   % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
##                                  Dload  Upload   Total   Spent    Left  Speed
## 
  0     0    0     0    0     0      0      0 --:--:-- --:--:-- --:--:--     0
100  421k  100  421k    0     0   598k      0 --:--:-- --:--:-- --:--:--  598k
## 1% Converting input to HTML...
## InputFormatPlugin: PDF Input running
## on /Users/marcoyel21/github/extraction_example_inf/sourcedoc.pdf
## pdftohtml log:
## Page-1
## Page-2
## Page-3
## Page-4
## Page-5
## Page-6
## Page-7
## Page-8
## Page-9
## Page-10
## Page-11
## Page-12
## Page-13
## Page-14
## Page-15
## Page-16
## Page-17
## Page-18
## Page-19
## Page-20
## Page-21
## Page-22
## Page-23
## Page-24
## Page-25
## Page-26
## Page-27
## Page-28
## Parsing all content...
## Generating default TOC from spine...
## 34% Running transforms on e-book...
## Merging user specified metadata...
## Detecting structure...
## Auto generated TOC with 0 entries.
## Flattening CSS and remapping font sizes...
## Source base font size is 12.00000pt
## Removing fake margins...
## Cleaning up manifest...
## Trimming unused files from manifest...
## Creating TXT Output...
## 67% Running TXT Output plugin
## Converting XHTML to TXT...
## TXT output written to /Users/marcoyel21/github/extraction_example_inf/file.txt
## Output saved to   /Users/marcoyel21/github/extraction_example_inf/file.txt
##   % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
##                                  Dload  Upload   Total   Spent    Left  Speed
## 
  0     0    0     0    0     0      0      0 --:--:-- --:--:-- --:--:--     0
 91  368k   91  336k    0     0   373k      0 --:--:-- --:--:-- --:--:--  372k
100  368k  100  368k    0     0   397k      0 --:--:-- --:--:-- --:--:--  396k
## 1% Converting input to HTML...
## InputFormatPlugin: PDF Input running
## on /Users/marcoyel21/github/extraction_example_inf/sourcedoc.pdf
## pdftohtml log:
## Page-1
## Page-2
## Page-3
## Page-4
## Page-5
## Page-6
## Page-7
## Page-8
## Page-9
## Page-10
## Page-11
## Page-12
## Page-13
## Page-14
## Page-15
## Page-16
## Page-17
## Page-18
## Page-19
## Page-20
## Page-21
## Page-22
## Page-23
## Page-24
## Parsing all content...
## Generating default TOC from spine...
## 34% Running transforms on e-book...
## Merging user specified metadata...
## Detecting structure...
## Auto generated TOC with 0 entries.
## Flattening CSS and remapping font sizes...
## Source base font size is 12.00000pt
## Removing fake margins...
## Cleaning up manifest...
## Trimming unused files from manifest...
## Creating TXT Output...
## 67% Running TXT Output plugin
## Converting XHTML to TXT...
## TXT output written to /Users/marcoyel21/github/extraction_example_inf/file.txt
## Output saved to   /Users/marcoyel21/github/extraction_example_inf/file.txt
##   % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
##                                  Dload  Upload   Total   Spent    Left  Speed
## 
  0     0    0     0    0     0      0      0 --:--:-- --:--:-- --:--:--     0
  4  344k    4 16166    0     0  80029      0  0:00:04 --:--:--  0:00:04 79635
100  344k  100  344k    0     0   677k      0 --:--:-- --:--:-- --:--:--  677k
## 1% Converting input to HTML...
## InputFormatPlugin: PDF Input running
## on /Users/marcoyel21/github/extraction_example_inf/sourcedoc.pdf
## pdftohtml log:
## Page-1
## Page-2
## Page-3
## Page-4
## Page-5
## Page-6
## Page-7
## Page-8
## Page-9
## Page-10
## Page-11
## Page-12
## Page-13
## Page-14
## Page-15
## Page-16
## Page-17
## Page-18
## Page-19
## Page-20
## Page-21
## Page-22
## Parsing all content...
## Generating default TOC from spine...
## 34% Running transforms on e-book...
## Merging user specified metadata...
## Detecting structure...
## Auto generated TOC with 0 entries.
## Flattening CSS and remapping font sizes...
## Source base font size is 12.00000pt
## Removing fake margins...
## Cleaning up manifest...
## Trimming unused files from manifest...
## Creating TXT Output...
## 67% Running TXT Output plugin
## Converting XHTML to TXT...
## TXT output written to /Users/marcoyel21/github/extraction_example_inf/file.txt
## Output saved to   /Users/marcoyel21/github/extraction_example_inf/file.txt
##   % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
##                                  Dload  Upload   Total   Spent    Left  Speed
## 
  0     0    0     0    0     0      0      0 --:--:-- --:--:-- --:--:--     0
100  428k  100  428k    0     0   643k      0 --:--:-- --:--:-- --:--:--  643k
## 1% Converting input to HTML...
## InputFormatPlugin: PDF Input running
## on /Users/marcoyel21/github/extraction_example_inf/sourcedoc.pdf
## pdftohtml log:
## Page-1
## Page-2
## Page-3
## Page-4
## Page-5
## Page-6
## Page-7
## Page-8
## Page-9
## Page-10
## Page-11
## Page-12
## Page-13
## Page-14
## Page-15
## Page-16
## Page-17
## Page-18
## Page-19
## Page-20
## Page-21
## Page-22
## Page-23
## Page-24
## Page-25
## Page-26
## Page-27
## Page-28
## Parsing all content...
## Generating default TOC from spine...
## 34% Running transforms on e-book...
## Merging user specified metadata...
## Detecting structure...
## Auto generated TOC with 0 entries.
## Flattening CSS and remapping font sizes...
## Source base font size is 12.00000pt
## Removing fake margins...
## Cleaning up manifest...
## Trimming unused files from manifest...
## Creating TXT Output...
## 67% Running TXT Output plugin
## Converting XHTML to TXT...
## TXT output written to /Users/marcoyel21/github/extraction_example_inf/file.txt
## Output saved to   /Users/marcoyel21/github/extraction_example_inf/file.txt
##   % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
##                                  Dload  Upload   Total   Spent    Left  Speed
## 
  0     0    0     0    0     0      0      0 --:--:-- --:--:-- --:--:--     0
 17  434k   17 79827    0     0   201k      0  0:00:02 --:--:--  0:00:02  201k
100  434k  100  434k    0     0   412k      0  0:00:01  0:00:01 --:--:--  412k
## 1% Converting input to HTML...
## InputFormatPlugin: PDF Input running
## on /Users/marcoyel21/github/extraction_example_inf/sourcedoc.pdf
## pdftohtml log:
## Page-1
## Page-2
## Page-3
## Page-4
## Page-5
## Page-6
## Page-7
## Page-8
## Page-9
## Page-10
## Page-11
## Page-12
## Page-13
## Page-14
## Page-15
## Page-16
## Page-17
## Page-18
## Page-19
## Page-20
## Page-21
## Page-22
## Page-23
## Page-24
## Page-25
## Page-26
## Page-27
## Page-28
## Parsing all content...
## Generating default TOC from spine...
## 34% Running transforms on e-book...
## Merging user specified metadata...
## Detecting structure...
## Auto generated TOC with 0 entries.
## Flattening CSS and remapping font sizes...
## Source base font size is 12.00000pt
## Removing fake margins...
## Cleaning up manifest...
## Trimming unused files from manifest...
## Creating TXT Output...
## 67% Running TXT Output plugin
## Converting XHTML to TXT...
## TXT output written to /Users/marcoyel21/github/extraction_example_inf/file.txt
## Output saved to   /Users/marcoyel21/github/extraction_example_inf/file.txt

Limpieza

El siguiente script, acomoda la información extraída de tal manera que crea la base de datos de nombre particular_funds_info.csv.

#indico cuantos documentos scrapee
num<-10
source("particular_cleaning.R")
## Warning in matrix(clave$V1, ncol = 1, nrow = docs): data length [43] is not a
## sub-multiple or multiple of the number of rows [10]
## Warning in matrix(liquidez$V1, ncol = 1, nrow = docs): data length [43] is not a
## sub-multiple or multiple of the number of rows [10]
## Warning in matrix(horario$V1, ncol = 1, nrow = docs): data length [43] is not a
## sub-multiple or multiple of the number of rows [10]
## Warning in matrix(plazo_min$V1, ncol = 1, nrow = docs): data length [43] is not
## a sub-multiple or multiple of the number of rows [10]
## Warning in matrix(fondo$V1, ncol = docs, nrow = 5): data length [215] is not a
## sub-multiple or multiple of the number of columns [10]
## Warning in matrix(ren_bruto$V1, ncol = docs, nrow = 5): data length [215] is not
## a sub-multiple or multiple of the number of columns [10]
## Warning in matrix(ren_neto$V1, ncol = docs, nrow = 5): data length [215] is not
## a sub-multiple or multiple of the number of columns [10]
datatable(data, options = list(scrollX = TRUE))

Conclusión

De esta manera obtuvimos un pipe automatico al que podemos dar de input las urls de los distintos fondos de la SO y el pipe extraerá, limpiará y ordenará la información.

Conclusiones

  • Se uso la técnica de pdf scrapping para la extracción y se limpio la información en R
  • Se crearon scripts con pipes utiles y funcionales listos para usarse.
  • Se desarrollo la capacidad de extraer información general de manera diaria, puesto que se detecto que BBVA no cambia sus urls sino que solo los actualiza.
  • Se logró extraer, limpiar y presentar información de manera óptima ( en términos de tiempo, esfuerzo y contenido),

Mejoras

  • Elaborar los scripts adicionales para las pocas variables que faltaron): se listan a continuación
x<-c(
"Página electrónica",
"Monto máximo de inversión",
"Horizonte de inversión",
"Nombre del director general de la Sociedad Operadora",
"Precio anterior",
"Variación",
"Variación %",
"Volumen total",
"Importe",
"ISIN",
"Fecha anterior",
"Comisiones"
)
  • Mejorar los scripts de tal manera que en cada iteración sean más generales y menos “casados” con la estructura de los documentos. Esto debido a que cambian, por ejemplo se encontró que BBVA tenía una columna menos en su información general en 2017.

  • Entablar comunicación con el usuario de los scripts de tal manera de proponerle una manera comoda para usar los scripts: por ejemplo, una app, un dashboard, un documento interactivo o el script, dependiendo. Esto debido a que en el caso de la información particular hay algunos inputs como urls a scrapear e indicar cantidad de documentos. Por el contrario, los scripts de información general están listos para usarse de manera diaria sin ningun input, por lo menos hasta que BBVA cambie la url (en todo caso simplemente habría que actualizar la url).

  • Entablar comunicación con el usuario de tal manera de determinar la manera de uso para asegurar la replicanilidad. Puede montarse un docker, pueden instalarse requerimientos en cada maquina, puede montarse un servicio web o una maquina virtual.

  • Mejorar la eficiencia en cuanto a los scripts de tal manera que no creen tantos archivos auxiliares. Esto es importante si el objetivo es escalar a Big Data.

  • Crear un documento de leyenda de variables y claves para comodidad del usuario.