174、電信客戶流失預(yù)測

電信行業(yè)在競爭日益激烈當(dāng)下,如何挽留更多用戶成為一項關(guān)鍵業(yè)務(wù)指標(biāo)。為了更好運營用戶,這就要求要了解流失用戶的特征,分析流失原因,預(yù)測用戶流失,確定挽留目標(biāo)用戶并制定有效方案。
一、提出問題
1、哪些用戶可能會流失?
2、流失概率更高的用戶有什么共同特征?
二、 理解數(shù)據(jù)
(1)采集數(shù)據(jù)
本數(shù)據(jù)集來自DF ,數(shù)據(jù)源地址:
https://www.datafountain.cn/dataSets/35/details#
本數(shù)據(jù)集描述了電信用戶是否流失以及其相關(guān)信息,共包含7044條數(shù)據(jù),共20個字段,分別介紹如下:
customerID : 用戶ID。
gender:性別。(Female & Male)
SeniorCitizen :老年人 (1表示是,0表示不是)
Partner :是否有配偶 (Yes or No)
Dependents :是否經(jīng)濟獨立 (Yes or No)
tenure : 客戶的職位(0-72,共73個職位)
PhoneService : 是否開通電話服務(wù)業(yè)務(wù) (Yes or No)
MultipleLines: 是否開通了多線業(yè)務(wù)(Yes 、No or No phoneservice 三種)
InternetService:是否開通互聯(lián)網(wǎng)服務(wù) (No, DSL數(shù)字網(wǎng)絡(luò),fiber optic光纖網(wǎng)絡(luò) 三種)
OnlineSecurity:是否開通網(wǎng)絡(luò)安全服務(wù)(Yes,No,No internetserive 三種)
OnlineBackup:是否開通在線備份業(yè)務(wù)(Yes,No,No internetserive 三種)
DeviceProtection:是否開通了設(shè)備保護業(yè)務(wù)(Yes,No,No internetserive 三種)
TechSupport:是否開通了技術(shù)支持服務(wù)(Yes,No,No internetserive 三種)
StreamingTV:是否開通網(wǎng)絡(luò)電視(Yes,No,No internetserive 三種)
StreamingMovies:是否開通網(wǎng)絡(luò)電影(Yes,No,No internetserive 三種)
Contract:簽訂合同方式 (按月,一年,兩年)
PaperlessBilling:是否開通電子賬單(Yes or No)
PaymentMethod:付款方式(bank transfer,credit card,electronic check,mailed check)
MonthlyCharges:月費用
TotalCharges:總費用
Churn:該用戶是否流失(Yes or No)
(2)導(dǎo)入數(shù)據(jù)

1.png

2.png

(3)查看數(shù)據(jù)集信息
3.png

4.png

三、數(shù)據(jù)清洗

(1)查找缺失值
5查找缺失值1.png
5查找缺失值2.png

數(shù)據(jù)集中有5174名用戶沒流失,有1869名客戶流失,數(shù)據(jù)集不均衡。

(2)查看數(shù)據(jù)類型
6查看數(shù)據(jù)類型.png

TotalCharges表示總費用,這里為對象類型,需要轉(zhuǎn)換為float類型

(3)轉(zhuǎn)換類型
6-2 轉(zhuǎn)換類型.png

再次查找缺失值:
7再次查找缺失值.png

這里存在11個缺失值,由于數(shù)量不多我們可以直接刪除這些行

(4)處理缺失值
8處理缺失值.png

(5)數(shù)據(jù)歸一化處理
9數(shù)據(jù)歸一化處理.png

四、數(shù)據(jù)可視化呈現(xiàn)

(1)查看流失客戶占比
10查看流失客戶占比.png
10流失客戶占比結(jié)果.png

由圖中結(jié)果可以看出,流失客戶占整體客戶的26.6%。

(2)性別、老年人、配偶、親屬對流客戶流失率的影響
11性別、老年人、配偶、親屬對流客戶流失率的影響.png
12性別、老年人占比結(jié)果.png
13配偶、親屬占比結(jié)果.png

