Está en la página 1de 15

SEGUNDA PRÁCTICA CALIFICADA

Alumno: Alexander Rodrigo Chiara Sinche


Correo: achiaras@uni.pe

1. Reproducir el procedimiento desarrollado por el profesor, en un solo programa.

El diagrama solución del ejercicio se realiza teniendo en cuenta los pasos del CRISP:

Entender el Negocio

Entendimiento de los Datos (Extracción)

Preparación de la Data

Planteamiento del Modelo

Evaluar, Conclusiones

• Se identificó el archivo CSV a trabajar (customer_segmentation.csv).


• Se identificó 8 campos presentes en el archivo, los cuales son los siguientes: InvoiceNo,
StockCode, Description, Quantity, InvoiceDate, UnitPrice, CustomerID, Country.
• Se determinó el objetivo del ejercicio, Clusterizar a los clientes.
• Se seleccionaron 3 variables para poder segmentar a los clientes (Recenty, Revenue,
Frequency)
o Recenty= Fecha Ultima Max compra (de todo el archivo)-fecha ultima compra
cliente.
o Revenue=Ingresos (UnitPrice*Quantity).
o Frequency=Cantidad de compras realizadas.
• Se procedió a realizar la programación en el Python.
• Se ejecutó el programa.
• Se obtuvieron conclusiones y recomendaciones.

Código Python desarrollado por el Profesor:

# importación de librerías
import pandas as pd
import numpy as np
import sys
import matplotlib.pyplot as plt
from sklearn.cluster import KMeans

#Definición de la función para ordenar


def order_cluster(cluster_field_name, target_field_name,df,ascending):
new_cluster_field_name = 'new_' + cluster_field_name
df_new = df.groupby(cluster_field_name)[target_field_name].mean().reset_index()
df_new = df_new.sort_values(by=target_field_name,ascending=ascending).reset_index(drop=True)
df_new['index'] = df_new.index
df_final = pd.merge(df,df_new[[cluster_field_name,'index']], on=cluster_field_name)
df_final = df_final.drop([cluster_field_name],axis=1)
df_final = df_final.rename(columns={"index":cluster_field_name})
return df_final
# Lectura de los datos y creación
tx_data = pd.read_csv('./data/customer_segmentation.csv', encoding='cp1252')
tx_data['InvoiceDate'] = pd.to_datetime(tx_data['InvoiceDate'])
tx_data['InvoiceYearMonth'] = tx_data['InvoiceDate'].map(lambda date: 100*date.year + date.month)
tx_uk = tx_data.query("Country=='United Kingdom'").reset_index(drop=True)
#Creación de una dataframe genérico para capturar el CustomerID y nuevos escores de segmentación
tx_user = pd.DataFrame(tx_data['CustomerID'].unique())
tx_user.columns = ['CustomerID']
# 3. Recency
tx_max_purchase = tx_uk.groupby('CustomerID').InvoiceDate.max().reset_index()
tx_max_purchase.columns = ['CustomerID','MaxPurchaseDate']
tx_max_purchase['Recency'] = (tx_max_purchase['MaxPurchaseDate'].max() -
tx_max_purchase['MaxPurchaseDate']).dt.days
tx_user = pd.merge(tx_user, tx_max_purchase[['CustomerID','Recency']], on='CustomerID')
#tx_user = tx_user[tx_user['Recency']<tx_user['Recency'].quantile(0.98)]
#Clusterizado Recency
kmeans = KMeans(n_clusters=4)
tx_user['RecencyCluster'] = kmeans.fit_predict(tx_user[['Recency']])
tx_user = order_cluster('RecencyCluster', 'Recency',tx_user,False)
# 4. Frecuencia
tx_frequency = tx_uk.groupby('CustomerID').InvoiceDate.count().reset_index()
tx_frequency.columns = ['CustomerID','Frequency']
tx_user = pd.merge(tx_user, tx_frequency, on='CustomerID')
#tx_user = tx_user[tx_user['Frequency']<tx_user['Frequency'].quantile(0.98)]
#Clusterizado Frecuencia
kmeans=KMeans(n_clusters=4)
tx_user['FrequencyCluster']=kmeans.fit_predict(tx_user[['Frequency']])
tx_user = order_cluster('FrequencyCluster', 'Frequency', tx_user, True )
# 5. Revenue
tx_uk['Revenue'] = tx_uk['UnitPrice'] * tx_uk['Quantity']
tx_revenue = tx_uk.groupby('CustomerID').Revenue.sum().reset_index()
tx_user = pd.merge(tx_user, tx_revenue, on='CustomerID')
#tx_user = tx_user[tx_user['Revenue']<tx_user['Revenue'].quantile(0.98)]
#Clusterizado Revenue
kmeans = KMeans(n_clusters=4)
tx_user['RevenueCluster'] = kmeans.fit_predict(tx_user[['Revenue']])
tx_user = order_cluster('RevenueCluster', 'Revenue',tx_user,True)
print(tx_user.head().to_string())
# Construcción de los 4 grupos para los clusters identificados
kmeans = KMeans(n_clusters=4)
tx_user['VVCCluster'] = kmeans.fit_predict(tx_user[['RecencyCluster', 'FrequencyCluster','RevenueCluster']])
print(tx_user.head().to_string())
print(tx_user.groupby('VVCCluster')['RecencyCluster', 'FrequencyCluster','RevenueCluster'].describe().to_string())
#Ploteo de la gráfica
fig = plt.figure()
ax = fig.add_subplot(111, projection='3d')
x = np.array(tx_user['RecencyCluster'])
y = np.array(tx_user['FrequencyCluster'])
z = np.array(tx_user['RevenueCluster'])
ax.set_title("Valor de Vida de los Clientes")
ax.set_xlabel("RecencyCluster")
ax.set_ylabel("FrequencyCluster")
ax.set_zlabel("RevenueCluster")
ax.scatter(x,y,z, marker="s", c=tx_user["VVCCluster"], s=40, cmap="RdBu")
plt.show()

