日本综合一区二区|亚洲中文天堂综合|日韩欧美自拍一区|男女精品天堂一区|欧美自拍第6页亚洲成人精品一区|亚洲黄色天堂一区二区成人|超碰91偷拍第一页|日韩av夜夜嗨中文字幕|久久蜜综合视频官网|精美人妻一区二区三区

RELATEED CONSULTING
相關(guān)咨詢
選擇下列產(chǎn)品馬上在線溝通
服務(wù)時間:8:30-17:00
你可能遇到了下面的問題
關(guān)閉右側(cè)工具欄

新聞中心

這里有您想知道的互聯(lián)網(wǎng)營銷解決方案
教你用Python寫一個電信客戶流失預(yù)測模型

 【導(dǎo)讀】

創(chuàng)新互聯(lián)是一家專業(yè)提供慈溪企業(yè)網(wǎng)站建設(shè),專注與網(wǎng)站設(shè)計、網(wǎng)站制作、H5開發(fā)、小程序制作等業(yè)務(wù)。10年已為慈溪眾多企業(yè)、政府機構(gòu)等服務(wù)。創(chuàng)新互聯(lián)專業(yè)網(wǎng)站制作公司優(yōu)惠進行中。

今天教大家如何用Python寫一個電信用戶流失預(yù)測模型。之前我們用Python寫了員工流失預(yù)測模型,這次我們試試Python預(yù)測電信用戶的流失。

01、商業(yè)理解

流失客戶是指那些曾經(jīng)使用過產(chǎn)品或服務(wù),由于對產(chǎn)品失去興趣等種種原因,不再使用產(chǎn)品或服務(wù)的顧客。

電信服務(wù)公司、互聯(lián)網(wǎng)服務(wù)提供商、保險公司等經(jīng)常使用客戶流失分析和客戶流失率作為他們的關(guān)鍵業(yè)務(wù)指標之一,因為留住一個老客戶的成本遠遠低于獲得一個新客戶。

預(yù)測分析使用客戶流失預(yù)測模型,通過評估客戶流失的風險傾向來預(yù)測客戶流失。由于這些模型生成了一個流失概率排序名單,對于潛在的高概率流失客戶,他們可以有效地實施客戶保留營銷計劃。

下面我們就教你如何用Python寫一個電信用戶流失預(yù)測模型,以下是具體步驟和關(guān)鍵代碼。

02、數(shù)據(jù)理解

此次分析數(shù)據(jù)來自于IBM Sample Data Sets,統(tǒng)計自某電信公司一段時間內(nèi)的消費數(shù)據(jù)。共有7043筆客戶資料,每筆客戶資料包含21個字段,其中1個客戶ID字段,19個輸入字段及1個目標字段-Churn(Yes代表流失,No代表未流失),輸入字段主要包含以下三個維度指標:用戶畫像指標、消費產(chǎn)品指標、消費信息指標。字段的具體說明如下:

03、數(shù)據(jù)讀入和概覽

首先導(dǎo)入所需包。

 
 
 
  1. df = pd.read_csv('./Telco-Customer-Churn.csv')
  2. df.head()  

讀入數(shù)據(jù)集

 
 
 
  1. df = pd.read_csv('./Telco-Customer-Churn.csv')
  2. df.head()  

04、數(shù)據(jù)初步清洗

