數(shù)據(jù)分析之KMeans聚類分析

聚類分析常用于用戶細分、市場細分等領域。

現(xiàn)有一份航空公司的客戶數(shù)據(jù),具體信息如下:

image.png

數(shù)據(jù)源鏈接:https://pan.baidu.com/s/1UyNSCmpqai-Jw4Xdj4H2ZQ

一、數(shù)據(jù)導入

import pandas as pd


#首先導入數(shù)據(jù),注意文件路徑為反斜杠
data=pd.read_csv('C:/Users/86138/Desktop/Python數(shù)據(jù)分析與挖掘?qū)崙?zhàn)/chapter7/demo/data/air_data.csv')
#查看數(shù)據(jù)的一些基本信息
print(data.head())
print(data.info())
print(data.describe())

二、數(shù)據(jù)處理

第1、選取聚類字段

客戶細分主要有R(recency,時間間隔),F(xiàn)(frequency,頻率或次數(shù)),M(monetary,金額)三個指標,即RFM,我們依據(jù)這三個數(shù)據(jù)進行聚類。

1、時間間隔

用當前時間減去最后一次乘機時間,得到時間間隔。

#計算距今天數(shù)
from datetime import datetime
data.replace('2014/2/29  0:00:00','2014/3/1',inplace=True)
data['LAST_FLIGHT_DATE']=pd.to_datetime(data['LAST_FLIGHT_DATE'])
data['DATEDIFF']=datetime.now()-data['LAST_FLIGHT_DATE']
data['DATEDIFF']=data['DATEDIFF'].dt.days     #提取天數(shù)

因為之前運行pd.to_datetime時報錯(時間列里2014/2/29 0:00:00這個時間錯誤,2014年并不是閏年2月并沒有29天),所以把2014/2/29 0:00:00修改為2014/3/1。

運行pd.to_datetime報錯可調(diào)用參數(shù)errors='ignore'或errors='coerce',ignore為直接忽略錯誤,coerce將非日期的字符串記為nat(not a time)。

2、乘機次數(shù)

F為FLIGHT_COUNT,乘機次數(shù)。

3、金額總額

#計算金額總額
data['SUM_YR']=data['SUM_YR_1']+data['SUM_YR_2']

第2、缺失值處理

在進行數(shù)據(jù)標準化之前進行缺失值處理,過濾掉那三個數(shù)據(jù)中的缺失值。

#缺失值處理
print(data['DATEDIFF'].isnull().sum())
print(data['FLIGHT_COUNT'].isnull().sum())
print(data['SUM_YR'].isnull().sum())
data=data[data['SUM_YR'].notnull()]     #篩選出非空值

運行發(fā)現(xiàn)SUM_YR列有689個缺失值,把它舍棄。

第3、數(shù)據(jù)標準化

確定聚類字段后,發(fā)現(xiàn)這三種數(shù)據(jù)不是同種單位,所以需要將數(shù)據(jù)標準化。

數(shù)據(jù)的標準化(normalization)是將數(shù)據(jù)按比例縮放,使之落入一個小的特定區(qū)間。在某些比較和評價的指標處理中經(jīng)常會用到,去除數(shù)據(jù)的單位限制,將其轉(zhuǎn)化為無量綱的純數(shù)值,便于不同單位或量級的指標能夠進行比較和加權。其中最典型的就是數(shù)據(jù)的歸一化處理,即將數(shù)據(jù)統(tǒng)一映射到[0,1]區(qū)間上。


z-score 標準化

Z標準化即減去均值,再除以標準差。

#數(shù)據(jù)標準化
data['R']=(data['DATEDIFF']-data['DATEDIFF'].mean())/(data['DATEDIFF'].std())
data['F']=(data['FLIGHT_COUNT']-data['FLIGHT_COUNT'].mean())/(data['FLIGHT_COUNT'].std())
data['M']=(data['SUM_YR']-data['SUM_YR'].mean())/(data['SUM_YR'].std())

三、模型構建

根據(jù)業(yè)務的需要,將客戶分為5類:重要保持客戶,重要發(fā)展客戶,重要挽留客戶,一般價值用戶與低價值用戶。
1、重要保持客戶:RFM都很好,時間間隔小,乘坐次數(shù)多,金額大。這類客戶價值大,對航空公司貢獻最大,是公司的重要客戶,公司要花精力維護好這類客戶。
2、重要發(fā)展客戶:最近乘坐過,但次數(shù)或金額較低。這類客戶最近有乘機需求,公司要刺激這類客戶再次消費,提高他們的消費水平。
3、重要挽留客戶:有段時間沒坐,但之前經(jīng)常坐或消費金額高。說明這類客戶消費能力不錯,只是近期無消費,公司要促進這類客戶的再次消費。
4、一般價值用戶:各項表現(xiàn)一般,價值不大。
5、低價值用戶:各項表現(xiàn)差,價值低。

