科大讯飞:电信客户流失预测挑战赛baseline

from google.colab import drive
drive.mount('/content/drive')
import os
os.chdir('/content/drive/MyDrive/chinese task/讯飞-电信用户流失')
Mounted at /content/drive

参考:

!pip install unzip
!unzip '/content/drive/MyDrive/chinese task/讯飞-电信用户流失/电信客户流失预测挑战赛数据集.zip'n

读取数据集:

import pandas as pd
train= pd.read_csv('./train.csv');
test=pd.read_csv('./test.csv')
train
客户ID 地理区域 是否双频 是否翻新机 当前手机价格 手机网络功能 婚姻状况 家庭成人人数 信息库匹配 预计收入 ... 客户生命周期内平均月费用 客户生命周期内的平均每月使用分钟数 客户整个生命周期内的平均每月通话次数 过去三个月的平均每月使用分钟数 过去三个月的平均每月通话次数 过去三个月的平均月费用 过去六个月的平均每月使用分钟数 过去六个月的平均每月通话次数 过去六个月的平均月费用 是否流失
0 0 7 0 -1 181 0 2 0 0 3 ... 24 286 91 351 121 23 303 101 25 0
1 1 13 1 0 1399 0 3 0 0 0 ... 44 447 190 483 199 40 488 202 44 1
2 2 14 1 0 927 0 2 4 0 6 ... 48 183 79 271 95 71 209 77 54 0
3 3 1 0 0 232 0 3 -1 1 -1 ... 42 303 166 473 226 72 446 219 65 1
4 4 0 -1 0 699 0 1 2 0 3 ... 36 119 24 88 15 35 106 21 37 1
... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ...
149995 149995 10 1 0 1350 0 3 0 0 0 ... 156 474 160 239 80 74 346 122 83 1
149996 149996 6 1 0 542 0 3 -1 1 -1 ... 52 968 208 1158 257 58 1307 261 57 0
149997 149997 15 1 0 1300 0 1 2 0 6 ... 39 504 205 544 203 45 531 205 47 1
149998 149998 12 1 0 1399 0 4 1 0 -1 ... 91 685 249 233 140 94 432 236 97 1
149999 149999 10 1 0 1049 0 3 -1 1 -1 ... 37 177 80 147 59 35 167 74 34 0

150000 rows × 69 columns

一、查看各字段中分布情况

train['是否流失'].value_counts()#查看正负样本数
#查看是否有缺失值
missing_counts = pd.DataFrame(train.isnull().sum())
missing_counts.columns = ['count_null']
missing_counts.describe()
#查看各字段数据类型
for col in train.columns:
  print(f'{
     col} \t {
     train.dtypes[col]} {
     train[col].nunique()}')
import pandas as pd
import numpy as np

from sklearn.metrics import roc_auc_score
from sklearn.metrics import accuracy_score
from sklearn.model_selection import KFold
import time
from lightgbm import LGBMClassifier
import lightgbm as lgb

import matplotlib.pyplot as plt
import matplotlib.gridspec as gridspec
import seaborn as sns
%matplotlib inline

import warnings
warnings.simplefilter('ignore', UserWarning)

import gc
gc.enable()
import time

1.2 使用pandas_profiling自动分析数据

参考:

conda install -c conda-forge pandas-profiling
#!pip install -U pandas-profiling[notebook]
#安装之后要重启kernal
import pandas as pd
import pandas_profiling
data = pd.read_csv('./train.csv')
profile = data.profile_report(title='Pandas Profiling Report')
profile.to_file(output_file="telecom_customers_pandas_profiling.html")

查看Pandas Profiling Report发现:

  • 类别特征:‘地理区域’,‘是否双频’,‘是否翻新机’,‘手机网络功能’,‘婚姻状况’,‘家庭成人人数’,‘信息库匹配’,‘信用卡指示器’,‘新手机用户’,‘账户消费限额’
  • 分箱特征有:‘预计收入’,
  • 异常值特征:‘家庭中唯一订阅者的数量’,‘家庭活跃用户数’,
  • 无用(数据不平衡)特征:‘平均呼叫转移呼叫数’,‘平均丢弃数据呼叫数’,[149797,148912]
#区分数值特征和类别特征
features=list(train.columns)
categorical_features =['地理区域','是否双频','是否翻新机','手机网络功能','婚姻状况','预计收入',
                       '家庭成人人数','信息库匹配','信用卡指示器','新手机用户','账户消费限额']
