Tengo la fortuna de impartir clases en varias formaciones donde mayormente suele hablar sobre Analítica de datos desde diferentes acercamientos: digital, científico, negocio, ingeniería, etc. En todos ellos siempre encuentro muy potenciadas determinadas características y en cambio otras muy disminuidas. Por ejemplo, cuando los asistentes tienen perfiles menos técnicos (BI, Analistas digitales, etc.) suelen tender a realizar análisis donde no se exploran todas las oportunidades (patrones y aprendizaje). Por el contrario, cuando son perfiles más programáticos se evidencia rápidamente la inexactitud en los resultados por falta de un profundo entendimiento del negocio. Esto es algo habitual y la solución pasa siempre por un equipo multidisciplinar perfectamente alineado, el resto de apuestas que habitualmente suelen buscar el ahorro en costes suelen derivar a futuro en una mayor inversión. «El que compra barato, paga dos veces».

El artículo que se explica a continuación trata de manera simplificada pero efectiva el desarrollo y el modelado de datos centrado en la clasificación de usuarios según su comportamiento de compra en un ecommerce donde se hayan configurado los eventos de comercio electrónico de GA4. Se explica a través de código Python y BigQuery cómo prever si un usuario comprará´o no. Lógicamente, lo que a continuación se muestra es una implementación perfectamente útil pero reducida con la intención de ayudar al lector a poder implantarlo inicialmente en su empresa. Ya que la realidad conllevaría una dedicación mucho más detallada y diferente según la tipología de cada negocio a analizar. Entre esta y otras razones, la explicación va a seguir un proceso similar a mi anterior post ‘Segmentación de usuarios de GA4 en BigQuery usando algoritmos de clusterización en Python‘, por lo que la cronología seguirá los siguietes puntos a detallar: conexión a BigQuery, creación de la consulta, tratamiento de datos, modelado de datos, comprobación del modelo y perfilado de usuarios.

 

Conexión a BigQuery

Lo primero, como ya se ha explicado en otros artículos previos, será añadir las librerías que vamos a necesitar. En este caso concreto y puesto que solo se va a mostrar un tipo de algoritmo debemos prestar especial atención a la línea ‘from sklearn import tree’, la cual se refiere al desarrollo de árboles de decisión.

# In [1]
import numpy as np import pandas as pd import matplotlib.pyplot as plt from sklearn import tree import warnings warnings.filterwarnings('ignore')

Para poder utilizar BigQuery desde cualquier código Python es necesario, al menos, activar la API de Bigquery y crear una cuenta de servicio (más información) con una clave JSON que deberemos guardar y enlazar como se ve a continuación.  

# In [2]
from google.oauth2 import service_account
from google.cloud import bigquery
from google.cloud.bigquery import ScalarQueryParameter

credentials=service_account.Credentials.from_service_account_file(
'C:/[RUTA]/[CUENTA DE SERVICIO].json'
)
client = bigquery.Client(credentials=credentials)

Creación de la consulta (query)

Es el momento de crear la consulta para obtener los datos deseados. Para esta implementación en concreto se ha optado por recoger varios eventos (view_search_results, add_to_cart, begin_checkout, add_payment_info, add_shipping_info, view_item, view_item_list, view_promotion) de comercio electrónico tipo que de alguna forma representan parta del funnel de compra habitual. Para ello, se va usar el conjunto de datos ‘ga4_obfuscated_sample_ecommerce’ (más información) que Google pone a nuestra disposición con información ya previamente añadida.

# In [3]
start_date='20210130'
end_date='20210131'

query="""
SELECT user_pseudo_id,event_name,event_timestamp, CASE WHEN 'first_visit' IN ( SELECT event_name FROM `bigquery-public-data.ga4_obfuscated_sample_ecommerce.events_*` t2 WHERE _TABLE_SUFFIX BETWEEN @START_DATE AND @END_DATE AND t2.user_pseudo_id = t1.user_pseudo_id ) THEN 1 ELSE 0 END AS new_user, CASE WHEN 'purchase' IN ( SELECT event_name FROM `bigquery-public-data.ga4_obfuscated_sample_ecommerce.events_*` t2 WHERE _TABLE_SUFFIX BETWEEN @START_DATE AND @END_DATE AND t2.user_pseudo_id = t1.user_pseudo_id ) THEN 1 ELSE 0 END AS purchaser FROM `bigquery-public-data.ga4_obfuscated_sample_ecommerce.events_*` t1 where _TABLE_SUFFIX BETWEEN @START_DATE AND @END_DATE AND ( event_name='view_search_results' OR event_name='add_to_cart' OR event_name='begin_checkout' OR event_name='add_payment_info' OR event_name='add_shipping_info' OR event_name='view_item' OR event_name='view_item_list' OR event_name='view_promotion' ) #AND (user_pseudo_id='6097102.6516338254' OR user_pseudo_id='68780200.6423809280' OR user_pseudo_id='71568861.8035326636' OR user_pseudo_id='72959035.2192369480' OR user_pseudo_id='74650484.1255761858') ORDER BY 1,3 ASC
"""
query_params = [
ScalarQueryParameter('START_DATE', 'STRING', start_date),
ScalarQueryParameter('END_DATE', 'STRING', end_date)
]job_config = bigquery.QueryJobConfig()
job_config.query_parameters = query_params
query = client.query(query, job_config=job_config)
results=query.result()

df=results.to_dataframe()

Tratamiento de datos