2. Explique paso a paso, qué es lo que está haciendo el procedimiento, apóyese de la


impresión de los resultados, intermedio.

#Importar librerias: Pandas, Numpy, sys, Matplotlib.pyplot,Kmeans


import pandas as pd
import numpy as np
import sys
import matplotlib.pyplot as plt
from sklearn.cluster import KMeans
Se define la función "order_cluster" cuyas variables de entrada son 4 campos)
def order_cluster(cluster_field_name, target_field_name,df,ascending):
Se nombra new_cluster_field_name
new_cluster_field_name = 'new_' + cluster_field_name
Se agrupa por cluster_field_name, target_field_name, promedio
df_new = df.groupby(cluster_field_name)[target_field_name].mean().reset_index()
Se ordena de manera ascendente
df_new = df_new.sort_values(by=target_field_name,ascending=ascending).reset_index(drop=True)
Se denomina un nuevo indice
df_new['index'] = df_new.index
Se combina las dataframe
df_final = pd.merge(df,df_new[[cluster_field_name,'index']], on=cluster_field_name)
Quitar etiquetas
df_final = df_final.drop([cluster_field_name],axis=1)
Se renombra las columnas
df_final = df_final.rename(columns={"index":cluster_field_name})
Retorna dataframe df_final
return df_final

Lee la data del archivo csv y crea una dataframe denominada "tx_data"

tx_data = pd.read_csv('./data/customer_segmentation.csv', encoding='cp1252')

Convertir formato de la columna InvoiceDate a formato fecha


tx_data['InvoiceDate'] = pd.to_datetime(tx_data['InvoiceDate'])
Agrega una columna adicional denominada "InvoiceYearMonth" el cual le genera un formato "añomes" con la funcion map(lambda date:)

tx_data['InvoiceYearMonth'] = tx_data['InvoiceDate'].map(lambda date: 100*date.year + date.month)

Se crea una nueva dataframe "tx_uk" el cual con ayuda de un filtro (query) solo considera filas con el campo Ciudad= "United Kingdom"
tx_uk = tx_data.query("Country=='United Kingdom'").reset_index(drop=True)
Crea una nueva dataframe solo considerando los códigos de clientes (CustomerID) sin repetir
tx_user = pd.DataFrame(tx_data['CustomerID'].unique())

