电信行业用户流失预警案例——python实现多模型预测

预警流失项目

代码及数据文件下载地址:电信行业用户流失预警案例——python实现多模型预测

#导入所需的库
import numpy as nm
import pandas as pd
import sklearn
#将数据文件转化为csv文件
#csv文件是逗号分隔文件,可以使用excel查看,便于后期处理。
""""
import csv
with open('list1_test.csv', 'w+', newline='') as csvfile:
    spamwriter = csv.writer(csvfile, dialect='excel')
    with open('list1_test.txt', 'r', encoding='utf-8') as filein:
        for line in filein:
            line_list = line.strip('\n').split(',')   #数据之间以,间隔
            spamwriter.writerow(line_list)
with open('list2_test1.csv', 'w+', newline='') as csvfile:
    spamwriter = csv.writer(csvfile, dialect='excel')
    with open('list2_test1.txt', 'r', encoding='utf-8') as filein:
        for line in filein:
            line_list = line.strip('\n').split(',')   #数据之间以,间隔
            spamwriter.writerow(line_list)
with open('list2_test2.csv', 'w+', newline='') as csvfile:
    spamwriter = csv.writer(csvfile, dialect='excel')
    with open('list2_test2.txt', 'r', encoding='utf-8') as filein:
        for line in filein:
            line_list = line.strip('\n').split(',')   #数据之间以,间隔
            spamwriter.writerow(line_list)
with open('list3_test.csv', 'w+', newline='') as csvfile:
    spamwriter = csv.writer(csvfile, dialect='excel')
    with open('list3_test.txt', 'r', encoding='utf-8') as filein:
        for line in filein:
            line_list = line.strip('\n').split(',')   #数据之间以,间隔
            spamwriter.writerow(line_list)
"""

合并数据文件

  调用pandas库中的merge函数,设置d_userid为合并标识,使用左连接方式,将用户所有信息连接到一个表格中,合并前需删除多余的month_id数据列,否则在合并时会出现填充错误。读取合并文件时设置参数为utf_8,否则会出现乱码。

#删除month_id数据列
inputfile1=r'month1list1.csv'
inputdata1=pd.read_csv(inputfile1,low_memory=False)
inputdata1=inputdata1.drop(['month_id'],axis=1)
inputfile2=r'month1list2a.csv'
inputdata2=pd.read_csv(inputfile2,low_memory=False)
inputdata2=inputdata2.drop(['month_id'],axis=1)
inputfile3=r'month1list2b.csv'
inputdata3=pd.read_csv(inputfile3,low_memory=False)
inputdata3=inputdata3.drop(['month_id'],axis=1)
outfile = r'month1list3.csv'
outdata = pd.read_csv(outfile,low_memory=False)
outdata =outdata.drop(['month_id'],axis=1)
#合并采用左连接方式
#第一次合并
outfile1 = pd.merge(outdata,inputdata1,left_on='d_userid',right_on='d_userid',how='left')
outfile1.to_csv('outfile.csv',encoding='utf_8',index=False)
outfile = r'outfile.csv'
outdata = pd.read_csv(outfile,low_memory=False)
#第二次合并
outfile2 = pd.merge(outdata,inputdata2,left_on='d_userid',right_on='d_userid',how='left')
outfile2.to_csv('outfile.csv',encoding='utf_8',index=False)
outfile = r'outfile.csv'
outdata = pd.read_csv(outfile,low_memory=False)
#第三次合并
outfile3 = pd.merge(outdata,inputdata3,left_on='d_userid',right_on='d_userid',how='left')
#文件保存
outfile3.to_csv('outfile.csv',encoding='utf_8',index=False)

数据去重

  通过调用drop_duplicates()方法,以d_userid作为唯一标识,去除数据集中的重复数据。

