热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

怎么用Python写一个电信客户流失预测模型

这篇文章主要讲解了“怎么用Python写一个电信客户流失预测模型”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,

这篇文章主要讲解了“怎么用Python写一个电信客户流失预测模型”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“怎么用Python写一个电信客户流失预测模型”吧!

01、商业理解

流失客户是指那些曾经使用过产品或服务,由于对产品失去兴趣等种种原因,不再使用产品或服务的顾客。

电信服务公司、互联网服务提供商、保险公司等经常使用客户流失分析和客户流失率作为他们的关键业务指标之一,因为留住一个老客户的成本远远低于获得一个新客户。

预测分析使用客户流失预测模型,通过评估客户流失的风险倾向来预测客户流失。由于这些模型生成了一个流失概率排序名单,对于潜在的高概率流失客户,他们可以有效地实施客户保留营销计划。

下面我们就教你如何用Python写一个电信用户流失预测模型,以下是具体步骤和关键代码。

02、数据理解

此次分析数据来自于IBM Sample Data Sets,统计自某电信公司一段时间内的消费数据。共有7043笔客户资料,每笔客户资料包含21个字段,其中1个客户ID字段,19个输入字段及1个目标字段-Churn(Yes代表流失,No代表未流失),输入字段主要包含以下三个维度指标:用户画像指标、消费产品指标、消费信息指标。字段的具体说明如下:

怎么用Python写一个电信客户流失预测模型

03、数据读入和概览

首先导入所需包。

df = pd.read_csv('./Telco-Customer-Churn.csv') df.head()

读入数据集

df = pd.read_csv('./Telco-Customer-Churn.csv') df.head()

怎么用Python写一个电信客户流失预测模型

04、数据初步清洗

首先进行初步的数据清洗工作,包含错误值和异常值处理,并划分类别型和数值型字段类型,其中清洗部分包含:

  • OnlineSecurity、OnlineBackup、DeviceProtection、TechSupport、StreamingTV、StreamingMovies:错误值处理

  • TotalCharges:异常值处理

  • tenure:自定义分箱

  • 定义类别型和数值型字段

