Ir al contenido principal

Customer Lifetime Value

En este tutorial, aprende a calcular el customer lifetime value en Python.
Actualizado 17 sept 2026  · 11 min leer

Explorar con IA

ChatGPTClaudePerplexity

El economista italiano Vilfredo Pareto afirmaba que el 80% del efecto procede del 20% de las causas: es la regla 80/20 o principio de Pareto. Del mismo modo, el 80% del negocio de muchas empresas proviene del 20% de sus clientes. Las compañías deben identificar a esos clientes clave y cultivar su relación para asegurar ingresos constantes. Para mantener una relación a largo plazo con los clientes, conviene planificar programas de fidelización como descuentos, ofertas, cupones, puntos y regalos.

Captar un cliente nuevo suele ser más caro que retener a uno existente: no necesitas invertir tantos recursos, tiempo ni esfuerzo en adquisición; basta con mantener satisfechos a los que ya tienes. Los analistas de negocio calculan con precisión el coste de adquisición de clientes usando el CLTV (Customer Lifetime Value). El CLTV indica los ingresos totales que aporta un cliente durante toda su relación con la empresa. Ayuda a centrarse en aquellos clientes con mayor potencial de ingresos futuros.

Customer Lifetime Value (CLTV)

«Customer Lifetime Value es un valor monetario que representa la cantidad de ingresos o beneficio que un cliente aportará a la empresa durante el tiempo que dure la relación». El CLTV muestra las implicaciones de captar clientes a largo plazo frente a clientes a corto plazo. El customer lifetime value (CLV) te ayuda a responder las preguntas de ventas más importantes para cualquier empresa:

  • ¿Cómo identificar a los clientes más rentables?
  • ¿Cómo puede una empresa ofrecer el mejor producto y maximizar los ingresos?
  • ¿Cómo segmentar a los clientes rentables?
  • ¿Qué presupuesto hay que invertir para captar clientes?

Calcular el customer lifetime value

Existen muchos enfoques para calcular el CLTV. Cada cual tiene su punto de vista. Para calcularlo necesitamos datos históricos de clientes, por lo que no se puede estimar directamente para clientes nuevos. Para resolverlo, los analistas de negocio desarrollan modelos de machine learning que predicen el CLTV de nuevos clientes. Veamos algunos enfoques para calcular el CLTV:

1) Puedes calcularlo sumando el beneficio/ingresos del cliente en un período dado. Por ejemplo, si el cliente lleva contigo 3 años, suma todo el beneficio de esos 3 años. Puedes promediar por año, semestre o mes, pero con este enfoque no podrás construir un modelo predictivo para clientes nuevos.

2) Construye un modelo de regresión para clientes existentes. Usa los últimos seis meses como variables independientes y los ingresos totales de tres años como variable dependiente, y entrena un modelo de regresión con estos datos.

3) El CLTV también puede implementarse usando valores RFM (recencia, frecuencia y valor monetario). Para más detalles, puedes consultar mi tutorial.

4) Usando la siguiente ecuación: CLTV = ((valor medio de pedido × frecuencia de compra)/tasa de abandono) × margen de beneficio.

      Customer Value = Average Order Value * Purchase Frequency
  • Average Order Value (AOV): el valor medio de pedido es el cociente entre los ingresos totales y el número total de pedidos. Representa la cantidad media que gasta un cliente en un pedido.

                         Average Order Value = Total Revenue / Total Number of Orders
    
  • Purchase Frequency (PF): la frecuencia de compra es el cociente entre el número total de pedidos y el número total de clientes. Indica el promedio de pedidos por cliente.

                        Purchase Frequency =  Total Number of Orders / Total Number of Customers
    
  • Churn rate: la tasa de abandono es el porcentaje de clientes que no vuelven a realizar un pedido.

  • Customer lifetime: es el período durante el cual el cliente ha estado realizando pedidos de forma continuada.

                                  Customer Lifetime=1/Churn Rate
    
  • Repeat rate: se define como el cociente entre el número de clientes con más de un pedido y el número de clientes únicos. Ejemplo: si tienes 10 clientes en un mes y 4 repiten, tu repeat rate es del 40%.

                                   Churn Rate= 1-Repeat Rate
    