可以看出,男性與女性用戶之間的流失情況基本沒有差異,而在老年用戶中流失占比明顯比非老年用戶更高,在所有數(shù)據(jù)中未婚與已婚人數(shù)基本持平,但未婚中流失人數(shù)比已婚中的流失人數(shù)高出了快一倍,從經(jīng)濟獨立情況來看,經(jīng)濟未獨立的用戶流失率要遠(yuǎn)遠(yuǎn)高于經(jīng)濟獨立的用戶。

(3)提取特征
14提取特征1.png
14提取特征2.png

(4)構(gòu)造相關(guān)性矩陣
15構(gòu)造相關(guān)性矩陣.png

(5)使用熱地圖顯示相關(guān)系數(shù)
16使用熱地圖顯示相關(guān)系數(shù)1.png
16使用熱地圖顯示相關(guān)系數(shù)2.png

結(jié)論:從上圖可以看出,互聯(lián)網(wǎng)服務(wù)、網(wǎng)絡(luò)安全服務(wù)、在線備份業(yè)務(wù)、設(shè)備保護業(yè)務(wù)、技術(shù)支持服務(wù)、網(wǎng)絡(luò)電視和網(wǎng)絡(luò)電影之間存在較強的相關(guān)性,多線業(yè)務(wù)和電話服務(wù)之間也有很強的相關(guān)性,并且都呈強正相關(guān)關(guān)系。

(6)使用one-hot編碼
17使用one-hot編碼.png

(7)電信用戶是否流失與各變量之間的相關(guān)性
18電信用戶是否流失與各變量之間的相關(guān)性1.png
18電信用戶是否流失與各變量之間的相關(guān)性2.png

由圖上可以看出,變量gender 和 PhoneService 處于圖形中間,其值接近于 0 ,這兩個變量對電信客戶流失預(yù)測影響非常小,可以直接舍棄。

(8)網(wǎng)絡(luò)安全服務(wù)、在線備份業(yè)務(wù)、設(shè)備保護業(yè)務(wù)、技術(shù)支持服務(wù)、網(wǎng)絡(luò)電視、網(wǎng)絡(luò)電影和無互聯(lián)網(wǎng)服務(wù)對客戶流失率的影響
19網(wǎng)絡(luò)安全服務(wù)、在線備份業(yè)務(wù)、設(shè)備保護業(yè)務(wù)、技術(shù)支持服務(wù)、網(wǎng)絡(luò)電視、網(wǎng)絡(luò)電影和無互聯(lián)網(wǎng)服務(wù)對客戶流失率的影響.png
20網(wǎng)絡(luò)安全服務(wù)、在線備份業(yè)務(wù)、設(shè)備保護業(yè)務(wù)和無互聯(lián)網(wǎng)服務(wù)對流失率的影響.png
21技術(shù)支持服務(wù)、網(wǎng)絡(luò)電視、網(wǎng)絡(luò)電影和無互聯(lián)網(wǎng)服務(wù)對流失率的影響.png

由上圖可以看出,在網(wǎng)絡(luò)安全服務(wù)、在線備份業(yè)務(wù)、設(shè)備保護業(yè)務(wù)、技術(shù)支持服務(wù)、網(wǎng)絡(luò)電視和網(wǎng)絡(luò)電影六個變量中,沒有互聯(lián)網(wǎng)服務(wù)的客戶流失率值是相同的,都是相對較低。
這可能是因為以上六個因素只有在客戶使用互聯(lián)網(wǎng)服務(wù)時才會影響客戶的決策,這六個因素不會對不使用互聯(lián)網(wǎng)服務(wù)的客戶決定是否流失產(chǎn)生推論效應(yīng)。

(9)簽訂合同方式對客戶流失率的影響
22簽訂合同方式對客戶流失率的影響.png

由圖上可以看出,簽訂合同方式對客戶流失率影響為:按月簽訂 > 按一年簽訂 > 按兩年簽訂,這可能表明,設(shè)定長期合同對留住現(xiàn)有客戶更有效。

