日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 编程资源 > 编程问答 >内容正文

编程问答

电信用户流失预测案例(1)

發(fā)布時(shí)間:2023/12/20 编程问答 47 豆豆
生活随笔 收集整理的這篇文章主要介紹了 电信用户流失预测案例(1) 小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

【Kaggle】Telco Customer Churn 電信用戶流失預(yù)測(cè)案例

前言:案例學(xué)習(xí)說(shuō)明與案例建模流程

??在學(xué)習(xí)了經(jīng)典機(jī)器學(xué)習(xí)算法和Scikit-Learn的調(diào)參策略之后,接下來(lái),我們將把此前所學(xué)到的內(nèi)容應(yīng)用到實(shí)踐當(dāng)中去。從本節(jié)開始,我們將圍繞Kaggle中的電信用戶流失數(shù)據(jù)集(Telco Customer Churn)進(jìn)行用戶流失預(yù)測(cè)。在此過(guò)程中,我們將綜合應(yīng)用此前所介紹的各種方法與技巧,并在實(shí)踐中提煉總結(jié)更多實(shí)用技巧。
??對(duì)于實(shí)戰(zhàn)案例的講解,我們將分為三個(gè)階段進(jìn)行,當(dāng)然這也是我們?cè)趨⑴c算法競(jìng)賽、或者在實(shí)際算法建模時(shí)的一般流程:

  • Stage 1.業(yè)務(wù)背景解讀與數(shù)據(jù)探索
    ??在拿到數(shù)據(jù)(接受任務(wù))的第一時(shí)間,需要對(duì)數(shù)據(jù)(也就是對(duì)應(yīng)業(yè)務(wù))的基本背景進(jìn)行解讀。由于任何數(shù)據(jù)都誕生于某業(yè)務(wù)場(chǎng)景下,同時(shí)也是根據(jù)某些規(guī)則來(lái)進(jìn)行的采集或者計(jì)算得出,因此如果可以,我們應(yīng)當(dāng)盡量去了解數(shù)據(jù)誕生的基本環(huán)境和對(duì)應(yīng)的業(yè)務(wù)邏輯,盡可能準(zhǔn)確的解讀每個(gè)字段的含義,而只有在無(wú)法獲取真實(shí)業(yè)務(wù)背景時(shí),才會(huì)考慮退而求其次通過(guò)數(shù)據(jù)情況去倒推業(yè)務(wù)情況。
    ??當(dāng)然,在進(jìn)行了數(shù)據(jù)業(yè)務(wù)背景解讀后,接下來(lái)就需要對(duì)拿到的數(shù)據(jù)進(jìn)行基本的數(shù)據(jù)探索。一般來(lái)說(shuō),數(shù)據(jù)探索包括數(shù)據(jù)分布檢驗(yàn)、數(shù)據(jù)正確性校驗(yàn)、數(shù)據(jù)質(zhì)量檢驗(yàn)、訓(xùn)練集/測(cè)試集規(guī)律一致性檢驗(yàn)等。當(dāng)然,這里可能涉及到的操作較多,也并非所有的操作都必須在一次建模過(guò)程中全部完成。但作為教學(xué)案例,我們將在后續(xù)的內(nèi)容中詳細(xì)介紹每個(gè)環(huán)節(jié)的相關(guān)操作及目的。
  • Stage 2.數(shù)據(jù)預(yù)處理與特征工程
    ??在了解了建模業(yè)務(wù)背景和基本數(shù)據(jù)情況后,接下來(lái)我們就需要進(jìn)行實(shí)際建模前的“數(shù)據(jù)準(zhǔn)備”工作了,也就是數(shù)據(jù)預(yù)處理(數(shù)據(jù)清洗)與特征工程。其中,數(shù)據(jù)清洗主要聚焦于數(shù)據(jù)集數(shù)據(jù)質(zhì)量提升,包括缺失值、異常值、重復(fù)值處理,以及數(shù)據(jù)字段類型調(diào)整等;而特征工程部分則更傾向于調(diào)整特征基本結(jié)構(gòu),來(lái)使數(shù)據(jù)集本身規(guī)律更容易被模型識(shí)別,如特征衍生、特殊類型字段處理(包括時(shí)序字段、文本字段等)等。
    ??當(dāng)然,很多時(shí)候我們并不刻意區(qū)分?jǐn)?shù)據(jù)清洗與特征工程之間的區(qū)別,很多時(shí)候數(shù)據(jù)清洗的工作也可以看成是特征工程的一部分。同時(shí),也有很多時(shí)候我們也不會(huì)一定要求在不同階段執(zhí)行不同操作,例如如果在數(shù)據(jù)探索時(shí)發(fā)現(xiàn)缺失值比例較小,則可以直接對(duì)其進(jìn)行均值/眾數(shù)填補(bǔ),而不用等到特征工程階段統(tǒng)一處理,再例如很多特征工程的方法需要結(jié)合實(shí)際建模效果來(lái)判別,所以有的時(shí)候特征衍生也會(huì)和建模過(guò)程交替進(jìn)行。
  • Stage 3.算法建模與模型調(diào)優(yōu)
    ??在經(jīng)過(guò)一系列準(zhǔn)備工作后,就將進(jìn)入到最終建模環(huán)節(jié)了,建模過(guò)程既包括算法訓(xùn)練也包括參數(shù)調(diào)優(yōu)。當(dāng)然,很多時(shí)候建模工作不會(huì)一蹴而就,需要反復(fù)嘗試各種模型、各種調(diào)參方法、以及模型融合方法。此外,很多時(shí)候我們也需要根據(jù)最終模型輸出結(jié)果來(lái)進(jìn)行數(shù)據(jù)預(yù)處理和特征工程相關(guān)方法調(diào)整。

??上述流程可以用如下流程圖進(jìn)行表示:

??本節(jié)我們將先從數(shù)據(jù)集業(yè)務(wù)背景開始介紹,并簡(jiǎn)單討論如何借助Kaggle平臺(tái)獲取更多幫助。同時(shí)我們也將圍繞獲取到的數(shù)據(jù)進(jìn)行數(shù)據(jù)探索。

Part 1.數(shù)據(jù)背景介紹與數(shù)據(jù)探索

一、業(yè)務(wù)背景與數(shù)據(jù)背景

1.數(shù)據(jù)集基本情況與數(shù)據(jù)集獲取方法

??本次案例的數(shù)據(jù)源自Kaggle平臺(tái)上分享的建模數(shù)據(jù)集:Telco Customer Churn,該數(shù)據(jù)集描述了某電信公司的用戶基本情況,包括每位用戶已注冊(cè)的相關(guān)服務(wù)、用戶賬戶信息、用戶人口統(tǒng)計(jì)信息等,當(dāng)然,也包括了最為核心的、也是后續(xù)建模需要預(yù)測(cè)的標(biāo)簽字段——用戶流失情況(Churn)。

