6.3.2. Churn in a TV Subscription Company#
6.3.2.1. Summary#
This is a private dataset provided by a TV cable provider [1]. The dataset consists of active customers during the first semester of 2014. The dataset as shipped contains 9,379 individual registries, each one with 46 attributes, including a churn label indicating whenever a customer is a churner. This label was created internally in the company, and can be regarded as highly accurate. In the dataset only 449 customers are churners, leading to a churn ratio of 4.79 %.
The features names are anonymized to protect the privacy of the customers.
Classes |
2 |
Churners |
449 |
Non-churners |
8930 |
Samples |
9379 |
Features |
46 |
6.3.2.2. Using the Dataset#
The dataset can be loaded through the load_churn_tv_subscriptions function.
This returns a Dataset object with the following attributes:
data: the feature matrixtarget: the target vectorcost_matrix: aCostMatrixover the four outcome termsinstance_costs: a dict of per-instance cost arrays ('tp_cost','tn_cost','fp_cost','fn_cost')feature_names: the feature namestarget_names: the target namesDESCR: the full description of the dataset
import pandas as pd
from empulse.datasets import load_churn_tv_subscriptions
dataset = load_churn_tv_subscriptions(backend=pd)
The backend argument selects the dataframe library used for data and target.
Pass the module itself — backend=pd for pandas or backend=pl for polars.
Unlike the other churn datasets, this one ships precomputed costs: its cost matrix is not
built from symbolic business parameters, so each of the four outcome terms is supplied directly
as an array in instance_costs. Those arrays are already costs, so they can be passed straight
through to the plain cost arguments of the models:
import pandas as pd
from empulse.datasets import load_churn_tv_subscriptions
from empulse.models import CSLogitClassifier
from sklearn.pipeline import Pipeline
from sklearn.preprocessing import StandardScaler
dataset = load_churn_tv_subscriptions(backend=pd)
X, y = dataset.data, dataset.target
costs = dataset.instance_costs
pipeline = Pipeline([
('scaler', StandardScaler()),
('model', CSLogitClassifier())
])
pipeline.fit(
X,
y,
model__tp_cost=costs['tp_cost'],
model__tn_cost=costs['tn_cost'],
model__fp_cost=costs['fp_cost'],
model__fn_cost=costs['fn_cost'],
)
To evaluate a model instead, wrap the cost matrix in a Metric and pass
the instance costs straight through:
6.3.2.3. Cost Matrix#
Actual positive \(y_i = 1\) |
Actual negative \(y_i = 0\) |
|
Predicted positive \(\hat{y}_i = 1\) |
|
|
Predicted negative \(\hat{y}_i = 0\) |
|
|
- with
\(\gamma_i\) : probability of the customer accepting the retention offer
\(CLV_i\) : customer lifetime value of the retained customer
\(d_i\) : cost of incentive offered to the customer
\(c_i\) : cost of contacting the customer