Archivo de la categoría: R

Obteniendo los parámetros de mi modelo GAM

Vimos como los modelos GAM iban más allá del GLM porque en el momento de obtener los parámetros asociados al modelo de un factor nos proponían, en vez de una función lineal una función de suavizado no paramétrica para aquellos factores susceptibles de transformar en variables numéricas ordinales con un sentido determinado. Se trabajó con un modelo de riesgo con una sola variable como era la edad y al sumarizar el modelo no era posible obtener los parámetros en la salida. En último término nuestra intención con este tipo de modelos es obtener esos parámetros para transformarlos en relatividades. Qué sentido tiene obtener un buen modelo para Negocio si su resultado no se puede expresar en términos de incrementos o descuentos, en términos de relatividades.

La entrada del blog que ahora os propongo nos permite extraer los parámetros de cualquier modelo GLM o GAM a partir de la función predict y una de las opciones más olvidadas por todos nosotros:

predict(modelo, newdata = datos,  type = "terms")

con type = “terms” lo que obtenemos en el momento de realizar la predicción son los parámetros del modelo que aplicamos, no es el resultado de la predicción.

Obteniendo las relatividades de nuestro modelo GAM

Partimos del ejemplo que estamos manejando en la serie de entradas:

library(dplyr)

varib <- c(edad = 2L, sexo = 1L, zona = 1L, clase_moto = 1L, antveh = 2L,
           bonus = 1L, exposicion = 8L, nsin = 4L, impsin = 8L)

varib.classes <- c("integer", rep("factor", 3), "integer",
                   "factor", "numeric", rep("integer", 2))

con <- url("https://staff.math.su.se/esbj/GLMbook/mccase.txt")
moto <- read.fwf(con, widths = varib, header = FALSE,
                 col.names = names(varib),
                 colClasses = varib.classes,
                 na.strings = NULL, comment.char = "")


library(mgcv)

moto$edad_numero <- as.numeric(moto$edad)

gam.1 <- gam(nsin ~ s(edad_numero,bs="cr",k=3) + zona, data=filter(moto,exposicion>0), 
             offset = log(exposicion), family = poisson(link='log'))
summary(gam.1)

Ejecutad este código y obtendréis un modelo GAM con la zona por la que circula el riesgo y una función de suavizado de la edad del asegurado. A la hora de sumarizar el modelo para la edad, la variable suavizada, no vemos parámetros solo una función, si queremos obtener parámetros solo aparece la zona, ¿cómo puedo obtener las relatividades que me arroja este modelo? Empleando predict como se indicó con anterioridad:

terminos <- data.frame(exp(predict(gam.1, newdata = moto, type = "terms")))
names(terminos) <- c("rela_zona","rela_edad") 
terminos <- cbind.data.frame(terminos,select(moto,zona,edad))

Se crea el data.frame terminos que tiene el exponencial del parámetro asociado a ese registro para los factores participantes en el modelo. Cabe señalar que predict no respeta el orden de las variables en el modelo, primero pone las variables que no están suavizadas y después las suavizadas. Después de obtener los parámetros registro a registro lo que hacemos es añadir al data frame los factores de los que deseamos obtener las relatividades y como os podéis imaginar la tabla de relatividades finalmente es el resultado de seleccionar los distintos elementos:

rela_zona <- distinct(select(terminos,zona,rela_zona))
rela_edad <- distinct(select(terminos,edad,rela_edad))

Ya sabéis, no subestiméis a predict...
 

Modelos GAM con R. Dejando satisfechos a los equipos de negocio

Los modelos GAM (Generalized Additive Model) son el conjuntos de modelos que tenemos los estadísticos, actuarios, data scientist o como nos denominen en el momento que leas esto para dejar a nuestros equipos de negocio contentos con los resultados de nuestro modelo GLM. No voy a entrar en los aspectos teóricos de este tipo de modelos, hay documentación como esta que os puede ayudar. Por qué se quedan contentos los equipos de negocio, porque nos ayudan a dar sentido a los modelos. Retomemos un ejemplo que vimos en otra entrada del blog: https://analisisydecision.es/los-parametros-del-modelo-glm-como-relatividades-como-recargos-o-descuentos/ en esta entrada presentamos como el resultado de un modelo GLM se transforma en una relatividad, en un mecanismo para ofrecer recargos y descuentos.