Implementación de CLTV en Python (usando la fórmula)

Importar las librerías necesarias

#import modules
import pandas as pd # for dataframes
import matplotlib.pyplot as plt # for plotting graphs
import seaborn as sns # for plotting graphs
import datetime as dt
import numpy as np

Cargar el dataset

Primero cargamos el dataset Online Retail usando la función de pandas para leer CSV/Excel. Puedes descargar los datos desde aquí.

data = pd.read_excel("Online_Retail.xlsx")
data.head()
  InvoiceNo StockCode Description Quantity InvoiceDate UnitPrice CustomerID Country
0 536365 85123A WHITE HANGING HEART T-LIGHT HOLDER 6 2010-12-01 08:26:00 2.55 17850.0 United Kingdom
1 536365 71053 WHITE METAL LANTERN 6 2010-12-01 08:26:00 3.39 17850.0 United Kingdom
2 536365 84406B CREAM CUPID HEARTS COAT HANGER 8 2010-12-01 08:26:00 2.75 17850.0 United Kingdom
3 536365 84029G KNITTED UNION FLAG HOT WATER BOTTLE 6 2010-12-01 08:26:00 3.39 17850.0 United Kingdom
4 536365 84029E RED WOOLLY HOTTIE WHITE HEART. 6 2010-12-01 08:26:00 3.39 17850.0 United Kingdom

Eliminar duplicados

A veces el dataset llega con ruido. Puede haber duplicados que sesguen tu análisis. En Python, pandas ofrece la función drop_duplicates(), que elimina los registros repetidos.

filtered_data=data[['Country','CustomerID']].drop_duplicates()

Vamos con los insights

#Top ten country's customer
filtered_data.Country.value_counts()[:10].plot(kind='bar')
<matplotlib.axes._subplots.AxesSubplot at 0x7fe677a887f0>
bar chart

En el dataset, la mayoría de clientes son del «United Kingdom». Así que puedes filtrar los datos para clientes del Reino Unido.

uk_data=data[data.Country=='United Kingdom']
uk_data.info()
<class 'pandas.core.frame.DataFrame'>
Int64Index: 495478 entries, 0 to 541893
Data columns (total 8 columns):
InvoiceNo      495478 non-null object
StockCode      495478 non-null object
Description    494024 non-null object
Quantity       495478 non-null int64
InvoiceDate    495478 non-null datetime64[ns]
UnitPrice      495478 non-null float64
CustomerID     361878 non-null float64
Country        495478 non-null object
dtypes: datetime64[ns](1), float64(2), int64(1), object(4)
memory usage: 34.0+ MB

La función describe() de pandas es muy útil para obtener estadísticas de resumen: devuelve el recuento, la media, la desviación estándar, los valores mínimo y máximo y los cuartiles.

uk_data.describe()
  Quantity UnitPrice CustomerID
count 495478.000000 495478.000000 361878.000000
mean 8.605486 4.532422 15547.871368
std 227.588756 99.315438 1594.402590
min -80995.000000 -11062.060000 12346.000000
25% 1.000000 1.250000 14194.000000
50% 3.000000 2.100000 15514.000000
75% 10.000000 4.130000 16931.000000
max 80995.000000 38970.000000 18287.000000

Aquí se observa que algunos clientes han pedido cantidades negativas, lo cual no es posible. Por tanto, filtra Quantity mayor que cero.

uk_data = uk_data[(uk_data['Quantity']>0)]
uk_data.info()
<class 'pandas.core.frame.DataFrame'>
Int64Index: 486286 entries, 0 to 541893
Data columns (total 8 columns):
InvoiceNo      486286 non-null object
StockCode      486286 non-null object
Description    485694 non-null object
Quantity       486286 non-null int64
InvoiceDate    486286 non-null datetime64[ns]
UnitPrice      486286 non-null float64
CustomerID     354345 non-null float64
Country        486286 non-null object
dtypes: datetime64[ns](1), float64(2), int64(1), object(4)
memory usage: 33.4+ MB