??需要注意的是,該數(shù)據(jù)并非競(jìng)賽數(shù)據(jù)集,而是Kaggle分享的一個(gè)高投票數(shù)據(jù)集(1788 votes),是Kaggle平臺(tái)上非常經(jīng)典的圍繞偏態(tài)數(shù)據(jù)集建模的數(shù)據(jù)集。該數(shù)據(jù)源自IBM商業(yè)社區(qū)(IBM Business Analytics Community)上分享的數(shù)據(jù)集,用于社區(qū)成員內(nèi)部學(xué)習(xí)使用。
??根據(jù)IBM商業(yè)社區(qū)分享團(tuán)隊(duì)描述,該數(shù)據(jù)集為某電信公司在加利福尼亞為7000余位用戶(個(gè)人/家庭)提供電話和互聯(lián)網(wǎng)服務(wù)的相關(guān)記錄。由于該數(shù)據(jù)集并不是競(jìng)賽數(shù)據(jù)集,因此數(shù)據(jù)集的下載方式相對(duì)容易,官網(wǎng)也只提供了網(wǎng)頁(yè)下載一種選項(xiàng)(無(wú)法通過(guò)命令行直接下載)。我們可以在該數(shù)據(jù)集的Kaggle主頁(yè)看到數(shù)據(jù)集的相關(guān)信息以及下載地址。此處我們簡(jiǎn)單介紹關(guān)于Kaggle數(shù)據(jù)集頁(yè)面的基本功能,既Kaggle平臺(tái)的基本使用方法,在后續(xù)的課程學(xué)習(xí)中,若是Kaggle案例,我們也將頻繁借助Kaggle主頁(yè)來(lái)獲取幫助。當(dāng)然,熟練使用Kaggle主頁(yè)獲取數(shù)據(jù)和挖掘信息(而不是借助第三方渠道),也是算法工程師必備技能之一。

  • 數(shù)據(jù)集主頁(yè)

??首先是數(shù)據(jù)集主頁(yè):



??此處我們能大致看到數(shù)據(jù)集基本信息,如總共只有一個(gè)數(shù)據(jù)文件(在其他很多情況下,一個(gè)建模目標(biāo)可能會(huì)包含多個(gè)數(shù)據(jù)集),總共21列,7043條數(shù)據(jù),以及其他各列的一些基本統(tǒng)計(jì)信息等。
??當(dāng)然,在數(shù)據(jù)集主頁(yè)上,我們可以直接點(diǎn)擊下載按鈕進(jìn)行數(shù)據(jù)集下載。下載完成后將其放到當(dāng)前操作主目錄下進(jìn)行讀取:

import numpy as np import pandas as pd tcc = pd.read_csv('WA_Fn-UseC_-Telco-Customer-Churn.csv') pd.set_option('max_colwidth',200) tcc.head(5)

tcc.info() # <class 'pandas.core.frame.DataFrame'> # RangeIndex: 7043 entries, 0 to 7042 # Data columns (total 21 columns): # # Column Non-Null Count Dtype # --- ------ -------------- ----- # 0 customerID 7043 non-null object # 1 gender 7043 non-null object # 2 SeniorCitizen 7043 non-null int64 # 3 Partner 7043 non-null object # 4 Dependents 7043 non-null object # 5 tenure 7043 non-null int64 # 6 PhoneService 7043 non-null object # 7 MultipleLines 7043 non-null object # 8 InternetService 7043 non-null object # 9 OnlineSecurity 7043 non-null object # 10 OnlineBackup 7043 non-null object # 11 DeviceProtection 7043 non-null object # 12 TechSupport 7043 non-null object # 13 StreamingTV 7043 non-null object # 14 StreamingMovies 7043 non-null object # 15 Contract 7043 non-null object # 16 PaperlessBilling 7043 non-null object # 17 PaymentMethod 7043 non-null object # 18 MonthlyCharges 7043 non-null float64 # 19 TotalCharges 7043 non-null object # 20 Churn 7043 non-null object # dtypes: float64(1), int64(2), object(18) # memory usage: 1.1+ MB

在其他一些情況下,我們可能需要借助命令行來(lái)進(jìn)行數(shù)據(jù)集下載和建模結(jié)果提交,相關(guān)內(nèi)容我們將在后續(xù)介紹競(jìng)賽數(shù)據(jù)集時(shí)詳細(xì)討論。

  • Discussion頁(yè)面

??此外,我們還能夠在Discussion頁(yè)面中看到圍繞該建模問(wèn)題的相關(guān)討論。值得一提的是,在很多場(chǎng)合下(尤其是在參加算法競(jìng)賽時(shí)),Discussion頁(yè)面中的討論帖都是重要的信息獲取渠道,其中不乏一些官方給出的補(bǔ)充問(wèn)答內(nèi)容、一些競(jìng)賽大神給出的自己的賽題理解、以及一些參賽者獨(dú)到的討論和見(jiàn)解。而從中快速捕獲信息,則能幫助你迅速建立信息優(yōu)勢(shì)。

??例如在本數(shù)據(jù)集相關(guān)的討論中,就有關(guān)于用戶流失業(yè)務(wù)背景的相關(guān)討論。其內(nèi)較為具體的說(shuō)明了到底什么是用戶流失、為什么要關(guān)注用戶流失,以及圍繞用戶流失在進(jìn)行建模時(shí),最好關(guān)注那些模型評(píng)估指標(biāo)。當(dāng)然,這些內(nèi)容我們也將隨后詳細(xì)探討。

  • Code頁(yè)面

??此外,我們還能夠在code頁(yè)面看到其他用戶分享的代碼,其中也不乏一些精彩的思路和方法,也有很多可以借鑒和學(xué)習(xí)的內(nèi)容。比如在該數(shù)據(jù)集的Code頁(yè)面,就有很多同學(xué)會(huì)比較關(guān)注的處理樣本不均衡的SHAP方法,以及該方法配合集成學(xué)習(xí)的使用方法:

當(dāng)然,Kaggle平臺(tái)上也有很多帶有廣告性質(zhì)的內(nèi)容,需要進(jìn)行甄別。

2.用戶流失業(yè)務(wù)背景與建模目標(biāo)

  • 電信業(yè)務(wù)基本背景介紹

