Segmentando las Estaciones de Servicio : ¿Dónde están las gasolineras mas económicas?

377731-campano-estacion-de-servicio-banner-01

Posted por @mirallesjm

a 19 de Enero, 2016

Motivación

La mayoría de las veces que pasamos por una estación de servicio, no podemos evitar girar la cabeza para revisar el panel de precios de la gasolina e intentar realizar una comparativa mental del resto de gasolineras conocidas. Establecer esta comparativa de precios resulta difícil principalmente porque no tenemos un único valor a comparar (Precio gasolina 95/98, gasóleo A/B, etc.) y dichos precios se mueven con un margen muy pequeño.

Nuestro objetivo pasa por visualizar esta información mediante un mapa que nos permita ver una primera distribución de precios y posteriormente aplicar técnicas de Machine Learning que nos permitan segmentar las estaciones de servicio vía precios y poder determinar grupos homogéneos de clasificación.

Análisis

Para realizar el estudio, disponemos de una base de datos de todas las estaciones de servicio de España (http://www.geoportalgasolineras.es/#/Descargas).

Lo primero que hacemos es descargarnos la información y leerla:

# Lectura del Dataset

Fuel <- read.table(“Gasolineras.txt”, header = TRUE, sep = “\t”, quote = “\””, dec = “,”,
na.strings = “NA”, fill = TRUE, comment.char = “”,stringsAsFactors = T)

# Dimension
dim(Fuel)

El dataset esta formado por 9.951 estaciones de servicio y 25 variables.

Observamos la estructura del dataset

# Recodificamos el nombre de los campos “Precio”

FuelPrecio <- select(Fuel, contains(“Precio”))

names(FuelPrecio) <- c(“PGasolina95″,”PGasoleoA”,”PGasoleoB”,”PBioEtanol”,”PNuevoGasoleoA”,

“PBioDiesel”,”PGasolina98″,”PGasNaturalComp”,”PGasNaturalLic”,

“PGasLicuPetro”)

# Estructura del dataset

str(FuelPrecio)

‘data.frame’: 9951 obs. of 10 variables:
$ PGasolina95 : num NA 1.17 1.23 1.16 1.22 …
$ PGasoleoA : num 1.06 1.05 1.12 1.03 1.12 …
$ PGasoleoB : num 0.726 NA NA NA NA NA 0.785 NA NA 0.8 …
$ PBioEtanol : num NA NA NA NA NA …
$ PNuevoGasoleoA : num NA 1.13 1.18 NA 1.18 …
$ PBioDiesel : num NA NA NA NA NA …
$ PGasolina98 : num NA 1.25 1.34 1.26 1.33 …
$ PGasNaturalComp: num NA NA NA NA NA NA NA NA NA NA …
$ PGasNaturalLic : num NA NA NA NA NA NA NA NA NA NA …
$ PGasLicuPetro : num NA NA NA NA NA NA NA NA NA NA …

summary(FuelPrecio)

PGasolina95 PGasoleoA PGasoleoB PBioEtanol
Min. :0.779 Min. :0.749 Min. :0.544 Min. :1.149
1st Qu.:1.195 1st Qu.:1.079 1st Qu.:0.729 1st Qu.:1.277
Median :1.239 Median :1.129 Median :0.789 Median :1.345
Mean :1.214 Mean :1.106 Mean :0.772 Mean :1.353
3rd Qu.:1.259 3rd Qu.:1.155 3rd Qu.:0.823 3rd Qu.:1.410
Max. :1.360 Max. :1.229 Max. :1.039 Max. :1.599
NA’s :476 NA’s :126 NA’s :7515 NA’s :9939
PNuevoGasoleoA PBioDiesel PGasolina98 PGasNaturalComp
Min. :0.814 Min. :0.909 Min. :0.890 Min. :0.689
1st Qu.:1.170 1st Qu.:1.039 1st Qu.:1.329 1st Qu.:0.853
Median :1.204 Median :1.089 Median :1.360 Median :0.898
Mean :1.184 Mean :1.081 Mean :1.340 Mean :0.859
3rd Qu.:1.220 3rd Qu.:1.126 3rd Qu.:1.389 3rd Qu.:0.898
Max. :1.329 Max. :1.232 Max. :1.555 Max. :0.995
NA’s :2834 NA’s :9873 NA’s :3429 NA’s :9914
PGasNaturalLic PGasLicuPetro
Min. :0.652 Min. :0.469
1st Qu.:0.689 1st Qu.:0.582
Median :0.689 Median :0.612
Mean :0.771 Mean :0.603
3rd Qu.:0.898 3rd Qu.:0.638
Max. :0.898 Max. :0.727
NA’s :9932 NA’s :9462

Podemos observamos la fuerte presencia de valores perdidos, dichos valores pueden ser un problema cuando se analiza un conjunto de datos.

En algunos casos, si el numero de datos perdidos es relativamente pequeño la eliminación de ellos puede ser una estrategia a seguir. En nuestro caso debido a la presencia significativa de valores perdidos, optamos por la opción de estimarlos mediante técnicas de Machine Learning.

Tratamiento de valores Missing

Una primera visualización de los valores perdidos nos la proporciona el paquete VIM.

library(VIM)

aggr_plot <- aggr(Fuel, numbers=TRUE, sortVars=TRUE, labels=names(Fuel), 
cex.axis=.5, gap=3, ylab=c("Histograma de valores perdidos","Pattern"))

rplot05

La visualización nos permite ver que casi un 75% de los registros no presentan missing, el 22% de los missing es debido a la variable “Precio Bio Etanol”.

Igualmente podemos realizar otra aproximación visual comparando dos variables:

marginplot(FuelPrecio[,c(“PGasolina95″,”PGasolina98”)])

rplot

Aquí podemos ver la distribución de valores perdidos del “Precio de la gasolina 98” con falta de valores del “Precio de la gasolina 95”. La parte azul nos muestra la distribución del resto de puntos.

Imputación de Misssing

A través de la librería MICE podemos asignar valores perdidos mediante técnicas predictivas.

library(mice)

Fuelmice<- mice(FuelPrecio,m=5,maxit=50,meth='rf',seed=500)
completedFuel <- complete(Fuelmice,1)
summary(completeFuel)

PGasolina95 PGasoleoA PGasoleoB
Min. :0.779 Min. :0.749 Min. :0.544
1st Qu.:1.189 1st Qu.:1.079 1st Qu.:0.720
Median :1.235 Median :1.129 Median :0.789
Mean :1.213 Mean :1.106 Mean :0.768
3rd Qu.:1.259 3rd Qu.:1.155 3rd Qu.:0.820
Max. :1.360 Max. :1.229 Max. :1.039
PBioEtanol PNuevoGasoleoA PBioDiesel
Min. :1.149 Min. :0.814 Min. :0.909
1st Qu.:1.283 1st Qu.:1.155 1st Qu.:1.064
Median :1.345 Median :1.194 Median :1.118
Mean :1.346 Mean :1.174 Mean :1.108
3rd Qu.:1.399 3rd Qu.:1.219 3rd Qu.:1.155
Max. :1.599 Max. :1.329 Max. :1.232
PGasolina98
Min. :0.890
1st Qu.:1.319
Median :1.359
Mean :1.338
3rd Qu.:1.384
Max. :1.555

En este caso utilizamos como modelo de imputación un Random Forest.

Fuel <- select(Fuel, -contains(“Precio”), completeFuel)

Clustering

Determinaremos una clusterización que nos permita comparar estaciones de servicio similares y diferentes entre si, de cara a poder seleccionar y encontrar estaciones de servicio adaptadas a nuestras necesidades.

Para ello determinaremos con las variables numéricas, una vez escaladas, las componentes principales y determinaremos el número optimo de segmentos.

# Seleccionamos los atributos numéricos y escalamos

Fuel_num

Fuel_scale # Aplicamos análisis de componentes principales
pc plot(pc)
plot(pc, type = “l”)
summary(pc)
# Obtenemos componentes principales
pc summary(pc)

# Primeras componentes principales
comp

# Plot
plot(comp, pch = 16, col= rgb(0,0,0,0.5))
wss

for (i in 2:15)

wss[i]

plot(1:15, wss, type = “b”, xlab = “Number of Cluster”, ylab = “Within groups sum of squares”)

# K-Means Clustering con 4 clusters

Fuel_Cluster Fuel_Cluster
aggregate(Fuel[,16:22], by=list(Fuel_Cluster$cluster), FUN = mean)

library(ggplot2)

Fuel$cluster

Fuel$PC1 Fuel$PC2

ggplot(Fuel, aes(PC1, PC2, color = Fuel$cluster)) +
geom_point()

El siguiente paso es ponerle cara a los clusters:

aggregate(Fuel[,16:22], by=list(Fuel_Cluster$cluster), FUN = mean)

Group.1 PGasolina95 PGasoleoA PGasoleoB PBioEtanol PNuevoGasoleoA
1 1 0.9402179 0.8586645 0.6861961 1.291664 0.9427451
2 2 1.2504438 1.1443182 0.8026884 1.472251 1.2108244
3 3 1.1654730 1.0503863 0.6936435 1.304441 1.1177545
4 4 1.2453041 1.1389383 0.7956955 1.301777 1.2053461
PBioDiesel PGasolina98
1 1.045405 1.049529
2 1.136626 1.372269
3 1.044700 1.299260
4 1.132222 1.368115

En este caso los cluster1 corresponden con estaciones de servicio económicas frente al cluster2 donde los precios son mucho mas altos.

rplot06

Visualización

Una de las formas mas atractiva de visualizar los datos es a través de los mapas. En este caso utilizaremos todo el potencial de  las librerías ggmap y ggplot2.

En nuestro Dataset, ya disponemos tanto de la longitud como de la latitud que nos permitirá georefenciar la estación de servicio y de esta forma visualizar su Cluster en mapa.

library(ggmap)
library(ggplot2)
Spain.map = get_map(location = “Spain”, zoom = 6, color=”bw”)
p p p p + theme(axis.title=element_blank(),
axis.text=element_blank(),
axis.ticks=element_blank()) + ggtitle(“Clusters Estaciones Servicio”)

rplot04

Podemos visualizar los clusters de manera individual:

rplot09

Podemos hacer zoom y ver el caso particular de la provincia de Almería.

rplot11

Anuncios

Responder

Introduce tus datos o haz clic en un icono para iniciar sesión:

Logo de WordPress.com

Estás comentando usando tu cuenta de WordPress.com. Cerrar sesión / Cambiar )

Imagen de Twitter

Estás comentando usando tu cuenta de Twitter. Cerrar sesión / Cambiar )

Foto de Facebook

Estás comentando usando tu cuenta de Facebook. Cerrar sesión / Cambiar )

Google+ photo

Estás comentando usando tu cuenta de Google+. Cerrar sesión / Cambiar )

Conectando a %s