电信客户流失预测----科大讯飞xDataWhale

记录第一次参加正式的数据挖掘竞赛,由科大讯飞xDatawhale举办的《电信客户流失预测挑战赛》

 报名链接:2022 iFLYTEK A.I.开发者大赛-讯飞开放平台

一、赛题概要

赛题背景

        随着市场饱和度的上升,电信运营商的竞争也越来越激烈,电信运营商亟待解决减少用户流失,延长用户生命周期的问题。对于客户流失率而言,每增加5%,利润就可能随之降低25%-85%。因此,如何减少电信用户流失的分析与预测至关重要。

        鉴于此,运营商会经常设有客户服务部门,该部门的职能主要是做好客户流失分析,赢回高概率流失的客户,降低客户流失率。某电信机构的客户存在大量流失情况,导致该机构的用户量急速下降。面对如此头疼的问题,该机构将部分客户数据开放,诚邀大家帮助他们建立流失预测模型来预测可能流失的客户。

 赛题任务

        给定某电信机构实际业务中的相关客户信息,包含69个与客户相关的字段,其中“是否流失”字段表明客户会否会在观察日期后的两个月内流失。任务目标是通过训练集训练模型,来预测客户是否会流失,以此为依据开展工作,提高用户留存。

评价指标

AUC评价指标

        AUC评价指标因为其不用手动设置阈值的特点常用于二分类的预测任务中。

简要分析

        通过上述描述可以了解到,题目是二分类预测,拥有69个特征字段,目标字段为”是否流失“。

二、数据探索(EDA)

配置环境导入相关包

#导入库
import pandas as pd
import os
import gc
import lightgbm as lgb
import xgboost as xgb
from catboost import CatBoostRegressor
from hyperopt import hp, fmin, tpe
from sklearn.linear_model import SGDRegressor, LinearRegression, Ridge
from sklearn.preprocessing import MinMaxScaler
from gensim.models import Word2Vec
import math
import numpy as np
from numpy.random import RandomState
from tqdm import tqdm
from sklearn.model_selection import StratifiedKFold, KFold
from sklearn.metrics import accuracy_score, f1_score, roc_auc_score, log_loss
import matplotlib.pyplot as plt
import time
import warnings
warnings.filterwarnings('ignore')

数据读入

train_data = pd.read_csv("train.csv")
test_data = pd.read_csv("test.csv")

 简要查看数据信息

#查看训练集和测试集前5行
train_data.head()
test_data.head()
#查看训练集和测试集的列
print('Train_data.columns:',train_data.columns)
print('Test_data.columns:',test_data.columns)
#查看训练集和测试集的形状
print('Train data shape:',train_data.shape)
print('Test data shape:',test_data.shape)

Train data shape: (150000, 69)
Test data shape: (30000, 68)
#查看数据信息
train_data.info()
test_data.info()
<class 'pandas.core.frame.DataFrame'>
RangeIndex: 150000 entries, 0 to 149999
Data columns (total 69 columns):
 #   Column                 Non-Null Count   Dtype