Filtrar las columnas necesarias

Aquí filtramos las columnas imprescindibles para calcular el CLTV. Solo necesitas cinco: CustomerID, InvoiceDate, InvoiceNo, Quantity y UnitPrice.

  • CustomerID identifica de forma única a tus clientes.
  • InvoiceDate te ayuda a calcular los días que el cliente ha permanecido activo.
  • InvoiceNo te permite contar cuántas transacciones ha realizado (frecuencia).
  • Quantity son las unidades compradas en cada transacción.
  • UnitPrice es el precio por unidad y te servirá para calcular el importe total comprado.
uk_data=uk_data[['CustomerID','InvoiceDate','InvoiceNo','Quantity','UnitPrice']]
#Calulate total purchase
uk_data['TotalPurchase'] = uk_data['Quantity'] * uk_data['UnitPrice']

Ahora vamos a realizar estas operaciones:

  • Calcular los días entre la fecha actual y la última compra de cada cliente.
  • Calcular el número de pedidos de cada cliente.
  • Calcular la suma del importe comprado por cada cliente.
uk_data_group=uk_data.groupby('CustomerID').agg({'InvoiceDate': lambda date: (date.max() - date.min()).days,
                                        'InvoiceNo': lambda num: len(num),
                                        'Quantity': lambda quant: quant.sum(),
                                        'TotalPurchase': lambda price: price.sum()})
uk_data_group.head()
  InvoiceDate InvoiceNo Quantity TotalPurchase
CustomerID        
12346.0 0 1 74215 77183.60
12747.0 366 103 1275 4196.01
12748.0 372 4596 25748 33719.73
12749.0 209 199 1471 4090.88
12820.0 323 59 722 942.34

Renombrar columnas

# Change the name of columns
uk_data_group.columns=['num_days','num_transactions','num_units','spent_money']
uk_data_group.head()
  num_days num_transactions num_units spent_money
CustomerID        
12346.0 0 1 74215 77183.60
12747.0 366 103 1275 4196.01
12748.0 372 4596 25748 33719.73
12749.0 209 199 1471 4090.88
12820.0 323 59 722 942.34

Calcular el CLTV con la siguiente fórmula:

 CLTV = ((Average Order Value x Purchase Frequency)/Churn Rate) x Profit margin.

 Customer Value = Average Order Value * Purchase Frequency

1. Calcular el valor medio de pedido

# Average Order Value
uk_data_group['avg_order_value']=uk_data_group['spent_money']/uk_data_group['num_transactions']
uk_data_group.head()
  num_days num_transactions num_units spent_money avg_order_value
CustomerID          
12346.0 0 1 74215 77183.60 77183.600000
12747.0 366 103 1275 4196.01 40.737961
12748.0 372 4596 25748 33719.73 7.336756
12749.0 209 199 1471 4090.88 20.557186
12820.0 323 59 722 942.34 15.971864

2. Calcular la frecuencia de compra

purchase_frequency=sum(uk_data_group['num_transactions'])/uk_data_group.shape[0]

3. Calcular el repeat rate y la tasa de abandono

# Repeat Rate
repeat_rate=uk_data_group[uk_data_group.num_transactions > 1].shape[0]/uk_data_group.shape[0]
#Churn Rate
churn_rate=1-repeat_rate
purchase_frequency,repeat_rate,churn_rate
(90.37107880642694, 0.9818923743942872, 0.018107625605712774)

4. Calcular el margen de beneficio

El margen de beneficio es un ratio de rentabilidad muy usado. Representa qué porcentaje de las ventas totales se convierte en ganancia. Supongamos que nuestro negocio tiene aproximadamente un 5% de margen sobre la venta total.