#数据去重
initfile_locate=r'outfile.csv'
#打开文件
initfile=pd.read_csv(initfile_locate,encoding='utf-8',low_memory=False)
initfile.drop_duplicates(subset='d_userid',inplace=True)
#保存文件
initfile.to_csv(initfile_locate,encoding='utf_8',index=False)
#查看去重后的数据集信息
initfile.shape
(150822, 29)
#查看去重后的数据前十项
initfile.head(10)
d_userid mou dou arpu mou_var dou_var arpu_var sms flux_4g call_ring ... brand_code start_date end_date service_type pay_mode cert_age chnl_type product_class_desc comp_type activity_type
0 1000925 165 349 30 22.34 -182.69 -5.95 1 1.00 24 ... 3G03 2017/11/1 0:00 2050/12/31 0:00 40AAAAAA 1 43.0 社会实体渠道 NaN 单卡
1 1000927 141 0 18 -4.60 0.00 0.00 0 0.00 18 ... 3G03 2017/1/1 0:00 2050/12/31 0:00 20AAAAAA 1 53.0 社会实体渠道 NaN 单卡
2 1000929 163 2 18 40.14 0.13 4.12 0 0.00 23 ... 3G03 2017/12/9 12:59 2050/12/31 0:00 40AAAAAA 1 46.0 社会实体渠道 NaN 单卡
3 1000930 37 475 18 -4.86 22.12 0.00 0 0.00 2 ... 3G03 2017/5/28 10:13 2050/12/31 0:00 20AAAAAA 1 59.0 营业厅 NaN 单卡
4 1000932 6 147 18 1.00 28.06 4.15 0 0.36 1 ... 3G03 2017/12/7 18:36 2050/12/31 0:00 40AAAAAA 1 30.0 社会实体渠道 NaN 单卡
5 1001009 18 6 18 3.80 1.01 4.11 0 1.00 3 ... 3G03 2017/12/1 14:59 2050/12/31 0:00 20AAAAAA 1 21.0 社会实体渠道 NaN 单卡
7 1001010 97 0 19 -13.34 0.00 0.90 0 0.00 6 ... 3G03 2017/3/11 10:55 2050/12/31 0:00 20AAAAAA 1 32.0 营业厅 NaN 单卡
9 1001012 154 176 23 -20.23 -15.74 0.58 0 0.98 6 ... 3G03 2017/8/1 0:00 2050/12/31 0:00 40AAAAAA 1 46.0 营业厅 NaN 单卡
11 1001014 69 5 14 16.26 -0.14 4.56 0 1.00 10 ... 3G03 2017/10/13 15:24 2050/12/31 0:00 20AAAAAA 1 64.0 营业厅 NaN 单卡
13 1001016 8 0 13 0.23 0.01 4.22 0 0.00 0 ... 3G03 2017/11/15 9:10 2018/4/30 23:59 20AAAAAA 1 48.0 社会实体渠道 NaN 单卡

10 rows × 29 columns

#统计显示数据集相关信息
initfile.columns
initfile.info()

Int64Index: 150822 entries, 0 to 150827
Data columns (total 29 columns):
 #   Column              Non-Null Count   Dtype  
---  ------              --------------   -----  
 0   d_userid            150822 non-null  int64  
 1   mou                 150822 non-null  int64  
 2   dou                 150822 non-null  int64  
 3   arpu                150822 non-null  int64  
 4   mou_var             150822 non-null  float64
 5   dou_var             150822 non-null  float64
 6   arpu_var            150822 non-null  float64
 7   sms                 150822 non-null  int64  
 8   flux_4g             150822 non-null  float64
 9   call_ring           150822 non-null  int64  
 10  unicom_score        150822 non-null  float64
 11  innet_months        150822 non-null  int64  
 12  is_card             150822 non-null  int64  
 13  is_group            150822 non-null  int64  
 14  is_lv               150822 non-null  int64  
 15  is_trans            150822 non-null  int64  
 16  is_acct_lost        150822 non-null  int64  
 17  product_mode        150808 non-null  float64
 18  product_id          150808 non-null  float64
 19  brand_code          150808 non-null  object 
 20  start_date          150808 non-null  object 
 21  end_date            150808 non-null  object 
 22  service_type        150822 non-null  object 
 23  pay_mode            150822 non-null  object 
 24  cert_age            146287 non-null  float64
 25  chnl_type           150822 non-null  object 
 26  product_class_desc  82618 non-null   object 
 27  comp_type           150822 non-null  object 
 28  activity_type       150822 non-null  object 
dtypes: float64(8), int64(12), object(9)
memory usage: 34.5+ MB

数据集分析

  通过使用matplotlib.pyplot中的相关方法对数据进行可视化分析,通过绘图查看数据分布和相关关系,通过绘制热图查看与用户流失最相关的15个 因素,便于后期建模预测。

#导入绘图分析相关包
import matplotlib.pyplot as plt
#可以直接在python console里面生成图像。
%matplotlib inline
import seaborn as sns
color=sns.color_palette()
sns.set_style('darkgrid')
#查看用户流失列的数据分布
initfile["is_acct_lost"].value_counts().plot(kind = 'bar')

电信行业用户流失预警案例——python实现多模型预测_第1张图片

#查看低价值用户数量分布
initfile["is_lv"].value_counts().plot(kind = 'bar')

电信行业用户流失预警案例——python实现多模型预测_第2张图片