numeric_features =[item for item in features if item not in categorical_features]
numeric_features=[i for i in numeric_features if i not in ['客户ID','是否流失']]
#多类别和少类别
categorical_features1 =['是否双频','是否翻新机','手机网络功能','信息库匹配','信用卡指示器','新手机用户','账户消费限额']
categorical_features2 =['地理区域','婚姻状况','预计收入','家庭成人人数']
#处理几个异常值
#train[train['家庭中唯一订阅者的数量'].values > 13]=14
#通过查看Pandas Profiling Report,发现以下列类别不平衡,打印出来看看情况
#还有一些异常值暂时没处理
cols=['家庭中唯一订阅者的数量','家庭活跃用户数','数据超载的平均费用','平均漫游呼叫数','平均丢弃数据呼叫数','平均占线数据调用次数',
     '未应答数据呼叫的平均次数','尝试数据调用的平均数','完成数据调用的平均数','平均三通电话数','平均峰值数据调用次数',
      '非高峰数据呼叫的平均数量','平均呼叫转移呼叫数']
for i in cols:
    print(train[i].value_counts())
  • lr=0.2时roc=0.84479;0.3时0.8379,;lr=0.15时0.84578
  • ‘num_leaves’,30改为45时,0.8468

这样调没啥用啊

#以下特征99.5%都是一种数值,可以考虑删掉。[149797,149493,149218,148912]
#lr=0.2时roc=0.84479
null_clos=['平均呼叫转移呼叫数','平均占线数据调用次数','未应答数据呼叫的平均次数','平均丢弃数据呼叫数']

for i in null_clos:
    del train[i]
    del test[i]
train

二、 使用baseline参数训练

《科大讯飞:电信客户流失预测挑战赛baseline》

  1. 全部特征跑10931轮,valid_acc=0.84298
  2. null importance跑5000轮:
    1. 选取split_feats大于0的特征(43种)可跑14402轮,valid_acc=0.83887
    2. 选取feats大于0的特征(23种)可跑10946轮,valid_acc=0.8193
  3. null importance跑1000轮:
    1. 选取split_feats大于0的特征(66种)可跑11817轮,valid_acc=0.84417
    2. 选取feats大于0的特征(58种)可跑11725轮,valid_acc=0.84345
from sklearn.model_selection import train_test_split
# 划分训练集和测试集
X_train,X_test,y_train,y_test=train_test_split(train.drop(labels=['客户ID','是否流失'],axis=1),train['是否流失'],random_state=10,test_size=0.2)
imp_df = pd.DataFrame()
lgb_train = lgb.Dataset(X_train, y_train,free_raw_data=False,silent=True)
lgb_eval = lgb.Dataset(X_test, y_test, reference=lgb_train,free_raw_data=False,
                       silent=True)

lgb_params = {
   
      'boosting_type': 'gbdt',
      'objective': 'binary',
      'metric': 'auc',
      'min_child_weight': 5,
      'num_leaves': 2 ** 5,
      'lambda_l2': 10,
      'feature_fraction': 0.7,
      'bagging_fraction': 0.7,
      'bagging_freq': 10,
      'learning_rate': 0.2,
      'seed': 2022,
      'n_jobs':-1}
    
    # 训练5000轮,每300轮报告一次acc,200轮没有提升就停止训练
clf = lgb.train(params=lgb_params,train_set=lgb_train,valid_sets=lgb_eval,
          num_boost_round=50000,verbose_eval=300,early_stopping_rounds=200)
roc= roc_auc_score(y_test, clf.predict( X_test))
y_pred=[1 if x >0.5 else 0 for x in clf.predict(X_test)]
acc=accuracy_score(y_test,y_pred)
Training until validation scores don't improve for 200 rounds.
[300]	valid_0's auc: 0.733101
[600]	valid_0's auc: 0.754127
[900]	valid_0's auc: 0.766728
[1200]	valid_0's auc: 0.777367
[1500]	valid_0's auc: 0.78594
[1800]	valid_0's auc: 0.792209
[2100]	valid_0's auc: 0.798424
[2400]	valid_0's auc: 0.80417
[2700]	valid_0's auc: 0.808074
[3000]	valid_0's auc: 0.811665
[3300]	valid_0's auc: 0.814679
[3600]	valid_0's auc: 0.817462
[3900]	valid_0's auc: 0.820151
[4200]	valid_0's auc: 0.822135
[4500]	valid_0's auc: 0.824544
[4800]	valid_0's auc: 0.825994
Did not meet early stopping. Best iteration is:
[4994]	valid_0's auc: 0.826797
roc,acc
(0.8267972007033084, 0.7533)