??在基本了解Kaggle平臺(tái)使用方法以及獲取到建模數(shù)據(jù)集之后,接下來(lái)我們需要圍繞電信用戶流失這一基本業(yè)務(wù)背景來(lái)進(jìn)行介紹,同時(shí)解釋本案例的最終建模目標(biāo)。
??我們知道,電信作為公共網(wǎng)絡(luò)、數(shù)據(jù)傳輸、電話語(yǔ)音通信等基礎(chǔ)服務(wù)提供方,一直以來(lái)都是國(guó)家支柱產(chǎn)業(yè)之一。而伴隨著移動(dòng)互聯(lián)網(wǎng)的普及、數(shù)字經(jīng)濟(jì)蓬勃發(fā)展,網(wǎng)絡(luò)這一基礎(chǔ)設(shè)施也愈發(fā)重要。有個(gè)非常形象的比喻,在過(guò)去,斷電會(huì)導(dǎo)致工廠停產(chǎn)、造成重大的經(jīng)濟(jì)損失,而現(xiàn)在,中斷網(wǎng)絡(luò)數(shù)字傳輸,則足以讓某些企業(yè)一夜損失上億。
??簡(jiǎn)而言之,在一定程度上,網(wǎng)絡(luò)的質(zhì)量和速度甚至?xí)苯記Q定著數(shù)字經(jīng)濟(jì)發(fā)展的質(zhì)量和速度。而伴隨著5G時(shí)代的到來(lái),5G的工業(yè)化應(yīng)用,如車聯(lián)網(wǎng)、物聯(lián)網(wǎng)、工業(yè)互聯(lián)網(wǎng)等,也將在未來(lái)發(fā)展成為萬(wàn)億規(guī)模產(chǎn)業(yè),并且增強(qiáng)寬帶、海量連接、低延時(shí)、高可靠的網(wǎng)絡(luò)基礎(chǔ)設(shè)施,將為構(gòu)建物聯(lián)網(wǎng)、人工智能等技術(shù)體系提供保障。
??而在此背景下,電信市場(chǎng)的競(jìng)爭(zhēng)也愈發(fā)激烈。一般來(lái)說(shuō)電信領(lǐng)域的運(yùn)營(yíng)商在3-4家時(shí)能保持一個(gè)健康的市場(chǎng)競(jìng)爭(zhēng)狀態(tài),而在國(guó)內(nèi),5G的運(yùn)營(yíng)商牌照也頒發(fā)了四家,除了三大運(yùn)營(yíng)商外(電信、聯(lián)通、移動(dòng)),還有中國(guó)廣電。而在數(shù)字時(shí)代,傳統(tǒng)的大眾營(yíng)銷已經(jīng)失去優(yōu)勢(shì),如何基于用戶信息和行為,來(lái)進(jìn)行更加精準(zhǔn)的營(yíng)銷,從而滿足用戶更加多樣化、層次化和個(gè)性化的需求,成為所有電信運(yùn)營(yíng)商必須面對(duì)的課題。而于此同時(shí),電信的公共客戶(個(gè)人或家庭用戶)用戶又同時(shí)具有易變性、發(fā)展性和替代性等特點(diǎn),且用戶需求彈性較小,外加普通用戶購(gòu)買電信產(chǎn)品周期較長(zhǎng),導(dǎo)致在實(shí)際的交易關(guān)系中,電信公司對(duì)公共客戶獲客較難、主動(dòng)拓展新用戶成本較高,因此維系既有用戶、防止用戶流失就成了重要的運(yùn)營(yíng)策略。
??當(dāng)然,對(duì)于電信運(yùn)營(yíng)商來(lái)說(shuō),用戶流失有很多偶然因素,不過(guò)通過(guò)對(duì)用戶屬性和行為的數(shù)字化描述,我們或許也能夠在這些數(shù)據(jù)中,挖掘?qū)е掠脩袅魇У摹爸虢z馬跡”,并且更重要的一點(diǎn),如果能夠?qū)崟r(shí)接入這些數(shù)據(jù),或許還能夠進(jìn)一步借助模型來(lái)對(duì)未來(lái)用戶流失的風(fēng)險(xiǎn)進(jìn)行預(yù)測(cè),從而及時(shí)制定挽留策略,來(lái)防止用戶真實(shí)流失情況發(fā)生。

  • 機(jī)器學(xué)習(xí)建模目標(biāo)

??也就是說(shuō),在此背景下,實(shí)際的算法建模目標(biāo)有兩個(gè),其一是對(duì)流失用戶進(jìn)行預(yù)測(cè),其二則是找出影響用戶流失的重要因子,來(lái)輔助運(yùn)營(yíng)人員來(lái)進(jìn)行營(yíng)銷策略調(diào)整或制定用戶挽留措施。
??綜合上述兩個(gè)目標(biāo)我們不難發(fā)現(xiàn),我們要求模型不僅要擁有一定的預(yù)測(cè)能力,并且能夠輸出相應(yīng)的特征重要性排名,并且最好能夠具備一定的可解釋性,也就是能夠較為明顯的闡述特征變化是如何影響標(biāo)簽取值變化的。據(jù)此要求,我們首先可以考慮邏輯回歸模型。邏輯回歸的線性方程能夠提供非常好的結(jié)果可解釋性,同時(shí)我們也可以通過(guò)邏輯回歸中的正則化項(xiàng)也可以用于評(píng)估特征重要性。

??當(dāng)然,此外我們也可以考慮構(gòu)建決策樹即集成模型來(lái)解決該問(wèn)題。決策樹同樣具有較好的可解釋性,并且也可以根據(jù)樹模型中的信息熵(或者基尼系數(shù))的下降情況來(lái)進(jìn)行特征重要性評(píng)估。

二、數(shù)據(jù)解讀與預(yù)處理

??在基本了解業(yè)務(wù)背景和建模目標(biāo)之后,我們開始圍繞數(shù)據(jù)集進(jìn)行解讀和探索。

1.字段解釋

??首先是圍繞數(shù)據(jù)集字段含義進(jìn)行解釋。該數(shù)據(jù)集并沒(méi)有提供相應(yīng)的數(shù)據(jù)字典作為不同字段的解釋,但由于數(shù)據(jù)集并沒(méi)有匿名字段,所以基本可以根據(jù)字段的名稱給出相應(yīng)的解釋:

tcc.info() # <class 'pandas.core.frame.DataFrame'> # RangeIndex: 7043 entries, 0 to 7042 # Data columns (total 21 columns): # # Column Non-Null Count Dtype # --- ------ -------------- ----- # 0 customerID 7043 non-null object # 1 gender 7043 non-null object # 2 SeniorCitizen 7043 non-null int64 # 3 Partner 7043 non-null object # 4 Dependents 7043 non-null object # 5 tenure 7043 non-null int64 # 6 PhoneService 7043 non-null object # 7 MultipleLines 7043 non-null object # 8 InternetService 7043 non-null object # 9 OnlineSecurity 7043 non-null object # 10 OnlineBackup 7043 non-null object # 11 DeviceProtection 7043 non-null object # 12 TechSupport 7043 non-null object # 13 StreamingTV 7043 non-null object # 14 StreamingMovies 7043 non-null object # 15 Contract 7043 non-null object # 16 PaperlessBilling 7043 non-null object # 17 PaymentMethod 7043 non-null object # 18 MonthlyCharges 7043 non-null float64 # 19 TotalCharges 7043 non-null object # 20 Churn 7043 non-null object # dtypes: float64(1), int64(2), object(18) # memory usage: 1.1+ MB

根據(jù)Kaggle的數(shù)據(jù)集介紹,以及IBM商業(yè)分析社區(qū)中提供的解釋,數(shù)據(jù)集中各字段解釋如下:

字段解釋
customerID用戶ID
gender性別
SeniorCitizen是否是老年人(1代表是)
Partner是否有配偶(Yes or No)
Dependents是否經(jīng)濟(jì)獨(dú)立(Yes or No)
tenure用戶入網(wǎng)時(shí)間
PhoneService是否開通電話業(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ò)或filber potic光線網(wǎng)絡(luò))
OnlineSecurity是否開通網(wǎng)絡(luò)安全服務(wù)(Yes、No or No internetservice)
OnlineBackup是否開通在線備份服務(wù)(Yes、No or No internetservice)
DeviceProtection是否開通設(shè)備保護(hù)服務(wù)(Yes、No or No internetservice)
TechSupport是否開通技術(shù)支持業(yè)務(wù)(Yes、No or No internetservice)
StreamingTV是否開通網(wǎng)絡(luò)電視(Yes、No or No internetservice)
StreamingMovies是否開通網(wǎng)絡(luò)電影(Yes、No or No internetservice)
Contract合同簽訂方式(按月、按年或者兩年)
PaperlessBilling是否開通電子賬單(Yes or No)
PaymentMethod付款方式(bank transfer、credit card、electronic check、mailed check)
MonthlyCharges月度費(fèi)用
TotalCharges總費(fèi)用
Churn是否流失(Yes or No)

同時(shí),根據(jù)官方給出的數(shù)據(jù)集說(shuō)明,上述字段基本可以分為三類,分別是用戶已注冊(cè)的服務(wù)信息、用戶賬戶信息和用戶人口統(tǒng)計(jì)信息,三類字段劃分情況如下:

2.數(shù)據(jù)質(zhì)量探索