---  ------                 --------------   -----
 0   客户ID                   150000 non-null  int64
 1   地理区域                   150000 non-null  int64
 2   是否双频                   150000 non-null  int64
 3   是否翻新机                  150000 non-null  int64
 4   当前手机价格                 150000 non-null  int64
 5   手机网络功能                 150000 non-null  int64
 6   婚姻状况                   150000 non-null  int64
 7   家庭成人人数                 150000 non-null  int64
 8   信息库匹配                  150000 non-null  int64
 9   预计收入                   150000 non-null  int64
 10  信用卡指示器                 150000 non-null  int64
 11  当前设备使用天数               150000 non-null  int64
 12  在职总月数                  150000 non-null  int64
 13  家庭中唯一订阅者的数量            150000 non-null  int64
 14  家庭活跃用户数                150000 non-null  int64
 15  新手机用户                  150000 non-null  int64
 16  信用等级代码                 150000 non-null  int64
 17  平均月费用                  150000 non-null  int64
 18  每月平均使用分钟数              150000 non-null  int64
 19  平均超额使用分钟数              150000 non-null  int64
 20  平均超额费用                 150000 non-null  int64
 21  平均语音费用                 150000 non-null  int64
 22  数据超载的平均费用              150000 non-null  int64
 23  平均漫游呼叫数                150000 non-null  int64
 24  当月使用分钟数与前三个月平均值的百分比变化  150000 non-null  int64
 25  当月费用与前三个月平均值的百分比变化     150000 non-null  int64
 26  平均掉线语音呼叫数              150000 non-null  int64
 27  平均丢弃数据呼叫数              150000 non-null  int64
 28  平均占线语音呼叫数              150000 non-null  int64
 29  平均占线数据调用次数             150000 non-null  int64
 30  平均未接语音呼叫数              150000 non-null  int64
 31  未应答数据呼叫的平均次数           150000 non-null  int64
 32  尝试拨打的平均语音呼叫次数          150000 non-null  int64
 33  尝试数据调用的平均数             150000 non-null  int64
 34  平均接听语音电话数              150000 non-null  int64
 35  平均完成的语音呼叫数             150000 non-null  int64
 36  完成数据调用的平均数             150000 non-null  int64
 37  平均客户服务电话次数             150000 non-null  int64
 38  使用客户服务电话的平均分钟数         150000 non-null  int64
 39  一分钟内的平均呼入电话数           150000 non-null  int64
 40  平均三通电话数                150000 non-null  int64
 41  已完成语音通话的平均使用分钟数        150000 non-null  int64
 42  平均呼入和呼出高峰语音呼叫数         150000 non-null  int64
 43  平均峰值数据调用次数             150000 non-null  int64
 44  使用高峰语音通话的平均不完整分钟数      150000 non-null  int64
 45  平均非高峰语音呼叫数             150000 non-null  int64
 46  非高峰数据呼叫的平均数量           150000 non-null  int64
 47  平均掉线或占线呼叫数             150000 non-null  int64
 48  平均尝试调用次数               150000 non-null  int64
 49  平均已完成呼叫数               150000 non-null  int64
 50  平均呼叫转移呼叫数              150000 non-null  int64
 51  平均呼叫等待呼叫数              150000 non-null  int64
 52  账户消费限额                 150000 non-null  int64
 53  客户生命周期内的总通话次数          150000 non-null  int64
 54  客户生命周期内的总使用分钟数         150000 non-null  int64
 55  客户生命周期内的总费用            150000 non-null  int64
 56  计费调整后的总费用              150000 non-null  int64
 57  计费调整后的总分钟数             150000 non-null  int64
 58  计费调整后的呼叫总数             150000 non-null  int64
 59  客户生命周期内平均月费用           150000 non-null  int64
 60  客户生命周期内的平均每月使用分钟数      150000 non-null  int64
 61  客户整个生命周期内的平均每月通话次数     150000 non-null  int64
 62  过去三个月的平均每月使用分钟数        150000 non-null  int64
 63  过去三个月的平均每月通话次数         150000 non-null  int64
 64  过去三个月的平均月费用            150000 non-null  int64
 65  过去六个月的平均每月使用分钟数        150000 non-null  int64
 66  过去六个月的平均每月通话次数         150000 non-null  int64
 67  过去六个月的平均月费用            150000 non-null  int64
 68  是否流失                   150000 non-null  int64
dtypes: int64(69)
memory usage: 79.0 MB

从输出的信息可以看到,本次数据都是int类型,暂时看没有缺失值,具体等待后面缺失值处理部分详细处理。

#describe 查看简要信息,看数据有无异常等情况
train_data.describe()

describe() 方法可以让我们快速的对数据整体有个概念,可以方便的从上面观察到一些异常值等。从上图可以看到,其中多项特征最小值为-1, 对于家庭成人人数等特征,猜测-1值为举办方对于缺失值的填充处理,后面可将-1作为异常值考虑。

相关性分析

查看对于’是否流失‘的相关系数:

