Kaggle实战:用Python从零到一搞定电信用户流失预测(附完整代码与数据集)

张开发
2026/4/18 14:44:31 15 分钟阅读

分享文章

Kaggle实战:用Python从零到一搞定电信用户流失预测(附完整代码与数据集)
Kaggle实战从数据清洗到模型部署的电信用户流失预测全流程指南项目背景与商业价值电信行业正面临前所未有的客户维系挑战。根据行业研究数据获取一个新客户的成本是保留现有客户的5-25倍而客户流失率每降低5%就能带来25%-95%的利润增长。这使得用户流失预测成为运营商最核心的数据分析应用场景之一。Kaggle上的Telco Customer Churn数据集记录了7043位电信客户的人口统计特征、服务订阅情况和账户信息是练习分类预测的绝佳材料。这个实战项目将带你完整走通从原始数据到预测模型的每个环节掌握可复用的数据分析方法论。环境准备与数据加载首先确保你的Python环境已安装以下核心库# 基础数据处理 import pandas as pd import numpy as np # 可视化 import matplotlib.pyplot as plt import seaborn as sns # 机器学习 from sklearn.model_selection import train_test_split from sklearn.preprocessing import OneHotEncoder, StandardScaler from sklearn.compose import ColumnTransformer from sklearn.pipeline import make_pipeline # 设置可视化风格 plt.style.use(ggplot)加载数据集并快速浏览数据结构# 从本地加载数据 df pd.read_csv(WA_Fn-UseC_-Telco-Customer-Churn.csv) # 显示前3行样本 print(df.head(3).T) # 转置以便查看所有特征 # 检查数据维度 print(f数据集形状{df.shape})提示建议立即创建数据备份df_raw df.copy()所有预处理操作在副本上进行保留原始数据用于对照检查。深度数据探索分析(EDA)数据结构校验首先执行数据质量检查# 检查唯一ID print(f唯一客户ID数量{df[customerID].nunique()} (应与总样本数一致)) # 缺失值检测 missing df.isnull().sum() print(f缺失值统计\n{missing[missing 0]})发现TotalCharges列存在11个空白值显示为空格需要特殊处理# 将空格替换为NaN并转换类型 df[TotalCharges] pd.to_numeric(df[TotalCharges], errorscoerce) # 分析缺失值样本特征 missing_data df[df[TotalCharges].isnull()] print(missing_data[[tenure, MonthlyCharges, TotalCharges]].describe())目标变量分布分析客户流失比例# 计算流失比例 churn_rate df[Churn].value_counts(normalizeTrue) print(f流失比例\n{churn_rate}) # 可视化展示 plt.figure(figsize(8,6)) sns.countplot(datadf, xChurn) plt.title(客户流失分布, pad20) plt.show()特征相关性分析构建热图观察数值特征间关系# 选择数值特征 num_features [tenure, MonthlyCharges, TotalCharges] plt.figure(figsize(10,8)) sns.heatmap(df[num_features].corr(), annotTrue, cmapcoolwarm) plt.title(数值特征相关性矩阵, pad20) plt.show()关键发现在网时长(tenure)与总费用(TotalCharges)呈现强正相关(0.83)月费(MonthlyCharges)与总费用相关性中等(0.65)特征工程实战数据清洗与转换处理分类变量和缺失值# 填补TotalCharges缺失值根据业务逻辑新用户总费用应为0 df[TotalCharges] df[TotalCharges].fillna(0) # 将二元分类变量转换为0/1 binary_cols [Partner, Dependents, PaperlessBilling, PhoneService] df[binary_cols] df[binary_cols].apply(lambda x: x.map({Yes:1, No:0})) # 目标变量编码 df[Churn] df[Churn].map({Yes:1, No:0})特征分箱技巧对连续变量进行有意义的离散化# 在网时长分段 df[tenure_group] pd.cut(df[tenure], bins[0, 12, 24, 48, 72, np.inf], labels[0-1年, 1-2年, 2-4年, 4-6年, 6年以上]) # 月费分级 df[MonthlyCharges_level] pd.qcut(df[MonthlyCharges], q4, labels[低, 中低, 中高, 高])构建特征管道使用ColumnTransformer创建自动化特征处理流程# 定义特征类型 numeric_features [tenure, MonthlyCharges, TotalCharges] categorical_features [Contract, InternetService, PaymentMethod] # 创建预处理管道 preprocessor ColumnTransformer( transformers[ (num, StandardScaler(), numeric_features), (cat, OneHotEncoder(dropfirst), categorical_features) ]) # 示例转换 sample_data df.head() print(preprocessor.fit_transform(sample_data))模型构建与优化基准模型建立划分数据集并建立逻辑回归基准# 划分训练测试集 X df.drop([customerID, Churn], axis1) y df[Churn] X_train, X_test, y_train, y_test train_test_split(X, y, test_size0.3, random_state42) # 构建建模管道 from sklearn.linear_model import LogisticRegression model make_pipeline( preprocessor, LogisticRegression(class_weightbalanced, max_iter1000) ) # 训练与评估 model.fit(X_train, y_train) print(f测试集准确率{model.score(X_test, y_test):.2f})决策树模型调优使用网格搜索优化决策树参数from sklearn.tree import DecisionTreeClassifier from sklearn.model_selection import GridSearchCV # 定义参数网格 param_grid { decisiontreeclassifier__max_depth: [3, 5, 7], decisiontreeclassifier__min_samples_split: [2, 5, 10], decisiontreeclassifier__min_samples_leaf: [1, 2, 4] } # 创建决策树管道 tree_pipe make_pipeline( preprocessor, DecisionTreeClassifier(random_state42) ) # 网格搜索 grid_search GridSearchCV(tree_pipe, param_grid, cv5, scoringroc_auc) grid_search.fit(X_train, y_train) # 输出最佳参数 print(f最佳参数组合{grid_search.best_params_}) print(f最佳模型AUC{grid_search.best_score_:.2f})模型解释与业务洞察分析特征重要性# 获取特征名称 cat_encoder preprocessor.named_transformers_[cat] cat_features cat_encoder.get_feature_names_out(categorical_features) all_features numeric_features list(cat_features) # 提取特征重要性 dt_model grid_search.best_estimator_.named_steps[decisiontreeclassifier] importances pd.Series(dt_model.feature_importances_, indexall_features) # 可视化Top10特征 importances.nlargest(10).plot(kindbarh) plt.title(Top10重要特征) plt.show()关键业务发现合同类型是最强预测因子按月签约客户流失风险显著更高在网时长是第二重要特征新客户(0-12个月)流失率是长期客户的3倍光纤互联网用户比DSL用户更可能流失电子支票支付方式与较高流失率相关模型部署与监控保存训练好的模型使用joblib持久化模型import joblib # 保存最佳模型 joblib.dump(grid_search.best_estimator_, churn_model.pkl) # 保存预处理管道 joblib.dump(preprocessor, preprocessor.pkl)创建预测API示例使用Flask构建简易预测服务from flask import Flask, request, jsonify import pandas as pd app Flask(__name__) # 加载模型和预处理 model joblib.load(churn_model.pkl) preprocessor joblib.load(preprocessor.pkl) app.route(/predict, methods[POST]) def predict(): data request.get_json() input_data pd.DataFrame([data]) processed preprocessor.transform(input_data) prediction model.predict_proba(processed)[0][1] # 获取流失概率 return jsonify({churn_probability: float(prediction)}) if __name__ __main__: app.run(host0.0.0.0, port5000)模型监控指标建议跟踪以下生产环境指标预测分布漂移比较训练集和生产数据的特征分布模型衰减定期(如每月)在新鲜数据上评估性能业务影响跟踪模型干预后的客户留存率变化项目总结与改进方向本项目的完整代码已上传GitHub包含数据清洗和探索的Jupyter笔记本模块化特征工程代码模型训练和调优脚本简易API部署示例后续优化建议尝试集成方法如随机森林和XGBoost引入更多行为数据如客服互动记录开发动态特征窗口计算近30天使用变化构建自动化再训练管道注意实际业务部署时需考虑模型可解释性要求可能需要使用SHAP或LIME等技术提供预测解释。

更多文章