首先進行初步的數(shù)據(jù)清洗工作,包含錯誤值和異常值處理,并劃分類別型和數(shù)值型字段類型,其中清洗部分包含:

  • OnlineSecurity、OnlineBackup、DeviceProtection、TechSupport、StreamingTV、StreamingMovies:錯誤值處理
  • TotalCharges:異常值處理
  • tenure:自定義分箱
  • 定義類別型和數(shù)值型字段
 
 
 
  1. # 錯誤值處理
  2. repl_columns = ['OnlineSecurity', 'OnlineBackup', 'DeviceProtection', 
  3.                 'TechSupport','StreamingTV', 'StreamingMovies']
  4. for i in repl_columns:
  5.     df[i]  = df[i].replace({'No internet service' : 'No'}) 
  6. # 替換值SeniorCitizen
  7. df["SeniorCitizen"] = df["SeniorCitizen"].replace({1: "Yes", 0: "No"}) 
  8. # 替換值TotalCharges
  9. df['TotalCharges'] = df['TotalCharges'].replace(' ', np.nan) 
  10. # TotalCharges空值:數(shù)據(jù)量小,直接刪除
  11. df = df.dropna(subset=['TotalCharges']) 
  12. df.reset_index(drop=True, inplace=True)  # 重置索引
  13. # 轉(zhuǎn)換數(shù)據(jù)類型
  14. df['TotalCharges'] = df['TotalCharges'].astype('float')
  15. # 轉(zhuǎn)換tenure
  16. def transform_tenure(x):
  17.     if x <= 12:
  18.         return 'Tenure_1'
  19.     elif x <= 24:
  20.         return 'Tenure_2'
  21.     elif x <= 36:
  22.         return 'Tenure_3'
  23.     elif x <= 48:
  24.         return 'Tenure_4'
  25.     elif x <= 60:
  26.         return 'Tenure_5'
  27.     else:
  28.         return 'Tenure_over_5' 
  29. df['tenure_group'] = df.tenure.apply(transform_tenure)
  30. # 數(shù)值型和類別型字段
  31. Id_col = ['customerID']
  32. target_col = ['Churn']
  33. cat_cols = df.nunique()[df.nunique() < 10].index.tolist() 
  34. num_cols = [i for i in df.columns if i not in cat_cols + Id_col] 
  35. print('類別型字段:\n', cat_cols)
  36. print('-' * 30) 
  37. print('數(shù)值型字段:\n', num_cols)
 
 
 
  1. 類別型字段:
  2.  ['gender', 'SeniorCitizen', 'Partner', 'Dependents', 'PhoneService', 
  3.   'MultipleLines', 'InternetService', 'OnlineSecurity',
  4.   'OnlineBackup', 'DeviceProtection', 'TechSupport',
  5.   'StreamingTV', 'StreamingMovies', 'Contract', 'PaperlessBilling', 
  6.   'PaymentMethod', 'Churn', 'tenure_group']
  7. ------------------------------
  8. 數(shù)值型字段:
  9.  ['tenure', 'MonthlyCharges', 'TotalCharges']

05、探索性分析

對指標進行歸納梳理,分用戶畫像指標,消費產(chǎn)品指標,消費信息指標。探索影響用戶流失的關(guān)鍵因素。

1. 目標變量Churn分布

經(jīng)過初步清洗之后的數(shù)據(jù)集大小為7032條記錄,其中流失客戶為1869條,占比26.6%,未流失客戶占比73.4%。

 
 
 
  1. df['Churn'].value_counts() 
  2. No     5163
  3. Yes    1869
  4. Name: Churn, dtype: int64
 
 
 
  1. trace0 = go.Pie(labels=df['Churn'].value_counts().index, 
  2.                 values=df['Churn'].value_counts().values,
  3.                 hole=.5,
  4.                 rotation=90,
  5.                 marker=dict(colors=['rgb(154,203,228)', 'rgb(191,76,81)'], 
  6.                             line=dict(color='white', width=1.3))
  7.                )
  8. data = [trace0] 
  9. layout = go.Layout(title='目標變量Churn分布')
  10. fig = go.Figure(data=data, layout=layout)
  11. py.offline.plot(fig, filename='./html/整體流失情況分布.html')

2.性別

分析可見,男性和女性在客戶流失比例上沒有顯著差異。

 
 
 
  1. plot_bar(input_col='gender', target_col='Churn', title_name='性別與是否流失的關(guān)系') 

3. 老年用戶

老年用戶流失比例更高,為41.68%,比非老年用戶高近兩倍,此部分原因有待進一步探討。

 
 
 
  1. plot_bar(input_col='SeniorCitizen', target_col='Churn', title_name='老年用戶與是否流失的關(guān)系') 

4. 是否有配偶

從婚姻情況來看,數(shù)據(jù)顯示,未婚人群中流失的比例比已婚人數(shù)高出13%。

 
 
 
  1. plot_bar(input_col='Partner', target_col='Churn', title_name='是否有配偶與是否流失的關(guān)系') 

5. 上網(wǎng)時長