是否流失                     1.000000
当前设备使用天数                 0.117242
手机网络功能                   0.088076
家庭中唯一订阅者的数量              0.035298
婚姻状况                     0.024911
平均语音费用                   0.024728
平均超额费用                   0.023879
信息库匹配                    0.022176
在职总月数                    0.021920
平均超额使用分钟数                0.019263
家庭活跃用户数                  0.014626
信用卡指示器                   0.013053
平均漫游呼叫数                  0.011900
当月费用与前三个月平均值的百分比变化       0.006713
客户ID                     0.001306
平均呼叫转移呼叫数               -0.003266
计费调整后的总费用               -0.003317
地理区域                    -0.003459
客户生命周期内的总费用             -0.003480
平均占线数据调用次数              -0.005112
未应答数据呼叫的平均次数            -0.006067
数据超载的平均费用               -0.006451
新手机用户                   -0.006805
平均丢弃数据呼叫数               -0.008222
客户生命周期内平均月费用            -0.010270
平均峰值数据调用次数              -0.011339
信用等级代码                  -0.012046
非高峰数据呼叫的平均数量            -0.012354
平均占线语音呼叫数               -0.012965
完成数据调用的平均数              -0.013026
平均掉线语音呼叫数               -0.013157
过去六个月的平均月费用             -0.013646
过去三个月的平均月费用             -0.013932
尝试数据调用的平均数              -0.013940
平均月费用                   -0.014820
客户生命周期内的总通话次数           -0.017114
计费调整后的呼叫总数              -0.017572
平均掉线或占线呼叫数              -0.017906
预计收入                    -0.018576
客户生命周期内的总使用分钟数          -0.018654
计费调整后的总分钟数              -0.019213
是否双频                    -0.019965
家庭成人人数                  -0.024942
客户整个生命周期内的平均每月通话次数      -0.025390
平均三通电话数                 -0.025761
客户生命周期内的平均每月使用分钟数       -0.026500
是否翻新机                   -0.029043
平均呼叫等待呼叫数               -0.030874
一分钟内的平均呼入电话数            -0.033057
过去六个月的平均每月通话次数          -0.034927
平均未接语音呼叫数               -0.036626
平均客户服务电话次数              -0.037086
当月使用分钟数与前三个月平均值的百分比变化   -0.038794
使用客户服务电话的平均分钟数          -0.040060
过去六个月的平均每月使用分钟数         -0.040761
平均接听语音电话数               -0.041215
过去三个月的平均每月通话次数          -0.044770
平均非高峰语音呼叫数              -0.047101
尝试拨打的平均语音呼叫次数           -0.049644
平均尝试调用次数                -0.050090
平均呼入和呼出高峰语音呼叫数          -0.050286
使用高峰语音通话的平均不完整分钟数       -0.051437
过去三个月的平均每月使用分钟数         -0.051533
平均完成的语音呼叫数              -0.052980
平均已完成呼叫数                -0.053415
已完成语音通话的平均使用分钟数         -0.054818
每月平均使用分钟数               -0.060694
账户消费限额                  -0.066694
当前手机价格                  -0.101998
Name: 是否流失, dtype: float64

对于目标’是否丢失‘ 相关系数较高的有当前设备使用天数 (0.117242)、 手机网络功能(0.088076)、当前手机价格 ( -0.101998)等。后面可以围绕相关系数较强的特征做进一步的特征构造、特征增强等。

卡方检验

        在做了皮尔森相关性分析后发现,每个特征对于目标特征的相关性都非常低,甚至都不能算得上是弱相关。在查阅了一些资料后,发现对于回归问题,也就是目标特征是连续值时,用皮尔森相关性来检验效果比较好。对于分类问题,目标特征是离散值时,可以考虑用卡方检验。

这里还需要注意一点是:

卡方检验输入的值不能为负值不然会报错         “Input X must be non-negative.”

也就是说在卡方检验前最好先进行区间缩放,是整个区间落在[0,1]内。

from sklearn.preprocessing import MinMaxScaler
from sklearn.feature_selection import SelectKBest
from sklearn.feature_selection import chi2

copy_train = train.copy()
#先进行区间缩放
MinMax_train = MinMaxScaler().fit_transform(copy_train)
#选择K个最好的特征,返回选择特征后的数据
SelectKBest(chi2, k=30).fit_transform(MinMax_train,train['是否流失'])

三、特征工程

数据预处理

无量纲化

        无量纲化主要包括标准化区间缩放,标准化是将满足正态分布的特征进一步转换为标准正态分布。区间缩放是将特征值缩放到某个区间内,常见的有[0,1]。

标准化需要计算特征的均值和标准差,在sklearn中可以直接调用。

from sklearn.preprocessing import StandardScaler

#返回值为标准化后的数据
StandardScaler().fit_transform()

区间缩放则常用最值进行缩放,也可以直接调用。

from sklearn.preprocessing import MinMaxScaler

#区间缩放,返回值为缩放到[0, 1]区间的数据
MinMaxScaler().fit_transform()

二值化

        对于某些特征,我们只要定性考虑时,可以对其设定一个阈值,对大于阈值的分为一类值(赋值为1),小于阈值的分为另一类(赋值为0)。则可以减少冗余特征信息。

