天天看點

愛數課實驗 | 使用線性判别分析來預測客戶流失

愛數課實驗 | 使用線性判别分析來預測客戶流失

愛數課:idatacourse.cn

領域:消費

簡介:本次實驗通過線性判别來分析預測客戶流失

資料:

./dataset/Discriminant-analysis-churn-dataset.csv

1. 目錄

愛數課實驗 | 使用線性判别分析來預測客戶流失

2. 簡介

目前,電信營運商面臨激烈的市場競争,客戶争奪愈演愈烈,每個企業都存在客戶流失的問題。在競争激烈的世界裡,對于每家公司來說,找出客戶流失的原因以應對這種情況至關重要。

預防客戶流失的重要性:1.獲得新客戶的成本很高,而且需要付出很多努力,而防止客戶流失的成本效益要高得多。2.競争顯着增加,産品往往相同甚至可以互換。客戶流失的可能性正在增加。是以,每家公司都應該制定長期的客戶忠誠度戰略。3.導緻客戶流失的因素有很多,公司必須識别、了解和消除每一個因素,以便客戶與公司保持聯系。4.使用正确的客戶體驗管理工具,定期進行客戶調查和接觸至關重要。

商業成功的關鍵就在于充分了解客戶的行為和偏好,為潛在客戶和現有客戶提供個性化的服務。使用客戶行為分析技術,可以分析客戶流失的原因,分析客戶的喜好,可以預測客戶業務情況的回饋,進而得到接近他們所需的資訊。同時為防止客戶流失做出改善例如:提供出色的客戶服務和支援,提供超越購買的價值,個性化客戶體驗等等。

3. 項目介紹

由于服務和客戶群體因素的影響,電信業務面臨頻繁客戶流失的挑戰。我們用于分析的資料集包括一個關于現有客戶購買服務相關因素的清單,以及關于他們是否購買服務的資訊。我們的目标是了解哪些因素對客戶流失的影響較大,并根據服務相關因素預測哪些客戶可能會而流失。本文将對流失使用者做特征分析和流失原因分析,幫助營運商發現并改善使用者體驗,以及幫助确定挽留目标使用者和制定方案。

4. 資料擷取

4.1 資料集介紹

用于分析的資料集包含了5000個客戶的資訊,包括賬戶長度、語音郵件資訊的數量、白天總費用、傍晚總費用、夜晚總費用、國際長途費用、客戶服務電話的數量和是否流失等字段。各個字段類型及含義如下表所示:

列名 類型 含義說明
account_length 整型 賬戶長度
number_vmail_messages 整型 語音郵件資訊的數量
total_day_charge 浮點型 白天總費用
total_eve_charge 浮點型 傍晚總費用
total_night_charge 浮點型 夜晚總費用
total_intl_charge 浮點型 國際長途總費用
number_customer_service_calls 整型 撥打客戶服務電話數量
churn 整型 是否流失(1表示流失,0表示未流失)

4.2 讀取資料

首先,使用Pandas庫的​

​red_csv()​

​​函數讀取資料。使用​

​head()​

​方法檢視資料的前幾條資訊。

import pandas as pd
import numpy as np      
df = pd.read_csv('./dataset/Discriminant-analysis-churn-dataset.csv') #讀取資料      
df.head(5)#檢視資料的前五行資訊      
愛數課實驗 | 使用線性判别分析來預測客戶流失

4.3 檢視資料基本資訊

df.info() #檢視資料基本資訊      
愛數課實驗 | 使用線性判别分析來預測客戶流失

​info()​

​方法可以檢視包括資料的次元,字段的名稱和類型,以及有無缺失值,資料占用的記憶體等資訊。可以看到,該資料集包含5000個樣本和8個字段,沒有缺失資料。隻有整型和浮點型資料,沒有字元型資料。

df.describe(include='all') #檢視資料基本統計資訊      
愛數課實驗 | 使用線性判别分析來預測客戶流失

​describe()​

​​方法可以檢視各個列的基本統計資訊。從輸出結果我們可以看到,賬戶長度​

​account_length​

​​、白天總費用​

​total_day_charge​

​等字段的樣本數量count,均值mean,方差std,最小值min,下四分位數25%,中位數50%,上四分位數75%,最大值max等資訊。

5. 資料探索性分析

在前面的任務中,通過​