Se le denomina al campo de la nuevadataframe "CustomerID"

tx_user.columns = ['CustomerID']

Se denomina una nueva dataframe "tx_max_purchase", agrupando a su CustomerID con su "InvoiceDate" fecha última de compra

tx_max_purchase = tx_uk.groupby('CustomerID').InvoiceDate.max().reset_index()

Se le donima a las columnas con sus nuevos nombres ('CustomerID','MaxPurchaseDate')

tx_max_purchase.columns = ['CustomerID','MaxPurchaseDate']
Se agrega la columna Recency la cual viene a ser la diferencia entre la última fecha de compra máxima de toda la data menos la última
fecha de compra de cada cliente.

tx_max_purchase['Recency'] = (tx_max_purchase['MaxPurchaseDate'].max() - tx_max_purchase['MaxPurchaseDate']).dt.days

Se denomina una nueva dataframe "tx_user" el cual solo tiene las columnas "CustomerID";"Recency"

tx_user = pd.merge(tx_user, tx_max_purchase[['CustomerID','Recency']], on='CustomerID')

Se define como cluster 4


kmeans = KMeans(n_clusters=4)
Se le agrega la columna RecencyCluster el cual denomina el cluster al cual pertenece el cliente (0,1,2,3)

tx_user['RecencyCluster'] = kmeans.fit_predict(tx_user[['Recency']])

Ordenar con la funcion "Order_Cluster" según RecencyCluster

tx_user = order_cluster('RecencyCluster', 'Recency',tx_user,False)


Se denomina una nueva dataframe "tx_frequency”, con las columnas CustomerID y su contador de compras(por fecha)

tx_frequency = tx_uk.groupby('CustomerID').InvoiceDate.count().reset_index()

Se le denomina a sus nuevas columnas CustomerID y Frequency


tx_frequency.columns = ['CustomerID','Frequency']

Combina las dos datasframe creada ("tx_user" y "tx_frequency") en tx_user


tx_user = pd.merge(tx_user, tx_frequency, on='CustomerID')

Se define como cluster 4


kmeans=KMeans(n_clusters=4)
Se le agrega una columna "FrecuencyCluster" para determinar el cluster por la frecuencia de compra

tx_user['FrequencyCluster']=kmeans.fit_predict(tx_user[['Frequency']])

Se ordena la dataframe tx_user por la columna FrecuencyCluster


tx_user = order_cluster('FrequencyCluster', 'Frequency', tx_user, True )
Se le agrega la columna "Revenue" (UnitPrice*Quantity) a la dataframe tx_uk
tx_uk['Revenue'] = tx_uk['UnitPrice'] * tx_uk['Quantity']

Se denomina una nueva dataframe "tx_revenue" el cual es agrupada por cliente y su total de Ingreso (Revenue)
tx_revenue = tx_uk.groupby('CustomerID').Revenue.sum().reset_index()

Se combina las dataframe (tx_user,tx-revenue) teniendo una nueva dateframe


tx_user = pd.merge(tx_user, tx_revenue, on='CustomerID')

Se define como cluster 4

kmeans = KMeans(n_clusters=4)
Se le agrega una columna "RevenueCluster" para determinar el cluster por el Ingreso del cliente
tx_user['RevenueCluster'] = kmeans.fit_predict(tx_user[['Revenue']])
Se ordena la dataframe tx_user por la columna RevenueCluster
tx_user = order_cluster('RevenueCluster', 'Revenue',tx_user,True)

Se imprime la dataframe "tx_user con todas sus columnas"


print(tx_user.head().to_string())

Se define como cluster 4


kmeans = KMeans(n_clusters=4)

Se le agrega una columna "VVCCluster" para determinar el nuevo cluster


tx_user['VVCCluster'] = kmeans.fit_predict(tx_user[['RecencyCluster', 'FrequencyCluster','RevenueCluster']])

Se imprime las estadísticas de los nuevos cluster ("VVCCluster")

print(tx_user.head().to_string())
print(tx_user.groupby('VVCCluster')['RecencyCluster', 'FrequencyCluster','RevenueCluster'].describe().to_string())