#热图绘制,查看与用户流失最相关的因素
para = 15
#查看相关度最高的15个特征
corrmat = initfile.corr() #获得相关性矩阵
cols = corrmat.nlargest(para,"is_acct_lost").index
cm = nm.corrcoef(initfile[cols].values.T)
#绘制热图
sns.set(font_scale=1.25)
hm = sns.heatmap(cm,cbar=True,annot=True,square=True,fmt='.2f',annot_kws={'size':10},yticklabels=cols.values,
                 xticklabels=cols.values)
plt.show()

电信行业用户流失预警案例——python实现多模型预测_第3张图片

  通过热图可以发现与用户流失最相关的因素分别是:is_lv(低价值用户),arpu(月均出账费),arpu_var(月出账费-方差),product_id(产品 编码),is_card(是否单卡),is_trans(是否转网),is_group(是否集客),dou(户均上网流量),sms(短信使用条数),flux_4g(4G流量使用量), call_ring(呼叫圈个数),cert_age(年龄),mou(户均通话时长)。接下来对其中的部分因素进行分析,并选择多个因素进行相关分析。

#查看is_trans(转网)与is_acct_lost的相关关系。
cust_0=initfile["is_trans"][initfile["is_acct_lost"]==0].value_counts()
cust_1=initfile["is_trans"][initfile["is_acct_lost"]==1].value_counts()
file_1=pd.DataFrame({u'lost':cust_1,u'retain':cust_0})
file_1.plot(kind="bar",stacked=True)
plt.show()

电信行业用户流失预警案例——python实现多模型预测_第4张图片

#查看is_trans(转网)与is_acct_lost的相关关系。
data = pd.concat([initfile["is_trans"],initfile["is_acct_lost"]],axis=1)
sns.countplot(x="is_acct_lost",hue="is_trans",data=data)

电信行业用户流失预警案例——python实现多模型预测_第5张图片

#查看is_lv(低价值)与is_acct_lost的相关关系。
cust_0=initfile["is_lv"][initfile["is_acct_lost"]==0].value_counts()
cust_1=initfile["is_lv"][initfile["is_acct_lost"]==1].value_counts()
file_1=pd.DataFrame({u'lost':cust_1,u'retain':cust_0})
file_1.plot(kind="bar",stacked=True)
plt.show()

电信行业用户流失预警案例——python实现多模型预测_第6张图片

#查看product_id与is_acct_lost的相关关系。(参考价值较低)
cust_0=initfile["product_id"][initfile["is_acct_lost"]==0].value_counts()
cust_1=initfile["product_id"][initfile["is_acct_lost"]==1].value_counts()
file_1=pd.DataFrame({u'lost':cust_1,u'retain':cust_0})
file_1.plot(kind="bar",stacked=True)
plt.show()

电信行业用户流失预警案例——python实现多模型预测_第7张图片

#查看is_card(单卡)与is_acct_lost的相关关系。
cust_0=initfile["is_card"][initfile["is_acct_lost"]==0].value_counts()
cust_1=initfile["is_card"][initfile["is_acct_lost"]==1].value_counts()
file_1=pd.DataFrame({u'lost':cust_1,u'retain':cust_0})
file_1.plot(kind="bar",stacked=True)
plt.show()

电信行业用户流失预警案例——python实现多模型预测_第8张图片

#查看is_group与is_acct_lost的相关关系。
cust_0=initfile["is_group"][initfile["is_acct_lost"]==0].value_counts()
cust_1=initfile["is_group"][initfile["is_acct_lost"]==1].value_counts()
file_1=pd.DataFrame({u'lost':cust_1,u'retain':cust_0})
file_1.plot(kind="bar",stacked=True)
plt.show()

电信行业用户流失预警案例——python实现多模型预测_第9张图片

#通过绘制散点图查看arpu,flux_4g,mou三列的相关关系。
sns.set()
cols = ['arpu','flux_4g','mou']
sns.pairplot(initfile[cols],size=2.5)
plt.show()

电信行业用户流失预警案例——python实现多模型预测_第10张图片

#查看cert_age的数据分布情况。
sns.distplot(initfile["cert_age"])

电信行业用户流失预警案例——python实现多模型预测_第11张图片

#查看arpu的数据分布情况。
plt.xlim(0,500)
sns.distplot(initfile["arpu"])

电信行业用户流失预警案例——python实现多模型预测_第12张图片

#查看mou的数据分布情况。
plt.xlim(0,1500)
sns.distplot(initfile["mou"])

电信行业用户流失预警案例——python实现多模型预测_第13张图片

#查看dou(流量)的数据分布情况。
plt.xlim(0,40000)
sns.distplot(initfile["dou"])

电信行业用户流失预警案例——python实现多模型预测_第14张图片

#查看call_ring的数据分布情况。
plt.xlim(0,50)
sns.distplot(initfile["call_ring"])

电信行业用户流失预警案例——python实现多模型预测_第15张图片