​info()​

​​,​

​describe()​

​等方法展示了資料的基本資訊。我們将利用Python中的繪圖庫如Matplotlib、Seaborn等,通過繪圖的方式對資料進行探索性分析。

5.1 流失客戶與未流失客戶餅狀圖

在這個項目中,​

​churn​

​客戶是否流失,流失客戶人數與未流失客戶人數的分布比例對模型預測至關重要,若分布不均則會對模型的預測效果産生影響。下面通過繪制餅狀圖的方式展現流失客戶與未流失客戶的的占比情況。

import matplotlib.pyplot as plt
import seaborn as sns
plt.rcParams['font.sans-serif']=['SimHei']   # 用來正常顯示中文标簽
%config InlineBackend.figure_format = 'svg'#讓圖表變成矢量形式,顯示更清晰      
fig =plt.figure(figsize=(6,4),dpi= 120)#figsize設定圖形大小,dpi設定圖形分辨率
plt.pie(df['churn'].value_counts(),explode=(0.1,0),labels=['未流失','流失'],autopct='%.2f%%')
plt.title('流失與未流失客戶占比') #設定标題      
愛數課實驗 | 使用線性判别分析來預測客戶流失

5.2 賬戶長度按客戶是否流失分組箱線圖

fig =plt.figure(figsize=(6,4),dpi= 120)#figsize設定圖形大小,dpi設定圖形分辨率
sns.boxplot(x='churn',y='account_length',data=df,palette='Set2')#繪制箱線圖
plt.xlabel('客戶是否流失') #設定x軸标簽
plt.ylabel('賬戶長度')#設定y軸标簽
plt.title('賬戶長度按客戶是否流失分組箱線圖')#設定标題      
愛數課實驗 | 使用線性判别分析來預測客戶流失

分析賬戶長度與客戶是否流失的關系,賬戶長度按客戶是否流失分組箱型線可以看到,兩組的差别并不明顯,賬戶長度對客戶流失并沒有太大影響。

5.3 語音郵件數量按客戶是否流失分組箱線圖

ig =plt.figure(figsize=(6,4),dpi= 120)#figsize設定圖形大小,dpi設定圖形分辨率
sns.boxplot(x='churn',y='number_vmail_messages',data=df,palette='Set2')#繪制箱線圖
plt.xlabel('客戶是否流失') #設定x軸标簽
plt.ylabel('語音郵件數量')#設定y軸标簽
plt.title('語音郵件數量按客戶是否流失分組箱線圖')#設定标題      
愛數課實驗 | 使用線性判别分析來預測客戶流失

分析語音郵件數量與客戶是否流失的關系,從語音郵件數量按客戶是否流失分組箱型線中可以看出,流失客戶的語音郵件數量較未流失客戶少。

5.4 白天總費用按客戶是否流失分組箱線圖

ig =plt.figure(figsize=(6,4),dpi= 120)#figsize設定圖形大小,dpi設定圖形分辨率
sns.boxplot(x='churn',y='total_day_charge',data=df,palette='Set3')
plt.xlabel('客戶是否流失') #設定x軸标簽
plt.ylabel('白天總費用')#設定y軸标簽
plt.title('白天總費用按客戶是否流失分組箱線圖')#設定标題      
愛數課實驗 | 使用線性判别分析來預測客戶流失

分析白天總費用與客戶是否流失的關系,從白天總費用按客戶是否流失分組箱線圖中可以看出,那些流失客戶的白天總費用相較于未流失客戶比較高。這可能表明,流失的客戶對他們的套餐資費并不滿意等等。

5.5 客戶服務電話數量用按客戶是否流失分組箱線圖

ig =plt.figure(figsize=(6,4),dpi= 120)#figsize設定圖形大小,dpi設定圖形分辨率
sns.boxplot(x='churn',y='number_customer_service_calls',data=df,palette='Set3')
plt.xlabel('客戶是否流失') #設定x軸标簽
plt.ylabel('客戶服務電話數量')#設定y軸标簽
plt.title('客戶服務電話數量按客戶是否流失分組箱線圖')#設定标題      
愛數課實驗 | 使用線性判别分析來預測客戶流失

分析客戶服務電話數量與客戶是否流失的關系,從客戶服務電話數量用按客戶是否流失分組箱線圖可以看出,客戶流失的客戶服務電話數量相對較高。這表明或許已流失的客戶嘗試聯系客服,但可能沒有得到滿意的解決等。