#模型構建
data2=data[['R','F','M']]                 #篩選出進行聚類的字段
from sklearn.cluster import KMeans       #導入KMeans聚類模型
kmodel=KMeans(n_clusters=4,n_jobs=4)     #n_clusters為分類數(shù),n_jobs為并行數(shù),一般等于CPU數(shù)較好
kmodel.fit(data2)                         #帶入數(shù)據(jù)訓練模型
print(kmodel.cluster_centers_)     #查看聚類中心
print(kmodel.labels_)          #查看各樣本對應的類別

導入sklearn庫出錯原因:sklearn依賴包numpy,pandas,matplotlib,scipy,但是之前安裝好的numpy并沒有mkl,所以我們需要下載numpy+mkl,下載鏈接:https://www.lfd.uci.edu/~gohlke/pythonlibs/#numpy

注意:建模的數(shù)據(jù)不能包含空值或無限值,否則會報錯


image.png

運行結果如下:


image.png

可以看出,第一和第四行聚類中心表現(xiàn)最差,頻率和金額最低,時間間隔大,為一般價值用戶與低價值用戶。
第三行聚類中心表現(xiàn)最好,時間間隔最小,乘機次數(shù)最多,金額最大,為類別2,這一類客戶價值最高,是航空公司重點維護的客戶。

第五行聚類中心頻率和金額較大,但有段時間沒乘坐過,是航空公司的重要挽留客戶。
第二行聚類中心近段時間乘坐過,但頻率或金額較低,是航空公司的重要發(fā)展客戶。

四、導出數(shù)據(jù)

導出數(shù)據(jù),更好地查看各個客戶對應的類別,然后根據(jù)不同的類別制定不同的政策。

#導出數(shù)據(jù),數(shù)據(jù)最后一列為各樣本對應的類別
data['LABELS']=kmodel.labels_
data.to_csv('C:/Users/86138/Desktop/Python數(shù)據(jù)分析與挖掘?qū)崙?zhàn)/chapter7/fenlei.csv')
print(data['LABELS'].value_counts)     #查看每類有多少個
print(data[data['LABELS']==0])         #篩選出類別0的數(shù)據(jù)

一些政策如積分兌換,會員升級,促銷活動,免費兌換,發(fā)行聯(lián)名卡等。

最后

完整的代碼如下:

import pandas as pd


#首先導入數(shù)據(jù),注意文件路徑為反斜杠,補全文件路徑
data=pd.read_csv('C:/Users/86138/Desktop/Python數(shù)據(jù)分析與挖掘?qū)崙?zhàn)/chapter7/demo/data/air_data.csv')
#查看數(shù)據(jù)的一些基本信息
print(data.head())
print(data.info())
print(data.describe())

#計算距今天數(shù)
from datetime import datetime
data.replace('2014/2/29  0:00:00','2014/3/1',inplace=True)
data['LAST_FLIGHT_DATE']=pd.to_datetime(data['LAST_FLIGHT_DATE'])
data['DATEDIFF']=datetime.now()-data['LAST_FLIGHT_DATE']
data['DATEDIFF']=data['DATEDIFF'].dt.days         #提取天數(shù)

#計算金額總額
data['SUM_YR']=data['SUM_YR_1']+data['SUM_YR_2']

#缺失值處理
print(data['DATEDIFF'].isnull().sum())
print(data['FLIGHT_COUNT'].isnull().sum())
print(data['SUM_YR'].isnull().sum())
data=data[data['SUM_YR'].notnull()]     #篩選出非空值

#數(shù)據(jù)標準化
data['R']=(data['DATEDIFF']-data['DATEDIFF'].mean())/(data['DATEDIFF'].std())
data['F']=(data['FLIGHT_COUNT']-data['FLIGHT_COUNT'].mean())/(data['FLIGHT_COUNT'].std())
data['M']=(data['SUM_YR']-data['SUM_YR'].mean())/(data['SUM_YR'].std())

#模型構建
data2=data[['R','F','M']]                 #篩選出進行聚類的字段
from sklearn.cluster import KMeans       #導入KMeans聚類模型
kmodel=KMeans(n_clusters=5,n_jobs=4)     #n_clusters為分類數(shù),n_jobs為并行數(shù),一般等于CPU數(shù)較好
kmodel.fit(data2)                         #帶入數(shù)據(jù)訓練模型
print(kmodel.cluster_centers_)     #查看聚類中心
print(kmodel.labels_)          #查看各樣本對應的類別

#導出數(shù)據(jù),數(shù)據(jù)最后一列為各樣本對應的類別
data['LABELS']=kmodel.labels_
data.to_csv('C:/Users/86138/Desktop/Python數(shù)據(jù)分析與挖掘?qū)崙?zhàn)/chapter7/fenlei.csv')
print(data['LABELS'].value_counts)     #查看每類有多少個
print(data[data['LABELS']==0])         #篩選出類別0的數(shù)據(jù)
?著作權歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

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

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