数据集二次处理

  为了取得更好地数据预测结果,需要对合并后的数据集合进行二次处理,即删除与用户流失相关度不高的列,并对数据集中的空值元素进行处理, 使其能够作为模型输入数据进行训练。

#删除不需要的列
#调用drop方法根据列名删除不需要的数据列
initfile=initfile.drop(['mou_var','dou_var','unicom_score','innet_months','product_mode','brand_code',
           'start_date','end_date','service_type','pay_mode','chnl_type','product_class_desc',
           'comp_type','activity_type'],axis=1)
#由于product_id处理较复杂且相关度较低,影响结果输出,因此去掉。
initfile=initfile.drop(['product_id'],axis=1)
#查看处理后的数据集相关信息
initfile.shape
initfile.head()
d_userid mou dou arpu arpu_var sms flux_4g call_ring is_card is_group is_lv is_trans is_acct_lost cert_age
0 1000925 165 349 30 -5.95 1 1.00 24 0 0 0 0 0 43.0
1 1000927 141 0 18 0.00 0 0.00 18 0 0 0 0 0 53.0
2 1000929 163 2 18 4.12 0 0.00 23 0 0 0 0 0 46.0
3 1000930 37 475 18 0.00 0 0.00 2 0 0 0 0 0 59.0
4 1000932 6 147 18 4.15 0 0.36 1 0 0 0 0 0 30.0

测试数据集处理

  模型训练后需要使用测试集进行验证,因此需要对测试数据集进行与训练数据集相同的处理。

#测试集处理
#合并数据文件
#merge方法,左连接方式
inputfile4=r'month2list1.csv'
inputdata4=pd.read_csv(inputfile4,low_memory=False)
inputdata4=inputdata4.drop(['month_id'],axis=1)
inputfile5=r'month2list2a.csv'
inputdata5=pd.read_csv(inputfile5,low_memory=False)
inputdata5=inputdata5.drop(['month_id'],axis=1)
inputfile6=r'month2list2b.csv'
inputdata6=pd.read_csv(inputfile6,low_memory=False)
inputdata6=inputdata6.drop(['month_id'],axis=1)
outfiles = r'month2list3.csv'
outdatas = pd.read_csv(outfiles,low_memory=False)
outdatas =outdatas.drop(['month_id'],axis=1)
outfile1s = pd.merge(outdatas,inputdata4,left_on='d_userid',right_on='d_userid',how='left')
outfile1s.to_csv('outfiles.csv',encoding='utf_8',index=False)
outfiles = r'outfiles.csv'
outdatas = pd.read_csv(outfiles,low_memory=False)
outfile2s = pd.merge(outdatas,inputdata5,left_on='d_userid',right_on='d_userid',how='left')
outfile2s.to_csv('outfiles.csv',encoding='utf_8',index=False)
outfiles = r'outfiles.csv'
outdatas = pd.read_csv(outfiles,low_memory=False)
outfile3s = pd.merge(outdatas,inputdata6,left_on='d_userid',right_on='d_userid',how='left')
outfile3s.to_csv('outfiles.csv',encoding='utf_8',index=False)
#数据去重
testfile_locate=r'outfiles.csv'
testfile=pd.read_csv(testfile_locate,encoding='utf-8',low_memory=False)
#testfile.shape
testfile.drop_duplicates(subset='d_userid',inplace=True)
testfile.to_csv(testfile_locate,encoding='utf_8',index=False)
testfile.shape
(161968, 29)
#删除不需要的列
testfile=testfile.drop(['mou_var','dou_var','unicom_score','innet_months','product_mode','brand_code',
           'start_date','end_date','service_type','pay_mode','chnl_type','product_class_desc',
           'comp_type','activity_type'],axis=1)
testfile=testfile.drop(['product_id'],axis=1)
#保存测试集文件
testfile.to_csv(testfile_locate,encoding='utf_8',index=False)
#测试集信息查看
testfile.head()
testfile.shape
(161968, 14)
#导入训练模型及结果分析相关包
from sklearn import model_selection
from sklearn import ensemble
from sklearn import metrics
from sklearn.metrics import precision_score, recall_score, f1_score
#查看处理前的数据集内是否有空值
print(nm.isnan(initfile).any())
d_userid        False
mou             False
dou             False
arpu            False
arpu_var        False
sms             False
flux_4g         False
call_ring       False
is_card         False
is_group        False
is_lv           False
is_trans        False
is_acct_lost    False
cert_age         True
dtype: bool
#数据集空值处理
#使用年龄的均值填充缺失数据
initfile['cert_age'].fillna(initfile['cert_age'].mean(),inplace=True)
testfile['cert_age'].fillna(testfile['cert_age'].mean(),inplace=True)
initfile.to_csv(initfile_locate,encoding='utf_8',index=False)
testfile.to_csv(testfile_locate,encoding='utf_8',index=False)
#查看处理后的数据集内是否有空值
print(nm.isnan(initfile).any())
d_userid        False
mou             False
dou             False
arpu            False
arpu_var        False
sms             False
flux_4g         False
call_ring       False
is_card         False
is_group        False
is_lv           False
is_trans        False
is_acct_lost    False
cert_age        False
dtype: bool
#划分数据集
result_train=initfile.is_acct_lost
result_test=testfile.is_acct_lost
train=initfile.drop(['is_acct_lost'],axis=1)
test=testfile.drop(['is_acct_lost'],axis=1)

