客户流失预测

这篇博客通过对五月九十万条数据的筛选、处理和建模,预测六月客户流失情况。使用了决策树和随机森林算法,发现特征处理和建模方法对结果影响较大,强调了业务理解和特征工程的重要性。
摘要由CSDN通过智能技术生成

根据五月数据,对六月客户是否流失做一个预测

五月数据 部分操作举例

五月数据九十万条,74个特征

数据筛选

导入数据,查看缺失值

data5.isnull().sum()

删除其中一列对结果影响并不大的四行缺失值
用众数填充另一列的缺失值

data5=data5.dropna(subset=["ZHU_OFFER_ID"])
#宽带接入方式CONSOLIDATE_CONNET_MODE
import numpy as np
from scipy.stats import mode
print("# Print mode(list):", mode(data5['CONSOLIDATE_CONNET_MODE']))
print("# CONSOLIDATE_CONNET_MODE中最常见的成员为:{},出现了{}次。".format(mode(data5['CONSOLIDATE_CONNET_MODE'])[0][0], mode(data5['CONSOLIDATE_CONNET_MODE'])[1][0]))
#把缺失的4730个数据填充为“FTTH接入”
data5['CONSOLIDATE_CONNET_MODE'] = data5['CONSOLIDATE_CONNET_MODE'].fillna('FTTH接入')

在这里插入图片描述

#Print mode(list): ModeResult(mode=array([‘FTTH接入’], dtype=object), count=array([852397]))
#CONSOLIDATE_CONNET_MODE中最常见的成员为:FTTH接入,出现了852397次。

查看热力图

plt.figure(figsize=(30, 30), dpi=120)
sns.heatmap(data5.corr())
plt.savefig('res.png')

在这里插入图片描述
对某些列做直方图、箱线图分析,判断是否为可用特征
(其实是带有人为主观的去判断,不是很准确吧)
举例:

#是否二路宽带
sns.countplot(x='IS_SECOND_KD',hue='IF_FALG',data=data5)

在这里插入图片描述

#宽带速率
sns.boxplot(y='CONSOLIDATE_SPEND', x='IF_FALG', data=data5,order=[1,0])
plt.ylim(0,700)

在这里插入图片描述
根据热力图进行分析,哪些数据可能会对结果有影响,将相关性太高太低的部分进行散点图绘制,找出某些特征中间的关联,仅保留个别特征。
绘制散点图,找出关系
在这里插入图片描述

数据处理

删除某些行数过小不会对结果造成太大影响的行

data5.drop(data5[data5['CONSOLIDATE_CONNET_MODE'] == "PON专线"].index, inplace=True)
data5.drop(data5[data5['CONSOLIDATE_CONNET_MODE'] == "EOC接入"].index, inplace=True)

独热编码

data5 = data5.join(pd.get_dummies(data5.CONSOLIDATE_CONNET_MODE))
data5 = data5.join(pd.get_dummies(data5.BILLING_MODE_ID))
data5 = data5.join(pd.get_dummies(data5.STATE_NAME))
data5 = data5.join(pd.get_dummies(data5.COUNTRY_FLAG))

分箱处理

ONLINE_LEN=list(data5['ONLINE_LEN'])
ONLINE_LEN_cats=pd.qcut(ONLINE_LEN,3,duplicates="drop")
ONLINE_LEN_dummies=pd.get_dummies(ONLINE_LEN_cats)
ONLINE_LEN_dummies
data5["ONLINE_LEN_(3.999, 25.0]"]=ONLINE_LEN_dummies.values[:,0]
data5["ONLINE_LEN_(25.0, 53.0]"]=ONLINE_LEN_dummies.values[:,1]
data5["ONLINE_LEN_(53.0, 782.0]"]=ONLINE_LEN_dummies.values[:,2]

建模

将筛选出的最终的特征提取出来,形成一个单独的表格

from sklearn.naive_bayes import GaussianNB

from sklearn.discriminant_analysis import LinearDiscriminantAnalysis

from sklearn.tree import DecisionTreeClassifier
from sklearn.linear_model import LogisticRegression as LR
from sklearn.metrics import recall_score
from sklearn.metrics import f1_score
X = feature_5.drop(['IF_FALG'],1)
y = feature_5['IF_FALG']

将五月数据分为训练集、测试集进行检测

from sklearn.model_selection import train_test_split
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.25, random_state=42)
dtc = DecisionTreeClassifier()
dtc.fit(X,y)
y_pred_dtc = dtc.predict(X_test)
print("决策树模型训练集的正确率:%s" % dtc.score(X,y))
print("决策树模型测试集的正确率:%s" % dtc.score(X_test,y_test))