??在了解數(shù)據(jù)集字段含義后,首先我們需要對(duì)數(shù)據(jù)集的數(shù)據(jù)質(zhì)量進(jìn)行探索,這也是數(shù)據(jù)探索的最基礎(chǔ)的角度。

  • 數(shù)據(jù)集正確性校驗(yàn)

??首先是數(shù)據(jù)集正確性校驗(yàn)。一般來(lái)說(shuō)數(shù)據(jù)集正確性校驗(yàn)分為兩種,其一是檢驗(yàn)數(shù)據(jù)集字段是否和數(shù)據(jù)字典中的字段一致,其二則是檢驗(yàn)數(shù)據(jù)集中ID列有無(wú)重復(fù)。由于該數(shù)據(jù)集并為提供數(shù)據(jù)字典,因此此處主要校驗(yàn)數(shù)據(jù)集ID有無(wú)重復(fù):

tcc['customerID'].nunique() == tcc.shape[0] #True

另外的方法

tcc['customerID'].unique() #array(['7590-VHVEG', '5575-GNVDE', '3668-QPYBK', ..., '4801-JZAZL', # '8361-LTMKD', '3186-AJIEK'], dtype=object) tcc['customerID'].nunique() #7043 len(set(tcc["customerID"])) #7043 tcc.shape #(7043, 21)

當(dāng)然,ID列沒(méi)有重復(fù),則數(shù)據(jù)集中也不存在完全重復(fù)的兩行數(shù)據(jù):

tcc.duplicated().sum() #數(shù)據(jù)中有沒(méi)有重復(fù)的兩行 #0
  • 數(shù)據(jù)缺失值檢驗(yàn)

??接下來(lái)進(jìn)一步檢查數(shù)據(jù)集缺失情況,我們可以通過(guò)isnull來(lái)快速查看數(shù)據(jù)集缺失情況:

tcc.isnull().sum() # customerID 0 # gender 0 # SeniorCitizen 0 # Partner 0 # Dependents 0 # tenure 0 # PhoneService 0 # MultipleLines 0 # InternetService 0 # OnlineSecurity 0 # OnlineBackup 0 # DeviceProtection 0 # TechSupport 0 # StreamingTV 0 # StreamingMovies 0 # Contract 0 # PaperlessBilling 0 # PaymentMethod 0 # MonthlyCharges 0 # TotalCharges 0 # Churn 0 # dtype: int64 '''也可以tcc.info()'''

此外,我們也可以通過(guò)定義如下函數(shù)來(lái)輸出更加完整的每一列缺失值的數(shù)值和占比:

def missing (df):"""計(jì)算每一列的缺失值及占比"""missing_number = df.isnull().sum().sort_values(ascending=False) # 每一列的缺失值求和后降序排序 missing_percent = (df.isnull().sum()/df.isnull().count()).sort_values(ascending=False) # 每一列缺失值占比missing_values = pd.concat([missing_number, missing_percent], axis=1, keys=['Missing_Number', 'Missing_Percent']) # 合并為一個(gè)DataFramereturn missing_valuesmissing(tcc)

此外,在info返回的信息中的non-null也能看出數(shù)據(jù)集不存在缺失值。

從上述結(jié)果能看出,數(shù)據(jù)集不存在缺失值。

沒(méi)有缺失只代表數(shù)據(jù)集中沒(méi)有None或者Nan,并不排除可能存在用別的值表示缺失值的情況,稍后我們將對(duì)其進(jìn)行進(jìn)一步分析。

3.字段類型探索

??接下來(lái),我們將進(jìn)一步圍繞數(shù)據(jù)集的字段類型來(lái)進(jìn)行調(diào)整。

  • 時(shí)序字段處理

??根據(jù)數(shù)據(jù)集info我們發(fā)現(xiàn),大多數(shù)字段都屬于離散型字段,并且object類型居多。對(duì)于建模分析來(lái)說(shuō),我們是無(wú)法直接使用object類型對(duì)象的,因此需要對(duì)其進(jìn)行類型轉(zhuǎn)化,通常來(lái)說(shuō),我們會(huì)將字段劃分為連續(xù)型字段和離散型字段,并且根據(jù)離散字段的具體含義來(lái)進(jìn)一步區(qū)分是名義型變量還是有序變量。不過(guò)在劃分連續(xù)/離散字段之前,我們發(fā)現(xiàn)數(shù)據(jù)集中存在一個(gè)入網(wǎng)時(shí)間字段,看起來(lái)像是時(shí)序字段。需要注意的是,從嚴(yán)格意義上來(lái)說(shuō),用時(shí)間標(biāo)注的時(shí)序字段即不數(shù)據(jù)連續(xù)型字段或離散型字段(盡管可以將其看成是離散字段,但這樣做會(huì)損失一些信息),因此我們需要重點(diǎn)關(guān)注入網(wǎng)時(shí)間字段是否是時(shí)間標(biāo)注的字段:

tcc['tenure'] # 0 1 # 1 34 # 2 2 # 3 45 # 4 2 # .. # 7038 24 # 7039 72 # 7040 11 # 7041 4 # 7042 66 # Name: tenure, Length: 7043, dtype: int64

簡(jiǎn)單查看我們發(fā)現(xiàn),該字段并不是典型的用年月日標(biāo)注的時(shí)間字段,如2020-08-01,而是一串連續(xù)的數(shù)值。當(dāng)然,我們可以進(jìn)一步查看該字段的取值范圍:

tcc['tenure'].nunique() #73

該字段總共有73個(gè)不同的取值,結(jié)合此前所說(shuō),數(shù)據(jù)集是第三季度的用戶數(shù)據(jù),因此我們推斷該字段應(yīng)該是經(jīng)過(guò)字典排序后的離散型字段。所謂字典排序,其本質(zhì)是一種離散變量的轉(zhuǎn)化方式,有時(shí)我們也可以將時(shí)序數(shù)據(jù)進(jìn)行字典排序,該過(guò)程我們可以通過(guò)如下示例進(jìn)行說(shuō)明:

也就是說(shuō),在第三季度中,這些用戶的行為發(fā)生在某73天內(nèi),因此入網(wǎng)時(shí)間字段有73個(gè)取值。不過(guò)由于該字段是經(jīng)過(guò)字典排序后的結(jié)果,因此已經(jīng)損失了原始信息,即每位用戶實(shí)際的入網(wǎng)時(shí)間。而在實(shí)際的分析過(guò)程中,我們可以轉(zhuǎn)化后的入網(wǎng)時(shí)間字段看成是離散變量,當(dāng)然也可以將其視作連續(xù)變量來(lái)進(jìn)行分析,具體選擇需要依據(jù)模型來(lái)決定。此處我們先將其視作離散變量,后續(xù)根據(jù)情況來(lái)進(jìn)行調(diào)整。

關(guān)于字典排序的代碼實(shí)現(xiàn)方法會(huì)在后續(xù)進(jìn)行介紹。

  • 連續(xù)/離散型變量標(biāo)注

??接下來(lái),我們來(lái)標(biāo)注每一列的數(shù)據(jù)類型,我們可以通過(guò)不同列表來(lái)存儲(chǔ)不同類型字段的名稱:

# 離散字段 category_cols = ['customerID', 'gender', 'SeniorCitizen', 'Partner', 'Dependents', 'tenure', 'PhoneService', 'MultipleLines', 'InternetService', 'OnlineSecurity', 'OnlineBackup', 'DeviceProtection', 'TechSupport', 'StreamingTV', 'StreamingMovies', 'Contract', 'PaperlessBilling','PaymentMethod']# 連續(xù)字段 numeric_cols = ['MonthlyCharges', 'TotalCharges']# 標(biāo)簽 target = 'Churn'# 驗(yàn)證是否劃分能完全 assert len(category_cols) + len(numeric_cols) + 1 == tcc.shape[1]

