1. 程式人生 > >R聚類分析航空公司資料(篩選出不同的客戶類別)

R聚類分析航空公司資料(篩選出不同的客戶類別)

效果圖如下 在這裡插入圖片描述 圖片是將3萬四千條航空公司資料用k-means演算法分成五個類,並通過ggplot2包作圖作出來的特徵屬性。 我們將通過不同的屬性值,分析出高價值使用者,低價值使用者,主力使用者,一般使用者,潛力使用者 在這裡插入圖片描述 可以分析得F,M,C自然是越高越好,C主要是判斷潛力使用者,F,M判斷主力使用者,R判斷使用者是否還在關注航空公司。 由於class5的F,M都高,我們可以判斷其為主力使用者(屬於航空公司需要保持,不允許流失的客戶) class4的R偏高,而F,M偏低,可以判斷class4使用者不關注航空公司,屬於低價值使用者, class3的L偏高,其他均為平均水平,屬於老使用者 class2的C偏高,屬於注重乘機體驗而不在乎錢的vip使用者,屬於高價值使用者,而F,M都偏低,說明客戶體驗不好,航空公司需要將該類別的F,M提高起來 class1的L偏低,還沒怎麼體驗航空公司的服務,屬於潛力使用者 通過客戶屬性的劃分和特徵屬性的分析,航空公司可以針對不同的客戶類群,制定不同的營銷方案和服務,來提高航空公司的競爭力和業績

通過雷達圖可以較清楚看出不同客戶的特徵屬性 在這裡插入圖片描述

分析過程

航空公司的屬性說明 航空公司資料中有特別多的屬性,我們第一步就需要篩選出我們對我們業務分析有用的屬性,忽略掉一些弱相關和沒有用的屬性。 在這裡插入圖片描述 在這裡插入圖片描述 總共有45條屬性資料,我們要在其中篩選出我們最需要的屬性 毫無疑問,第一年和第二年總票價是很重要的,我們需要將它們挑選出來。 在分析客戶是否為潛在價值大時,我們需要看平均折扣率,如果平均折扣率小,說明客戶在乎出行的質量而不是價格。 同樣我們需要找到使用者最後一次乘機的時間距離現在的時間,以此來判斷使用者是否還關注此家航空公司。 還有里程也是衡量使用者的重要因素。 第一次乘機到最後一次乘機可以判斷客戶的忠誠度。 所以我挑選出來的第一年和第二年總票價,平均折扣率,最後一次乘機的時間距離現在的時間,里程,第一次乘機。 下面通過R語言實現資料清洗過程

資料清洗有兩個部分,一個是缺失值刪除,一個是異常值刪除 下面進行缺失值刪除過程 首先需要選取需要刪除的屬性,通過對原始資料的觀察和summary函式,選擇第一年和第二年的缺失值進行刪除,用到which(is.na())函式,which用於定位。 再分析異常值。 觀察原始資料可以得到,存在第一年和第二年票價為0但是平均折扣率不為0的情況。 通過布林法則,可以刪除異常值 程式碼如下

#設定工作路徑
setwd("D:\\資料分析\\R語言基礎\\課程資料")
flight<-read.csv("air_data.csv",header = T)
#選取所需要探索的屬性
col <- c(15:18, 20:29) 
summary(flight[,col])
#刪除掉缺失值
flight<-flight[-which(is.na(flight$SUM_YR_1|flight$SUM_YR_2)),]
#查詢異常值
a<-flight$SUM_YR_1==0&flight$SUM_YR_2==0&flight$avg_discount!=0
flight<-flight[-which(a),]

屬性規約 在分析航空資料時,我們通常用到5個屬性L,R,F,M,C L=LOAD_TIME-FFP_DATE R=LOAD_TIME-LAST_FLIGHT_DATE F=FLIGHT_COUNT M=SEG_KM_SUM C=avg_discount 在轉化中,我們需要將LOAD_TIME和FFP_DATE和LAST_FLIGHT_DATE用as.date轉化為日期型別的資料 再transform函式和difftime計算時間差 在使用difftime的時候,需要注意units之間的區別,我首次使用difftime的時候,L的units是days而R的units是seconds,units不同自然無法分析,且units的範圍只有“auto”, “secs”, “mins”, “hours”, “days”, “weeks”其中的一個,我的想法是將units設定為days,並且將其除以30,得到months的units 計算出L與R後會發現L與R是difftime的屬性,需要將其轉化為numerical的型別。同時需要用summary判斷是否有缺失值。 程式碼塊如下

#建立副本
copy<-flight
#屬性規約2 10 11 17 29 23六個屬性
flight1<-flight[,c(2,10,11,17,19,29)]
#將因子型別轉化為資料型別
flight1$FFP_DATE<-as.Date(flight1$FFP_DATE)
flight1$LOAD_TIME<-as.Date(flight1$LOAD_TIME)
flight1$LAST_FLIGHT_DATE<-as.Date(flight1$LAST_FLIGHT_DATE)
#計算LRFMC
bh<-transform(flight1,L=difftime(LOAD_TIME,FFP_DATE,units = "days")/30,
              R=difftime(LOAD_TIME,LAST_FLIGHT_DATE ,units = "days")/30)