模型训练及实验结果

  通过使用不同的模型建模比较最终预测结果,一般情况下准确率高、召回率就低,召回率低、准确率高。模型评价使用准确率(查准率,预测为正的样本中有多少是真正的正样本),召回率(查全率,样本中的正例有多少被预测正确)和F1值(控制两者)来衡量模型质量,使用ROC曲线衡量模型检测方法真实性,数值越高,模型真实性越高。
在这里插入图片描述

随机森林模型

#随机森林建模
#设置分类器个数和随机种子
RF_class = ensemble.RandomForestClassifier(n_estimators=200, random_state=1234)
# 随机森林的拟合
RF_class.fit(train,result_train)
# 模型在测试集上的预测
RFclass_pred = RF_class.predict(test)
# 模型的准确率
print("准确率:",metrics.precision_score(result_test, RFclass_pred,average='binary'))
print("召回率:",metrics.recall_score(result_test, RFclass_pred,average='binary'))
print("F 1 值:",metrics.f1_score(result_test, RFclass_pred,average='binary'))
准确率: 0.7006369426751592
召回率: 0.13284021435580043
F 1 值: 0.223336082735867
#绘制ROC曲线
# 计算绘图数据  
y_score = RF_class.predict_proba(test)[:,1]
fpr,tpr,threshold = metrics.roc_curve(result_test, y_score)
roc_auc = metrics.auc(fpr,tpr)
# 绘图
plt.stackplot(fpr, tpr, color='steelblue', alpha = 0.5, edgecolor = 'black')
plt.plot(fpr, tpr, color='black', lw = 1)
plt.plot([0,1],[0,1], color = 'red', linestyle = '--')
plt.text(0.5,0.3,'ROC curve (area = %0.2f)' % roc_auc)
plt.xlabel('1-Specificity')
plt.ylabel('Sensitivity')
plt.show()

电信行业用户流失预警案例——python实现多模型预测_第16张图片

提升AdaBoost+决策树模型

Adaboost算法流程:
1)给数据中的每一个样本一个权重
2)训练数据中的每一个样本,得到第一个分类器
3)计算该分类器的错误率,根据错误率计算要给分类器分配的权重(注意这里是分类器的权重)
4)将第一个分类器分错误的样本权重增加,分对的样本权重减小(注意这里是样本的权重)
5)然后再用新的样本权重训练数据,得到新的分类器,到步骤3
6)直到步骤3中分类器错误率为0,或者到达迭代次数
7)将所有弱分类器加权求和,得到分类结果(注意是分类器权重)

# 集成学习提升Adaboost+决策树
#导入所需包
from sklearn.ensemble import AdaBoostClassifier
from sklearn.tree import DecisionTreeClassifier
#设置模型参数
#设置决策树深度,节点划分最小样本数量,叶子节点最小样本数,分类器个数,步长
#基分类器采用决策树
bdt = AdaBoostClassifier(DecisionTreeClassifier(max_depth=15, min_samples_split=20, min_samples_leaf=5),
                         algorithm="SAMME",
                         n_estimators=1000, learning_rate=0.1)
bdt.fit(train,result_train)

bdt_pred = bdt.predict(test)

print("准确率:",metrics.precision_score(result_test,bdt_pred,average='binary'))
print("召回率:",metrics.recall_score(result_test, bdt_pred,average='binary'))
print("F 1 值:",metrics.f1_score(result_test, bdt_pred,average='binary'))
准确率: 0.7142857142857143
召回率: 0.13359498830100386
F 1 值: 0.225090608507662
#绘制ROC曲线
# 计算绘图数据  
y_score = bdt.predict_proba(test)[:,1]
fpr,tpr,threshold = metrics.roc_curve(result_test, y_score)
roc_auc = metrics.auc(fpr,tpr)
# 绘图
plt.stackplot(fpr, tpr, color='steelblue', alpha = 0.5, edgecolor = 'black')
plt.plot(fpr, tpr, color='black', lw = 1)
plt.plot([0,1],[0,1], color = 'red', linestyle = '--')
plt.text(0.5,0.3,'ROC curve (area = %0.2f)' % roc_auc)
plt.xlabel('1-Specificity')
plt.ylabel('Sensitivity')
plt.show()