# Profit Margin
uk_data_group['profit_margin']=uk_data_group['spent_money']*0.05
uk_data_group.head()
  num_days num_transactions num_units spent_money avg_order_value profit_margin
CustomerID            
12346.0 0 1 74215 77183.60 77183.600000 3859.1800
12747.0 366 103 1275 4196.01 40.737961 209.8005
12748.0 372 4596 25748 33719.73 7.336756 1685.9865
12749.0 209 199 1471 4090.88 20.557186 204.5440
12820.0 323 59 722 942.34 15.971864 47.1170

5. Calcular el customer lifetime value

# Customer Value
uk_data_group['CLV']=(uk_data_group['avg_order_value']*purchase_frequency)/churn_rate
#Customer Lifetime Value
uk_data_group['cust_lifetime_value']=uk_data_group['CLV']*uk_data_group['profit_margin']
uk_data_group.head()
  num_days num_transactions num_units spent_money avg_order_value profit_margin CLV cust_lifetime_value
CustomerID                
12346.0 0 1 74215 77183.60 77183.600000 3859.1800 3.852060e+08 1.486579e+12
12747.0 366 103 1275 4196.01 40.737961 209.8005 2.033140e+05 4.265538e+07
12748.0 372 4596 25748 33719.73 7.336756 1685.9865 3.661610e+04 6.173424e+07
12749.0 209 199 1471 4090.88 20.557186 204.5440 1.025963e+05 2.098545e+07
12820.0 323 59 722 942.34 15.971864 47.1170 7.971198e+04 3.755789e+06

Modelo predictivo de CLTV

Vamos a construir un modelo de predicción de CLTV.

Aquí vas a predecir el CLTV con un modelo de regresión lineal.

Primero, usa los datos cargados y filtrados arriba.

uk_data.head()
  CustomerID InvoiceDate InvoiceNo Quantity UnitPrice TotalPurchase month_yr
0 17850.0 2010-12-01 08:26:00 536365 6 2.55 15.30 Dec-2010
1 17850.0 2010-12-01 08:26:00 536365 6 3.39 20.34 Dec-2010
2 17850.0 2010-12-01 08:26:00 536365 8 2.75 22.00 Dec-2010
3 17850.0 2010-12-01 08:26:00 536365 6 3.39 20.34 Dec-2010
4 17850.0 2010-12-01 08:26:00 536365 6 3.39 20.34 Dec-2010

Extrae mes y año de InvoiceDate.

uk_data['month_yr'] = uk_data['InvoiceDate'].apply(lambda x: x.strftime('%b-%Y'))
uk_data.head()
  CustomerID InvoiceDate InvoiceNo Quantity UnitPrice TotalPurchase month_yr
0 17850.0 2010-12-01 08:26:00 536365 6 2.55 15.30 Dec-2010
1 17850.0 2010-12-01 08:26:00 536365 6 3.39 20.34 Dec-2010
2 17850.0 2010-12-01 08:26:00 536365 8 2.75 22.00 Dec-2010
3 17850.0 2010-12-01 08:26:00 536365 6 3.39 20.34 Dec-2010
4 17850.0 2010-12-01 08:26:00 536365 6 3.39 20.34 Dec-2010

La tabla dinámica (pivot table) agrupa columnas en una tabla bidimensional para ofrecer un resumen multidimensional de los datos.

sale=uk_data.pivot_table(index=['CustomerID'],columns=['month_yr'],values='TotalPurchase',aggfunc='sum',fill_value=0).reset_index()
sale.head()
month_yr CustomerID Apr-2011 Aug-2011 Dec-2010 Dec-2011 Feb-2011 Jan-2011 Jul-2011 Jun-2011 Mar-2011 May-2011 Nov-2011 Oct-2011 Sep-2011
0 12346.0 0.00 0.00 0.00 0.00 0.00 77183.60 0.00 0.00 0.00 0.00 0.00 0.00 0.00
1 12747.0 0.00 301.70 706.27 438.50 0.00 303.04 0.00 376.30 310.78 771.31 312.73 675.38 0.00
2 12748.0 1100.37 898.24 4228.13 1070.27 389.64 418.77 1113.27 2006.26 1179.37 2234.50 10639.23 2292.84 6148.84
3 12749.0 0.00 1896.13 0.00 763.06 0.00 0.00 0.00 0.00 0.00 859.10 572.59 0.00 0.00
4 12820.0 0.00 0.00 0.00 210.35 0.00 170.46 0.00 0.00 0.00 0.00 0.00 343.76 217.77