??當(dāng)然,大多數(shù)時(shí)候離散型字段都在讀取時(shí)都是object類型,因此我們也可以通過(guò)如下方式直接提取object字段:

tcc.select_dtypes('object').columns #Index(['customerID', 'gender', 'Partner', 'Dependents', 'PhoneService', # 'MultipleLines', 'InternetService', 'OnlineSecurity', 'OnlineBackup', # 'DeviceProtection', 'TechSupport', 'StreamingTV', 'StreamingMovies', # 'Contract', 'PaperlessBilling', 'PaymentMethod', 'TotalCharges', # 'Churn'], # dtype='object')

然后,我們需要對(duì)不同類型字段進(jìn)行轉(zhuǎn)化。并且在此過(guò)程中,我們需要檢驗(yàn)是否存在采用別的值來(lái)表示缺失值的情況。就像此前所說(shuō)我們通過(guò)isnull只能檢驗(yàn)出None(Python原生對(duì)象)和np.Nan(numpy/pandas在讀取數(shù)據(jù)文件時(shí)文件內(nèi)部缺失對(duì)象的讀取后表示形式)對(duì)象。但此外我們還需要注意數(shù)據(jù)集中是否包含采用某符號(hào)表示缺失值的情況,例如某些時(shí)候可能使用空格(其本質(zhì)也是一種字符)來(lái)代替空格:

df = pd.DataFrame({'A':['Y', None, 'N', 'N'], 'B':[np.NaN, ' ', 'Y', 'N']}) df


此時(shí)在進(jìn)行檢驗(yàn)時(shí),空格的數(shù)據(jù)并不會(huì)被識(shí)別為缺失值(空格本身也是一種值)。

df.isnull()


但根據(jù)實(shí)際情況來(lái)看,空格可能確實(shí)是代表著數(shù)據(jù)采集時(shí)數(shù)據(jù)是缺失的,因此我們?nèi)匀恍枰獙⑵渥R(shí)別然后標(biāo)記為缺失值,此時(shí)可以通過(guò)比較數(shù)據(jù)集各列的取值水平是否和既定的一致來(lái)進(jìn)行檢查。例如,對(duì)于上述df數(shù)據(jù)集來(lái)說(shuō),特征A和B默認(rèn)情況只有Y和N兩種取值,而B列由于通過(guò)空格表示了缺失值,因此用nunique查看數(shù)據(jù)集的話,B列將出現(xiàn)3種取值:

df.nunique() #A 2 #B 3 #dtype: int64

注意,缺失值None或NaN并不是某一種取值

此時(shí)我們可以進(jìn)一步查看B列每個(gè)不同取值出現(xiàn)的次數(shù):

df['B'].explode().value_counts().to_dict() #{'Y': 1, 'N': 1, ' ': 1}

在判斷空格為缺失值后,我們即可對(duì)其進(jìn)行后續(xù)處理。我們可以先檢驗(yàn)離散變量是否存在這種情況:

tcc[category_cols].nunique() #customerID 7043 #gender 2 #SeniorCitizen 2 #Partner 2 #Dependents 2 #tenure 73 #PhoneService 2 #MultipleLines 3 #InternetService 3 #OnlineSecurity 3 #OnlineBackup 3 #DeviceProtection 3 #TechSupport 3 #StreamingTV 3 #StreamingMovies 3 #Contract 3 #PaperlessBilling 2 #PaymentMethod 4 #dtype: int64

我們也可以通過(guò)如下方式查看每個(gè)離散變量的不同取值:

for feature in tcc[category_cols]:print(f'{feature}: {tcc[feature].unique()}') #customerID: ['7590-VHVEG' '5575-GNVDE' '3668-QPYBK' ... '4801-JZAZL' '8361-LTMKD' # '3186-AJIEK'] #gender: ['Female' 'Male'] #SeniorCitizen: [0 1] #Partner: ['Yes' 'No'] #Dependents: ['No' 'Yes'] #tenure: [ 1 34 2 45 8 22 10 28 62 13 16 58 49 25 69 52 71 21 12 30 47 72 17 27 # 5 46 11 70 63 43 15 60 18 66 9 3 31 50 64 56 7 42 35 48 29 65 38 68 # 32 55 37 36 41 6 4 33 67 23 57 61 14 20 53 40 59 24 44 19 54 51 26 0 # 39] #PhoneService: ['No' 'Yes'] #MultipleLines: ['No phone service' 'No' 'Yes'] #InternetService: ['DSL' 'Fiber optic' 'No'] #OnlineSecurity: ['No' 'Yes' 'No internet service'] #OnlineBackup: ['Yes' 'No' 'No internet service'] #DeviceProtection: ['No' 'Yes' 'No internet service'] #TechSupport: ['No' 'Yes' 'No internet service'] #StreamingTV: ['No' 'Yes' 'No internet service'] #StreamingMovies: ['No' 'Yes' 'No internet service'] #Contract: ['Month-to-month' 'One year' 'Two year'] #PaperlessBilling: ['Yes' 'No'] #PaymentMethod: ['Electronic check' 'Mailed check' 'Bank transfer (automatic)' # 'Credit card (automatic)']'''或者''' for feature in category_cols:print("{0}:{1}".format(feature,tcc[feature].unique()))

通過(guò)對(duì)比離散變量的取值水平,我們發(fā)現(xiàn)并不存在通過(guò)其他值表示缺失值的情況。

需要注意的是,如果是連續(xù)變量,則無(wú)法使用上述方法進(jìn)行檢驗(yàn)(取值水平較多),但由于往往我們需要將其轉(zhuǎn)化為數(shù)值型變量再進(jìn)行分析,因此對(duì)于連續(xù)變量是否存在其他值表示缺失值的情況,我們也可以觀察轉(zhuǎn)化情況來(lái)判別,例如如果是用空格代表缺失值,則無(wú)法直接使用astype來(lái)轉(zhuǎn)化成數(shù)值類型。

# 無(wú)法全部轉(zhuǎn)化為數(shù)值型字段,運(yùn)行將報(bào)錯(cuò) # tcc[numeric_cols].astype(float)
  • 缺失值檢驗(yàn)與填補(bǔ)

發(fā)現(xiàn)在連續(xù)特征中存在空格。則此時(shí)我們需要進(jìn)一步檢查空格字符出現(xiàn)在哪一列的哪個(gè)位置,我們可以通過(guò)如下函數(shù)來(lái)進(jìn)行檢驗(yàn):

def find_index(data_col, val):"""查詢某值在某列中第一次出現(xiàn)位置的索引,沒(méi)有則返回-1:param data_col: 查詢的列:param val: 具體取值"""val_list = [val]if data_col.isin(val_list).sum() == 0:index = -1else:index = data_col.isin(val_list).idxmax()return index tcc["MonthlyCharges"].isin([" "]) #0 False #1 False #2 False #3 False #4 False # ... #7038 False #7039 False #7041 False #7042 False #Name: MonthlyCharges, Length: 7043, dtype: bool

查看空格第一次出現(xiàn)在哪一列的哪個(gè)位置:

for col in numeric_cols:print(find_index(tcc[col], ' ')) #-1 #488

即空格第一次出現(xiàn)在’TotalCharges’列的索引值為488的位置:

tcc['TotalCharges'].iloc[488] #' '