Se le denomina al ploteo de la figura "fig"


fig = plt.figure()
Se le agrega la caracteristicas del ploteo
ax = fig.add_subplot(111, projection='3d')
Se define x como un vector "RecencyCluster"
x = np.array(tx_user['RecencyCluster'])
Se define y como un vector "FrequencyCluster"
y = np.array(tx_user['FrequencyCluster'])
Se define z como un vector "RevenueCluster"
z = np.array(tx_user['RevenueCluster'])
Se denomina al título de la grafica
ax.set_title("Valor de Vida de los Clientes")
Se coloca título al eje x
ax.set_xlabel("RecencyCluster")
Se coloca título al eje y
ax.set_ylabel("FrequencyCluster")
Se coloca título al eje z
ax.set_zlabel("RevenueCluster")
Mas Características de la gráfica
ax.scatter(x,y,z, marker="s", c=tx_user["VVCCluster"], s=40, cmap="RdBu")

Plotear la gráfica
plt.show()

Tener en cuenta que en la gráfica final se presenta un hueco debido a las datos extremos en cada variable a considerar
(Revenue,Frequency, Recency)

3. Eliminar las instrucciones que sirven para imprimir los resultados.

Se procedió a eliminar los comandos Print () → El cual sirve para imprimir resultados en el
Python

import pandas as pd
import numpy as np
import sys
import matplotlib.pyplot as plt
from sklearn.cluster import KMeans

def order_cluster(cluster_field_name, target_field_name,df,ascending):


new_cluster_field_name = 'new_' + cluster_field_name
df_new = df.groupby(cluster_field_name)[target_field_name].mean().reset_index()
df_new = df_new.sort_values(by=target_field_name,ascending=ascending).reset_index(drop=True)
df_new['index'] = df_new.index
df_final = pd.merge(df,df_new[[cluster_field_name,'index']], on=cluster_field_name)
df_final = df_final.drop([cluster_field_name],axis=1)
df_final = df_final.rename(columns={"index":cluster_field_name})
return df_final
tx_data = pd.read_csv('./data/customer_segmentation.csv', encoding='cp1252')
tx_data['InvoiceDate'] = pd.to_datetime(tx_data['InvoiceDate'])
tx_data['InvoiceYearMonth'] = tx_data['InvoiceDate'].map(lambda date: 100*date.year + date.month)
tx_uk = tx_data.query("Country=='United Kingdom'").reset_index(drop=True)
tx_user = pd.DataFrame(tx_data['CustomerID'].unique())
tx_user.columns = ['CustomerID']

tx_max_purchase = tx_uk.groupby('CustomerID').InvoiceDate.max().reset_index()
tx_max_purchase.columns = ['CustomerID','MaxPurchaseDate']
tx_max_purchase['Recency'] = (tx_max_purchase['MaxPurchaseDate'].max() -
tx_max_purchase['MaxPurchaseDate']).dt.days
tx_user = pd.merge(tx_user, tx_max_purchase[['CustomerID','Recency']], on='CustomerID')

kmeans = KMeans(n_clusters=4)
tx_user['RecencyCluster'] = kmeans.fit_predict(tx_user[['Recency']])
tx_user = order_cluster('RecencyCluster', 'Recency',tx_user,False)

tx_frequency = tx_uk.groupby('CustomerID').InvoiceDate.count().reset_index()
tx_frequency.columns = ['CustomerID','Frequency']
tx_user = pd.merge(tx_user, tx_frequency, on='CustomerID')

kmeans=KMeans(n_clusters=4)
tx_user['FrequencyCluster']=kmeans.fit_predict(tx_user[['Frequency']])
tx_user = order_cluster('FrequencyCluster', 'Frequency', tx_user, True )

tx_uk['Revenue'] = tx_uk['UnitPrice'] * tx_uk['Quantity']


tx_revenue = tx_uk.groupby('CustomerID').Revenue.sum().reset_index()
tx_user = pd.merge(tx_user, tx_revenue, on='CustomerID')