# pred_array = np.array(dtc.predict_proba(features_test))
# pred_array

r_dtc = recall_score(y_test, y_pred_dtc, average='binary')
print("决策树模型的召回率:%s" % r_dtc)
f1score_dtc = f1_score(y_test, y_pred_dtc, average='binary')
print("决策树模型的f1值:%s" % f1score_dtc)

结果:
决策树模型训练集的正确率:0.9854719499671242
决策树模型测试集的正确率:0.9853323422951915
决策树模型的召回率:0.9479498152821976
决策树模型的f1值:0.9395471930683199

from sklearn.ensemble import RandomForestClassifier     #随机森林
forest = RandomForestClassifier(n_estimators=1000, random_state=0, n_jobs=-1)
forest.fit(X_train, y_train)

y_pred_forest = forest.predict(X_test)
print("随机森林算法训练集评分:%s" % forest.score(X_train,y_train))
print("随机森林算法测试集评分:%s" % forest.score(X_test,y_test))
pred_array = np.array(forest.predict_proba(X_test))
pred_array

#print(accuracy_score(y_test,y_pred_forest),roc_auc_score(y_test,y_pred_forest))
print("随机森林模型的召回率:%s" % recall_score(y_test,y_pred_forest),"随机森林模型的f1值:%s" % f1_score(y_test,y_pred_forest))

结果:
随机森林算法训练集评分:0.985750119848529
随机森林算法测试集评分:0.9821305267602288
随机森林模型的召回率:0.9377811917041589 随机森林模型的f1值:0.9265798080919424

六月

六月份数据太过庞大,因此进行了数据拆分,仅用了60万数据
选择的特征和五月完全一致,处理方式基本相同
将六月的处理后的特征提取出来
进行预测

X = feature_5.drop(['IF_FALG'],1)
y = feature_5['IF_FALG']
X_test_6 = feature_6.drop([ 'BILLING_ARRIVE_FLAG'],1)
y_test_6 = feature_6['BILLING_ARRIVE_FLAG']
dtc = DecisionTreeClassifier()
dtc.fit(X,y)
y_pred_dtc = dtc.predict(X_test_6)
print("决策树模型训练集的正确率:%s" % dtc.score(X,y))
print("决策树模型测试集的正确率:%s" % dtc.score(X_test_6,y_test_6))

# pred_array = np.array(dtc.predict_proba(features_test))
# pred_array

r_dtc = recall_score(y_test_6, y_pred_dtc, average='binary')
print("决策树模型的召回率:%s" % r_dtc)
f1score_dtc = f1_score(y_test_6, y_pred_dtc, average='binary')
print("决策树模型的f1值:%s" % f1score_dtc)

结果:
决策树模型训练集的正确率:0.9854719499671242
决策树模型测试集的正确率:0.9870322310729746
决策树模型的召回率:0.8396955786421841
决策树模型的f1值:0.641177013190665

from sklearn.metrics import classification_report
print(classification_report(y_test_6, y_pred_dtc))

在这里插入图片描述

from sklearn.ensemble import RandomForestClassifier     #随机森林
forest = RandomForestClassifier(n_estimators=1000, random_state=0, n_jobs=-1)
forest.fit(X_train, y_train)

y_pred_forest = forest.predict(X_test_6)
print("随机森林算法训练集评分:%s" % forest.score(X_train,y_train))
print("随机森林算法测试集评分:%s" % forest.score(X_test_6,y_test_6))
# pred_array = np.array(forest.predict_proba(X_test_6))
# pred_array

#print(accuracy_score(y_test_6,y_pred_forest),roc_auc_score(y_test_6,y_pred_forest))
print("随机森林模型的召回率:%s" % recall_score(y_test_6,y_pred_forest),"随机森林模型的f1值:%s" % f1_score(y_test_6,y_pred_forest))

结果:
随机森林算法训练集评分:0.985750119848529
随机森林算法测试集评分:0.9869738927808864
随机森林模型的召回率:0.852017395506161 随机森林模型的f1值:0.6434925413986587

print(classification_report(y_test_6, y_pred_forest))

在这里插入图片描述

查看所选特征的相关性

#互信息法及特征相关性
plt.figure(figsize=(50,50))
sns.heatmap(feature_6.corr(),annot=True,cmap='CMRmap_r')

在这里插入图片描述
小结:对特征的处理方式问题,导致结果并不是非常的好,加入的人为主观因素过多。特征处理其实还有很多种方法,后面也会再仔细想一想,面对特征时应该要发散思维想到更多直接的处理方式。有些简单粗暴的处理方式可能会更好。还是对业务数据的不熟练。建模也只是那些很普遍的建模方式,并没有根据实际的数据特征去思考最佳的建模方案。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值