接下來(lái)使用np.nan對(duì)空格進(jìn)行替換,并將’MonthlyCharges’轉(zhuǎn)化為浮點(diǎn)數(shù)類型:

tcc['TotalCharges']= tcc['TotalCharges'].apply(lambda x: x if x!= ' ' else np.nan).astype(float) tcc['MonthlyCharges'] = tcc['MonthlyCharges'].astype(float)

再次查看連續(xù)變量的缺失值占比情況:

missing(tcc[numeric_cols])


關(guān)于該缺失值應(yīng)該如何填補(bǔ),首先考慮的是,由于缺失值占比較小,因此可以直接使用均值進(jìn)行填充:

tcc['TotalCharges'].fillna(tcc['TotalCharges'].mean())

此外,我們也可以簡(jiǎn)單觀察缺失’TotalCharges’信息的每條數(shù)據(jù)實(shí)際情況,或許能發(fā)現(xiàn)一些蛛絲馬跡:

tcc[tcc['TotalCharges'].isnull()]


我們發(fā)現(xiàn),這11條數(shù)據(jù)的入網(wǎng)時(shí)間都是0,也就是說(shuō),這11位用戶極有可能是在統(tǒng)計(jì)周期結(jié)束前的最后時(shí)間入網(wǎng)的用戶,因此沒(méi)有過(guò)去的總消費(fèi)記錄,但是卻有當(dāng)月的消費(fèi)記錄。也就是說(shuō),該數(shù)據(jù)集的過(guò)去總消費(fèi)記錄不包括當(dāng)月消費(fèi)記錄,也就是不存在過(guò)去總消費(fèi)記錄等于0的記錄。我們可以簡(jiǎn)單驗(yàn)證:

(tcc['TotalCharges'] == 0).sum() #0

既然如此,我們就可以將這11條記錄的缺失值記錄為0,以表示在最后一個(gè)月統(tǒng)計(jì)消費(fèi)金額前,這些用戶的過(guò)去總消費(fèi)金額為0:

tcc['TotalCharges'] = tcc['TotalCharges'].fillna(0) tcc['TotalCharges'].isnull().sum() #0 tcc['TotalCharges'].describe() #count 7043.000000 #mean 2279.734304 #std 2266.794470 #min 0.000000 #25% 398.550000 #50% 1394.550000 #75% 3786.600000 #max 8684.800000 #Name: TotalCharges, dtype: float64

此外還有另一種便捷的方式,即直接使用pd.to_numeric對(duì)連續(xù)變量進(jìn)行轉(zhuǎn)化,并在errors參數(shù)位上輸入’coerce’參數(shù),表示能直接轉(zhuǎn)化為數(shù)值類型時(shí)直接轉(zhuǎn)化,無(wú)法轉(zhuǎn)化的用缺失值填補(bǔ),過(guò)程如下:

df1 = pd.read_csv('WA_Fn-UseC_-Telco-Customer-Churn.csv') df1.TotalCharges = pd.to_numeric(df1.TotalCharges, errors='coerce') # 查看缺失值情況 df1.TotalCharges.isnull().sum() #11 # 查看原空格處是否被標(biāo)記為缺失值 df1.TotalCharges.iloc[488] #nan # 查看字段整體類型 df1.TotalCharges.dtype #dtype('float64')

注意,此處暫時(shí)未對(duì)離散特征進(jìn)行變量類型轉(zhuǎn)化,是因?yàn)楸拘」?jié)后半段需要圍繞標(biāo)簽取值在不同特征維度上分布進(jìn)行分析,此時(shí)需要查看各特征的原始取值情況(例如性別是Male和Female,而不是0/1),因此我們會(huì)在本節(jié)結(jié)束后對(duì)離散變量再進(jìn)行字典編碼。

  • 異常值檢驗(yàn)

??當(dāng)然,對(duì)于連續(xù)型變量,我們可以進(jìn)一步對(duì)其進(jìn)行異常值檢測(cè)。首先我們可以采用describe方法整體查看連續(xù)變量基本統(tǒng)計(jì)結(jié)果:

tcc[numeric_cols].describe()


異常值檢測(cè)有很多方法,我們可以通過(guò)三倍標(biāo)準(zhǔn)差法來(lái)進(jìn)行檢驗(yàn),即以均值-3倍標(biāo)注差為下界,均值+3倍標(biāo)準(zhǔn)差為上界,來(lái)檢測(cè)是否有超過(guò)邊界的點(diǎn):

tcc['MonthlyCharges'].mean() + 3 * tcc['MonthlyCharges'].std() #155.03183375363483 tcc['MonthlyCharges'].mean() - 3 * tcc['MonthlyCharges'].std() #-25.5084488324364 tcc['TotalCharges'].mean() + 3 * tcc['TotalCharges'].std() #9080.117712630885 tcc['TotalCharges'].mean() - 3 * tcc['TotalCharges'].std() #-4520.649105503233

能夠發(fā)現(xiàn),數(shù)據(jù)集并不存在異常值點(diǎn)。

??此外,我們還可以通過(guò)箱線圖來(lái)進(jìn)行異常值點(diǎn)的識(shí)別(數(shù)據(jù)偏態(tài)嚴(yán)重用箱線圖好,正態(tài)分布兩種方法都好),和3倍標(biāo)準(zhǔn)差法利用均值和方差進(jìn)行計(jì)算不同,箱線圖主要借助中位數(shù)和四分位數(shù)來(lái)進(jìn)行計(jì)算,以上四分位數(shù)+1.5倍四分位距為上界、下四分位數(shù)-1.5倍四分位距為下界,超出界限則認(rèn)為是異常值。我們可以借助plt.boxplot繪圖函數(shù)迅速繪制箱線圖來(lái)觀察異常值點(diǎn)情況:

import seaborn as sns import matplotlib.pyplot as plt # MonthlyCharges上四分位數(shù) Q3 = tcc[numeric_cols].describe()['MonthlyCharges']['75%'] Q3 #89.85 # MonthlyCharges下四分位數(shù) Q1 = tcc[numeric_cols].describe()['MonthlyCharges']['25%'] Q1 #35.5 #MonthlyCharges的四分位距 IQR = Q3 - Q1 IQR #54.349999999999994 # 異常值上界 Q3 + 1.5 * IQR #171.375 # 異常值下界 Q1 - 1.5 * IQR #-46.02499999999999 tcc['MonthlyCharges'].min(), tcc['MonthlyCharges'].max() #(18.25, 118.75)Q3 = tcc[numeric_cols].describe()['TotalCharges']['75%'] Q1 = tcc[numeric_cols].describe()['TotalCharges']['25%'] IQR = Q3 - Q1 (Q1 - 1.5 * IQR, Q3 + 1.5 * IQR) #(-4683.525, 8868.675) tcc['TotalCharges'].min(), tcc['TotalCharges'].max() #(0.0, 8684.8)

??不過(guò)需要知道的是,由于數(shù)據(jù)集中沒(méi)有超出邊界的異常值點(diǎn),因此在實(shí)際繪制箱線圖時(shí),箱線圖的邊界會(huì)以數(shù)據(jù)集的極值為準(zhǔn):

plt.figure(figsize=(16, 6), dpi=200) plt.subplot(121) plt.boxplot(tcc['MonthlyCharges']) plt.xlabel('MonthlyCharges') plt.subplot(122) plt.boxplot(tcc['TotalCharges']) plt.xlabel('TotalCharges')


??能夠發(fā)現(xiàn),根據(jù)箱線圖的判別結(jié)果,數(shù)據(jù)并沒(méi)有異常值出現(xiàn)。當(dāng)然,此外我們還能通過(guò)連續(xù)變量的分布情況來(lái)觀察是否存在異常值:

