热门标签 | 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写一个电信客户流失预测模型这一问题有了更深刻的体会,具体使用情况还需要大家实践验证。这里是编程笔记,小编将为大家推送更多相关知识点的文章,欢迎关注!


推荐阅读
  • IjustinheritedsomewebpageswhichusesMooTools.IneverusedMooTools.NowIneedtoaddsomef ... [详细]
  • 拥抱Android Design Support Library新变化(导航视图、悬浮ActionBar)
    转载请注明明桑AndroidAndroid5.0Loollipop作为Android最重要的版本之一,为我们带来了全新的界面风格和设计语言。看起来很受欢迎࿰ ... [详细]
  • 本文介绍了Swing组件的用法,重点讲解了图标接口的定义和创建方法。图标接口用来将图标与各种组件相关联,可以是简单的绘画或使用磁盘上的GIF格式图像。文章详细介绍了图标接口的属性和绘制方法,并给出了一个菱形图标的实现示例。该示例可以配置图标的尺寸、颜色和填充状态。 ... [详细]
  • 本文整理了Java中java.lang.NoSuchMethodError.getMessage()方法的一些代码示例,展示了NoSuchMethodErr ... [详细]
  • 生成式对抗网络模型综述摘要生成式对抗网络模型(GAN)是基于深度学习的一种强大的生成模型,可以应用于计算机视觉、自然语言处理、半监督学习等重要领域。生成式对抗网络 ... [详细]
  • 本文讨论了在Windows 8上安装gvim中插件时出现的错误加载问题。作者将EasyMotion插件放在了正确的位置,但加载时却出现了错误。作者提供了下载链接和之前放置插件的位置,并列出了出现的错误信息。 ... [详细]
  • CSS3选择器的使用方法详解,提高Web开发效率和精准度
    本文详细介绍了CSS3新增的选择器方法,包括属性选择器的使用。通过CSS3选择器,可以提高Web开发的效率和精准度,使得查找元素更加方便和快捷。同时,本文还对属性选择器的各种用法进行了详细解释,并给出了相应的代码示例。通过学习本文,读者可以更好地掌握CSS3选择器的使用方法,提升自己的Web开发能力。 ... [详细]
  • 本文介绍了为什么要使用多进程处理TCP服务端,多进程的好处包括可靠性高和处理大量数据时速度快。然而,多进程不能共享进程空间,因此有一些变量不能共享。文章还提供了使用多进程实现TCP服务端的代码,并对代码进行了详细注释。 ... [详细]
  • 解决nginx启动报错epoll_wait() reported that client prematurely closed connection的方法
    本文介绍了解决nginx启动报错epoll_wait() reported that client prematurely closed connection的方法,包括检查location配置是否正确、pass_proxy是否需要加“/”等。同时,还介绍了修改nginx的error.log日志级别为debug,以便查看详细日志信息。 ... [详细]
  • 纠正网上的错误:自定义一个类叫java.lang.System/String的方法
    本文纠正了网上关于自定义一个类叫java.lang.System/String的错误答案,并详细解释了为什么这种方法是错误的。作者指出,虽然双亲委托机制确实可以阻止自定义的System类被加载,但通过自定义一个特殊的类加载器,可以绕过双亲委托机制,达到自定义System类的目的。作者呼吁读者对网上的内容持怀疑态度,并带着问题来阅读文章。 ... [详细]
  • 基于Socket的多个客户端之间的聊天功能实现方法
    本文介绍了基于Socket的多个客户端之间实现聊天功能的方法,包括服务器端的实现和客户端的实现。服务器端通过每个用户的输出流向特定用户发送消息,而客户端通过输入流接收消息。同时,还介绍了相关的实体类和Socket的基本概念。 ... [详细]
  • 本文介绍了使用readlink命令获取文件的完整路径的简单方法,并提供了一个示例命令来打印文件的完整路径。共有28种解决方案可供选择。 ... [详细]
  • [echarts] 同指标对比柱状图相关的知识介绍及应用示例
    本文由编程笔记小编为大家整理,主要介绍了echarts同指标对比柱状图相关的知识,包括对比课程通过率最高的8个课程和最低的8个课程以及全校的平均通过率。文章提供了一个应用示例,展示了如何使用echarts制作同指标对比柱状图,并对代码进行了详细解释和说明。该示例可以帮助读者更好地理解和应用echarts。 ... [详细]
  • 本文介绍了使用C++Builder实现获取USB优盘序列号的方法,包括相关的代码和说明。通过该方法,可以获取指定盘符的USB优盘序列号,并将其存放在缓冲中。该方法可以在Windows系统中有效地获取USB优盘序列号,并且适用于C++Builder开发环境。 ... [详细]
  • 本文整理了Java中org.apache.solr.common.SolrDocument.setField()方法的一些代码示例,展示了SolrDocum ... [详细]
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社区 版权所有