Ejercicio en Equipo

Importar la base de datos

 bd<-read.csv("C:\\Users\\enriq\\OneDrive\\Documentos\\Datos a Desiciones\\Modulo4\\ventas.csv")

Entender la base de datos

summary(bd)
##     BillNo            Itemname            Quantity            Date          
##  Length:522064      Length:522064      Min.   :-9600.00   Length:522064     
##  Class :character   Class :character   1st Qu.:    1.00   Class :character  
##  Mode  :character   Mode  :character   Median :    3.00   Mode  :character  
##                                        Mean   :   10.09                     
##                                        3rd Qu.:   10.00                     
##                                        Max.   :80995.00                     
##                                                                             
##      Hour               Price              CustomerID       Country         
##  Length:522064      Min.   :-11062.060   Min.   :12346    Length:522064     
##  Class :character   1st Qu.:     1.250   1st Qu.:13950    Class :character  
##  Mode  :character   Median :     2.080   Median :15265    Mode  :character  
##                     Mean   :     3.827   Mean   :15317                      
##                     3rd Qu.:     4.130   3rd Qu.:16837                      
##                     Max.   : 13541.330   Max.   :18287                      
##                                          NA's   :134041                     
##      Total          
##  Min.   :-11062.06  
##  1st Qu.:     3.75  
##  Median :     9.78  
##  Mean   :    19.69  
##  3rd Qu.:    17.40  
##  Max.   :168469.60  
## 
library(dplyr)
## 
## Attaching package: 'dplyr'
## The following objects are masked from 'package:stats':
## 
##     filter, lag
## The following objects are masked from 'package:base':
## 
##     intersect, setdiff, setequal, union
#count(bd,BillNo, sort = TRUE)
#count(bd,Itemname, sort = TRUE)
#count(bd,Date, sort = TRUE)
#count(bd,Hour, sort = TRUE)
#count(bd,Country, sort = TRUE)

Observaciones:

  1. Tenemos cantidades, precios y totales negativos.
  2. Fecha y hora no tienen el formato adecuado.
  3. Tenemos NA’s en CustomerID.

Limpieza la base de datos

# Cuantos NA tengo en la base de datos
sum(is.na(bd))
## [1] 134041
# Cuantos NA tento por variable
sapply(bd, function(x) sum(is.na(x)))
##     BillNo   Itemname   Quantity       Date       Hour      Price CustomerID 
##          0          0          0          0          0          0     134041 
##    Country      Total 
##          0          0
#Eliminar NA
bd <- na.omit(bd)

# Eliminar totales negativos 
bd <- bd[bd$Total>0,]

# Identificar outliers
boxplot(bd$Total, horizontal=TRUE)

Observaciones: 4. Tenemos outliers en Total.

# Obtener cantidad de visitas por cliente
Visitas<- group_by(bd,CustomerID) %>%
  summarize(Visitas=n_distinct(BillNo))

# Obtener el total por ticket
ticket_promedio <- aggregate(Total ~ CustomerID+BillNo, data=bd, sum)

# Obtener el ticket promedio
ticket_promedio <- aggregate(Total ~ CustomerID, data=ticket_promedio, mean)

# Juntar las tablas Visitas y Ticket Promedio
objetos<- merge(Visitas, ticket_promedio, by="CustomerID")

# Llamar a los renglones como CustomerID
rownames(objetos) <- objetos$CustomerID

# Eliminar columna CustomerID
objetos<-subset(objetos, select=-c(CustomerID))

# Eliminar datos fuera de los normal

# Los datos fuera de lo normal estan fuera de los siguientes limites:
#Limite inferior = Q1 - 1.5*IQR
#Limite superior = Q3 + 1.5*IQR
#Q1:Cuartil 1, Q3: Cuartil 3, IQR=Rango Intercuartil

# Columna Visitas
IQR_V <- IQR(objetos$Visitas)
IQR_V
## [1] 4
summary(objetos)
##     Visitas            Total         
##  Min.   :  1.000   Min.   :    3.45  
##  1st Qu.:  1.000   1st Qu.:  178.30  
##  Median :  2.000   Median :  292.00  
##  Mean   :  4.227   Mean   :  415.62  
##  3rd Qu.:  5.000   3rd Qu.:  426.63  
##  Max.   :209.000   Max.   :84236.25
LI_V <- 1-1.5*IQR_V
LI_V
## [1] -5
LS_V <- 5+1.5*IQR_V
LS_V
## [1] 11
objetos <- objetos[objetos$Visitas <=11,]

# Renombrar columnas
colnames(objetos)<-c("Visitas", "TicketPromedio")

# Ticket Promedio
IQR_TP<- IQR(objetos$TicketPromedio)
IQR_TP
## [1] 243.3733
LI_TP <- 178.30 - 1.5*IQR_TP
LI_TP
## [1] -186.76
LS_TP<- 426.63 + 1.5*IQR_TP
LS_TP
## [1] 791.69
objetos <- objetos[objetos$TicketPromedio <=791.69,]

Asignacion de grupos

# 1. Crear base de datos

df<- objetos

# 2. Determinar el número de grupos
grupos <- 4

# 3. Realizar la clasificación
segmentos <- kmeans(df,grupos)
# segmentos

# 4. Revisar la asignación de grupos
asignacion <- cbind(df, cluster=segmentos$cluster)
# asignacion

# 5. Graficar resultados
library(ggplot2)
library(factoextra)
## Welcome! Want to learn more? See two factoextra-related books at https://goo.gl/ve3WBa
# fviz_cluster(segmentos, data=df,
#             palette=c("red","blue","darkgreen", "yellow"),
#             ellipse.type="euclip",
#             star.plot=T,
#             repel=T,
#             ggtheme=theme()
#             )

# 6. Optimizar cantidad de grupos
library(cluster)
library(data.table)
## 
## Attaching package: 'data.table'
## The following objects are masked from 'package:dplyr':
## 
##     between, first, last
set.seed(123)

optimizacion <- clusGap(df, FUN=kmeans, nstart=1, K.max=7)
## Warning: Quick-TRANSfer stage steps exceeded maximum (= 188200)
plot(optimizacion, xlab="No. de clusters k")