Skip to content

Dataset Guide — Customer Churn Analysis

Source

Dataset: IBM/Kaggle Telco Customer Churn URL: https://www.kaggle.com/datasets/blastchar/telco-customer-churn File: WA_Fn-UseC_-Telco-Customer-Churn.csv Size: 7,043 rows × 21 columns


Column Descriptions

Column Type Description Notes
customerID str Unique customer identifier Format: XXXX-XXXXX
gender str Customer gender "Male" or "Female"
SeniorCitizen int Is customer a senior citizen? 0 or 1
Partner str Has a partner? "Yes" or "No"
Dependents str Has dependents? "Yes" or "No"
tenure int Months as a customer 0 to 72
PhoneService str Has phone service? "Yes" or "No"
MultipleLines str Multiple phone lines? "Yes", "No", "No phone service"
InternetService str Internet service provider "DSL", "Fiber optic", "No"
OnlineSecurity str Online security add-on "Yes", "No", "No internet service"
OnlineBackup str Online backup add-on "Yes", "No", "No internet service"
DeviceProtection str Device protection add-on "Yes", "No", "No internet service"
TechSupport str Tech support add-on "Yes", "No", "No internet service"
StreamingTV str Streaming TV subscription "Yes", "No", "No internet service"
StreamingMovies str Streaming movies subscription "Yes", "No", "No internet service"
Contract str Contract type "Month-to-month", "One year", "Two year"
PaperlessBilling str Paperless billing enrolled? "Yes" or "No"
PaymentMethod str Payment method "Electronic check", "Mailed check", "Bank transfer (automatic)", "Credit card (automatic)"
MonthlyCharges float Monthly charge amount (£) Range: 18.25 – 118.75
TotalCharges str Total charges to date Note: stored as string, has blanks for new customers
Churn str Did customer churn? "Yes" or "No" — this is our target variable

Key Data Quality Issues

Issue Column Fix
TotalCharges is a string, not float TotalCharges pd.to_numeric(..., errors="coerce")
11 rows have blank TotalCharges TotalCharges These are new customers with tenure=0 — fill with 0 or drop
SeniorCitizen is 0/1 not Yes/No SeniorCitizen Convert to "Yes"/"No" for consistency
Three-way "No internet service" values Multiple add-on columns Simplify to "Yes"/"No" or group with "No"

Summary Statistics

import pandas as pd

df = pd.read_csv("WA_Fn-UseC_-Telco-Customer-Churn.csv")
print(df.shape)           # (7043, 21)
print(df["Churn"].value_counts(normalize=True))
# No     0.7347
# Yes    0.2653

print(df["tenure"].describe())
# mean=32.4, median=29.0, std=24.6, min=0, max=72

Churn rate in this dataset: 26.5% — higher than a typical telecom company. This is intentional — the dataset is designed to make churn visible.


Tenure Buckets

Create this segmentation for analysis:

Bucket Months Label
New 0–6 "New (< 6 months)"
Growing 7–24 "Growing (6–24 months)"
Established 25–48 "Established (2–4 years)"
Loyal 49+ "Loyal (4+ years)"

Quick Data Exploration

import pandas as pd

df = pd.read_csv("WA_Fn-UseC_-Telco-Customer-Churn.csv")
df["TotalCharges"] = pd.to_numeric(df["TotalCharges"], errors="coerce")

# Churn rate by contract type
print(df.groupby("Contract")["Churn"].apply(lambda x: (x == "Yes").mean()).round(3))
# Month-to-month    0.427
# One year          0.113
# Two year          0.029

# Average tenure by churn status
print(df.groupby("Churn")["tenure"].mean().round(1))
# Churn
# No     37.6
# Yes    18.0

← Business Problem · Next: Data Cleaning →