三、Null Importances进行特征选择

def get_feature_importances(X_train, X_test, y_train, y_test,shuffle, seed=None):
    # 获取特征
    train_features = list(X_train.columns)   
    # 判断是否shuffle TARGET
    y_train,y_test= y_train.copy(),y_test.copy()
    if shuffle:
        # Here you could as well use a binomial distribution
        y_train,y_test= y_train.copy().sample(frac=1.0),y_test.copy().sample(frac=1.0)
    
    
    lgb_train = lgb.Dataset(X_train, y_train,free_raw_data=False,silent=True)
    lgb_eval = lgb.Dataset(X_test, y_test, reference=lgb_train,free_raw_data=False,silent=True)
    # 在 RF 模式下安装 LightGBM,它比 sklearn RandomForest 更快   
    lgb_params = {
   
      'boosting_type': 'gbdt',
      'objective': 'binary',
      'metric': 'auc',
      'min_child_weight': 5,
      'num_leaves': 2 ** 5,
      'lambda_l2': 10,
      'feature_fraction': 0.7,
      'bagging_fraction': 0.7,
      'bagging_freq': 10,
      'learning_rate': 0.2,
      'seed': 2022,
      'n_jobs':-1}
    
    # 训练模型
    clf = lgb.train(params=lgb_params,train_set=lgb_train,valid_sets=lgb_eval,
          num_boost_round=500,verbose_eval=50,early_stopping_rounds=30)

    #得到特征重要性
    imp_df = pd.DataFrame()
    imp_df["feature"] = list(train_features)
    imp_df["importance_gain"] = clf.feature_importance(importance_type='gain')
    imp_df["importance_split"] = clf.feature_importance(importance_type='split')
    imp_df['trn_score'] = roc_auc_score(y_test, clf.predict( X_test))
    
    return imp_df

np.random.seed(123)
# 获得市实际的特征重要性,即没有shuffletarget
actual_imp_df = get_feature_importances(X_train, X_test, y_train, y_test, shuffle=False)
actual_imp_df
Training until validation scores don't improve for 20 rounds.
[30]	valid_0's auc: 0.695549
[60]	valid_0's auc: 0.704629
[90]	valid_0's auc: 0.711638
[120]	valid_0's auc: 0.715182
[150]	valid_0's auc: 0.718961
[180]	valid_0's auc: 0.722121
[210]	valid_0's auc: 0.725615
[240]	valid_0's auc: 0.728251
[270]	valid_0's auc: 0.730962
[300]	valid_0's auc: 0.733101
[330]	valid_0's auc: 0.73578
[360]	valid_0's auc: 0.73886
[390]	valid_0's auc: 0.741238
[420]	valid_0's auc: 0.742486
[450]	valid_0's auc: 0.744295
[480]	valid_0's auc: 0.746555
Did not meet early stopping. Best iteration is:
[495]	valid_0's auc: 0.747792
feature importance_gain importance_split trn_score
0 地理区域 1956.600422 313 0.747792
1 是否双频 442.401141 62 0.747792
2 是否翻新机 269.466828 26 0.747792
3 当前手机价格 3838.696197 365 0.747792
4 手机网络功能 750.396258 51 0.747792
... ... ... ... ...
62 过去三个月的平均每月通话次数 2540.721027 325 0.747792
63 过去三个月的平均月费用 2098.813867 304 0.747792
64 过去六个月的平均每月使用分钟数 2375.925741 337 0.747792
65 过去六个月的平均每月通话次数 2541.735172 346 0.747792
66 过去六个月的平均月费用 2103.062207 313 0.747792

67 rows × 4 columns

<svg xmlns=“http://www.w3.org/2000/svg” height="24px"viewBox=“0 0 24 24”
width=“24px”>



null_imp_df = pd.DataFrame()
nb_runs = 10
import time
start = time.time()
dsp = ''
for i in range(nb_runs):
    # 获取当前的特征重要性
    imp_df = get_feature_importances(X_train, X_test, y_train, y_test, shuffle=True)
    imp_df['run'] = i + 1 
    # 将特征重要性连起来
    null_imp_df = pd.concat([null_imp_df, imp_df], axis=0)
    # 删除上一条信息
    for l in range(len(dsp)):
        print('\b', end='', flush=True)
    # Display current run and time used
    spent = (time.time() - start) / 60
    dsp = 'Done with %4d of %4d (Spent %5.1f min)' % (i + 1, nb_runs, spent)
    print(dsp, end='', flush=True)