kmeans = KMeans(n_clusters=4)
tx_user['RevenueCluster'] = kmeans.fit_predict(tx_user[['Revenue']])
tx_user = order_cluster('RevenueCluster', 'Revenue',tx_user,True)

kmeans = KMeans(n_clusters=4)
tx_user['VVCCluster'] = kmeans.fit_predict(tx_user[['RecencyCluster', 'FrequencyCluster','RevenueCluster']])
fig = plt.figure()
ax = fig.add_subplot(111, projection='3d')
x = np.array(tx_user['RecencyCluster'])
y = np.array(tx_user['FrequencyCluster'])
z = np.array(tx_user['RevenueCluster'])

ax.set_title("Valor de Vida de los Clientes")


ax.set_xlabel("RecencyCluster")
ax.set_ylabel("FrequencyCluster")
ax.set_zlabel("RevenueCluster")

ax.scatter(x,y,z, marker="s", c=tx_user["VVCCluster"], s=40, cmap="RdBu")


plt.show()

4. Analizar la influencia de los valores extremos en la formación de los grupos.

Se agregó los siguientes comandos en cada una de la sintaxis correspondiente a sus variables de
clusterización, están son (Revenue, Recenty y Frequency)

tx_user = tx_user[tx_user['Frequency']<tx_user['Frequency'].quantile(0.98)]
tx_user = tx_user[tx_user['Revenue']<tx_user['Revenue'].quantile(0.98)]
tx_user = tx_user[tx_user['Recency']<tx_user['Recency'].quantile(0.98)]

