跳至内容

营销中的数据科学:客户流失率预测

学习如何使用 Python 机器学习模型预测客户流失率,将营销数据转化为可操作的洞见。
更新 2026年8月31日  · 10分钟

用 AI 探索

ChatGPTClaudePerplexity

 

引言 

在过去的 10-15 年里,随着数字技术的发展,营销策略发生了显著变化。无论是知名品牌还是细分市场,都积累了海量交易数据、客户购买记录、偏好、购买力、购买活动、人口统计、评价等。所有这些数据都能帮助营销人员理解客户在不同阶段的行为,从购买意图到实际购买,再到成为长期客户。这正是数据科学发挥潜力的地方。

数据科学将营销大数据转化为可执行的洞见,即便有时它看起来并不直观,例如一些不易察觉的消费者行为模式和共现关系。由此,营销人员可以更清晰地洞察目标受众,吸引新客户并留住现有客户,优化营销策略,提升公司曝光度,打造更成功的广告活动,拓展新渠道,并进而显著提升公司营收。

客户流失率预测是数据科学在营销中最典型的用例之一。下面我们将更详细地讨论这一主题。

营销中的数据科学用例:客户流失率预测

客户流失是指客户取消其正在使用的服务订阅,从而不再是该服务的客户。客户流失率是在预设时间区间内发生流失的客户所占的百分比。它与追踪新客户的客户增长率相对应。

客户流失率是衡量客户满意度和公司整体业务健康状况的关键指标。除任何业务中都会出现的自然流失,或某些服务常见的季节性流失外,还有其他因素意味着公司某些方面出现问题,需要修复。这些因素包括:

  • 缺乏客户支持或支持质量低,
  • 负面的客户体验,
  • 转向条件或定价更优的竞争对手,
  • 客户优先级发生改变,
  • 长期客户不再感到满意,
  • 服务未能满足客户预期,
  • 财务问题,
  • 对客户支付的欺诈保护导致的影响。

高流失率对任何公司而言都是严重问题,原因如下:

  • 它与公司收入损失相关。
  • 获取新客户的成本远高于留住现有客户,尤其是在竞争激烈的市场。
  • 如果因客户服务不佳而导致流失,不满的前客户可能会在社交媒体或点评网站留下负面评价,严重损害公司的声誉。

客户留存是所有订阅制服务业务战略的关键组成部分。要预测客户流失率并采取相应的预防措施,需要收集并分析客户行为信息(购买间隔、成为客户的总体时长、取消记录、跟进电话与消息、线上活动等),并找出哪些属性及其组合是有流失风险客户的特征。提前了解哪些客户可能即将流失,尤其是高营收或长期客户,有助于公司集中精力制定有效策略,尽力挽留他们。做法可以包括致电此类客户并提供特别优惠,如礼品、折扣、在同价位升级订阅,或其他个性化体验。

从技术上讲,客户流失预测是一个典型的机器学习分类问题,即用“是”或“否”为客户打标,以区分其是否存在流失风险。我们将使用 Python 在真实世界数据上探究这一用例。

我们将以电信行业为例建模,在该业务模型中,客户可以在一份总协议下与电信公司签订多个服务。数据集包含清洗后的客户活动特征,以及指示客户是否流失的标签。

先看一眼数据并探索流失率分布:

import pandas as pd

telcom = pd.read_csv('telco.csv')
print(f'Number of customers: {telcom.shape[0]:,}\n'
      f'Churn values: {set(telcom['Churn'])}\n\n'
      f'Churn distribution, %:\n{round(telcom.groupby(['Churn']).size()/telcom.shape[0]*100).convert_dtypes()}')
Number of customers: 7,032
Churn values: {0, 1}

Churn distribution, %:
Churn
0    73
1    27
dtype: float64

有 27% 的客户发生了流失,这是一个相当高的比例。与之前的数据科学用例相比,这个数据集似乎并不存在严重的类别不平衡问题。

接下来,我们将对数据进行预处理,以便应用机器学习技术进行流失预测。这包括将数据拆分为训练集和测试集,并提取特征和目标变量:

from sklearn.model_selection import train_test_split

target = ['Churn']
custid = ['customerID']

cols = [col for col in telcom.columns if col not in custid + target]

X = telcom[cols]
y = telcom[target]

X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.25)

我们将使用的第一个建模算法是简单的逻辑回归分类模型,用来预测流失标签并评估结果的准确率:

from sklearn.linear_model import LogisticRegression
from sklearn.metrics import accuracy_score

lr = LogisticRegression()
lr.fit(X_train, y_train)
predictions = lr.predict(X_test)
print(f'Test accuracy: {round(accuracy_score(y_test, predictions), 4)}')
Test accuracy: 0.8009

接着,我们为逻辑回归模型增加一项功能:在进行特征缩放的同时使用 L1 正则化,使得在建模的同时完成特征选择。C 参数(正则化强度的倒数)的不同取值会影响模型的准确率。这里先将 C 设置为 0.025:

lr = LogisticRegression(penalty='l1', C=0.025, solver='liblinear')
lr.fit(X_train, y_train)
predictions = lr.predict(X_test)
print(f'Test accuracy: {round(accuracy_score(y_test, predictions), 4)}')
Test accuracy: 0.7969

现在,我们将对 L1 正则化的 C 参数进行调优,以找到在降低模型复杂度的同时仍保持良好性能指标的最优值。为此,我们会遍历不同的 C 取值,为每个取值训练一个逻辑回归模型,并计算性能指标。

列表 C 事先已包含参数的可选取值。数组 l1_metrics 有 3 列,第一列为 C 值,后两列分别是非零系数数量和模型准确率的占位符。让我们来试一试这一方法:

 C  Non-Zero Coeffs  Accuracy
0  1.0000             23.0  0.801479
1  0.5000             22.0  0.799204
2  0.2500             21.0  0.802048
3  0.1000             20.0  0.802617
4  0.0500             18.0  0.802048
5  0.0250             13.0  0.796928
6  0.0100              5.0  0.790102
7  0.0050              3.0  0.783276
8  0.0025              2.0  0.745734

可以看到,较小的 C 值会减少非零系数(即用于建模的特征)数量,从而降低模型复杂度,但同时也会降低模型准确率。看起来 C=0.05 是较优选择:在将特征数量减少至 18 的同时,准确率略高于未正则化模型。

现在,我们来尝试另一种建模算法——决策树模型:

from sklearn.tree import DecisionTreeClassifier

clf = DecisionTreeClassifier()
clf.fit(X_train, y_train)
predictions = clf.predict(X_test)
print(f'Test accuracy: {round(accuracy_score(y_test, predictions), 4)}')
Test accuracy: 0.7275

为了在避免过拟合的同时选择更精确的模型,我们可以尝试调整树的深度(max_depth 参数),并确定其最优值。技术流程与上文选择逻辑回归最优 C 参数类似:在这里,我们会遍历多个 max_depth 值,为每个值训练一棵决策树,然后计算性能指标。

列表 depth_list 事先已包含参数的可选取值。数组 depth_tuning 有 2 列,第一列为候选深度,另一列为准确率的占位符。让我们应用这一方法来寻找最优树深度:

depth_list = list(range(2, 15))
depth_tuning = np.zeros((len(depth_list), 2))
depth_tuning[:, 0] = depth_list

for index in range(len(depth_list)):
    clf = DecisionTreeClassifier(max_depth=depth_list[index])
    clf.fit(X_train, y_train)
    predictions = clf.predict(X_test)
    depth_tuning[index, 1] = accuracy_score(y_test, predictions)
   
col_names = ['Max_Depth', 'Accuracy']
print(pd.DataFrame(depth_tuning, columns=col_names))
 Max_Depth  Accuracy
0         2.0  0.756542
1         3.0  0.783276
2         4.0  0.782708
3         5.0  0.791809
4         6.0  0.778157
5         7.0  0.780432
6         8.0  0.757110
7         9.0  0.762230
8        10.0  0.763936
9        11.0  0.752560
10       12.0  0.745165
11       13.0  0.732651
12       14.0  0.727531

因此,随着深度增加,准确率先上升后下降。在 max_depth 为 5 时,模型达到最高准确率,因此可将其视为最优树深度。

在确定了逻辑回归与决策树模型的最佳参数后,我们将重建这些模型,并识别与解读推动流失上升或下降的主要因素。

对于逻辑回归模型,我们将提取并分析最终系数的指数值:

# Reconstructing the best model
lr = LogisticRegression(penalty='l1', C=0.05, solver='liblinear')
lr.fit(X_train, y_train)
predictions = lr.predict(X_test)

# Combining feature names and coefficients into one dataframe
feature_names = pd.DataFrame(X_train.columns, columns=['Feature'])
log_coef = pd.DataFrame(np.transpose(lr.coef_), columns=['Coefficient'])
coefficients = pd.concat([feature_names, log_coef], axis=1)

# Calculating exponents of the coefficients
coefficients['Exp_Coefficient'] = np.exp(coefficients['Coefficient'])

# Removing coefficients that are equal to zero
coefficients = coefficients[coefficients['Coefficient']!=0]
print(coefficients.sort_values(by=['Exp_Coefficient']))
                          Feature  Coefficient  Exp_Coefficient
21                          tenure    -0.907750         0.403431
4                 PhoneService_Yes    -0.820517         0.440204
17               Contract_Two year    -0.595271         0.551413
8                  TechSupport_Yes    -0.418254         0.658195
16               Contract_One year    -0.414158         0.660896
5               OnlineSecurity_Yes    -0.412228         0.662173
6                 OnlineBackup_Yes    -0.143100         0.866667
3                   Dependents_Yes    -0.039299         0.961463
7             DeviceProtection_Yes    -0.017465         0.982687
11            PaperlessBilling_Yes     0.071389         1.073999
1                SeniorCitizen_Yes     0.097904         1.102857
19  PaymentMethod_Electronic check     0.188533         1.207477
22                  MonthlyCharges     0.901454         2.463182

可以看到,对流失赔率影响最大的特征是 tenure(客户在网时长)。一般来说,系数的指数小于 1 会降低流失赔率,而大于 1 会提高流失赔率。

对于决策树模型,我们将提取并可视化 if-else 规则:

# Reconstructing the best model
clf = DecisionTreeClassifier(max_depth=5)
clf.fit(X_train, y_train)
predictions = clf.predict(X_test)

from sklearn import tree
import graphviz

# Exporting a graphviz object from the trained decision tree
exported = tree.export_graphviz(decision_tree=clf,
                                out_file=None,
                                feature_names=cols,
                                precision=1,
                                class_names=['Not churn', 'Churn'],
                                filled=True)
graph = graphviz.Source(exported)
display(graph)

机器学习决策树

我们得到了一张可读性良好的决策树可视化,能够从顶部开始将其解释为一组 if-else 规则。再次可以看出,客户在网时长是驱动流失的最重要变量。决策树还可以扩展更多层级,以获取关于其他变量的更多洞见。

下一步可以尝试进一步调整模型参数,采用不同的训练/测试划分方式,应用并比较其他机器学习算法,并分析多种评分指标来评估模型表现。

如果您想更深入地了解客户流失率预测以及数据科学在营销中的其他应用,这门关于Python 营销机器学习的课程是一个不错的起点。

主题
数据科学
机器学习