Si desarrollamos un modelo GLM en último término podríamos enseñar este gráfico al responsable comercial:

Parece evidente que a mayor edad mayor proporción de siniestros, además, a partir de los 40 – 45 puede considerarse que las relatividades no varían. Se aprecian tendencias, pero no tiene sentido de negocio aplicar directamente los resultados de las estimaciones, no podemos aplicar esas relatividades obtenidas, es necesario realizar un suavizado y seguramente nos veríamos tentados, una vez hecho el modelo, de aplicar unos suavizados posteriores a la obtención de los parámetros. Podríamos hacer:

#g2 es el gráfico anterior obtenido en https://analisisydecision.es/los-parametros-del-modelo-glm-como-relatividades-como-recargos-o-descuentos/

spline_edad_factor < - smooth.spline(relatividades$rela,w=relatividades$exp,spar=0.65)
g2 + geom_line(aes(y=spline_edad_factor$y *5000), group=1, color="green",size=1.5)

Con smoot.spline hacemos una función de suavizado para nuestras relatividades, el nivel del suavizado lo controlamos con el parámetro spar que va desde 0 (sin suavizado) a 1 (función lineal). El caso es que el resultado de ese suavizado ya podría tener un mayor sentido de negocio y tendríamos más contentos a nuestro equipo comercial, pero... lo estamos haciendo a posteriori, eso no es una estimación, es echar balones fuera. Bien, qué os parece si tenemos un mecanismo para hacer una función previa a la estimación, pues este mecanismo se denomina modelo GAM y la librería de R que vamos a emplear para aproximarnos a ellos es mgcv. Vamos a replicar el modelo más básico con la edad del conductor. Seguir leyendo Modelos GAM con R. Dejando satisfechos a los equipos de negocio

Los parámetros del modelo GLM como relatividades, como recargos o descuentos

Los modelos GLM son muy empleados en el ámbito actuarial para la obtención de modelos de riesgo, estos modelos de riesgo son los elementos fundamentales en el cálculo de tarifas y qué es una tarifa, imaginad el precio del seguro de vuestra vivienda, bueno pues es un cálculo en el que partiendo de un precio base se van añadiendo recargos y descuentos en función del tipo de riesgo que se quiera asegurar (recargos y descuentos en función de los metros cuadrados, de la ubicación de la vivienda de las calidades de construcción….). Esta es una visión muy simplista porque al final se tienen múltiples garantías y es necesaria la combinación de garantías, pero se puede entender de ese modo, un precio base al que recargamos o descontamos precio. Estos recargos y descuentos se denominan frecuentemente relatividades y hoy quiero acercaros a la obtención de esas relatividades y como un modelo GLM se transforma en el precio de un seguro.

En la línea habitual del blog vamos a ilustrar con un ejemplo usando unos datos muy conocidos para el trabajo con GLM y modelos de cálculo de tarifas. El primer paso es cargar el conjunto de datos en nuestra sesión de R:

library(dplyr)

varib <- c(edad = 2L, sexo = 1L, zona = 1L, clase_moto = 1L, antveh = 2L,
           bonus = 1L, exposicion = 8L, nsin = 4L, impsin = 8L)

varib.classes <- c("integer", rep("factor", 3), "integer",
                   "factor", "numeric", rep("integer", 2))

con <- url("https://staff.math.su.se/esbj/GLMbook/mccase.txt")
moto <- read.fwf(con, widths = varib, header = FALSE,
                 col.names = names(varib),
                 colClasses = varib.classes,
                 na.strings = NULL, comment.char = "")

Los datos empleados pertenecen a una cartera de motocicletas, disponemos del número de siniestros (variable nsin), el importe de los siniestros (impsin), la exposición al riesgo de ese registro y una serie de factores que creemos pueden influir en la estimación del número de siniestros o del importe de los siniestros como son la edad, la zona, el nivel de bonificación,… Vamos a partir del modelo más sencillo, un modelo de frecuencia siniestral en base a un factor edad. Si realizamos con R un GLM clásico haríamos:

moto$edad_factor <- case_when(
  as.numeric(moto$edad) <=18 ~ 18, as.numeric(moto$edad) >=60 ~ 60,
  TRUE ~ as.numeric(moto$edad))