6. 模型建構

判别分析(Discriminant Analysis)是一種分類方法,它通過一個已知類别的“訓練樣本”來建立判别準則,并通過預測變量來為未知類别的資料進行分類。線性判别式分析(Linear Discriminant Analysis,簡稱為LDA)是其中一種,也是模式識别的經典算法,在1996年由Belhumeur引入模式識别和人工智能領域。LDA以Bayes判别思想為基礎,當分類隻有兩種且總體服從多元正态分布條件下,Bayes判别與Fisher判别、距離判别是等價的。

基本思想是将高維的模式樣本投影到最佳鑒别矢量空間,以達到抽取分類資訊和壓縮特征空間維數的效果,投影後保證模式樣本在新的子空間有最大的類間距離和最小的類内距離,即模式在該空間中有最佳的可分離性。

6.1 資料集劃分

我們把資料劃分為訓練集和測試集,訓練集用于訓練模型,測試集用于評估模型性能。在Sklearn中的​

​model_selection​

​​子產品的​

​train_test_split()​

​函數可以進行訓練集和測試集的劃分。我們将資料按照分為訓練集和測試集。

y = df['churn'].values
X  = df.drop('churn',axis=1)

#資料集劃分
from sklearn.model_selection import train_test_split
X_train, X_test, y_train, y_test = train_test_split(X, y, 
                                   test_size=0.3,random_state=160,stratify=y)      

6.2 歸一化處理

由于資料中包含變量的次元各不相同,對其進行歸一化處理,以便每個變量的範圍對判别系數的影響相同。在Sklearn的​

​preprocessing​

​​子產品的​

​MinMaxScaler​

​類可以對資料進行Min-Max歸一化處理。

from sklearn.preprocessing import MinMaxScaler

#MinMaxScaler進行歸一化
scaler = MinMaxScaler()
X_train.loc[:,:]=scaler.fit_transform(X_train)
X_test.loc[:,:]=scaler.transform(X_test)      
愛數課實驗 | 使用線性判别分析來預測客戶流失

6.3 模型訓練與評估

LDA線性判别分析步驟:

第一步:計算每一類的的資訊向量的均值。

第二步:計算類内散布矩陣:

其中:

第三步:計算類間散布矩陣:

其中是全局資訊向量均值,和分别是類别内的資訊向量均值和樣本個數。

第四步:求解矩陣 

第五步:選取個最大特征值對應的特征向量形成特征矩陣。即特征轉換矩陣的寬度,和将為後空間的次元。

第六步:将資訊矩陣與特征轉換矩陣相乘進而實作降維。

使用Scikit-learn中的​

​LinearDiscriminantAnalysis​

​​類可以建構線性判别分析模型,​

​LinearDiscriminantAnalysis​

​​位于​

​sklearn.discriminant_analysis​

​​包,首先将其導入,然後再将劃分好的訓練集​

​X_trian​

​​,​

​y_train​

​​帶入模型中,調用​

​fit​

​方法進行模型訓練。

from sklearn.discriminant_analysis import LinearDiscriminantAnalysis
lda = LinearDiscriminantAnalysis() #聲明一個LinearDiscriminantAnalysis對象
lda.fit(X_train, y_train)#訓練模型      

LinearDiscriminantAnalysis()

print('模型預測準确率:',lda.score(X_test,y_test))      

模型預測準确率:0.864

可以看到建立的線性判别分析模型在客戶是否流失這個問題上準确率還是非常高的,達到了。

6.4 模型對比分析

使用Scikit-learn中的​

​LogisticRegression​

​​類可以建構邏輯回歸模型,​

​LogisticRegression​

​​位于​

​sklearn.linear_model​

​​包,首先将其導入,然後再将劃分好的訓練集​

​X_trian​

​​,​

​y_train​

​​帶入模型中,調用​

​fit​

​方法進行模型訓練。

from sklearn.linear_model import LogisticRegression


model_lr= LogisticRegression(class_weight='balanced',random_state=10)
model_lr.fit(X_train,y_train)      

LogisticRegression(class_weight='balanced', random_state=10)

print('模型預測準确率:',model_lr.score(X_test,y_test))      

模型預測準确率:0.7193333333333334