电信行业用户流失预警案例——python实现多模型预测_第17张图片

朴素贝叶斯模型

对于给出的待分类项,求解在此项出现的条件下各个类别出现的概率,哪个最大,就认为此待分类项属于哪个类别。

# 朴素贝叶斯
from sklearn.naive_bayes import GaussianNB

GNB = GaussianNB()

 # Binary data
GNB.fit(train,result_train)


GNB_pred = GNB.predict(test)

print("准确率:",metrics.precision_score(result_test, GNB_pred,average='binary'))
print("召回率:",metrics.recall_score(result_test, GNB_pred,average='binary'))
print("F 1 值:",metrics.f1_score(result_test, GNB_pred,average='binary'))
准确率: 0.09684560044272275
召回率: 0.013208544041059703
F 1 值: 0.023246546227417644
#绘制ROC曲线
# 计算绘图数据  
y_score = GNB.predict_proba(test)[:,1]
fpr,tpr,threshold = metrics.roc_curve(result_test, y_score)
roc_auc = metrics.auc(fpr,tpr)
# 绘图
plt.stackplot(fpr, tpr, color='steelblue', alpha = 0.5, edgecolor = 'black')
plt.plot(fpr, tpr, color='black', lw = 1)
plt.plot([0,1],[0,1], color = 'red', linestyle = '--')
plt.text(0.5,0.3,'ROC curve (area = %0.2f)' % roc_auc)
plt.xlabel('1-Specificity')
plt.ylabel('Sensitivity')
plt.show()

电信行业用户流失预警案例——python实现多模型预测_第18张图片

KNN模型

为了判断未知样本的类别,以所有已知类别的样本作为参照,计算未知样本与所有已知样本的距离,从中选取与未知样本距离最近的K个已知样本,根据少数 服从多数的投票法则(majority-voting),将未知样本与K个最邻近样本中所属类别占比较多的归为一类。

# KNN最近邻
from sklearn.neighbors import KNeighborsClassifier
#设置临近点个数
knn = KNeighborsClassifier(n_neighbors=5)
knn.fit(train,result_train)
knn_pred = knn.predict(test)

print("准确率:",metrics.precision_score(result_test, knn_pred,average='binary'))
print("召回率:",metrics.recall_score(result_test, knn_pred,average='binary'))
print("F 1 值:",metrics.f1_score(result_test, knn_pred,average='binary'))
准确率: 0.4182825484764543
召回率: 0.09117669258057212
F 1 值: 0.14971803928859143
#绘制ROC曲线
# 计算绘图数据  
y_score = knn.predict_proba(test)[:,1]
fpr,tpr,threshold = metrics.roc_curve(result_test, y_score)
roc_auc = metrics.auc(fpr,tpr)
# 绘图
plt.stackplot(fpr, tpr, color='steelblue', alpha = 0.5, edgecolor = 'black')
plt.plot(fpr, tpr, color='black', lw = 1)
plt.plot([0,1],[0,1], color = 'red', linestyle = '--')
plt.text(0.5,0.3,'ROC curve (area = %0.2f)' % roc_auc)
plt.xlabel('1-Specificity')
plt.ylabel('Sensitivity')
plt.show()

电信行业用户流失预警案例——python实现多模型预测_第19张图片

提升树模型

提升树模型可以看作是决策树的加法模型。

# 提升树
from sklearn.ensemble import GradientBoostingClassifier

gbm0 = GradientBoostingClassifier(n_estimators=1000, learning_rate=0.1, min_samples_split=50, min_samples_leaf=20, max_depth=7,
                                         max_features='sqrt', subsample=1, max_leaf_nodes=5000)
gbm0.fit(train,result_train)

gbm0_pred = gbm0.predict(test)

print("准确率:",metrics.precision_score(result_test, gbm0_pred,average='binary'))
print("召回率:",metrics.recall_score(result_test, gbm0_pred,average='binary'))
print("F 1 值:",metrics.f1_score(result_test, gbm0_pred,average='binary'))
准确率: 0.7024741622298779
召回率: 0.16929579590912522
F 1 值: 0.27283785427563556
#绘制ROC曲线
# 计算绘图数据  
y_score = gbm0.predict_proba(test)[:,1]
fpr,tpr,threshold = metrics.roc_curve(result_test, y_score)
roc_auc = metrics.auc(fpr,tpr)
# 绘图
plt.stackplot(fpr, tpr, color='steelblue', alpha = 0.5, edgecolor = 'black')
plt.plot(fpr, tpr, color='black', lw = 1)
plt.plot([0,1],[0,1], color = 'red', linestyle = '--')
plt.text(0.5,0.3,'ROC curve (area = %0.2f)' % roc_auc)
plt.xlabel('1-Specificity')
plt.ylabel('Sensitivity')
plt.show()