plt.figure(figsize=(16, 6), dpi=200) plt.subplot(121) sns.histplot(tcc['MonthlyCharges'], kde=True) plt.subplot(122) sns.histplot(tcc['TotalCharges'], kde=True)


當(dāng)然,通過(guò)上述圖像我們也能基本看出月消費(fèi)金額和總消費(fèi)金額的基本分布情況,對(duì)于大多數(shù)用戶來(lái)說(shuō)月消費(fèi)金額和總消費(fèi)金額都較小,而月消費(fèi)金額所出現(xiàn)的波動(dòng),極有可能是某些套餐的組合定價(jià)。

需要知道的是,對(duì)于異常值的檢測(cè)和處理也是需要根據(jù)實(shí)際數(shù)據(jù)分布和業(yè)務(wù)情況來(lái)判定,一般來(lái)說(shuō),數(shù)據(jù)分布越傾向于正態(tài)分布,則通過(guò)三倍標(biāo)準(zhǔn)差或者箱線圖檢測(cè)的異常值會(huì)更加準(zhǔn)確一些,此外,在很多時(shí)候,異常值或許是某類特殊用戶的標(biāo)識(shí),有的時(shí)候我們需要圍繞異常值進(jìn)行單獨(dú)分析,而不是簡(jiǎn)單的對(duì)其進(jìn)行修改。
對(duì)于異常值的修改,最通用的方法就是天花板蓋帽法

#天花板蓋帽法 len(tcc['MonthlyCharges'].tolist()) #7043 for i in range(0,7043):if tcc['MonthlyCharges'][i] > 100:tcc['MonthlyCharges'][i]=100 tcc['MonthlyCharges'].tolist()

三、變量相關(guān)性探索分析與探索性分析

1.標(biāo)簽取值分布

??在基本完成數(shù)據(jù)探索與處理之后,接下來(lái)我們可以通過(guò)探索標(biāo)簽在不同特征上的分布,來(lái)初步探索哪些特征對(duì)標(biāo)簽取值影響較大。當(dāng)然,首先我們可以先查看標(biāo)簽字段的取值分布情況:

y = tcc['Churn'] print(f'Percentage of Churn: {round(y.value_counts(normalize=True)[1]*100,2)} % --> ({y.value_counts()[1]} customer)\nPercentage of customer did not churn: {round(y.value_counts(normalize=True)[0]*100,2)} % --> ({y.value_counts()[0]} customer)') #Percentage of Churn: 26.54 % --> (1869 customer) #Percentage of customer did not churn: 73.46 % --> (5174 customer)'''或者''' (tcc['Churn'][tcc['Churn']=='No'].count())/tcc['Churn'].count() #0.7346301292063041 (tcc['Churn'][tcc['Churn']=='Yes'].count())/tcc['Churn'].count() #0.2653698707936959

也就是在總共7000余條數(shù)據(jù)中,流失用戶占比約為26%,整體來(lái)看標(biāo)簽取值并不均勻,但如果放到用戶流失這一實(shí)際業(yè)務(wù)背景中來(lái)探討,流失用戶比例占比26%已經(jīng)是非常高的情況了。當(dāng)然我們也可以通過(guò)直方圖進(jìn)行直觀的觀察:

sns.displot(y) #sns.countplot(y) #sns.histplot(y)

2.變量相關(guān)性分析

??接下來(lái),我們嘗試對(duì)變量和標(biāo)簽進(jìn)行相關(guān)性分析。從嚴(yán)格的統(tǒng)計(jì)學(xué)意義講,不同類型變量的相關(guān)性需要采用不同的分析方法,例如連續(xù)變量之間相關(guān)性可以使用皮爾遜相關(guān)系數(shù)進(jìn)行計(jì)算,而連續(xù)變量和離散變量之間相關(guān)性則可以卡方檢驗(yàn)進(jìn)行分析,而離散變量之間則可以從信息增益角度入手進(jìn)行分析。但是,如果我們只是想初步探查變量之間是否存在相關(guān)關(guān)系,則可以忽略變量連續(xù)/離散特性,統(tǒng)一使用相關(guān)系數(shù)進(jìn)行計(jì)算,這也是pandas中的.corr方法所采用的策略。

  • 計(jì)算相關(guān)系數(shù)矩陣

??當(dāng)然,首先我們可以先計(jì)算相關(guān)系數(shù)矩陣,直接通過(guò)具體數(shù)值大小來(lái)表示相關(guān)性強(qiáng)弱。不過(guò)需要注意的是,盡管我們可以忽略變量的連續(xù)/離散特性,但為了更好的分析分類變量如何影響標(biāo)簽的取值,我們需要將標(biāo)簽轉(zhuǎn)化為整型(也就是視作連續(xù)變量),而將所有的分類變量進(jìn)行啞變量處理:

# 剔除ID列 df3 = tcc.iloc[:,1:].copy()# 將標(biāo)簽Yes/No轉(zhuǎn)化為1/0 df3['Churn'].replace(to_replace='Yes', value=1, inplace=True) df3['Churn'].replace(to_replace='No', value=0, inplace=True)# 將其他所有分類變量轉(zhuǎn)化為啞變量,連續(xù)變量保留不變 df_dummies = pd.get_dummies(df3) df_dummies.head()


此處需要注意pd.get_dummies會(huì)將非數(shù)值類型對(duì)象類型進(jìn)行自動(dòng)啞變量轉(zhuǎn)化,而對(duì)數(shù)值類型對(duì)象,無(wú)論是整型還是浮點(diǎn)型,都會(huì)保留原始列不變:

df_dummies[['Churn', 'tenure', 'MonthlyCharges', 'TotalCharges']]


然后即可采用.corr方法計(jì)算相關(guān)系數(shù)矩陣:

df_dummies.corr()

當(dāng)然,在所有的相關(guān)性中,我們較為關(guān)注特征和標(biāo)簽之間的相關(guān)關(guān)系,因此可以直接挑選標(biāo)簽列的相關(guān)系數(shù)計(jì)算結(jié)果,并進(jìn)行降序排序:

df_dummies.corr()['Churn'].sort_values(ascending = False) # Churn 1.000000 # Contract_Month-to-month 0.405103 # OnlineSecurity_No 0.342637 # TechSupport_No 0.337281 # InternetService_Fiber optic 0.308020 # . . . # StreamingTV_No internet service -0.227890 # TechSupport_No internet service -0.227890 # OnlineBackup_No internet service -0.227890 # Contract_Two year -0.302253 # tenure -0.352229

需要知道的是,根據(jù)相關(guān)系數(shù)計(jì)算的基本原理,相關(guān)系數(shù)為正數(shù),則二者為正相關(guān),數(shù)值變化會(huì)更傾向于保持同步。例如Churn與Contract_Month-to-month相關(guān)系數(shù)為0.4,則說(shuō)明二者存在一定的正相關(guān)性,即Contract_Month-to-month取值為1(更大)越有可能使得Churn取值為1。也就是在Contract字段的Month-to-month取值結(jié)果和最終流失的結(jié)果相關(guān)性較大,也就是相比其他條件,Contract取值為Month-to-month的用戶流失概率較大,而tenure和Churn負(fù)相關(guān),則說(shuō)明tenure取值越大、用戶流失概率越小。其他結(jié)果解讀依此類推。

  • 熱力圖展示相關(guān)性