經(jīng)過分析,這方面可以得出兩個結(jié)論:

  • 用戶的在網(wǎng)時長越長,表示用戶的忠誠度越高,其流失的概率越低;
  • 新用戶在1年內(nèi)的流失率顯著高于整體流失率,為47.68%。
 
 
 
  1. plot_bar(input_col='tenure_group', target_col='Churn', title_name='在網(wǎng)時長與是否流失的關(guān)系') 

6. 付款方式

支付方式上,支付上,選擇電子支票支付方式的用戶流失最高,達到45.29%,其他三種支付方式的流失率相差不大。

 
 
 
  1. pd.crosstab(df['PaymentMethod'], df['Churn']) 
 
 
 
  1. plot_bar(input_col='PaymentMethod', target_col='Churn', title_name='付款方式與是否流失關(guān)系') 

7. 月費用

整體來看,隨著月費用的增加,流失用戶的比例呈現(xiàn)高高低低的變化,月消費80-100元的用戶相對較高。

 
 
 
  1. plot_histogram(input_col='MonthlyCharges', title_name='月費用與是否流失關(guān)系')

8. 數(shù)值型屬性相關(guān)性

從相關(guān)性矩陣圖可以看出,用戶的往來期間和總費用呈現(xiàn)高度相關(guān),往來期間越長,則總費用越高。月消費和總消費呈現(xiàn)顯著相關(guān)。

 
 
 
  1. plt.figure(figsize=(15, 10))  
  2. sns.heatmap(df.corr(), linewidths=0.1, cmap='tab20c_r', annot=True)
  3. plt.title('數(shù)值型屬性的相關(guān)性', fontdict={'fontsize': 'xx-large', 'fontweight':'heavy'}) 
  4. plt.xticks(fontsize=12)
  5. plt.yticks(fontsize=12)
  6. plt.show() 

06、特征選擇

使用統(tǒng)計檢定方式進行特征篩選。

 
 
 
  1. # 刪除tenure
  2. df = df.drop('tenure', axis=1) 
  3. from feature_selection import Feature_select
  4. # 劃分X和y
  5. X = df.drop(['customerID', 'Churn'], axis=1) 
  6. y = df['Churn']   
  7. fs = Feature_select(num_method='anova', cate_method='kf', pos_label='Yes')
  8. x_sel = fs.fit_transform(X, y)  
 
 
 
  1. 2020 09:30:02 INFO attr select success!
  2. After select attr: ['DeviceProtection', 'MultipleLines', 'OnlineSecurity', 
  3.                     'TechSupport', 'tenure_group', 'PaperlessBilling',
  4.                     'InternetService', 'PaymentMethod', 'SeniorCitizen', 
  5.                     'MonthlyCharges', 'Dependents', 'Partner', 'Contract', 
  6.                     'StreamingTV', 'TotalCharges', 'StreamingMovies', 'OnlineBackup']

經(jīng)過特征篩選,gender和PhoneService字段被去掉。

07、建模前處理

在python中,為滿足建模需要,一般需要對數(shù)據(jù)做以下處理:

  • 對于二分類變量,編碼為0和1;
  • 對于多分類變量,進行one_hot編碼;
  • 對于數(shù)值型變量,部分模型如KNN、神經(jīng)網(wǎng)絡(luò)、Logistic需要進行標準化處理。
 
 
 
  1. # 篩選變量
  2. select_features = x_sel.columns
  3. # 建模數(shù)據(jù)
  4. df_model = pd.concat([df['customerID'], df[select_features], df['Churn']], axis=1)
  5. Id_col = ['customerID']
  6. target_col = ['Churn']
  7. # 分類型
  8. cat_cols = df_model.nunique()[df_model.nunique() < 10].index.tolist() 
  9. # 二分類屬性
  10. binary_cols = df_model.nunique()[df_model.nunique() == 2].index.tolist()
  11. # 多分類屬性
  12. multi_cols = [i for i in cat_cols if i not in binary_cols] 
  13. # 數(shù)值型
  14. num_cols = [i for i in df_model.columns if i not in cat_cols + Id_col] 
  15. # 二分類-標簽編碼
  16. le = LabelEncoder()
  17. for i in binary_cols:
  18.     df_model[i] = le.fit_transform(df_model[i]) 
  19. # 多分類-啞變量轉(zhuǎn)換
  20. df_model = pd.get_dummies(data=df_model, columns=multi_cols) 
  21. df_model.head() 