(10)付款方式對客戶流失率的影響
23付款方式對客戶流失率的影響.png

由圖上可以看出,在四種支付方式中,使用Electronic check的用戶流流失率最高,其他三種支付方式基本持平,因此可以推斷電子賬單在設(shè)計上影響用戶體驗。
五、數(shù)據(jù)預(yù)處理

由前面結(jié)果可知,CustomerID表示每個客戶的隨機字符,對后續(xù)建模不影響,我這里選擇刪除CustomerID列;gender 和 PhoneService 與流失率的相關(guān)性低,可直接忽略。
24刪除不必要的列.png

對客戶的職位、月費用和總費用進(jìn)行去均值和方差縮放,對數(shù)據(jù)進(jìn)行標(biāo)準(zhǔn)化:
25對數(shù)據(jù)進(jìn)行標(biāo)準(zhǔn)化.png

使用箱線圖查看數(shù)據(jù)是否存在異常值:
26查看數(shù)據(jù)是否存在異常值.png

由以上結(jié)果可以看出,在三個變量中不存在明顯的異常值。

查看對象類型字段中存在的值:
27查看對象類型字段中存在的值.png

綜合之前的結(jié)果來看,在六個變量中存在No internet service,即無互聯(lián)網(wǎng)服務(wù)對客戶流失率影響很小,這些客戶不使用任何互聯(lián)網(wǎng)產(chǎn)品,因此可以將No internet service 和 No 是一樣的效果,可以使用 No 替代 No internet service。
28替換值.png

使用Scikit-learn標(biāo)簽編碼,將分類數(shù)據(jù)轉(zhuǎn)換為整數(shù)編碼:
29Scikit-learn標(biāo)簽編碼.png

六、構(gòu)建模型

(1)建立訓(xùn)練數(shù)據(jù)集和測試數(shù)據(jù)集
30建立訓(xùn)練數(shù)據(jù)集和測試數(shù)據(jù)集1.png
30建立訓(xùn)練數(shù)據(jù)集和測試數(shù)據(jù)集2.png

(2)選擇機器學(xué)習(xí)算法
31選擇機器學(xué)習(xí)算法.png

(3)訓(xùn)練模型
32訓(xùn)練模型.png

(4)評估模型

召回率(recall)的含義是:原本為對的當(dāng)中,預(yù)測為對的比例(值越大越好,1為理想狀態(tài))
精確率、精度(precision)的含義是:預(yù)測為對的當(dāng)中,原本為對的比例(值越大越好,1為理想狀態(tài))
F1分?jǐn)?shù)(F1-Score)指標(biāo)綜合了Precision與Recall的產(chǎn)出的結(jié)果

F1-Score的取值范圍從0到1的,1代表模型的輸出最好,0代表模型的輸出結(jié)果最差。
評估模型.png

綜上所述,在10種分類算法中樸素貝葉斯(Naive Bayes)的F1分?jǐn)?shù)最大為63.31%,所以使用樸素貝葉斯模型效果最好。

七、實施方案


實施方案.png

結(jié)果.png

八、結(jié)論
通過上述分析,我們可以大致勾勒出容易流失的用戶特征:

  1. 老年用戶與未婚且經(jīng)濟未獨立的青少年用戶更容易流失。
  2. 電話服務(wù)對用戶的流失沒有直接的影響。
  3. 提供的各項網(wǎng)絡(luò)服務(wù)項目能夠降低用戶的流失率。
  4. 簽訂合同越久,用戶的留存率越高。
  5. 采用electronic check支付的用戶更易流失。
    針對上述診斷結(jié)果,可有針對性的對此提出建議:
    推薦老年用戶與青少年用戶采用數(shù)字網(wǎng)絡(luò),且簽訂2年期合同(可以各種輔助優(yōu)惠等營銷手段來提高2年期合同的簽訂率),若能開通相關(guān)網(wǎng)絡(luò)服務(wù)可增加用戶粘性,因此可增加這塊業(yè)務(wù)的推廣,同時考慮改善電子賬單支付的用戶體驗。