La aplicación del ajuste de datos para poder aplicar la algoritmia más adelante pasa esencialmente por la generación del One-Hot Encoding (codificación ordinal entera de variables categóricas) y la creación de dos nuevas variables: buyer y new_user, siendo la primera el target (resultado de nuestra clasificación) y la segunda una característica más a añadir al modelado.

# In [4]
ohe = pd.get_dummies(df['event_name']) df = pd.concat([df, ohe], axis=1) df=df.drop(['event_name','event_timestamp'], axis=1) df=df.groupby('user_pseudo_id').agg({'buyer': 'mean', 'new_user': 'mean',**{col: 'mean' for col in ohe.columns}}).reset_index() df.head(2)

# Out[4] ...
Tratamiento de datos y codificación one-hot encoding

Tratamiento de datos y codificación

Modelado de datos

Como en casi cualquier desarrollo donde se aplican técnicas de Aprendizaje automático (Machine Learning), lo primero es dividir el conjunto de datos en 2 partes como normal común: entrenamiento (train) y pruebas (test); y puesto que como se tratará de aplicar un modelo de Aprendizaje supervisado definir cuál será la variable target y cuáles las features que definirán la predicción para poder llevar a cabo la clasificación deseada (usuario comprador o no comprador). 

# In [5]
df=df.drop(['user_pseudo_id'], axis=1) features=['view_promotion','view_search_results','view_item_list','view_item','add_to_cart','begin_checkout','add_shipping_info','add_payment_info'] train = df.sample(frac = .8, random_state = 14) test = df.drop(train.index) X_train = train[features] X_test = test[features] y_train = train['buyer'] y_test = test['buyer'] np.random.seed(0)

Por otro lado, aunque es uno de los algoritmos más conocidos, es oportuno explicar brevemente qué es un árbol de decisión. Éste es sin lugar a dudas uno de los algortimos de clasificación (aunque también se usa en regresión) más sencillos de integrar y por ello uno de los más usados para analizar datos. Explicado de manera sencilla es una estructura con forma de árbol que nos ayuda a tomar decisiones basadas en condiciones. Cada uno de sus nodos representa una característica y cada rama una decisión. Al seguir todas las ramas del árbol se alcanzan las hojas, las cuales representan los resultados finales de las decisiones. El árbol se construye dividiendo recursivamente el conjunto de datos en subconjuntos más pequeños, seleccionando las características más importantes para separar las clases objet (comprador o no comprador en este caso). 

# In [6]
depth = 8 clf = tree.DecisionTreeClassifier(criterion = 'entropy', max_depth = depth) clf = clf.fit(X_train, y_train) fig, ax = plt.subplots(figsize = (36, 20)) outree = tree.plot_tree(clf, fontsize = 10, max_depth = depth, impurity = False, filled = True, feature_names = features, class_names = True) for o in outree: connect = o.arrow_patch plt.show()

# Out[6]...
Árbol de decisión con eventos de comercio electrónico de GA4

Árbol de decisión con eventos de comercio electrónico de GA4

# In [7]
txt_representation = tree.export_text(clf, feature_names=features) print(txt_representation)

# Out[7] ...
Representación textual del árbol de decisión de GA4

Representación textual del árbol de decisión previo

Comprobación del modelo

Se puede realizar antes o en este momento, pero la comprobación del funcionamiento (rendimiento) del modelo creado tanto a la hora de entrenarlo como en las pruebas a posteriori es fundamentel para poder validar la implementación al completo. En este ejemplo parece que con los valores obtenidos, el resultado previamente obtenido al aplicar el árbol de decisión explica correctamente el comportamiento de compra del usuario.

# In [8]
train_scores = [] test_scores = [] for depth in range(1, 10): clf = tree.DecisionTreeClassifier(criterion = 'entropy', max_depth = depth) clf = clf.fit(X_train, y_train) train_scores.append(1 - clf.score(X_train, y_train)) test_scores.append(1 - clf.score(X_test, y_test)) plt.plot(range(1, 10), train_scores, '-o', label = "train") plt.plot(range(1, 10), test_scores, '-o', label = "test") plt.legend(loc = 'best') plt.xlabel('Máxima profundidad') plt.ylabel('Error de clasificación') plt.ylim(0.004, 0.011) plt.show()

# Out[8] ...
Comprobación del rendimiento del modelo del árbol de decisión

Comprobación del rendimiento del modelo del árbol de decisión

Perfilado de usuarios

Aunque visualmente con lo desarrollado ya se podría obtener muchas conclusiones del comportamiento de quienes compran y quienes no, la realidad es que podemos detallar todo esto mucho más y en parte gracias a la IA Generativa. Por ejemplo preguntando lo siguiente:

Perfilado de usuarios compradores usando Chat GPT y el árbol de decisión desarrollado

Perfilado de usuarios compradores del árbol de decisión desarrollado

Muchas veces no nos planteamos este tipo de desarrollos por prejuzgar la dificultad o el tiempo que pueden conllevar. Sin embargo, la complejidad no es tanta si la comparamos con los beneficios que podemos extraer. Quedarse únicamente en análisis superficiales o confiar demasiado únicamente en las bondades de las herramientas casi siempre suele derivar en análisis poco óptimos. 

Antes de finalizar, si quieres seguir aprendiendo y profundizar mucho más sobre este tipo de desarrollos, te recomiendo mi último libro ‘Analítica de datos con Python para marketing digital‘ de la editorial Anaya. ¡Nos vemos en el próximo artículo!

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *