6. 结果分析与解读

在这一阶段,我们对模型的训练结果进行详细分析,并从中提炼出对业务具有指导意义的洞察。通过分析模型的性能和数据特征,我们能够提供有关客户流失的重要见解,并为银行的客户管理策略提供指导。

6.1 主要结果回顾

通过前面的模型训练与评估,我们得到了如下主要结果:

  • 准确率、精确率、** 召回率和 F1分数** 表现良好,说明模型对正负样本的分类有较高的准确性。
  • AUC-ROC 曲线 的 AUC 值较高(接近1),表明模型在区分客户流失与非流失客户方面有较好的性能。
  • 混淆矩阵 显示出模型在预测流失客户和未流失客户时的分类表现,FN(假负例,即流失客户预测为未流失客户的数量)较少,这意味着模型在识别流失客户时的召回率较高。

6.2 特征重要性分析

通过 XGBoost 的特征重要性分析,我们能够识别出对客户流失预测影响最大的几个特征。这些特征提供了业务洞察,有助于指导银行采取更有效的客户保留措施。

特征排名前几的重要性分析如下:

  1. 年龄(Age):年龄是影响客户流失的重要因素。我们观察到,年纪较大的客户往往流失概率较高,可能是因为他们对金融服务的需求较低,或者对更为复杂的数字化服务感到不适应。银行可以针对这一人群提供个性化的服务,如简化的在线操作流程或电话服务等。
  2. 账户余额(Balance):余额较低的客户更容易流失,表明这类客户可能对银行的服务不满意,或在其他金融机构中找到了更好的条件。银行可以通过提供更多定制化的理财产品或账户优惠,来增强此类客户的忠诚度。
  3. 信用评分(CreditScore):信用评分较低的客户有更高的流失风险,可能是由于他们无法享受到较为优惠的贷款或信用产品。针对这部分客户,银行可以设计更加灵活的信用产品或提供更具吸引力的服务套餐,以增强用户粘性。
  4. 是否为活跃客户(IsActiveMember):活跃客户的流失概率较低,这表明客户活跃度与其流失风险之间有显著的关联。银行可以通过推出促销活动、奖励积分或会员优惠等手段,激励更多客户成为活跃用户。
  5. 地域(Geography):地理因素也对流失有影响,某些特定国家(如法国)客户流失率较高。银行可以根据不同地区的客户行为特征,进行差异化的客户关怀和本地化服务。

6.3 评估结果解释

根据模型的评估结果,我们可以解读如下几点:

  • 召回率较高:意味着模型能够准确识别出大部分流失客户。这对于业务来说是关键,因为我们更关心能否及时找到有流失风险的客户并采取相应措施。
  • 精确率适中:模型虽然在捕获流失客户方面表现出色,但也存在一定的误报(即将未流失客户误分类为流失客户)。这意味着在实施干预措施时,银行需要谨慎,确保不对未流失客户进行不必要的干预。
  • AUC值较高:表示模型在区分流失与非流失客户方面具有良好的能力。AUC值接近1表明该模型具有很好的二分类能力。

6.4 指导性业务建议

基于结果分析,我们可以为银行提供以下几个关键的业务建议,以帮助减少客户流失并提高客户满意度:

  1. 针对老龄客户的服务优化: 年龄是影响客户流失的主要因素之一。银行可以推出专门针对老年客户的简化金融产品和操作流程,并且提供更多人工客服支持,以增强老年客户对银行服务的信任感和依赖性。
  2. 提高低余额客户的忠诚度: 余额较低的客户流失风险较高。银行可以通过提供专门的理财计划或优惠贷款,吸引这些客户参与更多的金融活动,进而提高他们的粘性。此外,制定针对低余额客户的忠诚度计划也是一种有效策略。
  3. 灵活的信用产品设计: 对于信用评分较低的客户,银行可以推出定制化的信贷产品,比如灵活的还款方式和低息贷款。通过给这些客户提供更好的金融选择,银行能够减少他们的流失风险。
  4. 增加客户活跃度: 活跃客户流失风险较低,因此银行应当通过推出更多激励机制来提升客户的活跃度,例如定期发送理财建议、开展积分兑换活动、提高存款利率等。通过增强客户的参与感和互动性,减少客户的流失率。
  5. 本地化客户关怀: 地理因素对流失也有重要影响,不同地区客户的行为模式可能有较大差异。银行可以根据不同国家或地区的特征,实施差异化的市场推广策略,并提供符合当地文化和需求的产品和服务。

6.5 模型的局限性与未来改进方向

尽管 XGBoost 模型在本案例中表现出色,但它仍有一些局限性:

  • 模型解释性不足:树模型虽然在预测准确性上表现出色,但相较于线性模型,其解释性较弱,尤其是当特征交互较复杂时,模型的透明度下降。
  • 特征依赖性强:该模型对输入特征依赖较大,如果数据存在噪声或不完整,模型性能可能会受到影响。
  • 流失客户的潜在复杂行为未被完全捕捉:有些客户的流失可能受到复杂的行为或情感因素影响,而模型可能无法捕捉这些因素。未来可以引入更多关于客户情感分析的数据,比如客户反馈、投诉记录等,以提升模型的精度。

针对以上局限性,未来的改进方向可以包括:

  • 引入更多客户行为和情感相关的数据维度,例如客户的反馈意见、电话记录或社交媒体数据,从而更全面地捕捉客户流失的潜在原因。
  • 结合线性模型或其他解释性强的模型,以提高整体模型的可解释性,帮助业务人员更好地理解客户行为。

6.6 小结

  1. 数据分析解释:模型分析揭示了年龄、余额、信用评分、活跃状态和地理位置是影响客户流失的重要因素。模型性能评估表明其对客户流失的识别能力较强,尤其是高召回率表明其能够有效识别大部分流失客户。
  2. 指导性意义:银行可以根据这些特征采取针对性的策略来减少客户流失,例如优化老龄客户的服务、提升低余额客户的忠诚度、提供灵活的信用产品以及提升客户活跃度。这些策略可以帮助银行更好地管理客户关系,降低客户流失率,提高整体客户满意度。

7. 完整代码

import matplotlib.pyplot as plt
import pandas as pd
import seaborn as sns
from sklearn.metrics import classification_report, roc_auc_score
from sklearn.metrics import roc_curve, confusion_matrix
from sklearn.model_selection import GridSearchCV
from sklearn.model_selection import train_test_split
from sklearn.preprocessing import StandardScaler
from xgboost import XGBClassifier

file_path = './dataset/004/Churn_Modelling.csv'
df = pd.read_csv(file_path)

# 查看数据的基本信息
print(df.info())  # 显示数据的列信息和数据类型
print(df.describe())  # 显示数值型列的统计信息
print(df.head())  # 显示前几行数据,检查数据读取是否正常

# 检查是否存在缺失值
print(df.isnull().sum())  # 输出每列缺失值的数量

# 检查是否有重复值
print(f"重复值数量: {df.duplicated().sum()}")  # 查看重复值的数量

# 删除重复值(如果有的话)
df.drop_duplicates(inplace=True)

# 绘制数值列的箱线图,检查异常值
plt.figure(figsize=(12, 6))
sns.boxplot(data=df[['CreditScore', 'Age', 'Balance', 'EstimatedSalary']])
plt.title('Boxplot of Numeric Columns')
plt.show()

# 过滤年龄在合理范围之外的异常值
df = df[(df['Age'] > 18) & (df['Age'] < 100)]

# 对其他列也可以根据业务逻辑进行处理,如余额
df = df[df['Balance'] >= 0]

# 设置图形风格
sns.set(style='whitegrid', palette='bright')

# 绘制数值列的直方图
df[['CreditScore', 'Age', 'Balance', 'EstimatedSalary']].hist(bins=20, figsize=(12, 8), color='skyblue')
plt.suptitle('Histograms of Numeric Columns', fontsize=16)
plt.show()

# 绘制客户年龄和账户余额的散点图,观察数据分布趋势
plt.figure(figsize=(8, 6))
plt.scatter(df['Age'], df['Balance'], alpha=0.6, c=df['Exited'], cmap='coolwarm')
plt.title('Scatterplot of Age vs Balance')
plt.xlabel('Age')
plt.ylabel('Balance')
plt.colorbar(label='Exited')
plt.show()

# 只选择数值型特征进行相关性计算
numeric_df = df.select_dtypes(include=['number'])

# 计算相关性矩阵
corr_matrix = numeric_df.corr()

# 绘制热图展示相关性
plt.figure(figsize=(10, 8))
sns.heatmap(corr_matrix, annot=True, cmap='coolwarm', fmt='.2f', linewidths=0.5)
plt.title('Correlation Matrix')
plt.show()

# 最终检查是否还有缺失值和重复值
print(f"最终缺失值数量: {df.isnull().sum().sum()}")
print(f"最终重复值数量: {df.duplicated().sum()}")

# 保存清洗后的数据
df.to_csv('./dataset/004/Churn_Modelling_cleaned.csv', index=False)

# 丢弃不相关的列
df = df.drop(['RowNumber', 'CustomerId', 'Surname'], axis=1)

# 检查特征选择后的数据
print(df.head())

# 使用独热编码处理类别特征
df = pd.get_dummies(df, columns=['Geography', 'Gender'], drop_first=True)

# 查看编码后的数据集
print(df.head())

# 创建新特征:账户余额与预估工资的比率
df['BalanceSalaryRatio'] = df['Balance'] / df['EstimatedSalary']

# 检查新特征的分布
print(df[['Balance', 'EstimatedSalary', 'BalanceSalaryRatio']].head())

# 定义特征和目标变量
X = df.drop('Exited', axis=1)
y = df['Exited']

# 先划分训练集和测试集
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)

# 选择需要标准化的数值特征
numeric_features = ['CreditScore', 'Age', 'Tenure', 'Balance', 'NumOfProducts', 'EstimatedSalary', 'BalanceSalaryRatio']

# 初始化标准化器
scaler = StandardScaler()

# 在训练集上拟合标准化器
X_train[numeric_features] = scaler.fit_transform(X_train[numeric_features])

# 使用相同的标准化器转换测试集
X_test[numeric_features] = scaler.transform(X_test[numeric_features])

# 构建并训练XGBoost分类器
xgb_model = XGBClassifier(
    n_estimators=100,  # 初始树数量
    learning_rate=0.1,  # 初始学习率
    max_depth=4,  # 树的最大深度
    scale_pos_weight=3,  # 处理类别不平衡问题
    random_state=42  # 固定随机数种子
)

# 训练模型
xgb_model.fit(X_train, y_train)

# 测试集预测
y_pred = xgb_model.predict(X_test)

# 输出混淆矩阵、分类报告和AUC值
print(confusion_matrix(y_test, y_pred))
print(classification_report(y_test, y_pred))

# 计算AUC分数
y_pred_prob = xgb_model.predict_proba(X_test)[:, 1]  # 获取流失客户的预测概率
auc = roc_auc_score(y_test, y_pred_prob)
print(f"AUC Score: {auc:.2f}")

# 定义超参数网格
param_grid = {
    'n_estimators': [100, 200],
    'max_depth': [3, 4, 5],
    'learning_rate': [0.01, 0.1, 0.2],
    'scale_pos_weight': [1, 2, 3]
}

# 网格搜索
grid_search = GridSearchCV(estimator=XGBClassifier(random_state=42),
                           param_grid=param_grid,
                           scoring='roc_auc',
                           cv=3,
                           verbose=1)

# 训练网格搜索模型
grid_search.fit(X_train, y_train)

# 输出最佳参数
print("Best parameters found: ", grid_search.best_params_)

# 使用最佳参数训练最终模型
best_xgb_model = grid_search.best_estimator_
y_best_pred = best_xgb_model.predict(X_test)

# 输出最佳模型的评估结果
print(classification_report(y_test, y_best_pred))


# 绘制混淆矩阵
def plot_confusion_matrix(y_true, y_pred):
    cm = confusion_matrix(y_true, y_pred)
    plt.figure(figsize=(6, 6))
    sns.heatmap(cm, annot=True, fmt="d", cmap="Blues", cbar=False)
    plt.title("Confusion Matrix", fontsize=16)
    plt.ylabel('Actual', fontsize=12)
    plt.xlabel('Predicted', fontsize=12)
    plt.show()


# 绘制ROC曲线
def plot_roc_curve(y_true, y_pred_prob):
    fpr, tpr, thresholds = roc_curve(y_true, y_pred_prob)
    plt.figure(figsize=(8, 6))
    plt.plot(fpr, tpr, color="orange", label=f'AUC = {auc:.2f}')
    plt.plot([0, 1], [0, 1], linestyle='--', color='gray')
    plt.title("ROC Curve", fontsize=16)
    plt.xlabel("False Positive Rate", fontsize=12)
    plt.ylabel("True Positive Rate", fontsize=12)
    plt.legend(loc="lower right")
    plt.grid(True)
    plt.show()


# 绘制混淆矩阵和ROC曲线
plot_confusion_matrix(y_test, y_best_pred)
plot_roc_curve(y_test, best_xgb_model.predict_proba(X_test)[:, 1])
© 版权声明
THE END
喜欢就支持一下吧
点赞6 分享
评论 抢沙发
头像-大赛人网
欢迎您留下宝贵的见解!
提交
头像-大赛人网

昵称

取消
昵称

    请登录后查看评论内容