# 错误值处理 repl_columns = [&#39;OnlineSecurity&#39;, &#39;OnlineBackup&#39;, &#39;DeviceProtection&#39;,                  &#39;TechSupport&#39;,&#39;StreamingTV&#39;, &#39;StreamingMovies&#39;]  for i in repl_columns:     df[i]  = df[i].replace({&#39;No internet service&#39; : &#39;No&#39;})   # 替换值SeniorCitizen df["SeniorCitizen"] = df["SeniorCitizen"].replace({1: "Yes", 0: "No"})   # 替换值TotalCharges df[&#39;TotalCharges&#39;] = df[&#39;TotalCharges&#39;].replace(&#39; &#39;, np.nan)   # TotalCharges空值:数据量小,直接删除 df = df.dropna(subset=[&#39;TotalCharges&#39;])  df.reset_index(drop=True, inplace=True)  # 重置索引  # 转换数据类型 df[&#39;TotalCharges&#39;] = df[&#39;TotalCharges&#39;].astype(&#39;float&#39;)  # 转换tenure def transform_tenure(x):     if x <= 12:         return &#39;Tenure_1&#39;     elif x <= 24:         return &#39;Tenure_2&#39;     elif x <= 36:         return &#39;Tenure_3&#39;     elif x <= 48:         return &#39;Tenure_4&#39;     elif x <= 60:         return &#39;Tenure_5&#39;     else:         return &#39;Tenure_over_5&#39;   df[&#39;tenure_group&#39;] = df.tenure.apply(transform_tenure)  # 数值型和类别型字段 Id_col = [&#39;customerID&#39;] target_col = [&#39;Churn&#39;]  cat_cols = df.nunique()[df.nunique() < 10].index.tolist()  num_cols = [i for i in df.columns if i not in cat_cols + Id_col]   print(&#39;类别型字段:\n&#39;, cat_cols) print(&#39;-&#39; * 30)  print(&#39;数值型字段:\n&#39;, num_cols)
类别型字段:  [&#39;gender&#39;, &#39;SeniorCitizen&#39;, &#39;Partner&#39;, &#39;Dependents&#39;, &#39;PhoneService&#39;,    &#39;MultipleLines&#39;, &#39;InternetService&#39;, &#39;OnlineSecurity&#39;,   &#39;OnlineBackup&#39;, &#39;DeviceProtection&#39;, &#39;TechSupport&#39;,   &#39;StreamingTV&#39;, &#39;StreamingMovies&#39;, &#39;Contract&#39;, &#39;PaperlessBilling&#39;,    &#39;PaymentMethod&#39;, &#39;Churn&#39;, &#39;tenure_group&#39;] ------------------------------ 数值型字段:  [&#39;tenure&#39;, &#39;MonthlyCharges&#39;, &#39;TotalCharges&#39;]

05、探索性分析

对指标进行归纳梳理,分用户画像指标,消费产品指标,消费信息指标。探索影响用户流失的关键因素。

1. 目标变量Churn分布

怎么用Python写一个电信客户流失预测模型

经过初步清洗之后的数据集大小为7032条记录,其中流失客户为1869条,占比26.6%,未流失客户占比73.4%。

df[&#39;Churn&#39;].value_counts()  No     5163 Yes    1869 Name: Churn, dtype: int64
trace0 = go.Pie(labels=df[&#39;Churn&#39;].value_counts().index,                  values=df[&#39;Churn&#39;].value_counts().values,                 hole=.5,                 rotation=90,                 marker=dict(colors=[&#39;rgb(154,203,228)&#39;, &#39;rgb(191,76,81)&#39;],                              line=dict(color=&#39;white&#39;, https://img1.php1.cn/3cd4a/24de0/978/5dd43b6e592c4383.webp" alt="怎么用Python写一个电信客户流失预测模型">

分析可见,男性和女性在客户流失比例上没有显著差异。

plot_bar(input_col=&#39;gender&#39;, target_col=&#39;Churn&#39;, title_name=&#39;性别与是否流失的关系&#39;)

3. 老年用户

怎么用Python写一个电信客户流失预测模型

老年用户流失比例更高,为41.68%,比非老年用户高近两倍,此部分原因有待进一步探讨。

plot_bar(input_col=&#39;SeniorCitizen&#39;, target_col=&#39;Churn&#39;, title_name=&#39;老年用户与是否流失的关系&#39;)

4. 是否有配偶

怎么用Python写一个电信客户流失预测模型

从婚姻情况来看,数据显示,未婚人群中流失的比例比已婚人数高出13%。

plot_bar(input_col=&#39;Partner&#39;, target_col=&#39;Churn&#39;, title_name=&#39;是否有配偶与是否流失的关系&#39;)

5. 上网时长

怎么用Python写一个电信客户流失预测模型

经过分析,这方面可以得出两个结论:

  • 用户的在网时长越长,表示用户的忠诚度越高,其流失的概率越低;

  • 新用户在1年内的流失率显著高于整体流失率,为47.68%。

plot_bar(input_col=&#39;tenure_group&#39;, target_col=&#39;Churn&#39;, title_name=&#39;在网时长与是否流失的关系&#39;)

6. 付款方式

怎么用Python写一个电信客户流失预测模型

支付方式上,支付上,选择电子支票支付方式的用户流失最高,达到45.29%,其他三种支付方式的流失率相差不大。

pd.crosstab(df[&#39;PaymentMethod&#39;], df[&#39;Churn&#39;])

怎么用Python写一个电信客户流失预测模型

plot_bar(input_col=&#39;PaymentMethod&#39;, target_col=&#39;Churn&#39;, title_name=&#39;付款方式与是否流失关系&#39;)

7. 月费用

怎么用Python写一个电信客户流失预测模型

整体来看,随着月费用的增加,流失用户的比例呈现高高低低的变化,月消费80-100元的用户相对较高。

plot_histogram(input_col=&#39;MonthlyCharges&#39;, title_name=&#39;月费用与是否流失关系&#39;)

8. 数值型属性相关性

怎么用Python写一个电信客户流失预测模型

从相关性矩阵图可以看出,用户的往来期间和总费用呈现高度相关,往来期间越长,则总费用越高。月消费和总消费呈现显著相关。

plt.figure(figsize=(15, 10))   sns.heatmap(df.corr(), linewidths=0.1, cmap=&#39;tab20c_r&#39;, annot=True) plt.title(&#39;数值型属性的相关性&#39;, fOntdict={&#39;fontsize&#39;: &#39;xx-large&#39;, &#39;fontweight&#39;:&#39;heavy&#39;})  plt.xticks(fOntsize=12) plt.yticks(fOntsize=12) plt.show()

06、特征选择

使用统计检定方式进行特征筛选。

# 删除tenure df = df.drop(&#39;tenure&#39;, axis=1)   from feature_selection import Feature_select  # 划分X和y X = df.drop([&#39;customerID&#39;, &#39;Churn&#39;], axis=1)  y = df[&#39;Churn&#39;]     fs = Feature_select(num_method=&#39;anova&#39;, cate_method=&#39;kf&#39;, pos_label=&#39;Yes&#39;) x_sel = fs.fit_transform(X, y)
2020 09:30:02 INFO attr select success! After select attr: [&#39;DeviceProtection&#39;, &#39;MultipleLines&#39;, &#39;OnlineSecurity&#39;,                      &#39;TechSupport&#39;, &#39;tenure_group&#39;, &#39;PaperlessBilling&#39;,                     &#39;InternetService&#39;, &#39;PaymentMethod&#39;, &#39;SeniorCitizen&#39;,                      &#39;MonthlyCharges&#39;, &#39;Dependents&#39;, &#39;Partner&#39;, &#39;Contract&#39;,                      &#39;StreamingTV&#39;, &#39;TotalCharges&#39;, &#39;StreamingMovies&#39;, &#39;OnlineBackup&#39;]

经过特征筛选,gender和PhoneService字段被去掉。

07、建模前处理

在python中,为满足建模需要,一般需要对数据做以下处理:

  • 对于二分类变量,编码为0和1;

  • 对于多分类变量,进行one_hot编码;

  • 对于数值型变量,部分模型如KNN、神经网络、Logistic需要进行标准化处理。

# 筛选变量 select_features = x_sel.columns  # 建模数据 df_model = pd.concat([df[&#39;customerID&#39;], df[select_features], df[&#39;Churn&#39;]], axis=1)  Id_col = [&#39;customerID&#39;] target_col = [&#39;Churn&#39;]  # 分类型 cat_cols = df_model.nunique()[df_model.nunique() < 10].index.tolist()  # 二分类属性 binary_cols = df_model.nunique()[df_model.nunique() == 2].index.tolist() # 多分类属性 multi_cols = [i for i in cat_cols if i not in binary_cols]   # 数值型 num_cols = [i for i in df_model.columns if i not in cat_cols + Id_col]   # 二分类-标签编码 le = LabelEncoder()  for i in binary_cols:     df_model[i] = le.fit_transform(df_model[i])   # 多分类-哑变量转换 df_model = pd.get_dummies(data=df_model, columns=multi_cols)  df_model.head()

怎么用Python写一个电信客户流失预测模型

08、模型建立和评估

首先使用分层抽样的方式将数据划分训练集和测试集。

# 重新划分 X = df_model.drop([&#39;customerID&#39;, &#39;Churn&#39;], axis=1)  y = df_model[&#39;Churn&#39;]    # 分层抽样 X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=0, stratify=y)  print(X_train.shape, X_test.shape, y_train.shape, y_test.shape)   #修正索引 for i in [X_train, X_test, y_train, y_test]:     i.index = range(i.shape[0])
(5625, 31) (1407, 31) (5625,) (1407,)
# 保存标准化训练和测试数据 st = StandardScaler() num_scaled_train = pd.DataFrame(st.fit_transform(X_train[num_cols]), columns=num_cols) num_scaled_test = pd.DataFrame(st.transform(X_test[num_cols]), columns=num_cols)   X_train_sclaed = pd.concat([X_train.drop(num_cols, axis=1), num_scaled_train], axis=1) X_test_sclaed = pd.concat([X_test.drop(num_cols, axis=1), num_scaled_test], axis=1)

然后建立一系列基准模型并比较效果。

怎么用Python写一个电信客户流失预测模型

假如我们关注roc指标,从模型表现效果来看,Naive Bayes效果最好。我们也可以对模型进行进一步优化,比如对决策树参数进行调优。

parameters = {&#39;splitter&#39;: (&#39;best&#39;,&#39;random&#39;),               &#39;criterion&#39;: ("gini","entropy"),               "max_depth": [*range(3, 20)],              }  clf = DecisionTreeClassifier(random_state=25) GS = GridSearchCV(clf, parameters, scoring=&#39;f1&#39;, cv=10) GS.fit(X_train, y_train)  print(GS.best_params_)   print(GS.best_score_)
{&#39;criterion&#39;: &#39;entropy&#39;, &#39;max_depth&#39;: 5, &#39;splitter&#39;: &#39;best&#39;} 0.585900839405024
clf = GS.best_estimator_  test_pred = clf.predict(X_test) print(&#39;测试集:\n&#39;, classification_report(y_test, test_pred))
测试集:                precision    recall  f1-score   support             0       0.86      0.86      0.86      1033            1       0.61      0.61      0.61       374      accuracy                           0.79      1407    macro avg       0.73      0.73      0.73      1407 weighted avg       0.79      0.79      0.79      1407

将这棵树绘制出来。

import graphviz dot_data = tree.export_graphviz(decision_tree=clf, max_depth=3,                                  out_file=None,                                   feature_names=X_train.columns,                                  class_names=[&#39;not_churn&#39;, &#39;churn&#39;],                                   filled=True,                                  rounded=True                                 ) graph = graphviz.Source(dot_data)

怎么用Python写一个电信客户流失预测模型

输出决策树属性重要性排序:

imp = pd.DataFrame(zip(X_train.columns, clf.feature_importances_)) imp.columns = [&#39;feature&#39;, &#39;importances&#39;] imp = imp.sort_values(&#39;importances&#39;, ascending=False) imp = imp[imp[&#39;importances&#39;] != 0]  table  = ff.create_table(np.round(imp, 4)) py.offline.iplot(table)

怎么用Python写一个电信客户流失预测模型

后续优化方向:

  • 数据:分类技术应用在目标类别分布越均匀的数据集时,其所建立之分类器通常会有比较好的分类效能。针对数据在目标字段上分布不平衡,可采用过采样和欠采样来处理类别不平衡问题;

  • 属性:进一步属性筛选方法和属性组合;

  • 算法:参数调优;调整预测门槛值来增加预测效能。

感谢各位的阅读,以上就是“怎么用Python写一个电信客户流失预测模型”的内容了,经过本文的学习后,相信大家对怎么用Python写一个电信客户流失预测模型这一问题有了更深刻的体会,具体使用情况还需要大家实践验证。这里是编程笔记,小编将为大家推送更多相关知识点的文章,欢迎关注!


推荐阅读
  • Explore how Matterverse is redefining the metaverse experience, creating immersive and meaningful virtual environments that foster genuine connections and economic opportunities. ... [详细]
  • Explore a common issue encountered when implementing an OAuth 1.0a API, specifically the inability to encode null objects and how to resolve it. ... [详细]
  • DNN Community 和 Professional 版本的主要差异
    本文详细解析了 DotNetNuke (DNN) 的两种主要版本:Community 和 Professional。通过对比两者的功能和附加组件,帮助用户选择最适合其需求的版本。 ... [详细]
  • UNP 第9章:主机名与地址转换
    本章探讨了用于在主机名和数值地址之间进行转换的函数,如gethostbyname和gethostbyaddr。此外,还介绍了getservbyname和getservbyport函数,用于在服务器名和端口号之间进行转换。 ... [详细]
  • 本文详细介绍了Java中org.neo4j.helpers.collection.Iterators.single()方法的功能、使用场景及代码示例,帮助开发者更好地理解和应用该方法。 ... [详细]
  • 本文将介绍如何编写一些有趣的VBScript脚本,这些脚本可以在朋友之间进行无害的恶作剧。通过简单的代码示例,帮助您了解VBScript的基本语法和功能。 ... [详细]
  • 本文基于刘洪波老师的《英文词根词缀精讲》,深入探讨了多个重要词根词缀的起源及其相关词汇,帮助读者更好地理解和记忆英语单词。 ... [详细]
  • 前言--页数多了以后需要指定到某一页(只做了功能,样式没有细调)html ... [详细]
  • 优化ListView性能
    本文深入探讨了如何通过多种技术手段优化ListView的性能,包括视图复用、ViewHolder模式、分批加载数据、图片优化及内存管理等。这些方法能够显著提升应用的响应速度和用户体验。 ... [详细]
  • 本文详细介绍了 GWT 中 PopupPanel 类的 onKeyDownPreview 方法,提供了多个代码示例及应用场景,帮助开发者更好地理解和使用该方法。 ... [详细]
  • 本文介绍了Java并发库中的阻塞队列(BlockingQueue)及其典型应用场景。通过具体实例,展示了如何利用LinkedBlockingQueue实现线程间高效、安全的数据传递,并结合线程池和原子类优化性能。 ... [详细]
  • 使用 Azure Service Principal 和 Microsoft Graph API 获取 AAD 用户列表
    本文介绍了一段通用代码示例,该代码不仅能够操作 Azure Active Directory (AAD),还可以通过 Azure Service Principal 的授权访问和管理 Azure 订阅资源。Azure 的架构可以分为两个层级:AAD 和 Subscription。 ... [详细]
  • 深入解析Spring Cloud Ribbon负载均衡机制
    本文详细介绍了Spring Cloud中的Ribbon组件如何实现服务调用的负载均衡。通过分析其工作原理、源码结构及配置方式,帮助读者理解Ribbon在分布式系统中的重要作用。 ... [详细]
  • 本文详细介绍了Java编程语言中的核心概念和常见面试问题,包括集合类、数据结构、线程处理、Java虚拟机(JVM)、HTTP协议以及Git操作等方面的内容。通过深入分析每个主题,帮助读者更好地理解Java的关键特性和最佳实践。 ... [详细]
  • Android 渐变圆环加载控件实现
    本文介绍了如何在 Android 中创建一个自定义的渐变圆环加载控件,该控件已在多个知名应用中使用。我们将详细探讨其工作原理和实现方法。 ... [详细]
author-avatar
envmm_884_836
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有