电信行业用户流失预警案例——python实现多模型预测_第20张图片

引导聚集模型

# 引导聚集
from sklearn.ensemble import BaggingClassifier
from sklearn.tree import DecisionTreeClassifier

bc = BaggingClassifier(base_estimator= DecisionTreeClassifier(max_depth=7, min_samples_split=20, min_samples_leaf=5)
                         ,max_samples=0.5,max_features=0.5)

bc.fit(train,result_train)

bc_pred = bc.predict(test)

print("准确率:",metrics.precision_score(result_test, bc_pred,average='binary'))
print("召回率:",metrics.recall_score(result_test, bc_pred,average='binary'))
print("F 1 值:",metrics.f1_score(result_test, bc_pred,average='binary'))
准确率: 0.8637873754152824
召回率: 0.0196241225752887
F 1 值: 0.03837638376383764
#绘制ROC曲线
# 计算绘图数据  
y_score = bc.predict_proba(test)[:,1]
fpr,tpr,threshold = metrics.roc_curve(result_test, y_score)
roc_auc = metrics.auc(fpr,tpr)
# 绘图
plt.stackplot(fpr, tpr, color='steelblue', alpha = 0.5, edgecolor = 'black')
plt.plot(fpr, tpr, color='black', lw = 1)
plt.plot([0,1],[0,1], color = 'red', linestyle = '--')
plt.text(0.5,0.3,'ROC curve (area = %0.2f)' % roc_auc)
plt.xlabel('1-Specificity')
plt.ylabel('Sensitivity')
plt.show()

电信行业用户流失预警案例——python实现多模型预测_第21张图片

极度随机树模型

# 极度随机树
from sklearn.ensemble import ExtraTreesClassifier

etc = ExtraTreesClassifier(n_estimators=1000, max_depth=20, max_leaf_nodes=5000,
                                     max_features='auto', min_samples_split=50)

etc.fit(train,result_train)

etc_pred = etc.predict(test)

print("准确率:",metrics.precision_score(result_test, etc_pred,average='binary'))
print("召回率:",metrics.recall_score(result_test,etc_pred,average='binary'))
print("F 1 值:",metrics.f1_score(result_test, etc_pred,average='binary'))
准确率: 0.7306273062730627
召回率: 0.014944524115027549
F 1 值: 0.029289940828402368
#绘制ROC曲线
# 计算绘图数据  
y_score = etc.predict_proba(test)[:,1]
fpr,tpr,threshold = metrics.roc_curve(result_test, y_score)
roc_auc = metrics.auc(fpr,tpr)
# 绘图
plt.stackplot(fpr, tpr, color='steelblue', alpha = 0.5, edgecolor = 'black')
plt.plot(fpr, tpr, color='black', lw = 1)
plt.plot([0,1],[0,1], color = 'red', linestyle = '--')
plt.text(0.5,0.3,'ROC curve (area = %0.2f)' % roc_auc)
plt.xlabel('1-Specificity')
plt.ylabel('Sensitivity')
plt.show()

电信行业用户流失预警案例——python实现多模型预测_第22张图片

决策树模型

通过一系列if then决策规则的集合,将特征空间划分成有限个不相交的子区域,对于落在相同子区域的样本,决策树模型给出相同的预测值。这些if then 决策规则之间的层次关系形成一个树形结构,称之为决策树,这些不相交的子区域和树结构的叶子节点一一对应。

# 决策树
from sklearn.tree import DecisionTreeClassifier

dtc = DecisionTreeClassifier(splitter='random', max_depth=None)

dtc.fit(train,result_train)

dtc_pred = dtc.predict(test)

print("准确率:",metrics.precision_score(result_test, dtc_pred,average='binary'))
print("召回率:",metrics.recall_score(result_test, dtc_pred,average='binary'))
print("F 1 值:",metrics.f1_score(result_test, dtc_pred,average='binary'))
准确率: 0.2650814619110524
召回率: 0.18174956600498152
F 1 值: 0.2156450096270094
#绘制ROC曲线
# 计算绘图数据  
y_score = dtc.predict_proba(test)[:,1]
fpr,tpr,threshold = metrics.roc_curve(result_test, y_score)
roc_auc = metrics.auc(fpr,tpr)
# 绘图
plt.stackplot(fpr, tpr, color='steelblue', alpha = 0.5, edgecolor = 'black')
plt.plot(fpr, tpr, color='black', lw = 1)
plt.plot([0,1],[0,1], color = 'red', linestyle = '--')
plt.text(0.5,0.3,'ROC curve (area = %0.2f)' % roc_auc)
plt.xlabel('1-Specificity')
plt.ylabel('Sensitivity')
plt.show()