Sumemos las ventas de todos los meses.

sale['CLV']=sale.iloc[:,2:].sum(axis=1)
sale.head()
month_yr CustomerID Apr-2011 Aug-2011 Dec-2010 Dec-2011 Feb-2011 Jan-2011 Jul-2011 Jun-2011 Mar-2011 May-2011 Nov-2011 Oct-2011 Sep-2011 CLV
0 12346.0 0.00 0.00 0.00 0.00 0.00 77183.60 0.00 0.00 0.00 0.00 0.00 0.00 0.00 77183.60
1 12747.0 0.00 301.70 706.27 438.50 0.00 303.04 0.00 376.30 310.78 771.31 312.73 675.38 0.00 4196.01
2 12748.0 1100.37 898.24 4228.13 1070.27 389.64 418.77 1113.27 2006.26 1179.37 2234.50 10639.23 2292.84 6148.84 32619.36
3 12749.0 0.00 1896.13 0.00 763.06 0.00 0.00 0.00 0.00 0.00 859.10 572.59 0.00 0.00 4090.88
4 12820.0 0.00 0.00 0.00 210.35 0.00 170.46 0.00 0.00 0.00 0.00 0.00 343.76 217.77 942.34

Selección de variables

Debes dividir las columnas en variable dependiente (o objetivo) e independientes (o de entrada). Selecciona los últimos 6 meses como variables independientes.

X=sale[['Dec-2011','Nov-2011', 'Oct-2011','Sep-2011','Aug-2011','Jul-2011']]
y=sale[['CLV']]

Dividir los datos

Para evaluar el rendimiento del modelo, es buena práctica dividir el dataset en entrenamiento y prueba.

Separamos el dataset con train_test_split(). Hay que pasar 3 parámetros: features, target y el tamaño del conjunto de prueba. Además, puedes usar random_state como semilla para garantizar reproducibilidad. Si random_state es None, el generador usa np.random y la partición variará en cada ejecución.

#split training set and test set
from sklearn.cross_validation import train_test_split
X_train, X_test, y_train, y_test = train_test_split(X, y,random_state=0)

Desarrollo del modelo

Importa el módulo de regresión lineal y crea el objeto. Ajusta el modelo al conjunto de entrenamiento con fit() y realiza predicciones en test con predict().

# import model
from sklearn.linear_model import LinearRegression

# instantiate
linreg = LinearRegression()

# fit the model to the training data (learn the coefficients)
linreg.fit(X_train, y_train)

# make predictions on the testing set
y_pred = linreg.predict(X_test)
# print the intercept and coefficients
print(linreg.intercept_)
print(linreg.coef_)
[208.50969617]
[[0.99880551 0.80381254 1.60226829 1.67433228 1.52860813 2.87959449]]

¿Qué tal se ajusta el modelo a los datos?

Para evaluar el ajuste global del modelo lineal usamos el R-cuadrado. Es la proporción de varianza explicada por el modelo y toma valores entre 0 y 1. Cuanto más alto, mejor, porque indica que el modelo explica mayor varianza.

from sklearn import metrics

# compute the R Square for model
print("R-Square:",metrics.r2_score(y_test, y_pred))
R-Square: 0.9666074402817512

Este modelo tiene un R-cuadrado alto (0,96), por lo que ajusta bien a los datos.

Evaluación del modelo

