Python) 고객 생애 가치(CLV)에 대해서 알아보기

2022. 3. 17. 23:09분석 Python/구현 및 자료

728x90

도입부

CLV 또는 LTV로 부르는 ‘고객 생애 가치’는 고객이 비즈니스에 기여한 금전적 가치를 가리키는데, 회사가 얼마나 수익성이 있을지 또는 신규 고객을 확보하기 위해 얼마나 많은 비용을 지출할 수 있는지를 이해하는 데 중요한 지표입니다.
고객생애가치(Customer Lifetime Value (CLV))는 고객이 인수부터 비즈니스와의 관계가 종료될 때까지 지출할 총 금액입니다.
즉 개별 고객이 창출하는 비즈니스 가치를 말해줍니다. 
고객 관계(Customer Relationships)가 수익성이 있는지 판별하고자 CLV를 사용합니다. 
제품, 마케팅, 광고, 영업 팀은 CLV를 기준으로 수익성을 유지하면서 고객 확보, 참여, 유지에 얼마의 비용을 투여할 것인지 결정합니다. CLV를 계산하려면 몇 가지를 알아야 합니다.

 

알아야 할 개념

평균 구매 금액 (Average Purchase Value, APV)
 
평균 총 마진 (Average Gross Margin)
  • 총 마진 = (총매출 - 매출 원가) / (총수익)
 
고객 수명 
 
고객 확보 비용 (Customer Acquisition Cost, CAC)
 

고객 생애 가치(CLV)

 

고객 생애 가치는 고객이 인수부터 비즈니스와의 관계가 종료될 때까지 지출할 총금액입니다.

고객 생애 가치는 측정항목은 다양한 마케팅 및 분석 목적으로 사용됩니다.

그래서 측정하기 위해서는 다양하고 복잡한 공식들이 나올 수 있습니다.

 

 

 

 


단순한 고객 생애 가치 계산

계산하는 방식은 다양하지만 여기선 하나의 예시를 보여드립니다

$고객 생애 가치(CLV) = (평균 구매 금액 X 총 마진 X 구매 빈도 X 고객 수명) - 고객 획득 비용$

 

예시

평균 구매 금액 월간 구독료 $10
총 마진 70%
고객 수명 60개월(5년)
고객 획득 비용 $20

$CLV = 10 x 0.7 x 60 - 20 = 400$


 

 Implementation

 

아래 데이터는 다음과 같습니다.

전자 상거래 회사는 고객을 세분화하고 이러한 세그먼트에 따라 마케팅 전략을 결정하려고 합니다.

 

DataSet

https://archive.ics.uci.edu/ml/datasets/Online+Retail+II

 

Attribute Information:

InvoiceNo: Invoice number. Nominal. A 6-digit integral number uniquely assigned to each transaction. If this code starts with the letter ‘c’, it indicates a cancellation.
StockCode: Product (item) code. Nominal. A 5-digit integral number uniquely assigned to each distinct product.
Description: Product (item) name. Nominal.
Quantity: The quantities of each product (item) per transaction. Numeric.
InvoiceDate: Invoice date and time. Numeric. The day and time when a transaction was generated.
UnitPrice: Unit price. Numeric. Product price per unit in sterling (£).
CustomerID: Customer number. Nominal. A 5-digit integral number uniquely assigned to each customer.
Country: Country name. Nominal. The name of the country where a customer resides.

 

 

1. 데이터 준비

여기서는 간단한 고객 생애 가치를 계산해보고자 한다.

import pandas as pd
from sklearn.preprocessing import MinMaxScalerpd.set_option('display.max_columns', 20)
pd.set_option('display.max_rows', 20)
pd.set_option('display.float_format', lambda x: '%.5f' % x)
df_ = pd.read_excel("online_retail_II.xlsx", sheet_name="Year 2009-2010")
df = df_.copy()
df = df[~df["Invoice"].str.contains("C", na=False)]
#Issuing return invoices
df = df[(df['Quantity'] > 0)]
df.dropna(inplace=True) #Missing values
df["TotalPrice"] = df["Quantity"] * df["Price"]
cltv_c = df.groupby('Customer ID').agg({'Invoice': lambda x: x.nunique(),
                                        'Quantity': lambda x: x.sum(),
                                        'TotalPrice': lambda x: x.sum()})
cltv_c.columns = ['total_transaction', 'total_unit', 'total_price']
cltv_c.head()
 

2. Average Order Value

$\text {average_order_value}=\frac {\text {total_price}}{\text {total_transaction}}$

 

cltv_c['avg_order_value'] = cltv_c['total_price']/cltv_c['total_transaction']
 

3. Purchage Frequency

$\frac {\text {total_transaction}}{\text {total_number_of_costumers}}$

cltv_c["purchase_frequency"] = cltv_c['total_transaction']/cltv_c.shape[0]

 

4. Repeat Rate & Churn Rate

repeat_rate = cltv_c[cltv_c.total_transaction > 1].shape[0] / cltv_c.shape[0]
cltv_c[cltv_c.total_transaction > 1].shape
#If there is more than  'one' transaction choose it.
 OUT = (2893, 5)
churn_rate = 1 - repeat_rate

 

5. Profit Margin

$\text {profit_margin} = \text {total_price} * 0.10$

cltv_c['profit_margin'] = cltv_c['total_price'] * 0.10

6. Customer Value

$\text {customer_value} = \text {average_order_value} * \text {purchase_frequency}$

cltv_c['customer_value'] = (cltv_c['avg_order_value'] * cltv_c["purchase_frequency"]) / churn_rate

7. Customer Lifetime Value

$CLTV = \frac {\text {customer_value}}{\text {churn_rate}}  * \text {profit_margin}$

 

cltv_c['cltv'] = cltv_c['customer_value'] * cltv_c['profit_margin']
cltv_c

 

scaler = MinMaxScaler(feature_range=(0, 1))
scaler.fit(cltv_c[["cltv"]])
cltv_c["scaled_cltv"] = scaler.transform(cltv_c[["cltv"]])
cltv_c.sort_values(by="scaled_cltv", ascending=False).head()

 

8. Creating Segments

cltv_c["segment"] = pd.qcut(cltv_c["scaled_cltv"], 4, labels=["D", "C", "B", "A"])
cltv_c.head()
cltv_c[["total_transaction", "total_unit", "total_price", "cltv", "scaled_cltv"]].sort_values(by="scaled_cltv",ascending=False).head()
cltv_c.groupby('segment')[['total_transaction','total_unit','total_price','cltv','scaled_cltv']].agg({'count','mean','sum'})

 

 

 

 

 


Reference

https://mixpanel.com/ko/resources/how-to-calculate-lifetime-value/#:~:text=CLV%20%EB%98%90%EB%8A%94%20LTV%EB%A1%9C%20%EB%B6%80%EB%A5%B4%EB%8A%94,%ED%95%98%EB%8A%94%20%EB%8D%B0%20%EC%A4%91%EC%9A%94%ED%95%9C%20%EC%A7%80%ED%91%9C%EC%9E%85%EB%8B%88%EB%8B%A4.

https://python.plainenglish.io/customer-lifetime-value-calculation-clv-296827dc949e

728x90