bh$L<-as.numeric(bh$L)
bh$R<-as.numeric(bh$R)
#刪除缺失值
bh<-bh[-which(is.na(bh$LAST_FLIGHT_DATE)),]
#找出需要的屬性
bh1<-bh[,c("FLIGHT_COUNT","SEG_KM_SUM","avg_discount","L","R")]
#檢視屬性的最大值最小值
apply(bh1,2,range)
#進行標準化
bzh<-data.frame(scale(x=bh1))
names(bzh)<-c("F","M","C","L","R")

資料的標準化 一般如果得到的資料屬性的最大值和最小值的差很大的話,我們需要進行資料的標準化。來縮小最大值和最小值的差 進行標準化的過程分為兩步. 第一步用apply函式檢視屬性的最大最小值 apply(data,1or2,fun=range) 第二步用scale函式進行標準化 資料預處理完成後,就要進行模型的訓練了 在這裡我們用k-means演算法進行模型的訓練

#進行聚類分析
#設定隨機種子
set.seed(10)
#centers的數值代表的是類別的數量,我們一般選取3到8類
clust<-kmeans(bzh,centers = 5)

資料的視覺化和特徵屬性的分析 在使用ggplot2包之前,我們需要將寬格式轉化為長格式 電腦不讀取寬格式,讀取長格式,將寬格式轉化為長格式需要melt函式 寬格式 在這裡插入圖片描述 長格式 在這裡插入圖片描述

程式碼實現如下

#資料視覺化
install.packages("reshape")
install.packages("ggplot2")
library(reshape2)
library(ggplot2)
new<-as.data.frame(t(clust$centers))
colnames(new)<-paste("class",c(1:5),sep = "")
new<-data.frame(index=c("F","M","C","L","R"),new)
#短標識轉化為長標識
new<-melt(new,c("index"))

完整程式碼如下

#設定工作路徑
setwd("D:\\資料分析\\R語言基礎\\課程資料")
flight<-read.csv("air_data.csv",header = T)
#選取所需要探索的屬性
col <- c(15:18, 20:29) 
summary(flight[,col])
#刪除掉缺失值
flight<-flight[-which(is.na(flight$SUM_YR_1|flight$SUM_YR_2)),]
#查詢異常值
a<-flight$SUM_YR_1==0&flight$SUM_YR_2==0&flight$avg_discount!=0
flight<-flight[-which(a),]
#建立副本
copy<-flight
#屬性規約2 10 11 17 29 23六個屬性
flight1<-flight[,c(2,10,11,17,19,29)]
#將因子型別轉化為資料型別
flight1$FFP_DATE<-as.Date(flight1$FFP_DATE)
flight1$LOAD_TIME<-as.Date(flight1$LOAD_TIME)
flight1$LAST_FLIGHT_DATE<-as.Date(flight1$LAST_FLIGHT_DATE)
#計算LRFMC
bh<-transform(flight1,L=difftime(LOAD_TIME,FFP_DATE,units = "days")/30,
              R=difftime(LOAD_TIME,LAST_FLIGHT_DATE ,units = "days")/30)
bh$L<-as.numeric(bh$L)
bh$R<-as.numeric(bh$R)
#刪除缺失值
bh<-bh[-which(is.na(bh$LAST_FLIGHT_DATE)),]
#找出需要的屬性
bh1<-bh[,c("FLIGHT_COUNT","SEG_KM_SUM","avg_discount","L","R")]
#檢視屬性的最大值最小值
apply(bh1,2,range)
#進行標準化
bzh<-data.frame(scale(x=bh1))
names(bzh)<-c("F","M","C","L","R")
#進行聚類分析
#設定隨機種子
set.seed(10)
clust<-kmeans(bzh,centers = 5)
#資料視覺化
install.packages("reshape")
install.packages("ggplot2")
library(reshape2)
library(ggplot2)
new<-as.data.frame(t(clust$centers))
colnames(new)<-paste("class",c(1:5),sep = "")
new<-data.frame(index=c("F","M","C","L","R"),new)
#短標識轉化為長標識
new<-melt(new,c("index"))
#條形圖
colnames(new)<-c("index","class","centers")
ggplot(data = new,mapping = aes(x=index,y=centers),fill=class)+
  scale_y_continuous(limits = c(-1, 3)) + geom_bar(stat = "identity") + 
  facet_grid(class ~ .) + guides(fill = FALSE) + theme_bw()
  
# 每一簇各指標的關係程度  --雷達圖
install.packages("fmsb")
library(fmsb)
max <- apply(clust$centers, 2, max)
min <- apply(clust$centers, 2, min)
data.radar <- data.frame(rbind(max, min, clust$centers))
radarchart(data.radar, pty = 32, plty = 1, plwd = 2, vlcex = 0.7)
# 給雷達圖加圖例
L <- 1.2
for(i in 1:5){
  text(1.8, L, labels = paste("--class", i), col = i)
  L <- L - 0.2
}