from sklearn.preprocessing import Binarizer

#二值化,阈值设置为10,返回值为二值化后的数据
Binarizer(threshold=10).fit_transform()

OneHot编码

        有些特征的值之间并没有关系,例如当我们有[猫,狗,鸡]这样的输入我们不能直接令其编码为[1,2,3],这样会人为引入了大小关系。OneHot编码为[[1,0,0],[0,1,0],[0,0,1]]则避免了这一情况。

from sklearn.preprocessing import OneHotEncoder

#独热编码
OneHotEncoder().fit_transform()

特征选择

        当对数据进行预处理过后,还需要进行特征选择,选择出对于模型来说比较重要,有意义的特征,这样模型在学习的时候才能学到比较关键的信息,准确性才能高。

特征选择可以分为以下三种方法:

  • Filter 过滤法 
  • Wrapper  包装法
  • Embedded  嵌入法

Filter 过滤法

        过滤法的基本想法就是对每个特征值计算其相对于目标特征的信息值,得到多个结果。然后将多个服从某种计算方法的结果按照从大到小排序,输出前 k 个特征。显然,这样复杂度大大降低。那么关键的问题就是使用什么样的方法来度量,目标是选取目标特征关联最密切的一些特征。

  • Pearson相关系数
  • 卡方验证
  • 互信息和最大信息系数
  • 方差选择法

        Pearson相关系数:皮尔森相关系数衡量的是变量之间的线性相关性,结果的取值区间为[-1,1] , -1 表示完全的负相关), +1 表示完全的正相关, 0 表示没有线性相关性。

        卡方验证:卡方检验是检验类别型变量的相关性的常用方法

        互信息和最大信息系数:互信息也是评价类别型变量的相关性的常用方法

        方差选择法:方差选择法,先要计算各个特征的方差,然后根据阈值,选择方差大于阈值的特征。

Wrapper 包装法

        Wrapper的核心思想是递归消除。递归消除特征法使用一个基模型来进行多轮训练,每轮训练后,消除若干权值系数的特征,再基于新的特征集进行下一轮训练。过程如图。

这里写图片描述

Embedded 嵌入法


        和Wrapper 一样,嵌入法也是一种特征选择和算法训练同时进行的特征选择方法,其过程为先使 用使用带惩罚项的基模型进行训练,得到各个特征的权值系数,根据权值系数从大到小选择特征。嵌入法以惩罚项为核心进行特征选择,除了筛选出特征外,同时也进行了降维。

        经验来说,过滤法更快速,但更粗糙。包装法和嵌入法更精确,比较适合具体到算法去调整,但计算量比较大,运行时间长。当数据量很大的时候,优先使用方差过滤和互信息法调整,再上其他特征选择方法

Baseline

运行Baseline,分别跑了lgb、xgb以及catboost,分数如图。

根据结果可以看到,lgb的分数达到0.839这是没有对特征做太多处理,直接喂给模型的结果。

反向上分

后续按照前面的特征选择等方法做了尝试,做了特征选择如:Filter做特征选择、Wrapper做特征选择、hyperopt调参等等,结果没有提升反而下降了。甚至后面一度只有0.5,怀疑是做特征时有错误,导致学的都是错的。看来想要提分还是要先从特征入手,如何构建好的特征给模型可能就是对于这次比赛需要着重思考的地方吧。

 

每天都在反向上分,后续还会继续尝试做好特征并更新进度的。

参考文章

《精通特征工程》 爱丽丝·郑  阿曼达·卡萨丽

《机器学习算法竞赛实战》 王贺

《阿里云天池大赛赛题解析----机器学习篇》 天池平台

自动机器学习超参数调整(贝叶斯优化) - FlyingWarrior - 博客园 (cnblogs.com)

一种超参数优化技术-Hyperopt - 人工智能遇见磐创 - 博客园 (cnblogs.com)

参数优化 (apachecn.org)

lgb小结 - 知乎 (zhihu.com)

ds-ai-tech-notes/8.md at master · apachecn/ds-ai-tech-notes · GitHub

ds-ai-tech-notes/7.md at master · apachecn/ds-ai-tech-notes · GitHub

使用sklearn做单机特征工程 - jasonfreak - 博客园 (cnblogs.com)

​特征工程系列:聚合特征构造以及转换特征构造 - 云+社区 - 腾讯云 (tencent.com)

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值