08、模型建立和評估

首先使用分層抽樣的方式將數(shù)據(jù)劃分訓(xùn)練集和測試集。

 
 
 
  1. # 重新劃分
  2. X = df_model.drop(['customerID', 'Churn'], axis=1) 
  3. y = df_model['Churn']  
  4. # 分層抽樣
  5. X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=0, stratify=y) 
  6. print(X_train.shape, X_test.shape, y_train.shape, y_test.shape) 
  7. #修正索引
  8. for i in [X_train, X_test, y_train, y_test]:
  9.     i.index = range(i.shape[0]) 
 
 
 
  1. (5625, 31) (1407, 31) (5625,) (1407,)
 
 
 
  1. # 保存標準化訓(xùn)練和測試數(shù)據(jù)
  2. st = StandardScaler()
  3. num_scaled_train = pd.DataFrame(st.fit_transform(X_train[num_cols]), columns=num_cols)
  4. num_scaled_test = pd.DataFrame(st.transform(X_test[num_cols]), columns=num_cols) 
  5. X_train_sclaed = pd.concat([X_train.drop(num_cols, axis=1), num_scaled_train], axis=1)
  6. X_test_sclaed = pd.concat([X_test.drop(num_cols, axis=1), num_scaled_test], axis=1) 

然后建立一系列基準模型并比較效果。

假如我們關(guān)注roc指標,從模型表現(xiàn)效果來看,Naive Bayes效果最好。我們也可以對模型進行進一步優(yōu)化,比如對決策樹參數(shù)進行調(diào)優(yōu)。

 
 
 
  1. parameters = {'splitter': ('best','random'),
  2.               'criterion': ("gini","entropy"),
  3.               "max_depth": [*range(3, 20)],
  4.              }
  5. clf = DecisionTreeClassifier(random_state=25)
  6. GS = GridSearchCV(clf, parameters, scoring='f1', cv=10)
  7. GS.fit(X_train, y_train)
  8. print(GS.best_params_) 
  9. print(GS.best_score_) 
 
 
 
  1. {'criterion': 'entropy', 'max_depth': 5, 'splitter': 'best'}
  2. 0.585900839405024
 
 
 
  1. clf = GS.best_estimator_
  2. test_pred = clf.predict(X_test)
  3. print('測試集:\n', classification_report(y_test, test_pred)) 
 
 
 
  1. 測試集:
  2.                precision    recall  f1-score   support
  3.            0       0.86      0.86      0.86      1033
  4.            1       0.61      0.61      0.61       374
  5.     accuracy                           0.79      1407
  6.    macro avg       0.73      0.73      0.73      1407
  7. weighted avg       0.79      0.79      0.79      1407

將這棵樹繪制出來。

 
 
 
  1. import graphviz
  2. dot_data = tree.export_graphviz(decision_tree=clf, max_depth=3,
  3.                                  out_file=None, 
  4.                                  feature_names=X_train.columns,
  5.                                  class_names=['not_churn', 'churn'], 
  6.                                  filled=True,
  7.                                  rounded=True
  8.                                 )
  9. graph = graphviz.Source(dot_data) 

輸出決策樹屬性重要性排序:

 
 
 
  1. imp = pd.DataFrame(zip(X_train.columns, clf.feature_importances_))
  2. imp.columns = ['feature', 'importances']
  3. imp = imp.sort_values('importances', ascending=False)
  4. imp = imp[imp['importances'] != 0]
  5. table  = ff.create_table(np.round(imp, 4))
  6. py.offline.iplot(table)  

后續(xù)優(yōu)化方向:

  • 數(shù)據(jù):分類技術(shù)應(yīng)用在目標類別分布越均勻的數(shù)據(jù)集時,其所建立之分類器通常會有比較好的分類效能。針對數(shù)據(jù)在目標字段上分布不平衡,可采用過采樣和欠采樣來處理類別不平衡問題;
  • 屬性:進一步屬性篩選方法和屬性組合;
  • 算法:參數(shù)調(diào)優(yōu);調(diào)整預(yù)測門檻值來增加預(yù)測效能。

當前題目:教你用Python寫一個電信客戶流失預(yù)測模型
鏈接URL:http://www.dlmjj.cn/article/coopsgp.html