# coding: utf-8

# # 電信客戶流失預(yù)測

# ## 1、導(dǎo)入數(shù)據(jù)

# In[1]:

import numpy as np
import pandas as pd 
import os


# In[2]:

# 導(dǎo)入相關(guān)的包
import matplotlib.pyplot as plt
import seaborn as sns
from pylab import rcParams
import matplotlib.cm as cm

import sklearn
from sklearn import preprocessing
from sklearn.preprocessing import LabelEncoder               # 編碼轉(zhuǎn)換
from sklearn.preprocessing import StandardScaler
from sklearn.model_selection import StratifiedShuffleSplit

from sklearn.ensemble import RandomForestClassifier          # 隨機森林
from sklearn.svm import SVC, LinearSVC                       # 支持向量機
from sklearn.linear_model import LogisticRegression          # 邏輯回歸
from sklearn.neighbors import KNeighborsClassifier           # KNN算法
from sklearn.naive_bayes import GaussianNB                   # 樸素貝葉斯
from sklearn.tree import DecisionTreeClassifier              # 決策樹分類器
from xgboost import XGBClassifier
from catboost import CatBoostClassifier
from sklearn.ensemble import AdaBoostClassifier
from sklearn.ensemble import GradientBoostingClassifier     

from sklearn.metrics import classification_report, precision_score, recall_score, f1_score
from sklearn.metrics import confusion_matrix
from sklearn.model_selection import GridSearchCV
from sklearn.metrics import make_scorer
from sklearn.ensemble import VotingClassifier

from sklearn.decomposition import PCA
from sklearn.cluster import KMeans
from sklearn.metrics import silhouette_score

import warnings
warnings.filterwarnings('ignore')

get_ipython().magic('matplotlib inline')


# In[3]:

# 讀取數(shù)據(jù)文件
telcom=pd.read_csv(r"F:\data\WA_Fn-UseC_-Telco-Customer-Churn.csv")


# ## 2、查看數(shù)據(jù)集信息

# In[4]:

telcom.head(10)


# In[5]:

# 查看數(shù)據(jù)集大小
telcom.shape


# In[6]:

# 獲取數(shù)據(jù)類型列的描述統(tǒng)計信息
telcom.describe()


# ## 3、數(shù)據(jù)清洗

# In[7]:

# 查找缺失值
pd.isnull(telcom).sum()


# In[8]:

telcom["Churn"].value_counts()


# 數(shù)據(jù)集中有5174名用戶沒流失,有1869名客戶流失,數(shù)據(jù)集不均衡。

# In[9]:

telcom.info()


# TotalCharges表示總費用,這里為對象類型,需要轉(zhuǎn)換為float類型  

# In[10]:

telcom['TotalCharges']=telcom['TotalCharges'].convert_objects(convert_numeric=True) # convert_numeric=True表示強制轉(zhuǎn)換數(shù)字(包括字符串),不可轉(zhuǎn)換的值變?yōu)镹aN
telcom["TotalCharges"].dtypes


# In[11]:

# 再次查找是否存在缺失值
pd.isnull(telcom["TotalCharges"]).sum()


# 這里存在11個缺失值,由于數(shù)量不多我們可以直接刪除這些行

# In[12]:

# 刪除缺失值所在的行
telcom.dropna(inplace=True)
telcom.shape


# In[13]:

# 數(shù)據(jù)歸一化處理
# 對Churn 列中的值 Yes和 No分別用 1和 0替換,方便后續(xù)處理
telcom['Churn'].replace(to_replace = 'Yes', value = 1,inplace = True)
telcom['Churn'].replace(to_replace = 'No', value = 0,inplace = True)
telcom['Churn'].head()


# In[14]:

telcom['Churn'].replace(to_replace='Yes', value=1, inplace=True)
telcom['Churn'].replace(to_replace='No',  value=0, inplace=True)
telcom['Churn'].head()


# ## 4、數(shù)據(jù)可視化呈現(xiàn)

# In[15]:

# 查看流失客戶占比
"""
畫餅圖參數(shù):
labels  (每一塊)餅圖外側(cè)顯示的說明文字
explode  (每一塊)離開中心距離
startangle  起始繪制角度,默認(rèn)圖是從x軸正方向逆時針畫起,如設(shè)定=90則從y軸正方向畫起
shadow   是否陰影
labeldistance label  繪制位置,相對于半徑的比例, 如<1則繪制在餅圖內(nèi)側(cè)
autopct   控制餅圖內(nèi)百分比設(shè)置,可以使用format字符串或者format function
     '%1.1f'指小數(shù)點前后位數(shù)(沒有用空格補齊)
pctdistance 類似于labeldistance,指定autopct的位置刻度
radius   控制餅圖半徑
"""
churnvalue=telcom["Churn"].value_counts()
labels=telcom["Churn"].value_counts().index

rcParams["figure.figsize"]=6,6
plt.pie(churnvalue,labels=labels,colors=["whitesmoke","yellow"], explode=(0.1,0),autopct='%1.1f%%', shadow=True)
plt.title("Proportions of Customer Churn")
plt.show()


# In[16]:

# 性別、老年人、配偶、親屬對流客戶流失率的影響
f, axes = plt.subplots(nrows=2, ncols=2, figsize=(10,10))

plt.subplot(2,2,1)
gender=sns.countplot(x="gender",hue="Churn",data=telcom,palette="Pastel2") # palette參數(shù)表示設(shè)置顏色,這里設(shè)置為主題色Pastel2
plt.xlabel("gender")
plt.title("Churn by Gender")

plt.subplot(2,2,2)
seniorcitizen=sns.countplot(x="SeniorCitizen",hue="Churn",data=telcom,palette="Pastel2")
plt.xlabel("senior citizen")
plt.title("Churn by Senior Citizen")

plt.subplot(2,2,3)
partner=sns.countplot(x="Partner",hue="Churn",data=telcom,palette="Pastel2")
plt.xlabel("partner")
plt.title("Churn by Partner")

plt.subplot(2,2,4)
dependents=sns.countplot(x="Dependents",hue="Churn",data=telcom,palette="Pastel2")
plt.xlabel("dependents")
plt.title("Churn by Dependents")


# In[17]:

# 提取特征
charges=telcom.iloc[:,1:20]
# 對特征進(jìn)行編碼
"""
離散特征的編碼分為兩種情況:
1、離散特征的取值之間沒有大小的意義,比如color:[red,blue],那么就使用one-hot編碼
2、離散特征的取值有大小的意義,比如size:[X,XL,XXL],那么就使用數(shù)值的映射{X:1,XL:2,XXL:3}
"""
corrDf = charges.apply(lambda x: pd.factorize(x)[0])
corrDf .head()


# In[18]:

# 構(gòu)造相關(guān)性矩陣
corr = corrDf.corr()
corr


# In[19]:

# 使用熱地圖顯示相關(guān)系數(shù)
'''
heatmap    使用熱地圖展示系數(shù)矩陣情況
linewidths 熱力圖矩陣之間的間隔大小
annot      設(shè)定是否顯示每個色塊的系數(shù)值
'''
plt.figure(figsize=(20,16))
ax = sns.heatmap(corr, xticklabels=corr.columns, yticklabels=corr.columns, 
                 linewidths=0.2, cmap="YlGnBu",annot=True)
plt.title("Correlation between variables")


# 結(jié)論:從上圖可以看出,互聯(lián)網(wǎng)服務(wù)、網(wǎng)絡(luò)安全服務(wù)、在線備份業(yè)務(wù)、設(shè)備保護業(yè)務(wù)、技術(shù)支持服務(wù)、網(wǎng)絡(luò)電視和網(wǎng)絡(luò)電影之間存在較強的相關(guān)性,多線業(yè)務(wù)和電話服務(wù)之間也有很強的相關(guān)性,并且都呈強正相關(guān)關(guān)系。

# In[20]:

# 使用one-hot編碼
tel_dummies = pd.get_dummies(telcom.iloc[:,1:21])
tel_dummies.head()


# In[21]:

# 電信用戶是否流失與各變量之間的相關(guān)性
plt.figure(figsize=(15,8))
tel_dummies.corr()['Churn'].sort_values(ascending = False).plot(kind='bar')
plt.title("Correlations between Churn and variables")


# 由圖上可以看出,變量gender 和 PhoneService 處于圖形中間,其值接近于 0 ,這兩個變量對電信客戶流失預(yù)測影響非常小,可以直接舍棄。

# In[22]:

# 網(wǎng)絡(luò)安全服務(wù)、在線備份業(yè)務(wù)、設(shè)備保護業(yè)務(wù)、技術(shù)支持服務(wù)、網(wǎng)絡(luò)電視、網(wǎng)絡(luò)電影和無互聯(lián)網(wǎng)服務(wù)對客戶流失率的影響
covariables=["OnlineSecurity", "OnlineBackup", "DeviceProtection", "TechSupport", "StreamingTV", "StreamingMovies"]
fig,axes=plt.subplots(nrows=2,ncols=3,figsize=(16,10))
for i, item in enumerate(covariables):
    plt.subplot(2,3,(i+1))
    ax=sns.countplot(x=item,hue="Churn",data=telcom,palette="Pastel2",order=["Yes","No","No internet service"])
    plt.xlabel(str(item))
    plt.title("Churn by "+ str(item))
    i=i+1
plt.show()


# 由上圖可以看出,在網(wǎng)絡(luò)安全服務(wù)、在線備份業(yè)務(wù)、設(shè)備保護業(yè)務(wù)、技術(shù)支持服務(wù)、網(wǎng)絡(luò)電視和網(wǎng)絡(luò)電影六個變量中,沒有互聯(lián)網(wǎng)服務(wù)的客戶流失率值是相同的,都是相對較低。
# 
# 這可能是因為以上六個因素只有在客戶使用互聯(lián)網(wǎng)服務(wù)時才會影響客戶的決策,這六個因素不會對不使用互聯(lián)網(wǎng)服務(wù)的客戶決定是否流失產(chǎn)生推論效應(yīng)。

# In[23]:

# 簽訂合同方式對客戶流失率的影響
sns.barplot(x="Contract",y="Churn", data=telcom, palette="Pastel1", order= ['Month-to-month', 'One year', 'Two year'])
plt.title("Churn by Contract type")


# 由圖上可以看出,簽訂合同方式對客戶流失率影響為:按月簽訂 > 按一年簽訂 > 按兩年簽訂,這可能表明,設(shè)定長期合同對留住現(xiàn)有客戶更有效。

# In[24]:

# 付款方式對客戶流失率的影響
plt.figure(figsize=(10,5))
sns.barplot(x="PaymentMethod",y="Churn", data=telcom, palette="Pastel1", order= ['Bank transfer (automatic)', 'Credit card (automatic)', 'Electronic check','Mailed check'])
plt.title("Churn by PaymentMethod type")


# 由圖上可以看出,在四種支付方式中,使用Electronic check的用戶流流失率最高,其他三種支付方式基本持平,因此可以推斷電子賬單在設(shè)計上影響用戶體驗。




# ## 5、數(shù)據(jù)預(yù)處理

# 由前面結(jié)果可知,CustomerID表示每個客戶的隨機字符,對后續(xù)建模不影響,我這里選擇刪除CustomerID列;gender 和 PhoneService 與流失率的相關(guān)性低,可直接忽略。

# In[26]:

telcomvar=telcom.iloc[:,2:20]
telcomvar.drop("PhoneService",axis=1, inplace=True)

# 提取ID
telcom_id = telcom['customerID']

telcomvar.head()


# In[27]:

# 對客戶的職位、月費用和總費用進(jìn)行去均值和方差縮放,對數(shù)據(jù)進(jìn)行標(biāo)準(zhǔn)化
"""
標(biāo)準(zhǔn)化數(shù)據(jù),保證每個維度的特征數(shù)據(jù)方差為1,均值為0,使得預(yù)測結(jié)果不會被某些維度過大的特征值而主導(dǎo)。
"""
scaler = StandardScaler(copy=False)
# fit_transform()的作用就是先擬合數(shù)據(jù),然后轉(zhuǎn)化它將其轉(zhuǎn)化為標(biāo)準(zhǔn)形式
scaler.fit_transform(telcomvar[['tenure','MonthlyCharges','TotalCharges']])


# In[28]:

# tranform()的作用是通過找中心和縮放等實現(xiàn)標(biāo)準(zhǔn)化
telcomvar[['tenure','MonthlyCharges','TotalCharges']]=scaler.transform(telcomvar[['tenure','MonthlyCharges','TotalCharges']])


# In[29]:

# 使用箱線圖查看數(shù)據(jù)是否存在異常值
plt.figure(figsize = (8,4))
numbox = sns.boxplot(data=telcomvar[['tenure','MonthlyCharges','TotalCharges']], palette="Set2")
plt.title("Check outliers of standardized tenure, MonthlyCharges and TotalCharges")


# 由以上結(jié)果可以看出,在三個變量中不存在明顯的異常值

# In[30]:

# 查看對象類型字段中存在的值
def uni(columnlabel):
    print(columnlabel,"--" ,telcomvar[columnlabel].unique())  # unique函數(shù)去除其中重復(fù)的元素,返回唯一值
    
telcomobject=telcomvar.select_dtypes(['object'])
for i in range(0,len(telcomobject.columns)):
    uni(telcomobject.columns[i])


# 綜合之前的結(jié)果來看,在六個變量中存在No internet service,即無互聯(lián)網(wǎng)服務(wù)對客戶流失率影響很小,這些客戶不使用任何互聯(lián)網(wǎng)產(chǎn)品,因此可以將No internet service 和 No 是一樣的效果,可以使用 No 替代 No internet service

# In[31]:

telcomvar.replace(to_replace='No internet service', value='No', inplace=True)
telcomvar.replace(to_replace='No phone service', value='No', inplace=True)
for i in range(0,len(telcomobject.columns)):
    uni(telcomobject.columns[i])


# In[32]:

# 使用Scikit-learn標(biāo)簽編碼,將分類數(shù)據(jù)轉(zhuǎn)換為整數(shù)編碼
def labelencode(columnlabel):
    telcomvar[columnlabel] = LabelEncoder().fit_transform(telcomvar[columnlabel])
    
for i in range(0,len(telcomobject.columns)):
    labelencode(telcomobject.columns[i])
    
for i in range(0,len(telcomobject.columns)):
    uni(telcomobject.columns[i])


# ## 6、構(gòu)建模型

# ### (1)建立訓(xùn)練數(shù)據(jù)集和測試數(shù)據(jù)集

# In[33]:

"""
我們需要將數(shù)據(jù)集拆分為訓(xùn)練集和測試集以進(jìn)行驗證。
由于我們所擁有的數(shù)據(jù)集是不平衡的,所以最好使用分層交叉驗證來確保訓(xùn)練集和測試集都包含每個類樣本的保留人數(shù)。
交叉驗證函數(shù)StratifiedShuffleSplit,功能是從樣本數(shù)據(jù)中隨機按比例選取訓(xùn)練數(shù)據(jù)(train)和測試數(shù)據(jù)(test)
參數(shù) n_splits是將訓(xùn)練數(shù)據(jù)分成train/test對的組數(shù),可根據(jù)需要進(jìn)行設(shè)置,默認(rèn)為10
參數(shù)test_size和train_size是用來設(shè)置train/test對中train和test所占的比例
參數(shù) random_state控制是將樣本隨機打亂
"""
X=telcomvar
y=telcom["Churn"].values

sss=StratifiedShuffleSplit(n_splits=5, test_size=0.2, random_state=0)
print(sss)
print("訓(xùn)練數(shù)據(jù)和測試數(shù)據(jù)被分成的組數(shù):",sss.get_n_splits(X,y))


