Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.
Aplicación de herramientas de código abierto
en el sector asegurador mexicano
Ivan Rodriguez Ortiz
Resumen
En 2015 comenzaron a implementarse de forma progresiva diversos
cambios en la regulación de la industria asegurado...
Índice
Resumen...............................................................................................................
12.2 Descriptores de la base de datos de Salud 2012 ..................................
......................................
1. Introducción
El sector asegurador de México se encuentra frente a un cambio importante el cual
afectará de manera signi...
popularizado un modelo económico y de innovación conocido como Open Source, el
cual se basa en la premisa básica y fundame...
2. Metodología
Para el desarrollo teórico y metodológico, en la primera parte se presenta una
introducción a los impactos ...
3. El sector asegurador
3.1 Descripción del sector
El sector asegurador en México opera a través de 105 instituciones (de ...
Fig 2. - Composición de cartera por ramo (elaboración propia con datos de la CNSF)
En términos de concentración de mercado...
Fig 4. - Composición de mercado (elaboración propia con datos de la CNSF)
Para este año según la agencia calificadora Fitc...
requerimiento, el cual contiene un resumen de la operación de la institución así como
su balance financiero. Estos informe...
• Registro de Reaseguros cedidos
• Registro de Reaseguros tomados
• Registro de pólizas abiertas
• Registro de asegurados ...
4. El modelo de código abierto (Open Source)
4.1 El modelo Open Source
Se conoce como Open Source Software (OSS) a los pro...
Como caso concreto, una rama de desarrollos de proyecto de código abierto de gran
popularidad e importancia es el de siste...
usuarios finales tanto en software como en hardware. Ejemplo claro de esto es la
posibilidad que existía hasta hace un tie...
lo son los monopolios en industrias como la de las tecnologías de información. Con la
creciente participación de esta indu...
5. Herramientas propuestas
5.1 Python
A continuación se presenta una introducción a las tecnologías propuestas con el fin ...
• Python permite una mejor conectividad con mecanismos de peristencia de datos
como bases de datos relacionales, SQL, hoja...
• Fácil manejo de datos faltantes (representados como NaN).
• Mutabilidad en el tamaño de las estructuras de datos, es dec...
5.3 Mecanismos de persistencia y almacenamiento de información
Para poder analizar la información haciendo uso de técnicas...
en el modelo de red se estructuran los datos de tal forma que cada registro puede
tener múltiples padres e hijos, formando...
son conocidas como relacionales ya que su datos son almacenados en tablas que son
isomórficas a relaciones matemáticas (St...
suma_asegurada Float
plazo Int
id_asegurado Long (llave foránea)
Fig 8. – Modelo relacional para almacenar pólizas (Elabor...
documentos el cual es un conjunto de atributos y estructuras anidadas por lo que
pueden almacenar, indexar y recuperar un ...
ser persisitida por medio de serialización a un archivo de texto interoperable entre
diversas aplicaciones y sistemas.
Otr...
{
"poliza":"01210381738",
"inicio_vigencia":{
"dia":28,
"mes":3,
"anio":2008
},
"fin_vigencia":{
"dia":28,
"mes":3,
"anio"...
mecanismo son los archivos de texto plano separados por comas (CSV o Comma
Separated Values por sus siglas en inglés) los ...
cual generalmente debe contar con la capacidad de indexar los registros y pueda
proveer un esquema de tipos de datos.
6. C...
desarrollan y explican dos métodos para el cálculo de la Prima Neta Nivelada (PNN) con
Python, haciendo uso de la siguient...
15 0.000495
Fig. 12 - Extracto de Tabla de mortalidad individual 200 para vida individual
En la práctica para realizar est...
def pnnx(edad, sa, plazo, tabla_mortalidad):
    x, n, i = edad, plazo, 0.05
    suma_numerador, suma_denominador = 0, 0
 ...
Una vez generada la estructura de datos requerida para tabla de mortalidad, se forma
similar se requiere leer el archivo c...
transformación. De esta manera se trabaja con vectores en vez de haciendo
iteraciones a todos los registros lo cual result...
vt = pd.DataFrame({'vt': range(0, polizas['plazo'].max()+1), 't':
range(0,polizas['plazo'].max()+1)}, dtype='float')
def V...
        t = int(t)
        if(t == 0):
            denominador[t] = mortalidad['pxqx'].iloc[x]
        else:
            d...
7. Cálculo de Siniestros Ocurridos No Reportados
Como parte del análisis de la condición de solvencia de una aseguradora s...
Dos de los métodos más frecuentemente utilizados en la práctica son el Chain Ladder
(CLM) así como el método Bornhuetter-F...
Luego se deben determinar los valores mínimo y máximo de los factores Fi, j para
cada año de desarrollo j. Éstos se utiliz...
Para la simulación se requiere contar con unos factores para generar números
aleatorios de acuerdo a una fución de distrib...
    factores.loc['max'][indice_s] = sonr[indice_s].max() * 1.1 
    factores.loc['min'][indice_s] = sonr[indice_s].min() *...
41
8. Análisis exploratorio del ramo Salud
Una tarea importante del analista actuarial así como del organismo regulador es
an...
Es común que una base de datos de este tipo cuente con un gran número de columnas
así como renglones debido al nivel de de...
import pandas as pd
import numpy as np
base_salud = pd.read_csv('Salud2012.csv')
siniestros = pd.DataFrame()
siniestros['E...
max 106.000000 275301.670000 70.000000 1.000000
Para obtener mayor información de los diagnósticos se requiere adicionar u...
615 Z71 312 PERSONAS QUE SOLICITAN SERVICIOS DE SALUD PARA...
616 Z00 376 EXAMEN GENERAL E INVESTIGACION DE PERSONAS SIN.....
Fig. 17 - Extracto del archivo de texto generado con las correlaciones
Como paso posterior se puede analizar la relación e...
mercadotecnia y detección de fraudes. Como caso hipotético para un cliente potencial
que desea contratar una póliza o una ...
reportado a nivel póliza. Con esto se logra consistencia y confiabilidad en la
información reportada así como una disminuc...
map (k1, v1) → lista (k2, v2)
reduce (k2, lista (v2) ) → lista (v2)
Dicho de otra forma, en esencia la función map realiza...
Fig. 17 – Ejecución de un proceso MapReduce (Dean y Ghemawat)
El uso de MapReduce puede ser visto como complemento a las t...
Dentro de estos entregables, las Instituciones deberán remitir a la CNSF la información
correspondiente a los reportes rel...
Operación / Ramo Moneda
nacional
Moneda
extranjera
Moneda
indizada
Vida
Individual
Grupo
Pensiones derivadas de la
Segurid...
#!/usr/bin/env python
# Funcion map
import sys
for linea in sys.stdin:
    linea = linea.strip()
    keys = linea.split('|...
for linea in sys.stdin:
    linea = linea.strip()
    moneda_ramo, monto = linea.split('t')
    monto = float(monto)
    i...
Los flujos de datos definidos también se pueden ejecutar en modo local lo cual permite
trabajar con un subconjunto del uni...
montos por tipo de moneda y ramo. Se puede notar que existen diversos comandos y
sentencias que resultan familiares para u...
10. Conclusiones
En este trabajo se mostraron diversas aplicaciones en la industria aseguradora de
México que pueden ayuda...
11. Bibliografía
• About NumPy. (2014, noviembre 1). Consultado el 1 de diciembre de 2014:
http://docs.scipy.org/doc/numpy...
• Gartner Survey Reveals More than Half of Respondents Have Adopted Open-
Source Software Solutions as Part of IT Strategy...
• Vargas Cruz, K. (2014). Cálculo de la edad máxima estimada de la tabla de
mortalidad mexicana CNSF 2000-I, su importanci...
12. Anexos
12.1 Script para generación de archivo de texto plano con
información de pólizas para el cálculo de PNNx
<?php
...
dias_es_h3 Días de Estancia Hospitalaria 3
num_ot_eh Número de Otros Eventos Hospitalarios
nc_pri_d1 Número de Consultas P...
nex_lab_d7 Número de Exámenes de Laboratorio Diagnóstico 7
nex_lab_d8 Número de Exámenes de Laboratorio Diagnóstico 8
nex_...
nmedic_ot Número de Medicamentos Otros Diagnósticos
ncon_pre Número de Consultas Externas Prenatales
ncon_pue Número de Co...
mc_pri_d0 Monto de Consultas Externas de Primer Contacto Diagnóstico 10
mc_esp_d1 Monto de Consultas Externas de Especiali...
mex_img_d8 Monto de Exámenes de Imagenología y Gabinete Diagnóstico 8
mex_img_d9 Monto de Exámenes de Imagenología y Gabin...
Aplicación de herramientas de código abierto en el sector asegurador mexicano
Aplicación de herramientas de código abierto en el sector asegurador mexicano
Aplicación de herramientas de código abierto en el sector asegurador mexicano
Aplicación de herramientas de código abierto en el sector asegurador mexicano
Aplicación de herramientas de código abierto en el sector asegurador mexicano
Upcoming SlideShare
Loading in …5
×

Aplicación de herramientas de código abierto en el sector asegurador mexicano

467 views

Published on

Aplicación de herramientas de código abierto en el sector asegurador mexicano con Python, Map Reduce y Pig

Published in: Data & Analytics
  • Be the first to comment

  • Be the first to like this

Aplicación de herramientas de código abierto en el sector asegurador mexicano

  1. 1. Aplicación de herramientas de código abierto en el sector asegurador mexicano Ivan Rodriguez Ortiz
  2. 2. Resumen En 2015 comenzaron a implementarse de forma progresiva diversos cambios en la regulación de la industria aseguradora para implementar el modelo de gestión de riesgos conocido como Solvencia II inspirado por tendencias a nivel mundial y mejores prácticas. Esta nueva forma de reportar y gestionar la solvencia repercute de forma importante la manera en la que se genera y entrega la información al regulador sectorial así como el nivel de detalle al que se reporta. De igual forma las instituciones que opten por adoptar un modelo interno para el cálculos requieren implementar pruebas de backtesting que den soporte a sus modelos de riesgo. Las herramientas (mayormente comerciales) que actualmente son utilizadas en la práctica de seguros presentan limitantes técnicas y no se integran de manera óptima a su estrategia y arquitectura empresarial. Recientemente las instituciones en conjunto con el regulador han hecho énfasis en estudiar el impacto cuantitativo y cualitativo de ésta, sin embargo faltan estudios que analicen del impacto en materia tecnológica que esto representa para los participantes del sector. De ahí se desprende la importancia de analizar la factibilidad y aplicación de herramientas informáticas que se adecuen a las necesidades y recursos actuales de los participantes del sector. En concordancia con esto, el presente trabajo propone el uso de diversas herramientas para dar soporte al cumplimiento de las nuevas disposiciones de la regulación de solvencia para todos los partipantes del sector. En este trabajo se muestra el uso diversas aplicaciones para casos de uso específicos haciendo uso exclusivo de herramientas de código abierto que facilitan el procesamiento, generación y análisis de datos. 2
  3. 3. Índice Resumen...................................................................................................................2 1. Introducción..........................................................................................................5 2. Metodología..........................................................................................................7 3. El sector asegurador.............................................................................................8 3.1 Descripción del sector...............................................................................8 4. El modelo de código abierto (Open Source)........................................................13 4.1 El modelo Open Source...........................................................................13 4.2 Economía del Open Source......................................................................14 5. Herramientas propuestas....................................................................................17 5.1 Python.....................................................................................................17 5.2 Pandas y NumPy......................................................................................18 5.3 Mecanismos de persistencia y almacenamiento de información.............20 5.3.1 Bases de datos relacionales.......................................................20 5.3.2 Bases de datos NoSQL...............................................................23 5.3.3 Archivos de texto.......................................................................26 6. Cálculo de Prima Neta Nivelada para reservas...................................................28 6.1 Implementación de cálculo de Prima Neta Nivelada..............................28 6.2 Implementación de cálculo de PNN con librerías para análisis de datos 32 7. Cálculo de Siniestros Ocurridos No Reportados..................................................36 8. Análisis exploratorio del ramo Salud...................................................................41 9. Procesamiento de grandes volúmenes de datos.................................................45 9.1 MapReduce...........................................................................................47 9.2 Generación de vistas de análisis...........................................................49 9.3 Implementación en Pig Latin.................................................................53 10. Conclusiones.....................................................................................................55 11. Bibliografía........................................................................................................56 12. Anexos..............................................................................................................59 12.1 Script para generación de archivo de texto plano con información de pólizas para el cálculo de PNNx......................................................................59 3
  4. 4. 12.2 Descriptores de la base de datos de Salud 2012 .................................. ....................................................................................................................... 59 12.3 Extracto de la base de datos de Salud 2012....................................65 12.4 Script para generación de archivo de texto plano con deudores por prima en PHP................................................................................................66 12.5 Extracto de los catálogos de datos maestros para niveles contables, monedas y ramos.........................................................................................67 4
  5. 5. 1. Introducción El sector asegurador de México se encuentra frente a un cambio importante el cual afectará de manera significativa la forma en que las instituciones monitorean y reportan su condición de financiera así como la de solvencia. En 2015 entró en vigor la nueva regulación de solvencia conocida como Solvencia II, apoyado en la Ley de Instituciones de Seguros y Fianzas (LISF) así como la Circular Única de Seguros y Fianzas (CUSF). Este nuevo marco regulatorio está inspirado en esfuerzos globales por estandarizar la gestión de riesgos, el objetivo de Solvencia II es el desarrollo y establecimiento de un nuevo sistema que permita determinar los recursos propios mínimos a requerir a cada aseguradora, en función de los riesgos asumidos y la gestión que se realice de cada uno de ellos (Aguilera, 2013). Este nuevo esquema regulatorio está inspirado en una iniciativa de la Unión Europea la cual se ha convertido en una especie de modelo a seguir en todo el sector asegurador mundial. Este esquema de solvencia se basa en la atención de tres pilares. Las instituciones gubernamentales en conjunto con las aseguradoras se han dado a la tarea de elaborar la regulación para el caso específico de México y llevar a cabo los Estudios de Impacto Cuantitativo y Cualitativo (EIQ y EIC), los cuales en materia legistlativa culminaron con la publicación de la CUSF. Estos nuevos lineamientos tienen un impacto tan amplio en términos tecnológicos que se requiere determinar si las herramientas informáticas que se usan actualmente permiten dar soporte a estos nuevos requerimientos en tiempos de respuesta aceptables. Actualmente existen en el mercado diversas aplicaciones, plataformas y herramientas propietarias las cuales generalmente son las utilizadas en la industria, la mayoría de ellas cuentan con altos costos de licenciamiento1 . En años recientes se ha 1Se puede acotar la excepción del proyecto R, el cual es de uso difundido 5
  6. 6. popularizado un modelo económico y de innovación conocido como Open Source, el cual se basa en la premisa básica y fundamental que cualquier persona puede acceder a su código fuente e incluso derivar beneficios económicos basando su desarrollo en los componentes de un proyecto de código abierto. Estos beneficios económicos no se dan en forma de licenciamiento como el software propietario, sino a través de otras fuentes de ingresos y nuevos modelos de negocios. Actualmente la madurez de este modelo depende en gran medida del apoyo y difusión que ha recibido de empresas de gran importacia económica y tecnológica como Google, Yahoo y Facebook, de donde han surgido proyectos en versiones actualmente estables. La mayoría de las veces estos proyectos han surgido de una necesidad al interior de estas empresas por lo cual nacieron con aplicaciones prácticas en mente, asimismo cuentan con un equipo al interior dedicado especialmente al desarrollo, pruebas y mantenimiento de éstos. A lo largo de este trabajo se desarrolla un análisis de la factibilidad y aplicación de herramientas open source en aspectos concretos de la práctica de seguros haciendo uso principalmente del lenguaje de programación Python así como otras tecnologías relacionadas. Para esto se parte de la hipótesis y premisa que este lenguaje es idóneo para el análisis numérico y estadístico por el número de librerías desarrolladas para este propósito específico además de la facilidad que brinda para la manipulación de estructuras de datos. Para mostrar su aplicabilidad en cálculos actuariales se aborda el cálculo de conceptos relacionados con reservas y los triángulos de siniestros conocidos como SONR (Siniestos Ocurridos No Reportados) o IBNR por sus siglas en inglés (Incurred but Not Reported). Luego se realiza una exploración de datos por medio del cálculo de estadísticas e indicadores para el ramo de Salud. Finalmente se introduce a un modelo de programación el cual permite manejar un gran volumen de información presentado una agrupación de información de deudores por prima. 6
  7. 7. 2. Metodología Para el desarrollo teórico y metodológico, en la primera parte se presenta una introducción a los impactos que representa para las instituciones esta nueva regulación de solvencia, haciendo énfasis en el punto de vista de la información y datos. Posteriormente se presenta una introducción al marco teórico y se explica el modelo código abierto haciendo uso de diversos enfoques y modelos económicos. Seguido de esto se explica el ambiente de operación así como los componentes propuestos en esta aplicación. Luego se desarrollan y explican casos de uso específicos para las herramientas propuestas con el fin de mostrar su factibilidad2 . La mayoría de los datos utilizados para este trabajo fueron generados por medio de scripts desarrollados específicamente para esto con base en las especificaciones de casos reales de la industria y otras proveídas por la CNSF a excepción de la sección de clasificación y análisis de gastos de salud. Para este caso se usaron datos reales publicados, los cuales fueron transformados con las herramientas propuestas. Para la generación aleatoria de datos, se produjeron archivos de texto de tamaño considerable para mostrar su aplicabilidad en casos de uso reales del sector. 2 El código fuente se encuentra disponible en https://goo.gl/dMPwMi donde se considera pertinente muestran las salidas detalladas para cada fragmento de código. 7
  8. 8. 3. El sector asegurador 3.1 Descripción del sector El sector asegurador en México opera a través de 105 instituciones (de capital mayoritariamente extranjero) en diversos ramos, siendo los de Vida, Auto, Accidentes y enfermedades los principales. La composición de cartera que presenta el sector asegurador con cifras al cierre de diciembre de 2014 es la siguiente: Ramo % de cartera Vida 41.6 Automóviles 19.2 Accidentes y Enfermedades 15.8 Incendio y Terremoto 6.8 Pensiones 5.8 Diversos 4.8 Marítimo y Transportes 2.6 Responsabilidad Civil 1.9 Otros ramos 1.5 Fig. 1 - Composición de cartera por ramo (elaboración propia con datos de la CNSF) Al cierre del cuarto trimestre de 2014, la operación de Vida creció 2.8% en términos reales, en comparación al cuarto trimestre de 2013. La mayoría de los diferentes tipos de seguros que integran esta operación, mostraron el siguiente comportamiento: Vida Grupo y Vida Individual registraron incrementos reales anuales de 6.4% 4 y de 0.9%, respectivamente (CNSF, 2014). 8
  9. 9. Fig 2. - Composición de cartera por ramo (elaboración propia con datos de la CNSF) En términos de concentración de mercado diversos índices que tratan de medir este indicador mustran que ésta no es significativa en el país, respecto a este punto la composición de las principales empresas al cierre de 2014 fue la siguiente: Empresa % de participación Metlife México 14.3 Grupo Nacional Provincial 11.3 AXA Seguros 8.3 Seguros Banamex y Grupo Financiero Banamex 6.3 Seguros BBCA Bancomer y Grupo Financiero BBVA Bancomer 5.8 Otros 60.3 Fig 3. - Composición de mercado (elaboración propia con datos de la CNSF) 9 Vida Autos Accidentes y enfermedades Incendio y terremoto Pensiones Diversos Marítimo y tranportes Responsabilidad civil Otros
  10. 10. Fig 4. - Composición de mercado (elaboración propia con datos de la CNSF) Para este año según la agencia calificadora Fitch Ratings se espera que el sector asegurador mexicano presente un crecimiento de alrededor de seis a ocho porciento en términos nominales siendo los ramos de daños y vida grupo los que impulsen esto. Asimismo se espera que las compañías logren adaptarse a las iniciativas regulatorias derivadas de la nueva CUSF respecto a los nuevos requierimientos para gobierno corporativo y revelación de información. (Fitch Ratings, 2015). 3.2 Marco regulatorio En 2014 fue publicada la Ley de Instituciones de Seguros y Fianzas (LISF) la cual entró en vigor en 2015. Esta nueva legislación prevé la aplicación de la Circular Única de Seguros y Fianzas (CUSF), la cual propone un esquema de administración del negocio tipo Solvencia II (Fitch Ratings, 2015). Los productos principales de reporteo regulatorio son los Reportes Regulatorios (RR) y el Reporte de Solvencia y Condición Financiera (RSCF), os primeros spresentan un nivel de detalle mayor. El RSCF es un nuevo 10 Metlife GNP AXA Banamex BBVA Otros
  11. 11. requerimiento, el cual contiene un resumen de la operación de la institución así como su balance financiero. Estos informes se entregan de forma trimestral y su contenido es principalmente proveído por información financiera, de las pólizas así como los registros de emisión de las aseguradoras provenientes de sus sistemas transaccionales. Esta información estará disponible al público en general y tiene que ser dada a conocer a través de la página web de las instituciones (CNSF, 2014). Recientemente se han realizado estudios en conjunto con la industria conocidos como Estudios de Impacto Cualitativo (EIC) y Estudios de Impacto Cuantitativo (EIQ) con el fin de realizar ejercicios previos a la implementación completa de los mecanismos de entrega y conocer su impacto respecto a las metodologías que actualmente son utilizadas por las empresas del sector. Con esto surge la necesidad de contar el soporte tecnológico que permita una adecuada y oportuna gestión de riesgos con base en información histórica así como su posterior manipulación y análisis para la toma de decisiones y exposición a diversos riesgos. Se tiene que considerar adicionalmente que el volumen de datos que se genera para la operación, gestión y análisis financiero, mercadotecnia así como cumplimiento regulatorio es cada vez mayor. Asimismo para la práctica actuarial comúnmente se requiere obtener relaciones e intersecciones de todo ese universo de registros. En el caso de la CUSF se contempla que las aseguradoras del sector deberán realizar y almacenar diversos registros y auxiliares provenientes de distintos sistemas fuente heterogéneos. En estos registros se basan las entregas regulatorias por lo cual esta información debe ser confiable, completa y consistente. Entre los registros que se deben almacenar y reportar a las instituciones regulatorias se encuentran: • Inversiones • Registro de pólizas y certificados 11
  12. 12. • Registro de Reaseguros cedidos • Registro de Reaseguros tomados • Registro de pólizas abiertas • Registro de asegurados por pólizas de seguros de grupo y colectivo • Registro de cesiones y aceptaciones de Reaseguro facultativo • Registro de primas cobradas • Registro de deudores por primas • Registro de préstamos sobre pólizas • Registro de caducidades y terminaciones • Registro de primas netas, iniciales y de renovación • Registro de endosos • Registro de siniestros • Registro de rescates • Registro de vencimientos • Registro de salvamentos A continuación se proponen diversas aplicaicones prácticas que hacen uso de distintas librerías y aplicaciones para llevar a cabo exploración y análisis de datos con técnicas estadísticas así como la generación de información requerida para entregas regulatorias. 12
  13. 13. 4. El modelo de código abierto (Open Source) 4.1 El modelo Open Source Se conoce como Open Source Software (OSS) a los programas y/o aplicaciones de software, publicadas de forma que cualquiera tiene acceso a su código fuente. Este tipo de software de código abierto comúnmente es confundido con el “freeware”, el cual es software con derecho de propiedad que es puesto a disposición de los usuarios sin costo pero con restricciones en cuanto a modificación y distribución además su código fuente no está disponible públicamente lo cual es característica fundamental del software libre. Hoy en dia, las soluciones Open Source han madurado al grado que son incorporadas en los ambientes tecnologicos de las organizaciones ya que brindan diversos beneficios para las organizaciones entre las que se encuentran “flexibilidad, mayor inovacion, ciclos de desarrollo más cortos (Gartner, 2011)”. Se considera pionero en este rubro al desarrollador, hacker y activista Richard Stallman, quien en 1983 inició un movimiento organizado por medio de la fundación no lucrativa “The Free Software Foundation” y el proyecto GNU. El uso del software libre inició como un movimiento de usuarios y desarrolladores pero con los años se ha encontrado la forma de llevarlo a modelos de negocio de diversas compañías que han encontrado beneficios económicos en éste. Entre las creaciones computacionales que operan bajo este esquema y son de mayor uso se encuentran Linux (Mint, Ubuntu, etc), Open Office, Apache (server), PHP, Python y MySQL. Generalmente este software es publicado bajo licencias como la “GNU General Public license” la cual establece algunas cláusulas para su uso, modificación y distribución. Estas licencias no son restrictivas en cuanto a los usos comerciales que se les dé a sus aplicaciones. 13
  14. 14. Como caso concreto, una rama de desarrollos de proyecto de código abierto de gran popularidad e importancia es el de sistemas operativos. Anteriormente el uso de sistemas operativos de este tipo estaba limitado a servidores (de bases de datos, de aplicaciones, etc) y para su administración y adopción para uso cotidiano se requería de ciertos conocimientos avanzados en el dominio de computación y técnico. Sin embargo diversos proyectos de código abierto han optado por estudiar y mejorar su usabilidad por medio de interfaces de usuario más amigables para usuarios principiantes. 4.2 Economía del Open Source Con la creciente aceptación y proliferación de este tipo de software, han surgido controversias principalmente en cuanto a aspectos legales, de seguridad y éticos. En el primer rubro se puede mencionar que la mayor problemática expuesta es la falta de una regulación formal para el software libre. En el segundo rubro se ha planteado que el software libre muchas veces no es seguro de usar por las diversas fallas que puede presentar al no seguir lineamientos de calidad en su proceso de desarrollo. Finalmente algunos de los temas más controvertidos que han surgido con el uso del software libre se encuentran en el ámbito de la ética, donde quienes defienden su uso abogan por la libertad y el libre acceso al conocimiento y por lo tanto están tajantemente en contra de lucrar con éste como según ellos lo hacen las compañías desarrolladoras de software. Partiendo de las teorías económicas modernas de maximización de bienestar, el software libre ha contribuido a aumentar el excedente de los consumidores ya que al contar con una mayor aceptación, ha actuado como un fuerte competidor de la industria y con esto ha contribuido a la disminución de los precios que pagan los 14
  15. 15. usuarios finales tanto en software como en hardware. Ejemplo claro de esto es la posibilidad que existía hasta hace un tiempo de adquirir equipos directamente de los proveedores con sistemas operativos Linux, lo cual disminuye sustancialmente el costo inicial. Algunas compañías han encontrado en este tipo de software una oportunidad de obtener beneficios económicos cambiando su enfoque de vender un producto al de vender un servicio por medio de la creación de valor agregado. En la mayoría de los casos distribuyen software libre y comercializan servicios como son soporte técnico, capacitación, integración y certificación. Otra posibilidad es ofrecer una versión conocida como “Community” la cual ofrece funcionalidades básicas. Adicionalmente se ofrece un licenciamiento de versiones de paga que extienden estas funcionalidades básicas. Esta generación de valor agregado también resulta positiva para los mercados y el bienestar social. Aunado a esto se han creado nuevos mercados que giran en torno al software libre, lo cual ha obligado a muchas corporaciones que típicamente comercializan software a ser partícipes en inversiones relacionadas con el software libre con el fin de no ver reducida su participación en el mercado al ahorrar en estos costos de licenciamiento. Como lo explica el economista Michael Jensen en “Theory of the Firm: Managerial Behavior, Agency Costs and Ownership Structure”, la economía y las personas actúan bajo un esquema de incentivos. Bajo el supuesto que todo software desarrollado tuviera que operar bajo el esquema de software libre, no existiría el incentivo a invertir en investigación y desarrollo al no resultar redituable ante la posibilidad de desarrollar un producto similar basado en tecnologías ya existentes (Jensen, 1976). Esto nos lleva también al punto que la proliferación y mayor aceptación de software libre puede resultar favorable para contrarrestar los efectos negativos de fallas de mercado como 15
  16. 16. lo son los monopolios en industrias como la de las tecnologías de información. Con la creciente participación de esta industria en la economía global y con las proyecciones de crecimiento que tiene a futuro como pilar para el desarrollo de muchas economías, se podrá ver un mayor un efecto en beneficio de la competitividad y bienestar social traducido en el excedente del consumidor. Existen otros factores que incentivan la calidad en el desarrollo de software y el involucramiento de desarrolladores con proyectos de este tipo. A pesar que los desarrolladores y programadores involucrados en proyectos de este tipo sin recibir un sueldo fijo cuenten con diversos costos de oportunidad, éstos podrían ser rebasados por otro tipo de incentivos. Por ejemplo podría mejorar su productividad o encontrar un placer intrínseco como diversión así como factores sociales como la gratificación de otros. Los desarrolladores también podrían estar incentivados por colaborar en proyectos open source porque esto abre la posibilidad de otras oportunidades de trabajo a los desarrolladores (Lerner et Al, ). También como contrargumento a esta postura, las herramientas open source brindan calidad equiparable o mejor al software propietario en la medida en que están sujetas al escrutinio público y pruebas unitarias realizadas por medio de la comunidad, incluso una plataforma open source puede conllevar a una mayor inversión que una propietaria (Casadesus-Masanell et. Al, 2005). 16
  17. 17. 5. Herramientas propuestas 5.1 Python A continuación se presenta una introducción a las tecnologías propuestas con el fin de mostrar su aplicabilidad y factibilidad en el sector asegurador. A lo largo de este trabajo se hace uso del lenguaje de programación Python concebido en 1989 y el cual es un lenguaje multiparadigma de dominio general adecuable a un amplio espectro de problemas. Python fue concebido con un especial énfasis en la facilidad de lectura del código así como la calidad de software y productividad del programador (Lutz, 1999). Actualmente cuenta con las librerías y desarrollos existentes que permiten que el rango de aplicabilidad de Python incluye econometría, estadísticas y análisis numérico en general. Incluso su uso puede remplazar otros lenguajes de domino específico como son R, MATLAB o Julia (Sheppard, 2014). Aunado a esto, Python presenta ventajas frente al lenguaje R el cual es ampliamente conocido en el sector: • Python permite la creación de aplicaciones web y móviles no sólo scripts o fragmentos de código para el análisis técnico por lo que permite a las organizaciones contar con un ambiente tecnológico integrado. • Python permite de forma nativa el diseño y programación orientada a objetos así como el desarrollo guiado por pruebas3 . • Python permite la integración con tecnologías de procesamiento de grandes volúmenes de información, concretamente en este punto Python cuenta con potentes capacidades ETL (Extract Transform Load por sus siglas en inglés). 3 Desarrollo guiado por pruebas de software, o Test-driven development (TDD) es una práctica de ingenieria de sofware que permite el desarrollo de aplicaciones de manera ágil usando ciclos iterativos. 17
  18. 18. • Python permite una mejor conectividad con mecanismos de peristencia de datos como bases de datos relacionales, SQL, hojas de cálculo y archivos de texto. Éstos también son soportador por R pero por ejemplo no los servicios web REST y SOAP. • Python permite un mejor filtrado y selección de subconjuntos de información también cuenta con la precisión numérica y funciones matemáticas requeridas. En este punto es importante mencionar que en R el manejo de cadenas de texto y fechas es posible sin embargo no resulta tan natural como es el caso de otros lenguajes de programación. Python es un lenguaje interpretado, por lo que no requiere compilación previa a diferencia de C o Java. También es un lenguaje de tipado dinámico, es decir que una misma variable puede tomar valores de distinto tipo en distintos momentos y las verificaciones de tipo se realizan no al momento de compliación, sino al de ejecucíón. Python permite el desarrollo de aplicaciones para la cuales la velocidad de ejecución sea un aspecto muy importante, para esto se puede utilizar el compilador JIT (“just-in- time”) PyPy o Cython el cual permite la traducción de código fuente en Python al ejecuciones en el lenguaje C. 5.2 Pandas y NumPy Como se mencionó anteriormente existen diveras librerías y módulos de código abierto pensados especialmente en su aplicación a estadística y análisis de datos en Python. A lo largo de este trabajo se hace uso de Pandas y NumPy. Pandas es una librería que provee estructuras de datos y otras herramientas para el análisis de datos cuyo desarrollo contempla la optimización del rendimiento de los scripts o programas desarrollados con ésta, entre otras funcionalidades permite: 18
  19. 19. • Fácil manejo de datos faltantes (representados como NaN). • Mutabilidad en el tamaño de las estructuras de datos, es decir pueden ser insertadas y borradas columnas con facilidad. • Flexibilidad para agrupar, combinar, agregar y transformar datos así como indexar y derivar nuevos conjuntos de datos. • Lectura y escritura desde archivos CSV, Excel, y el formato HDF5. Pandas provee un conjunto de estructuras de datos como son Series, DataFrames (similares al mismo concepto en R) y Paneles. Las series son arreglos unidimensionales, mientras que los DataFrames son colecciones de series por lo tanto bidimensionales, finalemente los Paneles son colecciones de DataFrames por lo que estas estructuras son tridimensionales. Esta librería a su vez se basa en el uso de componentes de NumPy, el cual es un paquete para cómputo estadístico y científico en Python el cual ofrece estructuras de dato eficientes que sirven como contenedores para operaciones numéricas eficientes en términos de memoria. Ésta provee entre otros: • Un objeto tipo arreglo N-dimensional (ndarray) el cual es un contenedor multidimenional de elementos del mismo tipo y tamaño. • Funciones de álgebra lineal, transformadas de Fourier y generación de números aleatorios. • Funciones estadísticas como suma, media, desviación estándar, curtosis, mediana, cuantiles, covarianza y correlación. Asimismo NumPy provee una selección de generadores de números aleatorios para distribuciones específicas: bernoulli, beta, binomial, chi cuadrada, exponencal, f, gamma, laplace, lognormal, multinomial, normal multivariada, binomial negatica, normal, poisson, t estándar y uniforme. 19
  20. 20. 5.3 Mecanismos de persistencia y almacenamiento de información Para poder analizar la información haciendo uso de técnicas cuantitativas se requiere contar con un mecanismo de persistencia o almacenamiento de datos que permita trabajar con algoritmos y transformaciones dobre el sobre el universo de datos recopilados. Una base de datos es un objeto estructurado el cual consiste de datos y la descripción de los mismos conocida como metadatos. Existen diversos formatos y mecanismos de almacenamiento, a continuación se presentan los de uso más difundido en la práctica. Para ejemplificar las diferentes tecnologías se considera el diseño de una base de datos que contiene información relacionada con la emisión de pólizas del ramo de vida de una empresa aseguradora con los siguientes campos: Nombre del campo Descripción poliza Número de póliza conforma al sistema transaccional donde se realiza la emisión de las mismas inicio_vigencia Fecha de inicio de vigencia para la póliza en formato aaaa/mm/dd fin_vigencia Fecha de fin de vigencia para la póliza en formato aaaa/mm/dd suma_asegurada La suma aseguada de la póliza masculino Sexo en tipo booleano (1 es Masculino, 0 Femenino) plazo Plazo fecha_nacimiento Fecha de nacimiento del asegurado en formato aaaa/mm/dd Fig. 5 – Estructura de datos para información una póliza (Elaboración propia) 5.3.1 Bases de datos relacionales En términos generales, una base de datos se define como una colección de archivos relacionados, esta relación en sí misma depende del tipo de modelo utilizado. Dos de los primeros modelos definidos fueron el jerárquico y el de red. En el primero existían relaciones padre/hijo donde cada hijo sólo podía tener a lo más un padre. Por su parte 20
  21. 21. en el modelo de red se estructuran los datos de tal forma que cada registro puede tener múltiples padres e hijos, formando una estructura general de grafo. El modelo de bases de datos relacional propuesto originalmente por Edgar F. Codd representó un gran avance ya que permitía relacionar múltiples registros por medio de un campo en cómun. Con esta posibilidad para poder relacionar dos archivos éstos sólo debían tener un campo en común y esto brinda mayor flexibilidad en el modelado ya que todos los datos son representados en términos de tuplas agrupadas por medio de relaciones. Para realizar consultas y operaciones sobre bases de datos relacionales se hace uso del lenguaje Structured Query Language (SQL) el cual no es estándar pero las diversas implementaciones tienen la mayor parte de la sintaxis y funcionalidades en común. Para hacer uso de este tipo de persistencia de datos se requiere definir relaciones como su nombre lo indica el cual proviene del concepto matemático de relación. Fig. 6 – Relación matemática y su aplicación en bases de datos (Stajano, 1998) La figura anterior muetra una relación r entre dos conjuntas A y B. Una relación es un subconjunto del producto cartesiano de los conjuntos sobre los cuales está definida esta relación. En este caso r es un subconjunto de A×B. Este tipo de bases de datos 21
  22. 22. son conocidas como relacionales ya que su datos son almacenados en tablas que son isomórficas a relaciones matemáticas (Stajano, 1998). Este tipo de bases de datos de forma nativa no son óptimas para el manejo grandes volúmenes de datos ya que generalmente se requiere particionarlos y distribuirlos entre distintos nodos lo cual conlleva una mayor complejidad en la administración. Ejemplos de sistemas de este tipo son Microsoft SQL, Oracle, MySQL, PostgreSQL y recientemente MariaDB el cual fue derivado de MySQL y actualmente cuenta con la colaboración de desarrolladores que anteriormente formaban parte de este proyecto. Un inconveniente es la compatibilidad entre sistemas de administración de bases de datos (DBMS por sus siglas en inglés) de distintas soluciones incluidas las de código abierto. Para implementar almacenamiento de pólizas en una base de datos relacional con el esquema propuesto en la sección anterior podría ser modelado de la siguiente forma: Tabla ASEGURADOS Nombre del campo Tipo de dato id Long (llave primaria) sexo Booleano fecha_nacimiento Fecha nombre Text apellido_1 Text apellido_2 Text Fig 7. – Modelo relacional para almancenar asegurados (Elaboración propia) Tabla POLIZAS Nombre del campo Tipo de dato id Long (llave primaria) inicio_vigencia Fecha fin_vigencia Fecha 22
  23. 23. suma_asegurada Float plazo Int id_asegurado Long (llave foránea) Fig 8. – Modelo relacional para almacenar pólizas (Elaboración propia) Como se muestra se requiere relacionar diversas tablas para que la información tenga sentido. En este caso las pólizas se mantienen en una tabla independiente de los asegurados, siendo asociadas por medio de llaves primarias y foráneas. 5.3.2 Bases de datos NoSQL En respuesta a las limitantes mostradas por la tecnología relacionales respecto al manejo de grandes volúmenes de datos surgieron las tecnologías NoSQL. Las bases de datos relacionales fueron diseñadas inicialmente para ser ejecutadas en solo un servidor, por esta razón una de las formas de poder escalar este tipo de bases de datos sigue siendo aumentar las capacidades del nodo de cómputo con hardware. Otra necesidad que buscan resolver este tipo de base de datos es poder almacenar el creciente volumen de datos no estructurados que son generados en la operación de los negocios incluyendo las aseguradoras. Este tipo de datos al no tener predefinida una relación como la que requiere el modelo relacional no se adaptan de forma natural a éste. En términos de tiempos de respuesta, en muchos casos este tipo de bases de datos NoSQL presentan ventajas a comparación las relacionales. Para persistir datos bajo un modelo relacional se requiere separar la información en tablas interrelacionadas. Cada tabla contiene registros relacionado con otras tablas por lo que para ciertas consultas se requiere buscar y combinar datos de un gran número de tablas para poder procesar la consulta requerida, lo mismo sucede para la escritura bajo este modelo relacional. En contraste con esto, muchas de las bases de datos NoSQL usan el concepto de 23
  24. 24. documentos el cual es un conjunto de atributos y estructuras anidadas por lo que pueden almacenar, indexar y recuperar un objeto completo de forma más rápida. Adicionalmente las tecnologías NoSQL permiten escalar horizontalmente, es decir agregando nuevos nodo de cómputo. Estos nodos pueden ser utilizados para replicar los datos y guardar diversas copias de forma distribuída, de esta forma se cuenta con una mayor disponibilidad de lo datos. Otra características de este tipo de bases de datos son la posibilidad de realizar consultas de forma distribuída y mecanismos de caching de la información para reducir el tiempo de respuesta usando almacenamiento en memoria. Algunas de las herramientas más conocidas para este mecanismo de persistencia son MongoDB, Redis y CouchDB. Un posible modelo de la información relacionada con una póliza bajo este tipo es el siguiente: { "poliza":"01210381738", "inicio_vigencia":"2008/03/28", "fin_vigencia":"2020/03/28", "suma_asegurada":150000, "plazo":144, "asegurado":{ "sexo":1, "fecha_nacimiento":"1986/07/15" } } Fig. 9 – Modelo de registro/documento para una póliza El esquema anterior muestra una de las diferencias de las bases de datos NoSQL en ciertos casos en comparación con las bases de datos relacionales. Como se ejemplifica, la estructura con la información del asegurado está contenida dentro de la misma estructura que contiene la de la póliza, de forma anidada. Esta misma estructura puede 24
  25. 25. ser persisitida por medio de serialización a un archivo de texto interoperable entre diversas aplicaciones y sistemas. Otra de las ventajas que presentan este tipo de mecanismos de persistencia en comparación con las bases de datos relacionales es la facilidad de extensión del esquema de datos inicial. Suponiendo que se quisiera lograr lo siguiente: • Separar las fechas en campos distintos (día, mes, año para este caso de uso). Con esto se busca lograr que los campos de tipo fecha sean explotables por distintos lenguajes de programación ya que aunque los campos de tipo DATE son soportados por la gran mayoría de los sistemas manejadores de bases de datos (RDBMS), éstos no son interoperables de forma nativa con los lenguajes de programación que a su vez definen sus propios formatos y tipos de dato para las fechas. • Agregar el monto de la suma asegurada en otras monedas distintas a la moneda local o la principal. • Agregar la información del plazo de la póliza en otras unidades de tiempo. Lo anterior podría lograrse basándose en los mismos registros sin la necesidad de agregar tablas adicionales que relacionen la información, un posible esquema de datos es la siguiente: 25
  26. 26. { "poliza":"01210381738", "inicio_vigencia":{ "dia":28, "mes":3, "anio":2008 }, "fin_vigencia":{ "dia":28, "mes":3, "anio":2020 }, "suma_asegurada":{ "MXN":150000, "USD":10420.67 }, "plazo":{ "meses":144, "anios":12 }, "asegurado":{ "sexo":1, "fecha_nacimiento":{ "dia":15, "mes":7, "anio":1986 } } } Fig. 10 – Modelo de registro/documento para una póliza (Elaboración propia) De esta forma se logran agregar nuevos campos sin la necesidad de agregar nuevas tablas de relación o definir columnas o atributos en común lo cual brinda una flexibilidad en el modelado de los datos. 5.3.3 Archivos de texto Uno de los primeros mecanismos que existieron para implementar bases de datos fueron los modelos de sistemas de archivo. Éstos no requieren técnicas de modelado y la información es serializada directamente en archivos de texto. Una variante de este 26
  27. 27. mecanismo son los archivos de texto plano separados por comas (CSV o Comma Separated Values por sus siglas en inglés) los cuales pueden ser leídos y manipulados directamente por diversos lenguajes de programación, editores de texto y hojas de cálculo tanto propietarias como de código abierto. Éstos cuentan con un amplio uso y difusión en el sector asegurador mexicano donde generalmente se manipulan por medio de Microsoft Excel. En este tipo de mecanismo de persistencia generalmente cada registro es separado por comas, pero también son comúnmente utilizados otros caracteres. En el caso de la regulación Mexicana se utiliza el símbolo “|” para separar las columnas y adicionalmente se usa el símbolo “;” para indicar saltos de línea o fin de una tupla. Con esto se busca poder incluir los caracteres de comillas y comas dentro de las cadenas de texto del archivo, así mismo evita potenciales problemas de compatibilidad con distintas codificaciones de caracteres como UTF-8, ISO8859 y Windows 1252 por mencionar algunos, ya que éstos usan distintos caracteres para indicar saltos de línea. La información relacionada con la emisión de pólizas y siniestros del caso de uso planteado anteriormente podría ser modelada de la forma siguiente: poliza,inicio_vigencia,fin_vigencia,suma_asegurada,masculino,plazo,fecha_nacimiento 1,2002/03/01,2007/03/01,24859,1,5,1996/03/04 2,2010/05/01,2025/05/01,60763,1,15,1986/08/25 3,2011/12/01,2021/12/01,39875,0,10,1960/06/14 Fig. 11 - Extracto del archivo de texto con información de las pólizas (Elaboración propia) A diferencia de las hójas de cálculo, este mecanismo no tiene límite en el número de registros a generar por lo que puede ser utilizado para serializar información de gran volumen. Sin embargo la manipulación y análisis de información almacenada en este formato y mecanismo requiere en la mayoría de los casos su transferencia a otro el 27
  28. 28. cual generalmente debe contar con la capacidad de indexar los registros y pueda proveer un esquema de tipos de datos. 6. Cálculo de Prima Neta Nivelada para reservas 6.1 Implementación de cálculo de Prima Neta Nivelada Las reservas además de presentar una métrica de la posición de riesgo asumida por una aseguradora, repercuten directamente en la situación y rentabilidad financiera de las aseguradoras. Esto debido a que este cálculo es registrado contablemente y por lo tanto figura en los estados financieros (mismos que son del dominio público para todo el sector). Según datos de 2013 de la AMIS, la operación de Vida representa alrededor el 46% de las participación de mercado del sector (CNSF, 2014) y el 42% de los siniestros directos por lo que el cálculo de reservas aplicables a este ramo es de gran importancia. Una reserva en un seguro de vida corresponde a un pasivo que una aseguradora establece para el pago de obligaciones futuras (típicamente siniestros). En los modelos clásicos actuariales se establece una prima neta nivelada basada en tablas de mortalidad. Usualmente se usa una cuyas tasas de mortalidad incrementen de forma monotónica con la edad y hacen uso de una tasa de interés única (Easton, 2014). Para el caso específico de México, Vargas hace la comparación de diversos modelos con información de mortalidad observada en el país. Concluye que el modelo actualmente utilizado para fines regulatorios por la CNSF tiene un buen ajuste a la los datos observados analizados (Vargas, 2014). En este tipo de modelos, la prima neta nivelada se establece como el comnto al momento de la emisión y registro de una póliza, el cual en caso de ser reclamada y pagada equivale al valor presente neto de los beneficios estipulados. A continuación se 28
  29. 29. desarrollan y explican dos métodos para el cálculo de la Prima Neta Nivelada (PNN) con Python, haciendo uso de la siguiente formulación: PNNx= SA⋅∑ t=0 n−1 Vt +1 ⋅Pxt ⋅qx+t ∑ t=0 m−1 V t ⋅Pxt Donde PNNx : Prima Neta Nivelada a la edad x SA : Suma asegurada n: Plazo del contrato de la póliza Vt : (1+i)−t i: Tasa de interés Pxt : Probabilidad de sobrevivencia a la edad x+t qx+t : Tasa de mortalidad a la edad x+t Para este cálculo se utiliza el enfoque de los modelos clásicos, como se mencionó anteriormente este método consiste en hacer uso de las tablas de vida o tablas de mortalidad, las cuales representan la probabilidad que una persona sobreviva a una cierta edad X. Un extracto de la tabla de mortalidad aplicable a México es el siguiente: Edad qx 12 0.000396 13 0.000427 14 0.000460 29
  30. 30. 15 0.000495 Fig. 12 - Extracto de Tabla de mortalidad individual 200 para vida individual En la práctica para realizar este cálculo para una sola póliza es posible hacerlo por medio de hojas de cálculo. Sin embargo si se requiere el cálculo para muchas pólizas con distintas características como plazos, sexos y edades de asegurados o para que esto pueda ser aplicable en una institución con un gran volumen de suscripción, se requiere otro acercamiento a la solución del problema. Para el caso de una aseguradora con operación en México, la información de origen relacionada con pólizas requerida para el cálculo de la PNN podría ser tomada del archivo CSV que es entregada en los reportes regulatorios. Asimismo la tabla de mortalidad puede ser serializada de la siguiente forma: edad,qx 12,0.000368 13,0.000403 14,0.000432 15,0.000461 16,0.00049000 17,0.000509 Fig. 13 - Extracto del archivo de texto con información de la tabla de mortalidad A continuación se presenta una posible implementación en Python, la cual permite realizar el cálculo de PNN leyendo como entrada los archivo CSV descritos anteriormente. Para esta aplicación se generaron registros aleatorios por lo que no son válidos y consistentes sin embargo sirven para demostrar la aplicabilidad en un ambiente de operación real. Primeramente se requiere definir una función que tome como parámetros de entrada la edad del asegurado, la suma asegurada, el plazo y la tabla de mortalidad aplicable. En este caso: 30
  31. 31. def pnnx(edad, sa, plazo, tabla_mortalidad):     x, n, i = edad, plazo, 0.05     suma_numerador, suma_denominador = 0, 0     for t in range(0, n):         vt_mas_1 = pow(1 + i, ­(t + 1))         qx_mas_t = tabla_mortalidad[x + t]         if (t == 0):             tpx = 1         else:             tpx = 1 ­ qx_mas_t         suma_numerador += vt_mas_1 * tpx * qx_mas_t         vt = pow(1 + i, ­t)         suma_denominador += vt * tpx     pnnx = (sa * suma_numerador) / suma_denominador     return pnnx En primera instancia se definen y asignan las variables de la función, posteriormente se realizan iteraciones para realizar las sumatorias requeridas para el cálculo de PNN, finalmente se retorna el valor calculado por la función. Posteriormente se requiere leer el archivo de texto con la información relevante de las pólizas serializada. Con Python la lectura y escritura de archivos de texto CSV se logra de forma sencilla y nativa importando un módulo del mismo nombre. Haciendo uso de este módulo, se puede construir y almacenar la tabla de mortalidad en una estructura de datos del tipo diccionario (el cual guarda combinaciones únicas de llaves con valores o tuplas) la cual puede ser reutilizada para el cálculo de la PNN por póliza. Esto se logra de la forma siguiente: import csv import ast archivo_csv = open('tabla_mortalidad.csv') reader = csv.reader(archivo_csv) tabla_mortalidad = {} reader.next() for edad in reader:     tabla_mortalidad[ast.literal_eval(edad[0])] =  ast.literal_eval(edad[1]) 31
  32. 32. Una vez generada la estructura de datos requerida para tabla de mortalidad, se forma similar se requiere leer el archivo con la información de las pólizas y llamar la función anteriormente definida para el cálculo de la PNN para cada registro: archivo_csv = open('polizas.csv') reader = csv.reader(archivo_csv) reader.next() calculos_pnnx = {} for poliza in reader:     num_poliza = poliza[0]     plazo = int(poliza[1])     edad = ast.literal_eval(poliza[2])     sa = ast.literal_eval(poliza[3])     calculo_pnnx = pnnx(edad, sa, plazo, tabla_mortalidad)     calculos_pnnx[num_poliza] = calculo_pnnx Como se puede observar, los cálulos de PNN resultantes de llamar la función para cada póliza son almacenados en un diccionario el cual posteriormente puede ser utilizado para otros cálculos relacionados. Una posible mejora a este script consiste en incluir un paso previo de ETL (Extract Transform Load) para obtener los datos directamente de los sistemas transaccionales fuente y así evitar una generación de forma manual del archivo CSV con la información requerida de primas emitidas y retenidas, en este dominio también se pueden encontrar un gran número de líbrerías y conectores que facilitarían esta tarea en Python. 6.2 Implementación de cálculo de PNN con librerías para análisis de datos El cálculo de PNN puede ser computado haciendo uso de estructuras que representen de forma matricial o vectorial las pólizas aplicando funciones algebráicas de 32
  33. 33. transformación. De esta manera se trabaja con vectores en vez de haciendo iteraciones a todos los registros lo cual resulta familiar para usuarios que trabajan con el leguaje R. A continuación se presenta una posible implementación del cálculo de PNN por prima con Pandas, para esto primero se construye una estructura para las pólizas y tabla de mortalidad con base en los archivos CSV anteriormente descritos: import pandas as pd import numpy as np import copy polizas = pd.read_csv('polizas.csv') polizas = polizas.set_index('num_poliza') mortalidad = pd.read_csv('tabla_mortalidad.csv') mortalidad = mortalidad.set_index('edad') mortalidad['px'] = 1 ­ mortalidad['qx'] mortalidad['pxqx'] = mortalidad['px'] * mortalidad['qx'] En el fragmento anterior, se importa el archivo CSV para lectura y se asigna la columna que contiene el número de póliza como el indice de los registros para el caso de las pólizas, para el caso de la tabla de mortalidad de asigna la edad, los usuarios familiarizados con el lenguaje R pueden hacer la analogía con los DataFrames utilizados en éste. Una vez que se cuenta con las pólizas y la tabla de mortalidad en variables de datos, una posible solución consiste en calcular los componentes de la fórmula como columnas independientes y finalmente realizar transformaciones simples sobre éstas (sumas, restas divisiones y multiplicaciones en esencia). En este cálculo en particular, para logar esto se requiere la construcción de una estructura de datos que contenga los valores de Vt desde cero hasta el plazo máximo que se encuentre en el conjunto de datos haciendo uso de una función de transformación, esto se puede lograr de la siguiente forma: i = 0.05 33
  34. 34. vt = pd.DataFrame({'vt': range(0, polizas['plazo'].max()+1), 't': range(0,polizas['plazo'].max()+1)}, dtype='float') def Vt(vt):     vt['vt'] = pow(i+1, ­vt['t'])     return vt vt.apply(Vt, axis=1) vt['vt+1'] = vt['vt'].shift(­1) Posteriormente se puede realizar el cálculo de los numeradores y denominadores, para esto se realiza una iteración desde cero hasta el plazo máximo para todas las edades únicas que se encuentren en el conjunto ordenadas de forma ascendente, en este caso también se requiere una función de transformación simple y la lectura de la tabla de mortalidad construida previamente: # Tabla denominador numerador = pd.DataFrame({'x': sorted(polizas['edad'].unique())}, dtype='float') for t in range(0, polizas['plazo'].max()):     numerador[t] = t     numerador[t] = numerador[t].astype('float') # Tabla denominador denominador = copy.deepcopy(numerador) # Funcion de tansformacion para numerador def multiplica_num(numerador):     x = numerador['x'].astype('int32')     for t in numerador[1:]:         t = int(t)         if(t == 0):             numerador[t] = vt['vt'].iloc[t]          else:             numerador[t] = vt['vt'].iloc[t] *  mortalidad['pxqx'].iloc[x + t]     return numerador numerador = numerador.apply(multiplica_num, axis=1) # Funcion de transfomacion para denominador def multiplica_den(denominador):     x = denominador['x'].astype('int32')     for t in denominador[1:]: 34
  35. 35.         t = int(t)         if(t == 0):             denominador[t] = mortalidad['pxqx'].iloc[x]         else:             denominador[t] = vt['vt+1'].iloc[t] *  mortalidad['pxqx'].iloc[x + t]     return denominador denominador = denominador.apply(multiplica_den, axis=1) Como se ejemplifica por medio del desarrollo de este cálculo de forma vectorial, la librería Pandas permite aplicar funciones de transformación a cada combinación renglon / columna tan complicada como se requiera, con un código extensible y limpio. Permite obtener estadísticas para exploración y análisis preliminar de los datos. Esto permite construir un vector con todas combinaciones para las edades y plazos existentes de forma dinámica. 35
  36. 36. 7. Cálculo de Siniestros Ocurridos No Reportados Como parte del análisis de la condición de solvencia de una aseguradora se requiere entender la forma en que se valúan los activos y pasivos de la misma. La valuación de provisiones técnicas son parte fundamental del trabajo llevado a cabo por los actuarios de no Vida. Kaas, Grovaerts et al., explican que anteriormente los portafolios de los ramos distintos de vida eran financiados bajo un sistema pago sobre demanda (“pay- as-you-go” en inglés). Todos los reclamos de un año en particular eran pagados con la prima de ese mismo año sin importar del año en el que se haya originado el reclamo. Para obtener el balance financiero de ese portafolio debía asegurarse que existiera una equivalencia entre las primas cobradas y las pagadas para un año en particular. Derivado de eso sugían diferencias entre la prima de un año y los reclamos pagados a través del año. Esto se presenta ya que los reclamos que se originan en un año en particular muchas veces no pueden ser finalizados o tramitados ese mismo año, por ejemplo debido a procesos legales o por reclamo tardío. Se debe resolver entonces la pregunta siguiente: ¿Cuánto debe ser reservado para poder hacer frente a pagos futuros derivados de un periodo reciente en el pasado? Los triángulos (“run-off triangles” en inglés) son usados en la práctica de seguros en general para realizar pronósticos a futuro del número así como los montos de reclamos, es decir los casos donde puede tomar un tiempo después de un siniestro para que el monto a pagar por el reclamo sea conocido. El punto de partida para el uso de triángulos en el cálculo de reservas es el supuesto que el desarrollo de este tipo de reclamos sigue un patrón común en todos los periodos de siniestro. Para crear un triángulo de reclamos el primer paso es agrupar los reclamos por año de ocurrencia y posteriormente se procede a calcular la parte baja del triángulo. 36
  37. 37. Dos de los métodos más frecuentemente utilizados en la práctica son el Chain Ladder (CLM) así como el método Bornhuetter-Ferguson. Para este trabajo se considera el primero, el cual se basa en la premisa que el último patrón observado es válido para todos los años de ocurrencia de reclamos. Para cada año de desarrollo se calcula un factor resultante como un cociente el cual es usado para la estimación de las reclamaciones futuras. Existen casos donde se pueden encontrar valores negativos para los cuales existen algunos tratamientos especiales propuestos por diversos autores. A continuación se desarrolla una posible definición de cálculo para SONR y posteriormente se realiza una implementación del mismo en Python. Para este cálculo primeramente se debe agrupar y acomodar la información histórica de primas y siniestros del período n a n-5 (2008 a 2013) en un arreglo matricial de forma ascendente respecto al tiempo. Posteriormente se deben calcular, para cada ramo o tipo de seguro k, los índices de reclamaciones futuras de la forma siguiente: Fig. 14 – Representación de siniestros y prima emitida en triángulo En una etapa posterior deben ser calculados los índices de reclamaciones registradas por año de origen i y año de desarrollo j ( Fi , j ) como el cociente del monto de los siniestros ( Ri, j ) entre la prima emitida en el año de origen ( PEi ): Fi, j= Ri, j PEi 37 Año origen Primaemitida Siniestrosen1 Siniestrosen2 Siniestrosen3 Siniestrosen4 Siniestrosen5 Siniestrosen6 Siniestrosen7 2008 2009 2010 2011 2012 2013 2014 2015
  38. 38. Luego se deben determinar los valores mínimo y máximo de los factores Fi, j para cada año de desarrollo j. Éstos se utilizan para determinar un intervalo de generación de números aleatorios simulados Fi, j SIM . Luego se debe simular el monto de siniestros con base en la multiplicación del índice de reclamaciones, elegido al azar entre el 90% y el 110% del mínimo y máximo encontrados anteriormente por la prima emitida cada año de origen i: ri, j=Fi , j SIM ∗PEi Fi, j SIM ∈(0.9∗minFi, j ,1.1∗maxFi, j) Finalmente con el monto de los siniestros simulados, se debe estimar el valor de los siniestros futuros ocurridos pero no reportados. Esto se debe realizar para cada año de origen I y es la sumatoria de los siniestros provenientes de esos años de origen: ri=∑ j=1 n ri, j A continuación se presenta una posible implementación del cálculo de siniestros ocurridos pero no reportados SONR. Suponiendo que se cuenta con una estructura de datos (sonr) tipo DataFrame indexada por el año de emisión la cual contenga la información de los montos y años de los siniestros, así como la prima emitida agrupadas por año con la siguente forma: anio_emision prima_emitida anio_siniestro monto_siniestro 0 2008 6.078667e+09 NaN NaN 1 2009 5.410572e+09 NaN NaN 2 2010 5.699797e+09 NaN NaN 3 2011 7.238161e+09 NaN NaN 4 2012 8.594971e+09 NaN NaN anio_emision prima_emitida anio_siniestro monto_siniestro 33 2013 NaN 2014 1.558775e+09 34 2013 NaN 2015 5.828038e+07 35 2014 NaN 2015 7.674148e+08 36 NaN NaN NaN NaN 37 NaN NaN NaN NaN 38
  39. 39. Para la simulación se requiere contar con unos factores para generar números aleatorios de acuerdo a una fución de distribución uniforme con parámetros obtenido de multiplicar los factores máximo y mínimo por la prima emitida, es decir: p(x)= 1 b−a Donde a:0.9∗minFi, j∗primaemitida b:1.1∗maxFi, j∗primaemitida Se puede entonces definir una función de transformación sobre los renglones de esta estructura como el cociente del monto siniestro entre la prima emitida: def llena_factores(sonr):     for i in range(1, 8):         indice_s = 's' + str(i)         if not pd.isnull(sonr[indice_s]):             anio_emision = sonr['anio_emision']             factores_sonr[indice_s] =  sonr[indice_s].loc[anio_emision] /  sonr['prima_emitida'].loc[anio_emision]     return factores_sonr sonr = sonr.apply(llena_factores, axis=1) sonr = sonr.set_index('anio_emision') Posteriormente se deben encontrar los valores máximos y mínimos multiplicados por otro un factor constante los cuales serán los límites para los parámetros de la distribución uniforme: factores = pd.DataFrame({'limite': ['max', 'min']}) for anio_desarrollo in range(1,8):     factores['s' + str(anio_desarrollo)] = None factores = factores.set_index('limite')      for i in range(1, 8):     indice_s = 's' + str(i) 39
  40. 40.     factores.loc['max'][indice_s] = sonr[indice_s].max() * 1.1      factores.loc['min'][indice_s] = sonr[indice_s].min() * 0.9 Finalmente se debe realizar la generación de números aleatorios de acuerdo a la distribución uniforme, puede repetirse tantas veces como se requiera para un ramo específico: def simula_rec(sim_sonr):     for i in range(1, 8):         indice_s = 's' + str(i)         if pd.isnull(sim_sonr[indice_s]):             anio_emision = sim_sonr['anio_emision']             max = factores.loc['max'][indice_s]             min = factores.loc['min'][indice_s]             prima_emitida =  sonr['prima_emitida'].loc[anio_emision]             sim_sonr[indice_s] = random.uniform(min *  prima_emitida, max * prima_emitida)         else:             sim_sonr[indice_s] = None     return sim_sonr      sim_sonr = sim_sonr.apply(simula_rec, axis=1) sim_sonr = sim_sonr.set_index('anio_emision') Como se puede ver, este script permite la posibilidad de realizar el cálculo con un número y método de generación de números aleatorios potencialmente variables de forma dinámica. Asimismo se pueden calcular los diversos ramos y subramos de forma separada o realizar algunas modificaciones para clasificarlos a priori y después realizar el cálculo por categorías. Otra posible mejora es como en el caso de la aplicación práctica de PNN presentada, incluir un paso previo de ETL (Extract Transform Load) para obtener los datos directamente de los sistemas transaccionales fuente y así evitar una generación manual del archivo CSV con la información requerida de primas emitidas y retenidas. 40
  41. 41. 41
  42. 42. 8. Análisis exploratorio del ramo Salud Una tarea importante del analista actuarial así como del organismo regulador es analizar en retrospectiva con base en datos históricos, el comportamiento de las diferentes variables que intervienen en la ocurrencia de siniestros y emisión de pólizas con el fin de poderlas clasificar para la toma de decisiones. Específicamente en el ramo de salud se puede llevar a cabo la caracterización de la atención de siniestros desde la perspectiva financiera, de salud pública así como geográfica y con esto lograr un mejor entendimiento del ramo respondiendo a preguntas como las siguientes: 1. ¿Qué porcentaje de reclamos son para hombres y cuál para mujeres? 2. ¿Cuál es la edad promedio en la que se registran siniestros? 3. ¿Cuáles son los gastos más bajos y más altos de diagnóstico? 4. ¿Cuál es la enfermedad más común en el Distrito Federal? 5. ¿Qué edad es la que más reclamos presenta? 6. ¿Cuántos días en promedio permanece en el hospital un asegurado? A continuación se desarrolla el cálculo de diversas estadísticas con la ayuda de la librería Pandas. Como fuente se usó la información de Gastos de vida 2012, la cual está disponible al público en formato DBF. Un fragmento de los descriptores de los datos proporcionado por la CNSF es el siguiente:4 Nombre del campo Descripción edad Edad sexo Sexo lug_reside Lugar de Residencia diagnost1 Diagnóstico 1 dias_es_h1 Días de Estancia Hospitalaria mmed_d1 Monto de Medicamentos Diagnóstico 1 Fig. 15 – Extracto de descriptores del archivo Salud 2012 4 La lista completa de descriptores se encuentran en el Anexo 42
  43. 43. Es común que una base de datos de este tipo cuente con un gran número de columnas así como renglones debido al nivel de detalle que se requiere para entrega regulatoria y análisis de todas las posibles variables relevantes (en este caso son ciento sesenta y un columnas o campos). El problema con este diseño es que muchos registros en un esquema relacional se quedan sin utilizar si se hace una consulta de cuyo resultado sólo se requieren unos cuantos campos y generando matrices dispersas por lo que para este tipo de datos también se debe considerar el uso de bases de datos basadas en columnas o columnares. Éstas tienen la capacidad de leer directamente sólo las columnas requeridas para las consultas, asimismo cuentan con mecanismos de procesamiento en memoria con el fin de optimizar la lectura y escritura a comparación del uso de disco duro. En este caso se puede mencionar el proyecto MonetDB el cual es de código abierto y cuenta con extensiones para trabajar directamente con los lenguajes Python y R con base en datos almacenados en ésta. Antes de calcular estadísticas generales sobre los datos, se pueden agrupar los diversos campos para los cuales se desean los totales como montos de medicamentos y días de estancia hospitalaria: 43
  44. 44. import pandas as pd import numpy as np base_salud = pd.read_csv('Salud2012.csv') siniestros = pd.DataFrame() siniestros['EDAD'] = base_salud['EDAD'] siniestros['DIAGNOST1'] = base_salud['DIAGNOST1'] siniestros['TOTAL_MM'], siniestros['TOTAL_ES_H'] = 0, 0 for i in range(0,10):     siniestros['TOTAL_MM'] += base_salud['MMED_D' + str(i)] for i in range(1, 4):     siniestros['TOTAL_ES_H'] += base_salud['DIAS_ES_H' + str(i)] def sexo_bool(registro):     if registro['SEXO']  == 'M':         return 1     else:         return 0          siniestros['SEXO'] = base_salud.apply(sexo_bool, axis=1) print siniestros.describe() En la primera parte se importa la información del archivo de texto plano5 a una estructura de datos, posteriormente se filtran sólo algunos campos de interés y se realiza la suma de los campos con los montos de medicamentos y la estancia hospitalaria. Finalmente se aplica una función de transformación que convierte el sexo en una variable booleana (la cual sólo puede tomar valores 0 ó 1) para poder calcular diversas estadísticas de la misma. Al ejecutar este script se pueden observar las medias, desviaciones así como máximos y mínimos: EDAD TOTAL_MM TOTAL_ES_H SEXO count 50350.000000 50350.000000 50350.000000 50350.000000 mean 33.477577 804.282491 0.194816 0.442483 std 19.924554 3370.977818 1.197046 0.496686 min 0.000000 0.000000 0.000000 0.000000 25% 17.000000 0.000000 0.000000 0.000000 50% 33.000000 0.000000 0.000000 0.000000 75% 48.000000 160.570000 0.000000 1.000000 5 Ver anexos para un extracto de este archivo 44
  45. 45. max 106.000000 275301.670000 70.000000 1.000000 Para obtener mayor información de los diagnósticos se requiere adicionar un conjunto de datos con las enfermedades, un posible archivo de texto puede tener la siguiente estructura: clave,descripcion 000,NINGUNO 999,DESEMPLEO A00,COLERA A01,FIEBRE TIFOIDEA Y PARATIFOIDEA A02,OTRAS INFECCIONES POR SALMONELLA A03,SHIGELOSIS Fig. 16 - Extracto del archivo de texto con información de la tabla de mortalidad Con base en estos dos conjuntos de datos se pueden agregar nuevos campos y filtar por entidad federativa para realizar el análisis específico de una de éstas, en este caso el Distrito Federal, el cual es identificado por la clave “9”: siniestros_df = pd.DataFrame() siniestros_df = base_salud[base_salud['LUG_RESIDE'] == 9] siniestros_df['OCURRENCIAS'] = 0 siniestros_df = siniestros_df.groupby('DIAGNOST1').count()['OCURRENCIAS'] enfermedades = pd.read_csv('./archivos­texto/enfermedades.csv') enfermedades.columns = ['DIAGNOST1', 'descripcion'] siniestros_df = siniestros_df.order() siniestros_df = pd.DataFrame(siniestros_df) siniestros_df.reset_index(level=0, inplace=True) print siniestros_df.merge(enfermedades).tail(5) Al ejecutar este script se puede ver los 5 diagnósticos con el mayor número de occurencias en el Distrito Federal para el periodo analizado, esta información puede ser usada posteriormente para una mejor comprensión de la dinámica entre las variables a nivel nacional o para una región específica del país: DIAGNOST1 OCURRENCIAS descripcion 614 J00 268 RINOFARINGITIS AGUDA (RESFRIADO COMUN) 45
  46. 46. 615 Z71 312 PERSONAS QUE SOLICITAN SERVICIOS DE SALUD PARA... 616 Z00 376 EXAMEN GENERAL E INVESTIGACION DE PERSONAS SIN... 617 Z10 405 CONTROL GENERAL DE SALUD DE RUTINA DE SUBPOBLA... 618 000 1636 NINGUNO Finalmente se puede calcular de forma fácil una matriz de covarianzas con la correlaciones entre todas las posibles combinaciones de variables y posteriormente guardarlas en un archivo en disco, De este conjunto de datos resulta una matriz de 159 columnas por 159 columnas: import pandas as pd siniestros = pd.read_csv('archivos­texto/Salud2012.csv') siniestros.corr().to_csv('corr_salud.csv') Al abrir el archivo de texto exportado en una herramienta de hoja de cálculo se puede realizar una exploración de forma visual y con distintos formatos de número sobre las correlaciones calculadas: 46
  47. 47. Fig. 17 - Extracto del archivo de texto generado con las correlaciones Como paso posterior se puede analizar la relación entre variables para las cuales se encuentre una correlación significativa en sentido positivo o negativo. 9. Procesamiento de grandes volúmenes de datos En años recientes el estudio de herramientas y algoritmos para el manejo de grandes volúmenes de datos conocido como Big data ha recibido especial importancia lo cual se ha traducido también en un gran interés de parte de la comunidad de código abierto. Asimismo los costos actuales de hardware, la popularización del cómputo en nube y la infraestrucura como servicio han permitido que la aplicación de algoritmos y aplicaciones propuestas para esto sean factibles en diversas industrias de forma costeable y autogestionable. De especial interés para este trabajo son los proyectos de código abierto relacionados con la recolección, almacenamiento y procesamiento de grandes volúmenes de datos. Al evaluar la adopción de estas herramientas para un dominio específico es necesario determinar el tipo de datos con los que se cuetna y el tipo de análisis o aplicación que se quiere llevar a cabo. Especialmente se debe conocer si lo que se busca es optimizar la latencia o la tasa de transferencia (comúnmente conocido como throughput en inglés) ya que el algoritmo y herramienta aplicados depende en gran medida de esto. El primer término (latencia) se define como el tiempo requerido para procesar un registro, esto es medido en unidades de tiempo (horas, minutos, segundos, etc). Por su parte la tasa de transferencia o throughput hace referencia al número de registros procesados por unidad de tiempo. En el caso de las aseguradoras se pueden indentificar casos de uso en los cuales se busca el procesamiento en tiempo real (optimización de latencia) como por ejemplo para fines comerciales o de 47
  48. 48. mercadotecnia y detección de fraudes. Como caso hipotético para un cliente potencial que desea contratar una póliza o una aseguradora y para hacer esto se desea evaluar si autoriza un pago por siniestro ocurrido y reclamado, se requiere que la respuesta se obtenga en el menor tiempo de respuesta posible considerando la mayor historia y variables con las que se cuenten. Para este trabajo se desarrolla una aplicación que optimiza la tasa de transferencia o throughput, concretamente se propone la generación de la información pública requerida para el reporte de solvencia con base en los archivos entregados a nivel póliza, por lo que en este caso es deseable poder procesar el mayor número de registros posibles por unidad de tiempo. Como se expuso anteriormente, en el caso del marco regulatorio bajo el nuevo esquema de Solvencia II se contempla en esta etapa inicial el uso extensivo de archivo de texto plano los cuales requieren una rigurosa validación por medio de reglas de negocio especificadas por la CNSF. Si bien este mecanismo de serialización de datos no cuenta con límite en cuanto al número de registros o tamaño de almacenamiento (el cual es dictado por el mecanismo de almacenamiento escogido), cuenta con la desventaja que su procesamiento no puede ser realizado directamente sobre este formato con las herramientas actualmente uilizadas. La aplicación propuesta a continuación consiste en el uso del modelo de programación MapReduce, el cual inicialmente surgió de las necesidades de análisis y procesamiento al interior de Google y posteriormente fue propuesto formalmente en un trabajo publicado. Hadoop es la herramienta en la cual se desarrolla la aplicación práctica en esta sección, la cual permite trabajar con datos de entrada basados en archivos de texto semiestructurados lo cual se adecua a las necesidades del sector ya que con esto se puede lograr la agregación de información requerida para el RSCF con base en lo 48
  49. 49. reportado a nivel póliza. Con esto se logra consistencia y confiabilidad en la información reportada así como una disminución de esfuerzos y recursos requeridos para cumplir con el marco regulatorio. A continuación se introduce el modelo MapReduce y el proyecto Hadoop, posteriormente se desarrolla la generación de deudores por prima con base en un universo de pólizas. 9.1 MapReduce El modelo de programación MapReduce surgido al interior de Google tiene como objetivo principal permitir el procesamiento y generación de grandes conjuntos de datos. Su definición inicial también contempla la partición de los datos de entrada así como su distribución y la existencia de mecanismos de tolerancia a fallos. Asimismo la investigación inicial y las implementaciones actuales hacen énfasis en la facilidad que debe existir para adicionar nodos a la red de cómputo por medio de máquinas genéricas sin la necesidad que cumplan con ciertas características específicas o configuraciones avanzadas. Este modelo se basa en la definición de dos funciones conocidas como map y reduce. La primera función (map) toma una tupla (llave/valor) como entrada y produce un conjunto intermedio de tuplas (llaves/valores). El trabajo de una librería o herramienta MapReduce es entre otros agrupar todos los valores intermedios asociados con la misma llave I y hacerlos llegar a la función reduce. Esta función también es definida por el usuario y toma como entrada una llave intermedia I así como un conjunto de valores asociados con esa llave. Luego agrupa o une todos estos valores para formar un conjunto de valores generalmente más pequeño, típicamente cero o un solo valor de salida se produce por cada llamado a una función reduce. Los tipos de dato asociados con las funciones map y reduce definidas por el usuario pueden ser representados de la siguiente manera: 49
  50. 50. map (k1, v1) → lista (k2, v2) reduce (k2, lista (v2) ) → lista (v2) Dicho de otra forma, en esencia la función map realiza filtrado y ordenamiento (por ejemplo ordenar un universo de pólizas en diversos ramos) mientras que la función reduce realiza una operación de recopilación (por ejemplo realizar el conteo de las pólizas por cada ramo, arrojando las frecuencias para cada uno). Si bien este paradigma no es aplicable a cualquier tipo de problema, existen un gran número de aplicaciones reales en diversos dominios donde las tareas se pueden expresar haciendo uso de este modelo. Los programas implementados con este modelo cuentan con la ventaja que pueden ser paralelizados y ejecutados en un gran número de nodos de cómputo de forma automática lo cual abstrae esta tarea del programador (Dean y Ghemawat, 2008). Una característica muy importante de este modelo de programación es que los llamados a la función map son distribuidos a través de múltiples nodos o máquinas particionando de forma automática. 50
  51. 51. Fig. 17 – Ejecución de un proceso MapReduce (Dean y Ghemawat) El uso de MapReduce puede ser visto como complemento a las tecnologías de bases de datos relacionales. MapReduce resulta más eficiente para problemas en los que se tiene que analizar el universo de datos (un conjunto completo) y en lotes. Por su parte las tecnologías relacionales funcionan mejor para realizar consultas o actualizaciones de conjuntos de datos que han sido previamente indexados y con volúmenes relativamente menores, por la misma razón MapReduce no es un modelo ideal para realizar escrituras o actualizaciones a los conjuntos de datos. Otra diferencia importante es que la aplicación de estas tecnologías se adecúa tanto para datos estructurados como para datos semi estructurados, los cuales no tienen una estructura interna o esquema predefinidos y éstos puede ser interpretados al momento de procesar ya que las tuplas llave/valor no están definidas de antemano sino que son escogidas al momento de realizar una implementación específica. Adicionalmente se puede mencionar que MapReduce generalmente usa como soporte bases de datos consideradas NoSQL, las cuales fueron presentadas anteriormente en este trabajo. 9.2 Generación de vistas de análisis De acuerdo a la nueva LISF, a partir de la entrada de la nueva regulación las instituciones efectuarán la entrega del Reporte Regulatorio sobre Estados Financieros (RR-7) mediante la integración de 3 productos que agrupan la información dependiendo la periodicidad de entrega: • Entregable RR7EFITR - Estados Financieros Información Trimestral • Entregable RR7EFIA1 - Estados Financieros Información Anual 1 • Entregable RR7EFIA2: - Estados Financieros Información Anual 2 51
  52. 52. Dentro de estos entregables, las Instituciones deberán remitir a la CNSF la información correspondiente a los reportes relacionados con el esquema general de los estados financieros y los relativos a los conceptos que integran a los estados financieros por medio de veinticuatro archivos de información estructurada. Para la información financiera se hace uso de un catálogo que considera cuatro niveles, de tal manera que se pueden establecer relaciones jerárquicas. A continuación se presenta una posible agrupación para distintas vistas de análisis de la información para deudores por prima, con base en registros estructurados de la forma siguiente: nivel_1|nivel_2|nivel_3|nivel_4|moneda|consecutivo|afectacion|referencia_regimen| operacion|cve_ramo|primas_por_cobrar_total|recargos|impuestos|derechos_poliza| comi_x_dev|recargos_dev|derechos_poliza_dev|primas_por_cobrar|; 140|3|0|0|10|7763160|3||2000|040|5935|124|949.6|318|119|165|92|5117|; 140|4|0|0|20|10609020|3||5000|010|2349.6|141|375.936|264|56|138|56|745|; 140|4|0|0|10|6401445|3||5000|034|18641.936|158|2982.70976|69|184|189|96| 17570|; 140|1|0|0|20|7658915|3||5000|010|25549.70976|176|4087.9535616|455|127|178| 74|21557|; 140|2|0|0|30|4905517|3||5000|051|17352.9535616|80|2776.472569856|260|173| 192|3|12557|; 140|3|0|0|10|7189143|3||2000|010|16964.472569856|64|2714.315611177|451| 166|127|53|13327|; 140|4|0|0|20|6042681|3||4000|034|14682.315611177|154|2349.1704977883|122| 83|57|11|11541|; 140|2|0|0|30|14966886|3||3000|040|19328.170497788|74|3092.5072796461|117| 8|157|64|16559|; Fig. 18 - Extracto del archivo de deudores por prima generado Con fines de análisis de estos registros o para reporteo regulatorio podría sumarizarse esta información en una vista de mayor utilidad como la siguiente: 52
  53. 53. Operación / Ramo Moneda nacional Moneda extranjera Moneda indizada Vida Individual Grupo Pensiones derivadas de la Seguridad social Accidentes y Enfermedades Accidentes Personales Gastos Médicos Salud Daños Responsabilidad civil y riesgos Marítimo y Transportes Incendio Fianzas Fidelidad Judiciales De crédito Fig. 19 - Agrupamiento de deudores por prima para análisis Con base en catálogos que contengan la especificación de llaves o identificadores (ver Anexos) se puede construir una implementación del modelo MapReduce para generar esta vista de análisis. A continuación se presenta una implementación en Python usando un archivo no válido ni consistente de acuerdo a las reglas definidas por la CNSF, sin embargo sirve para ejemplificar la aplicación de las funciones map y reduce sobre la especificación anterior: 53
  54. 54. #!/usr/bin/env python # Funcion map import sys for linea in sys.stdin:     linea = linea.strip()     keys = linea.split('|')     nivel_1, nivel_2 = keys[0], keys[1]     if nivel_1 != '140' or nivel_2 not in ['1','2','4']:         print('%st%d' % (­1, 0) )     else:         moneda = keys[4]         ramo = keys[9]         primas_por_cobrar = keys[10]         key = moneda + ramo         value = float(primas_por_cobrar)         print('%st%d' % (key, value) ) El fragmento de código anterior corresponde a la implementación de una posible función map. Primeramente se leen las líneas con lo registros y se separan los elementos de acuerdo al caracter utilizado para delimitar las columnas (“|”). Posteriormente se filtran sólo lo niveles 140 y subniveles 1,2 y 4 los cuales son los únicos requeridos para la generación de esta vista de análisis. En esta misma parte podrían realizarse otro tipo de validaciones comúnmente requeridas en la práctica de seguros como validación de fechas, cotejamiento de vigencia de pólizas y filtrado para pólizas duplicadas. Finalmente se separan lo elementos llave y valor de las tuplas y son usados como respuesta para que puedan ser procesados por la función reduce descrita de la siguiente forma: #!/usr/bin/env python # Funcion reduce import sys moneda_ramo_eval = None monto_eval = 0 54
  55. 55. for linea in sys.stdin:     linea = linea.strip()     moneda_ramo, monto = linea.split('t')     monto = float(monto)     if moneda_ramo_eval == moneda_ramo:         monto_eval += monto     else:         if moneda_ramo_eval:             print '%st%s' % (moneda_ramo_eval, monto_eval)         monto_eval = monto         moneda_ramo_eval = moneda_ramo if moneda_ramo_eval == moneda_ramo:     print '%st%s' % (moneda_ramo_eval, monto_eval) Los parámetros de entrada para esta función son los resultados de aplicar la función map sobre el universo de registros de lo cual resultan tuplas valor/llave. En este caso la función reduce se encarga de obtener los montos requeridos y clasificarlo por tipo de moneda y ramo. 9.3 Implementación en Pig Latin En la sección anterior se presentó una implementaciń haciendo uso de funciones definidas manualmente por el usuario. Sin embargo para la aplicación del modelo de programación MapReduce existen otras alternativas las cuales no requieren un diseño en términos de funciones map y reduce. Un ejemplo es el proyecto Pig mantenido por la organización Apache. Consiste en una plataforma para el análisis de conjuntos de gran volumen de datos haciendo uso de un lenguaje de alto nivel conocido como Pig Latin por medio del cual se definen flujos de datos. Esta plataforma está ligada a una infraestructura de nodos los cuales se encargan de la paralelización de la ejecución. Pig se encarga de compilar el código y traducirlo en una secuencia de programas MapReduce haciendo uso de Hadoop u otras implementaciones existentes como Spark. 55
  56. 56. Los flujos de datos definidos también se pueden ejecutar en modo local lo cual permite trabajar con un subconjunto del universo de datos previo a la ejecución en paralelo. En el caso del sector asegurador esto permite que los analistas lleven a cabo el desarrollo y pruebas en una computadora de escritorio previo a su ejecución distribuída la cual es demandante en términos recursos de ancho de banda y almacenamiento. Esta herramienta permite también una forma más natural y sencilla de relacionar conjuntos de datos usando operadores familiares para usuarios con experencia previa en lenguajes de manipulación de datos. Una posible implementación de la aplicación de la sección anterior, la cual toma información transaccional y la agrupa para fines de análisis y reporteo, es la siguiente: deudores = LOAD 'deudores.txt' using PigStorage('|') AS (nivel_1:int, nivel_2:int, nivel_3:int, nivel_4:int, moneda:int, consecutivo:int, afectacion:int, referencia_regimen:chararray,  operacion:int, cve_ramo:chararray, primas_por_cobrar_total:float, recargos:float, impuestos:float,  derechos_poliza:float, comi_x_dev:float, recargos_dev:float, derechos_poliza_dev:float,  primas_por_cobrar:float); deudores = FILTER deudores BY nivel_1 == 140 AND (nivel_2 == 1 OR nivel_2 == 2 OR nivel_2 == 4); grupos_deudores = GROUP deudores BY (cve_ramo, moneda); totales_ramo_moneda = FOREACH grupos_deudores GENERATE group,  SUM(deudores.primas_por_cobrar_total); DUMP totales_ramo_moneda; En la primera parte del fragmento anterior se asigna un tipo de datos a las columnas para conformar el esquema de datos sobre el cual se va a trabajar, para esto se realiza la lectura directamente desde un archivo de texto en modo local6 . Luego se filtran los niveles y subniveles deseados para esta vista de análisis, finalmente se agrupan los 6 Esto se puede realizar en la etapa de desarrollo y pruebas, posteriormente debe ser ejecutado en una red de nodos 56
  57. 57. montos por tipo de moneda y ramo. Se puede notar que existen diversos comandos y sentencias que resultan familiares para usuarios de SQL. 57
  58. 58. 10. Conclusiones En este trabajo se mostraron diversas aplicaciones en la industria aseguradora de México que pueden ayudar a cumplir con los nuevos requerimientos derivados de Solvencia II usando herramientas de código abierto las cuales diminuyen el costo total de propiedad en herramientas tecnológicas y se adaptan a su arquitectura empresarial actual. Se concluye que el lenguaje de programación propuesto en la mayoría de los casos desarrollados (Python) se adecua a las necesidades del sector, presentando una baja barrera de entrada a los analistas y actuarios que actualmente llevan a cabo estas tareas. Primeramente se realizó el cálculo de la PNN para un conjunto de pólizas haciendo uso de tablas de mortalidad. Luego se desarrolló este mismo cálculo por medio de transformaciones vectoriales. Luego se desarrollo un cálculo SONR que se adecúa a diversos escenarios de generación de números aleatorios haciendo uso de distintas distribucione por medio de una librería para análisis de datos (Pandas). En los dos casos anteriores se presenta cómo las herramientas utilizadas van de la mano con los mecanismos de persistencia de datos actualmente utilizado en la práctica y para fines de reporteo regulatorio. Posteriormente se desarrolló un análsis exploratorio de datos del ramo Salud que permiten comprender la forma en que se relacionan las distintas variables así como estadísticas generales. En la parte final se mostró una posible forma de implementar el modelo de cómputo map reduce para la generación de vistas de análisis con base en un conjunto de datos a nivel transaccional. 58
  59. 59. 11. Bibliografía • About NumPy. (2014, noviembre 1). Consultado el 1 de diciembre de 2014: http://docs.scipy.org/doc/numpy-1.9.1/about.html. • Aguilera, M. (2013, noviembre 1). El proceso de implementación de la nueva legislación en materia de seguros y finazas en México. Consultado el 1 de julio de 2014: http://www.cnsf.gob.mx/Eventos/Seminarios/1.1%20MAguilera_Seminario %20CNSF_14.11.2013_print.pdf • Athey, S., & Ellison, G. (2014). Dynamics of Open Source Movements. Journal of Economics & Management Strategy, 294-316. • Casadesus-Masanell, R., & Llanes, G. (2015). Investment Incentives in Open- Source and Proprietary Two-Sided Platforms. Journal of Economics & Management Strategy, 306-324. • Circular Única de Seguros y Fianzas. (2014, diciembre 19). Consultada el 1 de junio de 2014. • Couchbase NoSQL Whitepaper - Why NoSQL? (n.d.). Consultado el 1 de febrero de 2015. • Dean, J., & Ghemawat, S. (2008). MapReduce. Communications of the ACM Commun. ACM, 107-107. • Edlich, S., Friedland, A., Hampe, J., Brauer, B., & Brückner, M. (n.d.). NoSQL. Einstieg in Die Welt Nichtrelationaler Web 2.0 Datenbanken NoSQL. • Información detallada del sector asegurador. (2014). Consultado el 8 de julio de 2014: http://www.cnsf.gob.mx/EntidadesSupervisadas/InstitucionesSociedadesMutualistas/Pag inas/DetalladaSeguros.aspx. 59
  60. 60. • Gartner Survey Reveals More than Half of Respondents Have Adopted Open- Source Software Solutions as Part of IT Strategy. (2011, febrero 1). Consultado el 1 de julio de 2014. • Harris, T., & Easton, A. (2014). Actuarial aspects of individual life insurance and annuity contracts (3.rd ed.). Winsted, Conn: ACTEX Publications. • Jensen, M., & Meckling, W. (1976). Theory of the Firm: Managerial Behavior, Agency Costs and Ownership Structure. Journal of Financial Economics, 3(4). • Kaas, R. (2009). Modern actuarial risk theory using R (2da ed.). Berlin: Springer- Verlag. • Lerner, J., & Tirole, J. (2005). The Economics of Technology Sharing: Open Source and Beyond. • Lutz, M., & Ascher, D. (1999). Learning Python. Beijing: O'Reilly. • Pandas: Powerful Python data analysis toolkit. (2015, junio 13). Consultado el 20 de , de http://pandas.pydata.org/pandas-docs/stable/. • Perspectivas 2015: México Sector Asegurador. (2015). Consultado el 1 de mayo de 2015. • Raghunathan, S., Prasad, A., Mishra, B., & Chang, H. (2005). Open Source Versus Closed Source: Software Quality in Monopoly and Competitive Markets. IEEE Transactions on Systems, Man, and Cybernetics - Part A: Systems and Humans IEEE Trans. Syst., Man, Cybern. A, 35(6), 903-918. • Sheppard, K. (2014, August 1). Introduction to Python for Econometrics, Statistics and Numerical Analysis: Second Edition. Consutado el 21 de agosto de 2015, de http://www.kevinsheppard.com/images/0/09/Python_introduction.pdf • Stajano, F. (1998). A Gentle Introduction to Relational and Object Oriented Databases. ORL Technical Report. 60
  61. 61. • Vargas Cruz, K. (2014). Cálculo de la edad máxima estimada de la tabla de mortalidad mexicana CNSF 2000-I, su importancia y sus aplicaciones. Consultado el 10 de febrero de 2015, de http://www.cnsf.gob.mx/Eventos/Premios_2014/Segundo Lugar Seguros LEUCE 2014.pdf. • Weindorfer, B. (2012, octubre 1). A practical guide to the use of the chain-ladder method for determining technical provisions for outstanding reported claims in non-life insurance. Working Paper Series by the University of Applied Sciences Bfi Vienna • White, T. (2010). Hadoop the definitive guide. (2da ed.). Sebastopol: O'Reilly Media. 61
  62. 62. 12. Anexos 12.1 Script para generación de archivo de texto plano con información de pólizas para el cálculo de PNNx <?php define("NUM_REGISTROS", 10000); $plazos = array(1, 5, 10, 15, 20); $edades = range(12, 65); $polizas = array(); file_put_contents("polizas.csv", "num_poliza,plazo,edad,suma_asegurada" . PHP_EOL); foreach (range(1, NUM_REGISTROS) as $poliza) { $num_poliza = $poliza; $plazo = $plazos[array_rand($plazos)); $edad = $edades[array_rand($edades)); $suma_asegurada = rand(10000, 70000); $poliza = "$num_poliza,$plazo,$edad,$suma_asegurada" . PHP_EOL; file_put_contents("polizas.csv", $poliza, FILE_APPEND); print $poliza; } ?> 12.2 Descriptores de la base de datos de Salud 2012 Nombre Descripción edad Edad sexo Sexo gpo_fam Grupo Familiar lug_reside Lugar de Residencia tip_seguro Tipo de Seguro diagnost1 Diagnostico 1 cnt Contador prima_emi Prima Emitida dias_es_h1 Días de Estancia Hospitalaria dias_es_h2 Días de Estancia Hospitalaria 2 62
  63. 63. dias_es_h3 Días de Estancia Hospitalaria 3 num_ot_eh Número de Otros Eventos Hospitalarios nc_pri_d1 Número de Consultas Primer Diagnóstico 1 nc_pri_d2 Número de Consultas Primer Diagnóstico 2 nc_pri_d3 Número de Consultas Primer Diagnóstico 3 nc_pri_d4 Número de Consultas Primer Diagnóstico 4 nc_pri_d5 Número de Consultas Primer Diagnóstico 5 nc_pri_d6 Número de Consultas Primer Diagnóstico 6 nc_pri_d7 Número de Consultas Primer Diagnóstico 7 nc_pri_d8 Número de Consultas Primer Diagnóstico 8 nc_pri_d9 Número de Consultas Primer Diagnóstico 9 nc_pri_d0 Número de Consultas Primer Diagnóstico 10 nc_esp_d1 Número de Consultas de Especialidad Diagnostico 1 nc_esp_d2 Número de Consultas de Especialidad Diagnostico 2 nc_esp_d3 Número de Consultas de Especialidad Diagnostico 3 nc_esp_d4 Número de Consultas de Especialidad Diagnostico 4 nc_esp_d5 Número de Consultas de Especialidad Diagnostico 5 nc_esp_d6 Número de Consultas de Especialidad Diagnostico 6 nc_esp_d7 Número de Consultas de Especialidad Diagnostico 7 nc_esp_d8 Número de Consultas de Especialidad Diagnostico 8 nc_esp_d9 Número de Consultas de Especialidad Diagnostico 9 nc_esp_d0 Número de Consultas de Especialidad Diagnostico 10 nex_lab_d1 Número de Exámenes de Laboratorio Diagnóstico 1 nex_lab_d2 Número de Exámenes de Laboratorio Diagnóstico 2 nex_lab_d3 Número de Exámenes de Laboratorio Diagnóstico 3 nex_lab_d4 Número de Exámenes de Laboratorio Diagnóstico 4 nex_lab_d5 Número de Exámenes de Laboratorio Diagnóstico 5 nex_lab_d6 Número de Exámenes de Laboratorio Diagnóstico 6 63
  64. 64. nex_lab_d7 Número de Exámenes de Laboratorio Diagnóstico 7 nex_lab_d8 Número de Exámenes de Laboratorio Diagnóstico 8 nex_lab_d9 Número de Exámenes de Laboratorio Diagnóstico 9 nex_lab_d0 Número de Exámenes de Laboratorio Diagnóstico 10 nex_img_d1 Número de Exámenes de Imagenología Diagnóstico 1 nex_img_d2 Número de Exámenes de Imagenología Diagnóstico 2 nex_img_d3 Número de Exámenes de Imagenología Diagnóstico 3 nex_img_d4 Número de Exámenes de Imagenología Diagnóstico 4 nex_img_d5 Número de Exámenes de Imagenología Diagnóstico 5 nex_img_d6 Número de Exámenes de Imagenología Diagnóstico 6 nex_img_d7 Número de Exámenes de Imagenología Diagnóstico 7 nex_img_d8 Número de Exámenes de Imagenología Diagnóstico 8 nex_img_d9 Número de Exámenes de Imagenología Diagnóstico 9 nex_img_d0 Número de Exámenes de Imagenología Diagnóstico 10 nmed_d1 Número de Medicamentos Diagnóstico 1 nmed_d2 Número de Medicamentos Diagnóstico 2 nmed_d3 Número de Medicamentos Diagnóstico 3 nmed_d4 Número de Medicamentos Diagnóstico 4 nmed_d5 Número de Medicamentos Diagnóstico 5 nmed_d6 Número de Medicamentos Diagnóstico 6 nmed_d7 Número de Medicamentos Diagnóstico 7 nmed_d8 Número de Medicamentos Diagnóstico 8 nmed_d9 Número de Medicamentos Diagnóstico 9 nmed_d0 Número de Medicamentos Diagnóstico 10 npri_con_o Número de Consultas de Primer Contacto Otros Diagnósticos ncon_esp_o Número de Consultas Externas de Primer Contacto Otros Diagnósticos nex_lab_ot Número de Exámenes de Laboratorio Clínico Otros Diagnósticos nex_img_ot Número de Exámenes de Imagenología Otros Diagnósticos 64
  65. 65. nmedic_ot Número de Medicamentos Otros Diagnósticos ncon_pre Número de Consultas Externas Prenatales ncon_pue Número de Consultas Externas Puérperas nsem_gesab Número de Gestación Aborto npla_fam Número de Consultas Planificación Familiar con_ni_san Número de Consultas de Niño Sano n_otcons_p Número de Otras Consultas Externas de Prevención nex_lab_p Número de Exámenes de Laboratorio Clínico Prevención nex_img_p Número de Exámenes de Imagenología Prevención n_apre_sb Número de Acciones Preventivas de Salud Bucal n_acur_sb Número de Acciones Curativas de Salud Bucal m_hos_1 Monto del Evento Hospitalario 1 m_hm_1 Monto de Honorarios Médicos Evento Hospitalario 1 m_hos_2 Monto del Evento Hospitalario 2 m_hm_2 Monto de Honorarios Médicos Evento Hospitalario 2 m_hos_3 Monto del Evento Hospitalario 3 m_hm_3 Monto de Honorarios Médicos Evento Hospitalario 3 m_hos_ot Monto de Hospitalización de Otros Eventos Hospitalarios m_hm_ot Monto de Honorarios Médicos Otros Eventos Hospitalarios mc_pri_d1 Monto de Consultas Externas de Primer Contacto Diagnóstico 1 mc_pri_d2 Monto de Consultas Externas de Primer Contacto Diagnóstico 2 mc_pri_d3 Monto de Consultas Externas de Primer Contacto Diagnóstico 3 mc_pri_d4 Monto de Consultas Externas de Primer Contacto Diagnóstico 4 mc_pri_d5 Monto de Consultas Externas de Primer Contacto Diagnóstico 5 mc_pri_d6 Monto de Consultas Externas de Primer Contacto Diagnóstico 6 mc_pri_d7 Monto de Consultas Externas de Primer Contacto Diagnóstico 7 mc_pri_d8 Monto de Consultas Externas de Primer Contacto Diagnóstico 8 mc_pri_d9 Monto de Consultas Externas de Primer Contacto Diagnóstico 9 65
  66. 66. mc_pri_d0 Monto de Consultas Externas de Primer Contacto Diagnóstico 10 mc_esp_d1 Monto de Consultas Externas de Especialidad Diagnóstico 1 mc_esp_d2 Monto de Consultas Externas de Especialidad Diagnóstico 2 mc_esp_d3 Monto de Consultas Externas de Especialidad Diagnóstico 3 mc_esp_d4 Monto de Consultas Externas de Especialidad Diagnóstico 4 mc_esp_d5 Monto de Consultas Externas de Especialidad Diagnóstico 5 mc_esp_d6 Monto de Consultas Externas de Especialidad Diagnóstico 6 mc_esp_d7 Monto de Consultas Externas de Especialidad Diagnóstico 7 mc_esp_d8 Monto de Consultas Externas de Especialidad Diagnóstico 8 mc_esp_d9 Monto de Consultas Externas de Especialidad Diagnóstico 9 mc_esp_d0 Monto de Consultas Externas de Especialidad Diagnóstico 10 mex_lab_d1 Monto de Exámenes de Laboratorio Diagnóstico 1 mex_lab_d2 Monto de Exámenes de Laboratorio Diagnóstico 2 mex_lab_d3 Monto de Exámenes de Laboratorio Diagnóstico 3 mex_lab_d4 Monto de Exámenes de Laboratorio Diagnóstico 4 mex_lab_d5 Monto de Exámenes de Laboratorio Diagnóstico 5 mex_lab_d6 Monto de Exámenes de Laboratorio Diagnóstico 6 mex_lab_d7 Monto de Exámenes de Laboratorio Diagnóstico 7 mex_lab_d8 Monto de Exámenes de Laboratorio Diagnóstico 8 mex_lab_d9 Monto de Exámenes de Laboratorio Diagnóstico 9 mex_lab_d0 Monto de Exámenes de Laboratorio Diagnóstico 10 mex_img_d1 Monto de Exámenes de Imagenología y Gabinete Diagnóstico 1 mex_img_d2 Monto de Exámenes de Imagenología y Gabinete Diagnóstico 2 mex_img_d3 Monto de Exámenes de Imagenología y Gabinete Diagnóstico 3 mex_img_d4 Monto de Exámenes de Imagenología y Gabinete Diagnóstico 4 mex_img_d5 Monto de Exámenes de Imagenología y Gabinete Diagnóstico 5 mex_img_d6 Monto de Exámenes de Imagenología y Gabinete Diagnóstico 6 mex_img_d7 Monto de Exámenes de Imagenología y Gabinete Diagnóstico 7 66
  67. 67. mex_img_d8 Monto de Exámenes de Imagenología y Gabinete Diagnóstico 8 mex_img_d9 Monto de Exámenes de Imagenología y Gabinete Diagnóstico 9 mex_img_d0 Monto de Exámenes de Imagenología y Gabinete Diagnóstico 10 mmed_d1 Monto de Medicamentos Diagnóstico 1 mmed_d2 Monto de Medicamentos Diagnóstico 2 mmed_d3 Monto de Medicamentos Diagnóstico 3 mmed_d4 Monto de Medicamentos Diagnóstico 4 mmed_d5 Monto de Medicamentos Diagnóstico 5 mmed_d6 Monto de Medicamentos Diagnóstico 6 mmed_d7 Monto de Medicamentos Diagnóstico 7 mmed_d8 Monto de Medicamentos Diagnóstico 8 mmed_d9 Monto de Medicamentos Diagnóstico 9 mmed_d0 Monto de Medicamentos Diagnóstico 10 m_ot_co_d1 Monto por Otros Conceptos Diagnóstico 1 m_ot_co_d2 Monto por Otros Conceptos Diagnóstico 2 m_ot_co_d3 Monto por Otros Conceptos Diagnóstico 3 m_ot_co_d4 Monto por Otros Conceptos Diagnóstico 4 m_ot_co_d5 Monto por Otros Conceptos Diagnóstico 5 m_ot_co_d6 Monto por Otros Conceptos Diagnóstico 6 m_ot_co_d7 Monto por Otros Conceptos Diagnóstico 7 m_ot_co_d8 Monto por Otros Conceptos Diagnóstico 8 m_ot_co_d9 Monto por Otros Conceptos Diagnóstico 9 m_ot_co_d0 Monto por Otros Conceptos Diagnóstico 10 m_pcont_ot Monto de Consultas Externas de Primer Contacto Otros Diagnósticos m_cesp_ot Monto de Consultas Externas de Especialidad Otros Diagnósticos mex_lab_ot Monto de Exámenes de Laboratorio Clínico Otros Diagnósticos mex_img_ot Monto de Exámenes de Imagenología y Gabinete Otros Diagnósticos mmedic_ot Monto de Medicamentos Otros Diagnósticos 67

×