Carga de datos formato csv
data <- read.csv("https://raw.githubusercontent.com/VictorGuevaraP/Mineria-de-datos-2020/master/Desafiliado_miss.csv", sep = ";")
Ahora establecemos la estructura inical de las variable de la data y un resumen de la data total, de la siguente manera:
names (data)
## [1] "Genero" "Ocupación"
## [3] "Plan_Internacional" "Min_En_Dia"
## [5] "Min_Internacionales" "Reclamos"
## [7] "Llamadas_Internacionales" "Desafiliado"
names (data)[2] = "Ocupacion"
str(data)
## 'data.frame': 3333 obs. of 8 variables:
## $ Genero : Factor w/ 2 levels "Femenino","Masculino": 2 2 2 2 2 2 2 2 1 2 ...
## $ Ocupacion : Factor w/ 5 levels " ","Educación",..: 5 3 2 5 2 4 2 1 3 1 ...
## $ Plan_Internacional : Factor w/ 2 levels "no","si": 1 1 1 2 2 2 1 2 1 2 ...
## $ Min_En_Dia : num 265 162 243 299 NA ...
## $ Min_Internacionales : num 10 13.7 12.2 6.6 10.1 6.3 7.5 7.1 8.7 11.2 ...
## $ Reclamos : int 1 1 0 2 3 0 3 0 1 0 ...
## $ Llamadas_Internacionales: int 3 3 5 7 3 6 7 6 4 5 ...
## $ Desafiliado : Factor w/ 2 levels "no","si": 1 1 1 1 1 1 1 1 1 1 ...
summary(data)
## Genero Ocupacion Plan_Internacional Min_En_Dia
## Femenino :1714 :332 no:3010 Min. : 0.0
## Masculino:1619 Educación :745 si: 323 1st Qu.:143.6
## Negocios :732 Median :179.9
## Otros :797 Mean :180.0
## Proyectos personales:727 3rd Qu.:216.7
## Max. :350.8
## NA's :216
## Min_Internacionales Reclamos Llamadas_Internacionales Desafiliado
## Min. : 0.00 Min. :0.000 Min. : 0.000 no:2850
## 1st Qu.: 8.50 1st Qu.:1.000 1st Qu.: 3.000 si: 483
## Median :10.30 Median :1.000 Median : 4.000
## Mean :10.24 Mean :1.563 Mean : 4.479
## 3rd Qu.:12.10 3rd Qu.:2.000 3rd Qu.: 6.000
## Max. :20.00 Max. :9.000 Max. :20.000
## NA's :138
De acuerdo a ello se establece lo siguiente:
Se tiene 3333 datos de 8 variables
Variables:
En la varibale Ocupación, el nivel el cual se encuentra vacio, se cambia como “No_Especificado”. Y en el caso de la variable Reclamos, cambiamos a factor.
data$Ocupacion <- factor(data$Ocupacion, levels = c("Proyectos personales","Negocios","Educación","Otros"," "),
labels = c("Proyectos personales","Negocios","Educación","Otros","No_Especificado"))
data$Ocupacion[is.na(data$Ocupacion)] <- "No_Especificado"
data$Reclamos <- as.factor(data$Reclamos)
Se verifica que en la columna Ocupación, sale el nivel “No_Especificado”. Y en la variable Reclamos, es correcta la conversión a factor.
summary(data)
## Genero Ocupacion Plan_Internacional Min_En_Dia
## Femenino :1714 Proyectos personales:727 no:3010 Min. : 0.0
## Masculino:1619 Negocios :732 si: 323 1st Qu.:143.6
## Educación :745 Median :179.9
## Otros :797 Mean :180.0
## No_Especificado :332 3rd Qu.:216.7
## Max. :350.8
## NA's :216
## Min_Internacionales Reclamos Llamadas_Internacionales Desafiliado
## Min. : 0.00 1 :1181 Min. : 0.000 no:2850
## 1st Qu.: 8.50 2 : 759 1st Qu.: 3.000 si: 483
## Median :10.30 0 : 697 Median : 4.000
## Mean :10.24 3 : 429 Mean : 4.479
## 3rd Qu.:12.10 4 : 166 3rd Qu.: 6.000
## Max. :20.00 5 : 66 Max. :20.000
## NA's :138 (Other): 35
#install.packages("mice")
library(mice)
## Warning: package 'mice' was built under R version 3.6.3
##
## Attaching package: 'mice'
## The following objects are masked from 'package:base':
##
## cbind, rbind
md.pattern(data)
## Genero Ocupacion Plan_Internacional Reclamos Llamadas_Internacionales
## 2992 1 1 1 1 1
## 203 1 1 1 1 1
## 125 1 1 1 1 1
## 13 1 1 1 1 1
## 0 0 0 0 0
## Desafiliado Min_Internacionales Min_En_Dia
## 2992 1 1 1 0
## 203 1 1 0 1
## 125 1 0 1 1
## 13 1 0 0 2
## 0 138 216 354
library(VIM)
## Warning: package 'VIM' was built under R version 3.6.3
## Loading required package: colorspace
## Loading required package: grid
## Loading required package: data.table
## VIM is ready to use.
## Since version 4.0.0 the GUI is in its own package VIMGUI.
##
## Please use the package to use the new (and old) GUI.
## Suggestions and bug-reports can be submitted at: https://github.com/alexkowa/VIM/issues
##
## Attaching package: 'VIM'
## The following object is masked from 'package:datasets':
##
## sleep
aggr(data, col=c('green', 'red'),
ylab = c("Histograma de NAs", "Patrón"))
apply(is.na(data), 2, mean)
## Genero Ocupacion Plan_Internacional
## 0.00000000 0.00000000 0.00000000
## Min_En_Dia Min_Internacionales Reclamos
## 0.06480648 0.04140414 0.00000000
## Llamadas_Internacionales Desafiliado
## 0.00000000 0.00000000
mean(is.na(data$Min_En_Dia))
## [1] 0.06480648
mean(is.na(data$Min_Internacionales))
## [1] 0.04140414
hist(data$Min_Internacionales, main = "Minutos Internacionales", xlab ="Min_Internacionales", ylab = "Frecuencia")
hist(data$Min_En_Dia, main = "Minutos consumidos en el día", xlab ="Min_En_Dia", ylab = "Frecuencia")
hist(data$Llamadas_Internacionales, main = "Cantidad de llamadas realizadas", xlab ="Llamadas_Internacionales", ylab = "Frecuencia")
Se puede visualizar en todos los boxplot los siguientes valores: - Primer cuartil: el 25% de los valores son menores o igual a este valor. - Mediana o Segundo Cuartil: Divide en dos partes iguales la distribución. De forma que el 50% de los valores son menores o igual a este valor. - Tercer cuartil: el 75% de los valores son menores o igual a este valor. - Rango Intercuartílico (RIC): Diferencia entre el valor del tercer cuartil y el primer cuartil. - Outlier: Los valores atípicos (outilers en inglés) son aquellos puntos que están mas allá del límite inferior o superior.
par(mfrow = c(2,2))
boxplot(data$Min_En_Dia, main = "Min_En_Dia con outliers", xlab ="Min_En_Dia")$out
## [1] 332.9 337.4 326.5 350.8 335.5 30.9 334.3 346.8 12.5 25.9 0.0 0.0
## [13] 19.5 329.8 7.9 27.0 345.3 2.6 7.8 18.9 29.9
boxplot(data$Min_Internacionales, main = "Min_Internacionales con outliers", xlab ="Min_Internacionales")$out
## [1] 20.0 17.6 2.7 18.9 0.0 18.0 2.0 0.0 18.2 0.0 1.3 0.0 0.0 0.0 2.2
## [16] 18.0 0.0 17.9 0.0 18.4 2.0 2.9 3.1 17.6 2.6 0.0 0.0 18.2 0.0 18.0
## [31] 1.1 0.0 18.3 0.0 0.0 2.1 2.1 2.4 2.5 0.0 17.8
boxplot(data$Llamadas_Internacionales, main = "Llamadas_Internacionales con outliers", xlab ="Llamadas_Internacionales")$out
## [1] 19 15 11 12 13 11 12 11 13 12 11 11 18 11 12 13 12 12 11 15 13 15 11 11 14
## [26] 13 11 13 13 12 11 14 15 18 12 13 11 14 11 12 14 15 12 11 16 11 11 11 11 15
## [51] 11 14 11 11 12 13 11 11 16 13 11 13 11 15 11 12 13 18 12 12 12 11 13 11 13
## [76] 14 20 17
#Par, vuelve a la normalidad, el tamaño original
par(mfrow = c(1,1))
boxplot(Llamadas_Internacionales ~ Reclamos,
data = data,
main = "Llamadas_Internacionales según los Reclamos ")$out
## [1] 19 15 11 12 12 12 12 12 13 11 13 15 11 16 11 11 13 13 11 13 11 11 18 15 15
## [26] 13 12 14 18 12 13 11 14 12 11 11 15 14 11 12 11 13 13 11 12 13 18 12 12 13
## [51] 14 20 12 11 13 14 11 13 12 11 11 11 11 11 12 11 17 13 11 14 15 11 15 11 11
## [76] 16 11 11 7
boxplot(Min_Internacionales ~ Reclamos,
data = data,
main = "Min_Internacionales según los Reclamos ")$out
## [1] 20.0 18.9 0.0 3.3 0.0 17.5 2.1 2.4 2.7 18.0 2.0 0.0 18.2 1.3 0.0
## [16] 0.0 18.0 0.0 2.0 2.6 18.2 18.0 18.3 0.0 2.1 2.5 0.0 17.6 0.0 0.0
## [31] 18.4 2.9 3.1 17.6 0.0 1.1 0.0 2.2 0.0 0.0 0.0 17.8 15.0 5.3 5.9
## [46] 15.8
boxplot(Min_En_Dia ~ Reclamos,
data = data,
main = "Min_En_Dia según los Reclamos ")$out
## [1] 337.4 34.0 334.3 19.5 329.8 7.9 350.8 30.9 346.8 12.5 25.9 35.1
## [13] 321.3 0.0 326.3 345.3 322.4 18.9 335.5 7.8 27.0 2.6 332.9 0.0
## [25] 46.5 253.7
boxplot(Min_Internacionales~ Desafiliado,
data = data,
main = "Min_Internacionales los Desafiliados ")$out
## [1] 2.7 18.9 0.0 18.0 0.0 17.5 18.2 0.0 1.3 0.0 0.0 0.0 2.2 18.0 0.0
## [16] 0.0 18.4 2.0 2.9 17.6 2.6 0.0 0.0 18.2 0.0 18.0 1.1 0.0 0.0 0.0
## [31] 2.1 17.5 2.1 2.4 2.5 0.0 17.8 20.0 2.0
boxplot(Min_Internacionales ~ Ocupacion,
data = data,
main = "Min_Internacionales según la Ocupación ")$out
## [1] 17.6 2.7 0.0 2.0 0.0 17.5 0.0 18.4 2.0 3.1 17.3 18.0 0.0 2.4 0.0
## [16] 18.9 2.6 0.0 0.0 1.1 0.0 2.1 2.5 20.0 0.0 2.2 0.0 17.6 0.0 0.0
## [31] 2.1 3.5 17.5 18.2 1.3 0.0 18.0 17.9 0.0 17.3 3.4 18.2 3.3 18.3 17.8
## [46] 0.0
boxplot(Min_En_Dia ~ Ocupacion,
data = data,
main = "Min_En_Dia según la Ocupación ")$out
## [1] 0.0 7.8 350.8 334.3 346.8 19.5 345.3 332.9 337.4 335.5 25.9 0.0
## [13] 2.6 326.5 30.9 315.6 321.6 12.5 35.1 7.9 317.8 40.4 324.7 18.9
## [25] 27.0
boxplot(Llamadas_Internacionales ~ Desafiliado,
data = data,
main = "Min_Internacionales según los Desafiliados ")$out
## [1] 19 11 12 13 11 12 13 12 11 11 18 11 12 13 12 15 13 15 11 11 14 13 11 13 13
## [26] 12 14 15 18 12 13 11 14 11 12 14 12 11 16 11 11 11 11 11 11 11 12 13 11 11
## [51] 16 13 13 11 15 11 12 18 12 12 12 11 13 11 13 14 17 15 11 10 12 10 11 10 11
## [76] 15 10 15 10 14 10 10 11 10 13 20
#install.packages("ggplot2")
library(ggplot2)
ggplot(data)+
geom_histogram(mapping = aes(x=Min_Internacionales, color=Genero))
## `stat_bin()` using `bins = 30`. Pick better value with `binwidth`.
## Warning: Removed 138 rows containing non-finite values (stat_bin).
- Histograma de Llamadas_Internacionales de acuerdo al Reclamos
ggplot(data)+
geom_bar(mapping = aes(x=Llamadas_Internacionales, color=Reclamos))
## Warning: position_stack requires non-overlapping x intervals
Tomamos en cuenta las variables a patir de la segunda columna, es decir, desde la Ocupación. Ya que en el género no se visualizó mucha variación en si es femenino o masculino.
newdata=data[,2:8]
Capar los valores extremos, es decir, localizar todo lo que cayera fuera del bigote más arriba o más abajo de 1,5 veces de el rango intercuartilico. Y decidir capar dichas obsevaciones sustituyendolas con el percentil número 5. En el caso de los que están debajo del bigote inferior y con el percentil 95 con los que están por encima del bigote superior.
replace_outliers <- function(x, removeNA = TRUE){
qrts <- quantile(x, probs = c(0.25, 0.75), na.rm = removeNA)
caps <- quantile(x, probs = c(.05, 0.95), na.rm = removeNA)
iqr <- qrts[2]-qrts[1]
h <- 1.5*iqr
x[x<qrts[1]-h] <- caps[1]
x[x>qrts[2]+h] <- caps[2]
x
}
Es un reemplazo no una imputación, de los valores atípicos
La función como entrada tiene vector numérico como entrada x, que sería la data$columna. Con el parámetro opcional que sería removeNA = TRUE.
En primer lugar se obtiene los cuantil es Q1 y Q3 para poder calcular el rango inter cuatulico. Se hace uso de la función quantile para el parametro de entrada x, para obrtener aquellos que están exactamente con probabilidad 0.25 por debajo y 0.75 pordebajo y como segundo parametro na.rm igual a removeNA que se ha pasado.
Obteniendo los valores de caping, los cuales detallamos que si está por debajo del rango intercuartil, se tomará el cuantil número 5 y por encima se tomará el 95, al igual que al cuantil de antes el de x. En este caso con probabilidades .05 y .95 con el mismo segundo parámetro de na.rm = removeNA.
Se calcula el rango intercualtilico. El qrts[2], representa el 95 osea menos del 95 - el del 0.25 qrts[1]. Voy a otener 1,5 veces el rando intercualtil el cual será igual a:
h <- 1.5*iqr h, que representa la altura.
x[x<qrts[1]-h] <- caps[1]
Reemplazo todo lo que se encuentre en “x”, los valores que se encuentrn por debajo del 1er cuantil - h con el caps número 1
Reemplazo todo lo que se encuentre en “x”, los valores que se encuentren por encima del 3er cuantil + h con el caps número 2
Devuelvo x como valor final de la ejecucuón.
Las hacemos uso en las variables: Min_Internacionales, Llamadas_Internacionales, Min_En_Dia. En las cuales fueron en dónde se presentaron los valores atípicos.
capped_Min_Internacionales <-replace_outliers(newdata$Min_Internacionales)
capped_Min_En_Dia <-replace_outliers(newdata$Min_En_Dia)
capped_Llamadas_Internacionales <- replace_outliers(newdata$Llamadas_Internacionales)
Se puede visualizar, una comparación con el uso del boxplot, de la data principal seleccionada con la data actual que se tiene sin outliers.
par(mfrow = c(1,2))
boxplot(data$Min_Internacionales, main = "Min_Internacionales con outliers")
boxplot(capped_Min_Internacionales, main = "Min_Internacionales outliers")
boxplot(data$Min_En_Dia, main = "Min_En_Dia con outliers")
boxplot(capped_Min_En_Dia, main = "Min_En_Dia sin outliers")
boxplot(data$Llamadas_Internacionales, main = "Llamadas_Internacionales con outliers")
boxplot(capped_Llamadas_Internacionales, main = "Llamadas_Internacionales sin outliers")
Hacemos uso de la función knnImputació. La función rellena todos los valores de NA usando los k Vecinos más cercanos de cada caso con valores de NA. Por defecto utiliza los valores de los vecinos y obtiene una media ponderada (por la distancia al caso) de sus valores para rellenar las incógnitas. Se hace uso de la librería “DMwR”
# install.packages("DMwR")
library(DMwR)
## Loading required package: lattice
## Registered S3 method overwritten by 'xts':
## method from
## as.zoo.xts zoo
## Registered S3 method overwritten by 'quantmod':
## method from
## as.zoo.data.frame zoo
##
## Attaching package: 'DMwR'
## The following object is masked from 'package:VIM':
##
## kNN
dataFinal <- knnImputation(newdata)
summary(newdata)
## Ocupacion Plan_Internacional Min_En_Dia
## Proyectos personales:727 no:3010 Min. : 0.0
## Negocios :732 si: 323 1st Qu.:143.6
## Educación :745 Median :179.9
## Otros :797 Mean :180.0
## No_Especificado :332 3rd Qu.:216.7
## Max. :350.8
## NA's :216
## Min_Internacionales Reclamos Llamadas_Internacionales Desafiliado
## Min. : 0.00 1 :1181 Min. : 0.000 no:2850
## 1st Qu.: 8.50 2 : 759 1st Qu.: 3.000 si: 483
## Median :10.30 0 : 697 Median : 4.000
## Mean :10.24 3 : 429 Mean : 4.479
## 3rd Qu.:12.10 4 : 166 3rd Qu.: 6.000
## Max. :20.00 5 : 66 Max. :20.000
## NA's :138 (Other): 35
Se pueden visualizar los NA’s en las variables
summary(dataFinal)
## Ocupacion Plan_Internacional Min_En_Dia
## Proyectos personales:727 no:3010 Min. : 0.0
## Negocios :732 si: 323 1st Qu.:146.0
## Educación :745 Median :179.2
## Otros :797 Mean :179.8
## No_Especificado :332 3rd Qu.:214.4
## Max. :350.8
##
## Min_Internacionales Reclamos Llamadas_Internacionales Desafiliado
## Min. : 0.00 1 :1181 Min. : 0.000 no:2850
## 1st Qu.: 8.60 2 : 759 1st Qu.: 3.000 si: 483
## Median :10.30 0 : 697 Median : 4.000
## Mean :10.24 3 : 429 Mean : 4.479
## 3rd Qu.:12.00 4 : 166 3rd Qu.: 6.000
## Max. :20.00 5 : 66 Max. :20.000
## (Other): 35
No se reflejan los NA’s en las variables.
write.csv(dataFinal, file = "dataFinal.csv")
getwd()
## [1] "D:/VII CICLO/MINERIA DE DATOS/CLASES/SEMANA3/E1"