null_imp_df
feature importance_gain importance_split trn_score run
0 地理区域 38.622730 5 0.505320 1
1 是否双频 0.000000 0 0.505320 1
2 是否翻新机 0.000000 0 0.505320 1
3 当前手机价格 30.980300 4 0.505320 1
4 手机网络功能 0.000000 0 0.505320 1
... ... ... ... ... ...
62 过去三个月的平均每月通话次数 109.945481 14 0.503911 10
63 过去三个月的平均月费用 35.344621 4 0.503911 10
64 过去六个月的平均每月使用分钟数 55.200380 7 0.503911 10
65 过去六个月的平均每月通话次数 53.439080 6 0.503911 10
66 过去六个月的平均月费用 47.455200 6 0.503911 10

670 rows × 5 columns

<svg xmlns=“http://www.w3.org/2000/svg” height="24px"viewBox=“0 0 24 24”
width=“24px”>



def display_distributions(actual_imp_df_, null_imp_df_, feature_):
    plt.figure(figsize=
  • 3
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: 保险反欺诈预测是金融数据分析的重要应用之一。该赛题是基于保险数据集,旨在通过分析和挖掘数据特征,建立一个反欺诈预测模型的基准线。 首先,我们需要对保险数据集进行预处理和清洗,包括处理缺失值、异常值和重复值等。然后,我们可以进行特征工程,提取出与反欺诈相关的特征。常见的特征可以包括被保险人的年龄、职业、保险金额、历史理赔记录等信息。 接下来,我们可以选择合适的机器学习算法来构建预测模型。常用的算法包括逻辑回归、决策树、随机森林等。在构建模型之前,我们需要将数据集划分为训练集和测试集,用训练集进行模型训练,然后用测试集评估模型的性能。 评估模型的性能可以使用常见的指标,如准确率、精确率、召回率和F1值等。这些指标可以帮助我们评估模型的预测能力和误判率。 最后,我们需要对模型进行优化和改进。可以通过调整模型的参数、增加更多的特征或者尝试其他的机器学习算法来提高模型的预测性能。同时,对于不平衡样本问题,可以采用欠采样、过采样或者集成学习等方法来解决。 总结起来,保险反欺诈预测baseline建立包括数据预处理、特征工程、模型构建和优化等步骤。通过不断地优化和改进,我们可以建立一个有效的反欺诈预测模型,提高保险公司的风险控制能力。 ### 回答2: 金融数据分析赛题2: 保险反欺诈预测baseline是指在保险领域中,利用金融数据分析的方法来预测保险反欺诈的基础模型。 保险反欺诈预测是指利用大数据和机器学习算法等技术手段,对保险投保人的风险进行分析和预测,从而提高保险公司的风险管理能力,减少保险欺诈行为。 基于金融数据分析的保险反欺诈预测baseline主要包括以下几个步骤: 1. 数据收集:收集与保险欺诈相关的数据,包括投保人的基本信息、历史保险记录、理赔记录等,以及其他与保险欺诈相关的非保险数据。 2. 数据清洗和预处理:对收集到的数据进行清洗和预处理,包括去除异常值、缺失值处理、数据标准化等。确保数据的质量和可用性。 3. 特征工程:根据业务需求和领域知识,对数据进行特征提取和构建。包括基本特征、组合特征和衍生特征等。 4. 模型选择和训练:选择适用于保险反欺诈预测的机器学习模型,例如逻辑回归、决策树、支持向量机等。通过训练数据拟合模型,并进行调参和验证,得到最佳模型。 5. 模型评估和优化:利用评价指标如准确率、召回率、F1值等对模型进行评估,并进行模型优化和调整,提高模型的预测性能。 6. 模型应用和部署:将优化后的模型应用于实际场景,进行实时预测和反欺诈行为识别。并对模型进行监测和更新,保持模型的准确性和稳定性。 基于以上步骤,金融数据分析赛题2的保险反欺诈预测baseline可以建立一个初步的保险反欺诈预测模型,并得到一组基本的预测结果。然后可以根据比赛的具体要求和模型效果进行进一步的改进和优化,提高保险反欺诈预测的准确性和稳定性。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值