moto$edad_factor <- as.factor(moto$edad_factor)

glm.1 <- glm(nsin ~ edad_factor+offset(log(exposicion)), data=filter(moto,exposicion>0),
             family=poisson())
summary(glm.1)

Hemos creado un factor edad que va desde los 18 años hasta los 60, realizamos una regresión de poisson para estimar el número de siniestros, como al final lo que deseamos es crear una proporción de siniestros de la forma nsin/exposición (frecuencia siniestral) lo que hacemos es poner el nsin como variable dependiente y la exposición como variable offset, la única variable regresora es la edad en formato factor, con este modelo obtendremos un estimador para cada nivel del factor. Es un modelo aditivo de la forma log(Y) = B0 + Edad18*B1 + Edad19*B2 + … + log(exp) + Error pero si realizamos el exponencial de los parámetros obtenidos con el modelo tendremos E[Y/exp] = B’0 * Edad18*B’1 * Edad19*B`2 * … Es decir, el valor esperado para la frecuencia siniestral es función de unos parámetros que recargan o descuentan esa frecuencia esperada. Esos B’ que son el resultado de exp(B) es lo que denominamos relatividades. Esto es muy utilizado para la realización de modelos de riesgo en el cálculo de tarifas.

Obtención de las relatividades

Reiterando, el exponencial del parámetro obtenido con la formulación del modelo es lo que denominamos relatividad y esa relatividad multiplicada por un término independiente nos daría como resultado la estimación de la proporción de siniestros, la estimación de la frecuencia siniestral para cada nivel del factor. También es relevante estudiar y comprender como R presenta esos parámetros, si hacemos el exponencial de los parámetros del modelo glm.1 que hemos hecho tenemos:

data.frame(exp(glm.1$coefficients))
              exp.glm.1.coefficients.
(Intercept)                0.02986346
edad_factor19              0.48892314
edad_factor20              0.95974062
edad_factor21              0.73651804
….

¿Qué está pasando con la edad 18? Del término independiente pasa directamente a la edad 19 y de ahí hasta la edad 60, una estimación para cada nivel del factor a excepción del nivel 18. Bien, R considera al primer nivel del factor el nivel base, si lo vemos en forma de estimador un factor toma valor 1 si la observación está en ese nivel del factor y toma 0 si no lo está, pues si todos los estimadores presentes en el modelo toman el valor 0 el modelo estima que la proporción de siniestros en la edad 18 es de 0.02986, R no muestra ese estimador porque directamente no es necesario calcularlo, la edad 18 tiene una frecuencia siniestral del 3% Seguir leyendo Los parámetros del modelo GLM como relatividades, como recargos o descuentos

Parámetros en nuestra consulta SQL Server desde R. Truco R

Me han preguntado hoy como parametrizar una consulta de Sql Server desde R y la verdad es que es algo que me parecía muy sencillo y no me había planteado compartirlo. En mi caso suelo emplear la librería RODBC para acceder a Sql Server porque realizo las consultas vía ODBC, por este motivo lo primero debéis tener es configurado el origen de datos ODBC e instalada la librería RODBC en R. Para acceder vía R a los datos de Sql Server lo primero es crear la conexión a la BBDD:

conexion <- odbcConnect("ORIGEN_ODBC")

Ya estamos en disposición de realizar nuestras consultas sobre la BBDD de SQL Server, en R debemos ejecutar siempre:

objeto_r <- sqlQuery(conexion,"")

Con sqlQuery realizamos la consulta tal cual la realizaríamos en Sql Server y obtendremos el objeto en R o directamente puede salirnos en la consola. Recomiendo siempre cerrar las conexiones ODBC, R nos lo irá recordando de todas formas:

odbcCloseAll()

Con odbccloseAll cerramos todas las conexiones ODBC. Y si deseamos añadir parámetros a nuestra consulta desde R sólo tenemos que recordar que en sqlQuery metemos un texto por ello podremos hacer:

fecha <- '2019-08-01' 
conexion <- odbcConnect("ORIGEN_ODBC")
objeto_r <- sqlQuery(conexion,paste0("SELECT * FROM TABLA WHERE FECHA>", fecha ,"AND ESTADO='1'"))
odbcCloseAll()

En ocasiones realizamos consultas más complejas, yo suelo "jugar con frases" y directamente pasar a sqlQuery la frase. Truco sencillo.

Geometría básica con R. Triángulos, circunferencias, estrellas, distancias, ángulos,…

Trabajar con triángulos y R es bien sencillo con el paquete learnGeom. La entrada viene a cuento por una duda en lista de correo de ayuda en R que no pude ayudar a resolver por no disponer de un equipo informático en ese momento. Es un paquete que nos permite visualizar los aspectos básicos de la geometría que todos tenemos olvidada. Un ejemplo de uso sería:

#install.packages("LearnGeom")
library(LearnGeom)

x_min <- 0; x_max <- 100
y_min <- 0; y_max <- 100

CoordinatePlane(x_min, x_max, y_min, y_max)

A <-c(50,50)
B <- c(70,70)
C <- c(70,50)

triangulo <- CreatePolygon(A, B, C)
Draw(triangulo, "grey")
PolygonAngles(triangulo)

 

Fijamos un plano, en este caso de 0 a 100 en ambos ejes y sobre ese plano pintamos un polígono indicando los vértices y como resultado obtenemos un triángulo rectángulo, podemos ver los ángulos que forman los vértices también y hay otras funciones interesantes como distancias entre puntos que nos sirven para recordar a Pitágoras;

DistancePoints(A,B)
sqrt(20^2+20^2)

Llegué a este paquete por lo sencillo que resultaba obtener los ángulos entre los puntos y poderlos graficar:

angle <- Angle(A, B, C, label = TRUE)
angle <- Angle(A, C, B, label = TRUE)
angle <- Angle(B, A, C, label = TRUE)

Trazar circunferencias con dirección es otra de las posibilidades con las que estoy trabajando:

CoordinatePlane(x_min, x_max, y_min, y_max)
Draw(triangulo, "transparent")
direction <- "anticlock"
inicio = 0 
fin = 45
Arc2 <- CreateArcAngles(A, 20, inicio, fin, direction)
Draw(Arc2, "red")

Por algún motivo que desconozco mi cabeza sólo puede trabajar con la dirección contraria a las agujas del reloj, es curioso. Por último, por si alguien tiene que hacer ese tipo de estructuras geométricas podemos trazar estrellas con R fijando el inicio y el ángulo de rotación:

CoordinatePlane(x_min, x_max, y_min, y_max)
Star(A, 180, 10, color= "blue")

Esta función te lleva a otra más interesante (Scissor). Ya sabéis learnGeom un paquete de R para trabajar aspectos básicos (o no tan básicos) de la geometría. Yo esto intentando hacer un proceso que haga la vuelta perfecta para todos los circuitos automovilísticos del mundo con R. Seguramente abandone el proyecto, pero siempre es bueno compartir algún conocimiento adquirido.

Paquete opendataes en rOpenSpain para acceder a los datos de datos.gob.es con R

Por medio de una conversación en Twitter he llegado al paquete opendataes para acceder mediante R a la API de datos.gob.es Este paquete desarrollado inicialmente por Jorge López necesita colaboraciones porque tenemos a nuestro alcance más de 22.000 conjuntos de datos de acceso libre para realizar nuestros propios estudios.

Conocía rOpenSpain por MicroDatoEs y tengo pendiente trabajar con CatastRo pero ya estáis tardando en ejecutar remotes::install_github(“ropenspain/opendataes”) e instalar opendata, además tenemos que colaborar para mejorar las consultas a la API porque se abre un mundo de datos accesible desde R brutal.

Los principales problemas de los españoles. Animaciones con R y gganimate

La realización de gráficos animados con R, gganimate y ggplot2 es algo que quiero empezar a trabajar en mis visualizaciones de datos, una buena forma de llamar la atención sobre nuestros gráficos. Para ilustrar el ejemplo he recogido los datos que publica mensualmente el CIS con las 3 principales preocupaciones de los españoles que podéis encontrar en este enlace, por cierto, este enlace tiene toda la pinta de ser una salida en SAS, no me parece muy apropiado pero no diré nada porque imagino que serán lectores del blog (ya podíais hacer una salida más acorde con los tiempos). El caso es que la primera parte de nuestro trabajo será el “scrapeado” de la web. Scrapear verbo regular de la primera conjugación:

library(XML)
library(dplyr)
library(lubridate)

#Lectura de los datos del CIS
url < - "http://www.cis.es/cis/export/sites/default/-Archivos/Indicadores/documentos_html/TresProblemas.html"
doc = htmlParse(url,  encoding = "UTF-8")
tableNodes = getNodeSet(doc, "//table")

#Leemos la tabla que tiene un formato un tanto peculiar
problemas <- readHTMLTable(tableNodes[[2]], skip.rows=1)
problemas <- problemas %>% filter(!is.na(V1)) 

#Transformamos los puntos en 0, parece que estuviera hecho con SAS
haz.cero.na=function(x){ifelse(x==".",0,as.numeric(as.character(x)))}

problemas < - cbind.data.frame(as.character(problemas$V1),sapply(problemas,haz.cero.na),stringsAsFactors=FALSE)
problemas <- problemas %>% select(-V1)

#El primer elemento de la tabla contiene los nombres que vamos a emplear
nombres < - readHTMLTable(tableNodes[[2]])[1,]
nombres$V1="Problema" 
nombres <- as.vector(t(nombres))

names(problemas) <- nombres

#Hay un registro en la tabla que tiene el número de encuestas, no es necesario
problemas <- filter(problemas,Problema != "(N)")

Cosas interesantes en el código. Hacemos HTMLParse de la web y nos quedamos con las tablas, Seguir leyendo Los principales problemas de los españoles. Animaciones con R y gganimate

Mapa de códigos postales con R. Aunque el mapa es lo de menos

Entrada para facilitar la realización de mapas de códigos postales de España con R. Todo parte del trabajo de Íñigo Flores al que ya mencionamos en otra entrada. Íñigo descargó de Cartociudad y recopiló los objetos shape file para realizar estos gráficos y los subió a su repositorio, están desactualizados pero puede ser suficiente para la realización de mapas de códigos postales. Íñigo subió en formato .zip todos los archivos necesarios provincia a provincia como lo tenía Cartociudad. Podemos clonarnos el repositorio o leer directamente de github, en cualquier caso necesitamos una función en R que nos permita leer archivos comprimidos en formato zip y cuando lea el zip seleccionar que expresamente lea el archivo shp que contiene el spatial data.

Función para la lectura de archivos comprimidos zip con R

library(maptools)

leer.zip <- function(archivozip) {
  zipdir <- tempfile()
  dir.create(zipdir)

  unzip(archivozip, exdir=zipdir)
  
  archivo <- list.files(zipdir)
   
  archivo <- archivo[grepl("shp",archivo)>0]
  archivo <- paste(zipdir, archivo, sep="/")
  readShapeSpatial(archivo)
} 

Esta función leer.zip permite leer archivos zip, guardarlos en un directorio temporal y posteriormente sólo lee aquel archivo extraído que en su nombre contenga el texto “shp”. Función interesante que modificada ligeramente os permitirá descomprimir cualquier archivo y leer el elemento que deseáis, además de un buen ejemplo de uso de unzip. En este punto, como comentamos antes, podemos leer directamente de github con R.

Leer archivo zip de github con R

url <- 'https://github.com/inigoflores/ds-codigos-postales/raw/master/archive/42605-NAVARRA.zip'

tf = tempfile(tmpdir=tempdir(), fileext=".zip")
download.file(url, tf)
navarra <- leer.zip(tf)

Creamos un temporal para descargarnos el zip pero es necesario especificar la extensión. Descargamos de la url correspondiente el archivo con los elementos comprimidos y el objeto navarra será el resultado de la lectura del shapefile con los códigos postales de Navarra. La otra forma es clonar el repositorio y acceder directamente al directorio:

navarra <- leer.zip('C:\\temp\\personales\\wordpress\\ds-codigos-postales-master\\archive\\42605-NAVARRA.zip')

Otro de los motivos de esta entrada es mostraros como podemos realizar mapas de modo rápido con la librería tmap.

Ejemplo de mapa quick & dirty con R

library(tmap)

navarra <- leer.zip('C:\\temp\\personales\\wordpress\\ds-codigos-postales-master\\archive\\42605-NAVARRA.zip')
navarra@data$dato <- rpois(nrow(navarra@data),2)
qtm(shp = navarra, fill = "dato", fill.palette = "Blues")

La función qtm se traduce como -Quick thematic plot- y quick es muy quick. El mejor balance entre rápido y sencillo que hay (bajo mi punto de vista). En el ejemplo se pinta un dato aleatorio pero podéis hacer una left join con vuestros datos (que me conozco a algunos). Y si queremos crear un objeto con cada uno de los elementos que preparó Íñigo podemos hacer.

Lectura de archivos y creación de data frame mediante un bucle que lee otro data frame

trabajo <- 'C:/temp/personales/wordpress/ds-codigos-postales-master/archive/'
provincias <- list.files(trabajo)
provincias <- data.frame(archivo=provincias)
provincias$nombre <- substr(provincias$archivo,regexpr("-",provincias$archivo)+1,length(provincias$archivo))
provincias$nombre <- gsub('.zip','',provincias$nombre)

for (i in 1:nrow(provincias) ){
  instruccion <- paste0(provincias$nombre[i],' <- leer.zip("',trabajo,provincias$archivo[i],'")')
  eval(parse(text=instruccion))
}

Código rudimentario que crea un data frame a partir de los archivos de un directorio de trabajo, los archivos son los .zip que nos clonamos de github y con ellos vamos a crear 52 data frame para cada una de las provincias. El nombre de los archivos es XXXX-provincia.zip por eso tenemos que usar algunas funciones de texto para obtener el nombre de la provincia como regexpr que nos permite encontrar la primera posición en la se encuentra un patrón dentro de un texto, por otro lado gsub nos sirve para sustituir un patrón de texto por otro. Así leemos desde el – y posteriormente tenemos que eliminar el .zip para tener el nombre de cada provincia. Y por último un clásico en mis programas de R herencia de los tiempos en los que trabajaba con macros en SAS, tengo que recorrer ese data frame con los elementos del directorio y el nombre del objeto será una columna del data frame y el archivo a leer otra columna, para evaluar un texto el mítico eval ( parse ( text = nunca me falla, habrá formas más elegantes pero esta son dos líneas. Siempre hay que poner talento en la construcción de la instrucción y acordarse de cerrar paréntesis y demás. Ejecutando eso tendríamos un objeto para cada provincia, si queremos toda España.

Creación de un mapa de España por códigos postales

trabajo <- 'C:/temp/personales/wordpress/ds-codigos-postales-master/archive/'
provincias <- list.files(trabajo)
provincias <- data.frame(archivo=provincias)
provincias$nombre <- substr(provincias$archivo,regexpr("-",provincias$archivo)+1,length(provincias$archivo))
provincias$nombre <- gsub('.zip','',provincias$nombre)

for (i in 1:nrow(provincias) ){
  instruccion <- paste0('borrar <- leer.zip("',trabajo,provincias$archivo[i],'")')
  eval(parse(text=instruccion))
  if (i == 1) {espania <- borrar}
  espania <- rbind(espania,borrar)
  remove(borrar)
}

plot(espania)

Otro bucle con la marca de la casa pero que funciona perfectamente, leemos uno a uno cada zip con las provincias y con rbind podemos unir los objetos spatial para poder pintar el mapa de España y cuidado que esto si genera un objeto de casi 120 MB. Podéis manejar los objetos spatial data y así reducir su tamaño, así como idea por si pongo el código en el repositorio.

El caso es que ya sabéis como hacer un mapa de España de códigos postales con R, incluso si sois avezados podéis guardar el objeto final resultante y utilizarlo con QGIS u otra herramienta que uséis para hacer mapas. Además esta entrada es todo un compendio de malas prácticas en programación con R que funcionan a las mil maravillas, desde leer archivos zip con R, seleccionar el que deseamos a funciones de texto para extraer con condiciones, ejemplo de gráfico de mapa rápido con tmap y un bucle que lee un data frame y genera objetos con él.

Guardar objeto de R como shapefile (shp)

 writeSpatialShape(espania, "C:/temp/personales/wordpress/espania.shp")

Por último podemos guardar el objeto resultante de R para usarlo directamente con QGIS, se generan todos los archivos necesarios, el shp, el dbf y el otro.

Ejecutar un código al iniciar la sesión de R

A raíz de una conversación en Twitter os traigo un pequeño truco de R para aquellos que tenéis funciones predefinidas y que tenéis que cargarlas al iniciar las sesiones de R, es como ejecutar el código nada más abrir R. En mi caso el código que quiero ejecutar son una serie de utilidades que tengo guardadas en C:\carpeta, con source(“C:/carpeta/Utils.R”, encoding=”UTF-8″) R cargaría todo el código R alojado en ese script de R y necesito que se ejecute el script al inicial la sesión de R, no quiero poner esa línea al principio de cada programa. Lo primero que tenemos que hacer es buscar donde tenemos instalado R, una vez hallamos accedido a la correspondiente carpeta vamos a la subcarpeta /etc y tenemos un archivo llamado Rprofile.site lo abrimos con un editor de texto:

# Things you might want to change

# options(papersize="a4")
# options(editor="notepad")
# options(pager="internal")

# set the default help type
# options(help_type="text")
  options(help_type="html")

# set a site library
# .Library.site <- file.path(chartr("\\", "/", R.home()), "site-library")

# set a CRAN mirror
# local({r <- getOption("repos")
#       r["CRAN"] <- "http://my.local.cran"
#       options(repos=r)})

# Give a fortune cookie, but only to interactive sessions
# (This would need the fortunes package to be installed.)
#  if (interactive()) 
#    fortunes::fortune()

source("C:/carpeta/Utils.R", encoding="UTF-8")

Pues en ese archivo ponemos source("C:/carpeta/Utils.R", encoding="UTF-8") y cada vez que abramos nuestro R, desde RStudio por ejemplo, se ejecutará el script con nuestras utilidades.

Inteligencia Arficial frente a un juego de niños. La partícula tonta de Nicolás

Pablo Picasso decía que en aprender a pintar como los pintores del renacimiento tardó unos años pero pintar como los niños le llevó toda la vida y en ocasiones creo que hacemos las cosas difíciles porque nos creemos que hacemos cosas difíciles y entonces llega un niño de nueve años y dice “Papá un punto que primero vaya a la izquierda y luego a la derecha no es tan difícil”.
Os pongo en antecedentes, el pasado 7 de mayo fui al AWS Summit de Madrid porque Sergio Caballero iba a contar uno de los casos de uso. Los de AWS no se deben ni imaginar de las maravillas que ha hecho Sergio en el Ayuntamiento de Alcobendas porque sólo dejaron que hablara 10 minutos, muy torpes ellos, su trabajo es mejor escaparate que el planteado por Mai-Lan Tomsen, un error en el planteamiento de la jornada. El caso es que había una “competición” de vehículos que circulaban por un circuito guiados por complicados algoritmos de inteligencia artificial. Vimos algún “bucanero serio” de alguno de los participantes, ya sabemos reinforcement learning, pero reinforcement reinforcement. Otros participantes más o menos honrosos, en fin, distraído. Viendo la competición me entraron ganas de participar y al llegar a casa me siento a preparar un algoritmo que recorriera el circuito del Jarama de Madrid, no un circuito cualquiera un circuito donde yo he visto ganar carreras a Jorge Martínez Aspar.

Portátil y R, empiezo mi trabajo con imager, busco en la Wikipedia el circuito, lo cargo, genero un data frame, selecciono puntos y comienzo a diseñar mi propia estrategia de reinforcement learning combinadas con técnicas de machine learning, algo como “SVM direccionables” se acerca por detrás mi hijo y me suelta “Papá un punto que primero vaya a la izquierda y luego a la derecha no es tan difícil”. Bueno, pues en 20 minutos sale esto:

De momento no funciona pero no me digáis que no es genial la idea, lo que hace con pocas líneas de código y una consulta en sql. En el repositorio de analisisydecision tenéis el código en R que realiza esta maravilla, he llamado al código partícula tonta y tiene aspectos interesantes en cuanto al uso de la librería imager de R para el tratamiento de imágenes y como transformo una imagen en un data frame de coordenadas y por supuesto la genial idea de Nicolás.

Por cierto, al ver el resultado Nicolás dijo que no sólo derecha e izquierda, también era necesario un arriba y abajo. Tengo abandonado el proyecto, como muchos, pero la anécdota me ayudó en mi trabajo.