电信行业用户流失预警案例——python实现多模型预测_第23张图片

SVC模型

"""
nvidia-smi
"""
'\nnvidia-smi\n'
# SVC支持向量机(模型已建好,但机器原因没有跑出结果)
"""
from sklearn import svm

svc = svm.SVC(kernel='rbf', gamma=0.002)


svc.fit(train,result_train)

svc_pred = svc.predict(test)

print("准确率:",metrics.precision_score(result_test, svc_pred,average='binary'))
print("召回率:",metrics.recall_score(result_test, svc_pred,average='binary'))
print("F 1 值:",metrics.f1_score(result_test,svc_pred,average='binary'))
"""
'\nfrom sklearn import svm\n\nsvc = svm.SVC(kernel=\'rbf\', gamma=0.002)\n\n\nsvc.fit(train,result_train)\n\nsvc_pred = svc.predict(test)\n\nprint("准确率:",metrics.precision_score(result_test, svc_pred,average=\'binary\'))\nprint("召回率:",metrics.recall_score(result_test, svc_pred,average=\'binary\'))\nprint("F 1 值:",metrics.f1_score(result_test,svc_pred,average=\'binary\'))\n'
""""
# 计算绘图数据  

y_score = svc.predict_proba(test)[:,1]
fpr,tpr,threshold = metrics.roc_curve(result_test, y_score)
roc_auc = metrics.auc(fpr,tpr)
# 绘图
plt.stackplot(fpr, tpr, color='steelblue', alpha = 0.5, edgecolor = 'black')
plt.plot(fpr, tpr, color='black', lw = 1)
plt.plot([0,1],[0,1], color = 'red', linestyle = '--')
plt.text(0.5,0.3,'ROC curve (area = %0.2f)' % roc_auc)
plt.xlabel('1-Specificity')
plt.ylabel('Sensitivity')
plt.show()
""""
  File "", line 15
    """"
        
^
SyntaxError: EOL while scanning string literal

感知机模型(不可用)

# 感知机(不可用)
"""
from sklearn.linear_model import Perceptron

clf = Perceptron()

clf.fit(train,result_train)

clf_pred = clf.predict(test)

print("准确率:",metrics.precision_score(result_test, clf_pred,average='binary'))
print("召回率:",metrics.recall_score(result_test, clf_pred,average='binary'))
print("F 1 值:",metrics.f1_score(result_test, clf_pred,average='binary'))
"""
# 计算绘图数据  
"""
y_score = clf.predict_proba(test)[:,1]
fpr,tpr,threshold = metrics.roc_curve(result_test, y_score)
roc_auc = metrics.auc(fpr,tpr)
# 绘图
plt.stackplot(fpr, tpr, color='steelblue', alpha = 0.5, edgecolor = 'black')
plt.plot(fpr, tpr, color='black', lw = 1)
plt.plot([0,1],[0,1], color = 'red', linestyle = '--')
plt.text(0.5,0.3,'ROC curve (area = %0.2f)' % roc_auc)
plt.xlabel('1-Specificity')
plt.ylabel('Sensitivity')
plt.show()
"""

逻辑斯蒂回归模型(测试不可用)

# 逻辑斯蒂回归
#第二类数据样本较少,警告,且不能正确输出结果(很难处理数据不平衡的问题)
"""
from sklearn.linear_model import LogisticRegression

logClassifier = LogisticRegression()

logClassifier.fit(train,result_train)

log_pred = logClassifier.predict(test)

print("准确率:",metrics.precision_score(result_test, log_pred,average='binary'))
print("召回率:",metrics.recall_score(result_test, log_pred,average='binary'))
print("F 1 值:",metrics.f1_score(result_test, log_pred,average='binary'))
"""
# 计算绘图数据  
"""
y_score = logClassifier.predict_proba(test)[:,1]
fpr,tpr,threshold = metrics.roc_curve(result_test, y_score)
roc_auc = metrics.auc(fpr,tpr)
# 绘图
plt.stackplot(fpr, tpr, color='steelblue', alpha = 0.5, edgecolor = 'black')
plt.plot(fpr, tpr, color='black', lw = 1)
plt.plot([0,1],[0,1], color = 'red', linestyle = '--')
plt.text(0.5,0.3,'ROC curve (area = %0.2f)' % roc_auc)
plt.xlabel('1-Specificity')
plt.ylabel('Sensitivity')
plt.show()
"""

你可能感兴趣的:(python,数据挖掘,机器学习,boosting)