# In[34]:

# 建立訓(xùn)練數(shù)據(jù)和測試數(shù)據(jù)
for train_index, test_index in sss.split(X, y):
    print("train:", train_index, "test:", test_index)
    X_train,X_test=X.iloc[train_index], X.iloc[test_index]
    y_train,y_test=y[train_index], y[test_index]


# In[35]:

# 輸出數(shù)據(jù)集大小
print('原始數(shù)據(jù)特征:', X.shape,
      '訓(xùn)練數(shù)據(jù)特征:',X_train.shape,
      '測試數(shù)據(jù)特征:',X_test.shape)

print('原始數(shù)據(jù)標(biāo)簽:', y.shape,
      '   訓(xùn)練數(shù)據(jù)標(biāo)簽:',y_train.shape,
      '   測試數(shù)據(jù)標(biāo)簽:',y_test.shape)


# ### (2)選擇機器學(xué)習(xí)算法

# In[36]:

# 使用分類算法,這里選用10種分類算法
Classifiers=[["Random Forest",RandomForestClassifier()],
             ["Support Vector Machine",SVC()],
             ["LogisticRegression",LogisticRegression()],
             ["KNN",KNeighborsClassifier(n_neighbors=5)],
             ["Naive Bayes",GaussianNB()],
             ["Decision Tree",DecisionTreeClassifier()],
             ["AdaBoostClassifier", AdaBoostClassifier()],
             ["GradientBoostingClassifier", GradientBoostingClassifier()],
             ["XGB", XGBClassifier()],
             ["CatBoost", CatBoostClassifier(logging_level='Silent')]  
]


# ### (3)訓(xùn)練模型

# In[37]:

Classify_result=[]
names=[]
prediction=[]
for name,classifier in Classifiers:
    classifier=classifier
    classifier.fit(X_train,y_train)
    y_pred=classifier.predict(X_test)
    recall=recall_score(y_test,y_pred)
    precision=precision_score(y_test,y_pred)
    class_eva=pd.DataFrame([recall,precision])
    Classify_result.append(class_eva)
    name=pd.Series(name)
    names.append(name)
    y_pred=pd.Series(y_pred)
    prediction.append(y_pred)


# ### (4)評估模型

# In[38]:

# 評估模型
"""
召回率(recall)的含義是:原本為對的當(dāng)中,預(yù)測為對的比例(值越大越好,1為理想狀態(tài))
精確率、精度(precision)的含義是:預(yù)測為對的當(dāng)中,原本為對的比例(值越大越好,1為理想狀態(tài))
F1分?jǐn)?shù)(F1-Score)指標(biāo)綜合了Precision與Recall的產(chǎn)出的結(jié)果
F1-Score的取值范圍從0到1的,1代表模型的輸出最好,0代表模型的輸出結(jié)果最差。
"""

names=pd.DataFrame(names)
names=names[0].tolist()
result=pd.concat(Classify_result,axis=1)
result.columns=names
result.index=["recall","precision","f1score"]
result


# 綜上所述,在10種分類算法中樸素貝葉斯(Naive Bayes)的F1分?jǐn)?shù)最大為63.31%,所以使用樸素貝葉斯模型效果最好。

# ## 7、實施方案

# 預(yù)測數(shù)據(jù)集特征(由于沒有提供預(yù)測數(shù)據(jù)集,這里選取后10行作為需要預(yù)測的數(shù)據(jù)集)
pred_X = telcomvar.tail(10)

# 提取customerID
pre_id = telcom_id.tail(10)

# 使用樸素貝葉斯方法,對預(yù)測數(shù)據(jù)集中的生存情況進(jìn)行預(yù)測
model = GaussianNB()
model.fit(X_train,y_train)
pred_y = model.predict(pred_X)

# 預(yù)測結(jié)果
predDf = pd.DataFrame({'customerID':pre_id, 'Churn':pred_y})
predDf




最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容