??當(dāng)然,我們也可以通過(guò)一些可視化的方式來(lái)展示特征和標(biāo)簽之間的相關(guān)性,例如可以考慮使用熱力圖進(jìn)行相關(guān)性的可視化展示:

plt.figure(figsize=(15,8), dpi=200) sns.heatmap (df_dummies.corr())

  • 柱狀圖展示相關(guān)性

??當(dāng)然,很多時(shí)候如果特征較多,熱力圖的展示結(jié)果并不直觀,此時(shí)我們可以考慮進(jìn)一步使用柱狀圖來(lái)進(jìn)行表示:

sns.set() plt.figure(figsize=(15,8), dpi=200)df_dummies.corr()['Churn'].sort_values(ascending = False).plot(kind='bar')

3.探索性數(shù)據(jù)分析

??當(dāng)然,直接計(jì)算整體相關(guān)系數(shù)矩陣以及對(duì)整體相關(guān)性進(jìn)行可視化展示是一種非常高效便捷的方式,在實(shí)際的算法競(jìng)賽中,我們也往往會(huì)采用上述方法快速的完成數(shù)據(jù)相關(guān)性檢驗(yàn)和探索工作。不過(guò),如果是對(duì)于業(yè)務(wù)分析人員,可能我們需要為其展示更為直觀和具體的一些結(jié)果,才能有效幫助業(yè)務(wù)人員對(duì)相關(guān)性進(jìn)行判別。此時(shí)我們可以考慮圍繞不同類型的屬性進(jìn)行柱狀圖的展示與分析。當(dāng)然,此處需要對(duì)比不同字段不同取值下流失用戶的占比情況,因此可以考慮使用柱狀圖的另一種變形:堆疊柱狀圖來(lái)進(jìn)行可視化展示:

fig,axes=plt.subplots(nrows=1,ncols=2,figsize=(12,6), dpi=100)# 柱狀圖 plt.subplot(121) sns.countplot(x="gender",hue="Churn",data=tcc,palette="Blues", dodge=True) plt.xlabel("Gender") plt.title("Churn by Gender")# 柱狀堆疊圖 plt.subplot(122) sns.countplot(x="gender",hue="Churn",data=tcc,palette="Blues", dodge=False) plt.xlabel("Gender") plt.title("Churn by Gender")#x: x軸上的條形圖,以x標(biāo)簽劃分統(tǒng)計(jì)個(gè)數(shù) #y: y軸上的條形圖,以y標(biāo)簽劃分統(tǒng)計(jì)個(gè)數(shù) #hue: 在x或y標(biāo)簽劃分的同時(shí),再以hue標(biāo)簽劃分統(tǒng)計(jì)個(gè)數(shù)

注,此處堆疊圖簡(jiǎn)單理解其實(shí)就是純粹的重合,并不是上下堆疊,而是深色柱狀圖覆蓋在淺色柱狀圖的上面。

接下來(lái),我們將根據(jù)此前劃分的字段類型來(lái)進(jìn)行逐類分析:

  • 用戶人口統(tǒng)計(jì)信息

首先是用戶的人口統(tǒng)計(jì)信息:

col_1 = ["gender", "SeniorCitizen", "Partner", "Dependents"]fig,axes=plt.subplots(nrows=2,ncols=2,figsize=(16,12), dpi=200)for i, item in enumerate(col_1):plt.subplot(2,2,(i+1))ax=sns.countplot(x=item,hue="Churn",data=tcc,palette="Blues", dodge=False)plt.xlabel(item)plt.title("Churn by "+ item)


能夠發(fā)現(xiàn),老年用戶、未結(jié)婚用戶以及經(jīng)濟(jì)未獨(dú)立用戶流失比例相對(duì)較高,而性別因素對(duì)是否流失影響不大。在實(shí)際制定運(yùn)營(yíng)策略時(shí),這三類用戶需要重點(diǎn)關(guān)注。

  • 已注冊(cè)的服務(wù)信息

??然后繼續(xù)分析服務(wù)屬性字段與用戶流失之間的關(guān)系:

col_2 = ["OnlineSecurity", "OnlineBackup", "DeviceProtection", "TechSupport", "StreamingTV", "StreamingMovies"]fig,axes=plt.subplots(nrows=2,ncols=3,figsize=(16,12))for i, item in enumerate(col_2):plt.subplot(2,3,(i+1))ax=sns.countplot(x=item,hue="Churn",data=tcc,palette="Blues",order=["Yes","No","No internet service"], dodge=False)plt.xlabel(item)plt.title("Churn by "+ item)


能夠發(fā)現(xiàn),未開通網(wǎng)絡(luò)服務(wù)的用戶、以及開通了網(wǎng)絡(luò)服務(wù)并且同時(shí)開通很多增值服務(wù)的用戶往往流失概率較小,而開通網(wǎng)絡(luò)服務(wù)、未開通其他增值服務(wù)的用戶流失概率較大。因此可以考慮更多的提供免費(fèi)體驗(yàn)增值服務(wù)的機(jī)會(huì),增加增值服務(wù)宣傳,促進(jìn)用戶購(gòu)買,從而提升用戶粘性。

  • 用戶合同屬性

??接下來(lái)進(jìn)一步分析用戶合同屬性與流失率之間的關(guān)系:

col_3 = ["Contract", "PaperlessBilling", "PaymentMethod"]fig,axes=plt.subplots(nrows=2,ncols=2,figsize=(16,12))for i, item in enumerate(col_3):plt.subplot(2,2,(i+1))ax=sns.countplot(x=item,hue="Churn",data=tcc,palette="Blues", dodge=False)plt.xlabel(item)plt.title("Churn by "+ item)


能夠發(fā)現(xiàn),一次性簽署服務(wù)周期越短的用戶越容易流失,并且相比其他支付方式,在線支付的用戶更容易流失。因此可能需要在實(shí)際運(yùn)營(yíng)過(guò)程中更多的引導(dǎo)用戶簽訂長(zhǎng)期合同,無(wú)論是通過(guò)折扣還是滿贈(zèng),借此提升用戶生命周期。此外,需要更加關(guān)注在線支付用戶的實(shí)際產(chǎn)品體驗(yàn),也可以考慮提升在線支付本身的用戶體驗(yàn)或者提供更多的價(jià)格優(yōu)惠,以此提升在線支付用戶滿意度。

??當(dāng)然,如果能獲取更多的實(shí)際業(yè)務(wù)背景知識(shí),則能夠進(jìn)行更加深入的數(shù)據(jù)分析與用戶挽留策略的制定。不過(guò)需要知道的是,無(wú)論是作為實(shí)際建模預(yù)測(cè)項(xiàng)目,還是結(jié)合實(shí)際業(yè)務(wù)進(jìn)行數(shù)據(jù)分析,在完成數(shù)據(jù)清洗后對(duì)變量進(jìn)行相關(guān)性分析,都是了解數(shù)據(jù)情況的重要手段,也是所有建模過(guò)程中必備的環(huán)節(jié)。在后續(xù)的內(nèi)容中,我們也將在此基礎(chǔ)上進(jìn)一步來(lái)進(jìn)行特征工程以及模型訓(xùn)練的相關(guān)工作,最終借助模型,來(lái)進(jìn)行實(shí)時(shí)的用戶流失預(yù)測(cè),并且根據(jù)最終的模型結(jié)果來(lái)更精確的判別變量重要性,以及根據(jù)模型方程來(lái)判斷變量影響流失概率的量化結(jié)果。

總結(jié)

以上是生活随笔為你收集整理的电信用户流失预测案例(1)的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

如果覺(jué)得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。