Al quitarle los valores extremos de cada Campo (Recency, Revenue y Frequency) se corrige el
problema de las colas observadas (En la gráfica de la izquierda esas colas forman ese vacío
(hueco).
En la gráfica de la derecha se observa una mejor cohesión entre las variables y ya no presenta el
hueco debido a que se eliminó los extremos (que representaban el 0.02)

Recency:

La gráfica de la izquierda representa los datos completos y el de la derecha los datos completos
menos los valores extremos.

La primera Tabla representa la data general, se consideran 3,792 datos.

La segunda tabla comprende la data general menos los extremos, estas suman 3,714 clientes
Revenue:
La gráfica de la izquierda representa los datos completos y el de la derecha los datos completos
menos los valores extremos. Se observa que existe una mejor apreciación (distribución) de la
data. Pero se resalta valores negativos por motivos posibles de devolución.

La primera Tabla representa la data general, se consideran 3,790 datos.

La segunda tabla comprende la data general menos los extremos, estas suman 3,714 clientes

Frequency:
La gráfica de la izquierda representa los datos completos y el de la derecha los datos completos
menos los valores extremos. Se observa que existe una mejor apreciación (mejor distribución)
de la data.


La primera Tabla representa la data general, se consideran 3,792 datos.

La segunda tabla comprende la data general menos los extremos, estas suman 3,714 clientes
5. Para el ejercicio 10, determine la cantidad de grupos VVC apropiado.

Se analizó gráficamente la cantidad de grupos VVC y se obtuvo lo siguiente:

Grupo VVC=2 Grupo VVC=3 Grupo VVC=4 Grupo VVC=5

Baja cohesión Baja cohesión Moderada Muchos grupos,


Cohesión diferencia mínima

Por lo visto gráficamente se considera como cantidad de grupos ideal (Grupos VVC=4)

6. Haciendo un análisis manual, determine el orden de los grupos VVC, es decir qué grupo
VVC es el de mayor rendimiento y cuál el de menor rendimiento (se trata de identificar
los criterios).

Analizando los criterios por separado, El cluster de frecuencia que presenta mayor rendimiento
son donde los clientes tienen el mayor número de compras.

Fre.Cluster count mean std min 25% 50% 75% max


0 2,398 24.98 16.90 1 11 22 37 63
1 866 101.01 25.70 64 79 97 121 155
2 325 209.01 37.78 156 176 203 237 289
3 125 362.70 56.71 291 316 347 412 489
En el cluster de Recency tiene mayor rendimiento los que tengan menor recency.

Rec.Cluster count mean std min 25% 50% 75% max


0 464 283.81 35.75 231 254 277 311 360
1 539 174.09 29.10 125 150 173 198 227
2 917 75.42 20.88 47 58 71 89 124
3 1,794 18.21 13.09 0 7 17 28 46
En el cluster de Revenue tiene mayor rendimiento los que tengan Mayores Ingresos.

Rev.Cluster count mean stdmin 25% 50% 75% max


-
0 2,386 388.08 266.17 193.67 343.48 582.83 942.34
4,287.63
1 863 1,495.44 393.24 944.10 1,140.31 1,423.29 1,800.61 2,323.50
2 341 3,151.63 575.50 2,333.42 2,633.01 3,079.10 3,563.85 4,464.10
3 124 5,788.05 918.30 4,509.37 5,029.98 5,613.26 6,580.95 7,904.28

Para poder tener un mejor análisis se necesitaría conocer los costos por clientes, y de esta
manera se podría calcular su rentabilidad (Ingresos-Costos).
RecencyCluster FrequencyCluster RevenueCluster Total
Prom- Prom- Prom-
VVCCluster count mean std mean std mean std Suma Prom
Mm Mm Mm
1 983 0.53 0.50 0.5 0.11 0.33 1 0.09 0.31 1 2.5
0 1,694 2.58 0.49 2.5 0.13 0.34 0.5 0.14 0.35 0.5 3
2 713 2.71 0.50 2 1.14 0.49 1 1.21 0.53 1.5 3.5
3 324 2.86 0.42 1.5 2.31 0.60 2 2.25 0.63 2 5.5
Total 3,714

El orden de los grupos sería el seguimiento del cluster 1,0,2,3

7. Diga cuántos clientes tiene la empresa en cada grupo VVC.

RecencyCluster FrequencyCluster RevenueCluster


VVCCluster count mean std min max mean std min max mean std min max
0 1,694 2.58 0.49 2 3 0.13 0.34 0 1 0.14 0.35 0 1
1 983 0.53 0.50 0 1 0.11 0.33 0 2 0.09 0.31 0 2
2 713 2.71 0.50 1 3 1.14 0.49 0 2 1.21 0.53 0 3
3 324 2.86 0.42 0 3 2.31 0.60 1 3 2.25 0.63 1 3
Total 3,714

La empresa maneja 4 grupos de clientes y el total de clientes es 3,714.

8. Prepare un breve Dx de la empresa usando estos resultados.

Con los resultados obtenidos luego de analizar la data se obtiene lo siguiente:

FrequencyCluster count Share(%)


0 2,398 65%
1 866 23%
2 325 9%
3 125 3%
Total 3,714 100%
La mayor cantidad de sus clientes (65%) tienen una baja frecuencia de compras por lo cual se
debería velar por estos clientes (acciones o propuestas), el 3% de clientes compran
regularmente.

RecencyCluster count Share(%)


0 464 12%
1 539 15%
2 917 25%
3 1,794 48%
Total 3,714 100%
El 48% de sus clientes presentan días de compras cercanas, lo cuales representan sus clientes
regulares y un 12% de clientes antiguos que todavía no ejercen alguna compra próxima.
RevenueCluster count Share(%)
0 2,386 64%
1 863 23%
2 341 9%
3 124 3%
Total 3,714 100%
El 3% y 9% de sus clientes representan ingresos fuertes para la empresa, la mayoría de sus
clientes (64%) son ingresos regulares.

Para propósitos de clasificar a sus clientes la empresa los agrupo en 4 grupos;


VVCCluster count Share(%)
0 1,694 46%
1 983 26%
2 713 19%
3 324 9%
Total 3,714 100%

Teniendo en cuenta que la mayoría de sus clientes (46%) se encuentran en el primer bloque,
26% en el segundo, 19% en el tercero y 9% en el último, por lo cual asignar estrategias de
acuerdo con el bloque y tener presente las variables de ingresos, frecuencia de compra y
diferencia de ultima día de compra.

Entre algunas recomendaciones están:


• Descuentos, Rebates de Compra (Volumen).
• Margen de reconocimientos por objetivos.
• Políticas externas e internas a la empresa.

También podría gustarte