Para problemas de regresión se usan las siguientes métricas (Ritchie Ng):

  • MAE (error absoluto medio): media del valor absoluto de los errores.
  • MSE (error cuadrático medio): media de los errores al cuadrado.
  • RMSE (raíz del error cuadrático medio): raíz cuadrada del MSE.
# calculate MAE using scikit-learn
print("MAE:",metrics.mean_absolute_error(y_test,y_pred))

#calculate mean squared error
print("MSE",metrics.mean_squared_error(y_test, y_pred))
# compute the RMSE of our predictions
print("RMSE:",np.sqrt(metrics.mean_squared_error(y_test, y_pred)))
MAE: 595.0282284701234
MSE 2114139.8898678957
RMSE: 1454.0082151995896

El RMSE es más popular que MSE y MAE porque se interpreta en las mismas unidades que y.

Ventajas y limitaciones del CLTV

El CLTV te ayuda a diseñar un plan de negocio eficaz y a escalar tu actividad. Permite crear segmentos de clientes con sentido, que a su vez ayudan a identificar las necesidades de cada segmento.

El customer lifetime value es una herramienta, no una estrategia. El CLTV identifica a los clientes más rentables, pero cómo rentabilizarlos depende de tu estrategia. A menudo los modelos de CLTV se confunden o se usan mal. La obsesión por el CLTV puede generar puntos ciegos: las empresas se enfocan solo en el mejor segmento y en repetir negocio con él, pero también es importante atender al resto de clientes.

Conclusión

¡Enhorabuena, has llegado al final del tutorial!

En este recorrido has visto en detalle qué es el customer lifetime value, distintos enfoques para calcular el CLTV, su implementación desde cero en Python, un modelo de predicción y sus pros y contras. También repasaste conceptos básicos de pandas como groupby y pivot table para resumir columnas y filas seleccionadas.

Ojalá ahora puedas aplicar el concepto de CLTV para analizar tus propios datasets. ¡Gracias por leer!

Si quieres seguir aprendiendo a analizar datos de clientes en Python, haz el curso de DataCamp Customer Analytics & A/B Testing in Python.

Temas
Python
Ciencia de datos

Cursos de Python

Curso

Introducción a Python

4 h
7M
Domina los fundamentos del análisis de datos con Python en cuatro horas y descubre sus paquetes más usados.
Ver detallesRight Arrow
Iniciar Curso
Ver másRight Arrow
Relacionado
Clustering k-means

Tutorial

Introducción a k-Means Clustering con scikit-learn en Python

En este tutorial, aprenda a aplicar k-Means Clustering con scikit-learn en Python

Kevin Babitz

8 min

Tutorial

Funciones en Python: cómo llamar y escribir funciones

Descubre cómo escribir funciones en Python reutilizables y eficientes. Domina los parámetros, las sentencias return y temas avanzados como las funciones lambda. Organiza mejor tu código con main() y otras buenas prácticas.
Karlijn Willems's photo

Karlijn Willems

14 min

Tutorial

Las mejores técnicas para gestionar valores perdidos que todo científico de datos debe conocer

Explore varias técnicas para manejar eficazmente los valores perdidos y sus implementaciones en Python.
Zoumana Keita 's photo

Zoumana Keita

15 min

Tutorial

Tutorial de ecuación normal para regresión lineal

Aprende qué es la ecuación normal y cómo puedes utilizarla para construir modelos de machine learning.
Kurtis Pykes 's photo

Kurtis Pykes

8 min

Tutorial

Tutorial de visualización de datos con Python y Tableau

Aprende a utilizar Python para ampliar las funciones de visualización de datos de Tableau.
Abid Ali Awan's photo

Abid Ali Awan

15 min

Python

Tutorial

Comprender la regresión logística en el tutorial de Python

Aprende sobre la regresión logística, sus propiedades básicas, y construye un modelo de machine learning sobre una aplicación del mundo real en Python.
Avinash Navlani's photo

Avinash Navlani

10 min

Ver MásVer Más