setwd("~/Desktop/data hw/hw3")
airline<- read.csv(file ="airline_survey.csv")
airline<-na.omit(airline)
set.seed(100)
library(tidyverse)
## ─ Attaching packages ──────────────────── tidyverse 1.3.1 ─
## ✓ ggplot2 3.3.5     ✓ purrr   0.3.4
## ✓ tibble  3.1.4     ✓ dplyr   1.0.7
## ✓ tidyr   1.1.4     ✓ stringr 1.4.0
## ✓ readr   2.0.2     ✓ forcats 0.5.1
## ─ Conflicts ───────────────────── tidyverse_conflicts() ─
## x dplyr::filter() masks stats::filter()
## x dplyr::lag()    masks stats::lag()

#1. #a.任選1種監督式學習方法配適模型,預測滿意度satisfaction (2類:滿意、中立或不滿意)

改變變數型態

airline$satisfaction <- as.factor(ifelse(airline$satisfaction == "satisfied", 1, 0))
airline$Gender<- as.factor(ifelse(airline$Gender=="Male",1,0))
airline$Customer.Type<- as.factor(ifelse(airline$Customer.Type=="Loyal Customer",1,0))
airline$Type.of.Travel<- as.factor(ifelse(airline$Type.of.Travel=="Business travel",1,0))
airline$Class<- as.factor(ifelse(airline$Class=="Business",2,ifelse(airline$Class=="Eco Plus",1,0)))
airline<- airline %>% mutate(
  Flight.Distance = (Flight.Distance - min(Flight.Distance)) / (max(Flight.Distance) - min(Flight.Distance)),
  Departure.Delay.in.Minutes= (Departure.Delay.in.Minutes - min(Departure.Delay.in.Minutes)) / (max(Departure.Delay.in.Minutes) - min(Departure.Delay.in.Minutes)),
  Arrival.Delay.in.Minutes= (Arrival.Delay.in.Minutes - min(Arrival.Delay.in.Minutes)) / (max(Arrival.Delay.in.Minutes) - min(Arrival.Delay.in.Minutes))
)

隨機抽取2000筆資料,並建立測試集&訓練集

airline.1<-airline[sample(1:nrow(airline),2000),]
traind<-airline.1[sample(1:nrow(airline.1),1600),]
testd<-airline.1[sample(1:nrow(airline.1),400),]

跑隨機樹森林模型,mtry=8

library(randomForest)
## randomForest 4.6-14
## Type rfNews() to see new features/changes/bug fixes.
## 
## 載入套件:'randomForest'
## 下列物件被遮斷自 'package:dplyr':
## 
##     combine
## 下列物件被遮斷自 'package:ggplot2':
## 
##     margin
tuneRF(x = traind[,-25], y = traind[,25]) #mtry=8
## mtry = 4  OOB error = 7.94% 
## Searching left ...
## mtry = 2     OOB error = 9.69% 
## -0.2204724 0.05 
## Searching right ...
## mtry = 8     OOB error = 7.12% 
## 0.1023622 0.05 
## mtry = 16    OOB error = 7.75% 
## -0.0877193 0.05

##        mtry OOBError
## 2.OOB     2 0.096875
## 4.OOB     4 0.079375
## 8.OOB     8 0.071250
## 16.OOB   16 0.077500
RF <- randomForest(satisfaction~. ,data=traind, importane = T, na.action = na.omit)
RF
## 
## Call:
##  randomForest(formula = satisfaction ~ ., data = traind, importane = T,      na.action = na.omit) 
##                Type of random forest: classification
##                      Number of trees: 500
## No. of variables tried at each split: 4
## 
##         OOB estimate of  error rate: 6.44%
## Confusion matrix:
##     0   1 class.error
## 0 885  39  0.04220779
## 1  64 612  0.09467456

錯誤率: 利用OOB(Out Of Bag)運算出來

plot(RF)
legend("topright", colnames(RF$err.rate),col=1:3,cex=0.8,fill=1:3)

#b. 找出重要變數:哪些因素影響客戶滿意度

從數據大小可看出變數的重要性,我們選取前5筆作為重要變數: Online.boarding、Inflight.wifi.service、Type.of.Travel、Class、 Inflight.entertainment

importance(RF)
##                                   MeanDecreaseGini
## X                                        19.752433
## id                                       25.634554
## Gender                                    3.100736
## Customer.Type                            16.534574
## Age                                      28.657630
## Type.of.Travel                           76.296602
## Class                                    61.557633
## Flight.Distance                          33.113697
## Inflight.wifi.service                    81.193913
## Departure.Arrival.time.convenient        12.663420
## Ease.of.Online.booking                   26.165765
## Gate.location                            13.215822
## Food.and.drink                           13.047854
## Online.boarding                         126.279860
## Seat.comfort                             35.894711
## Inflight.entertainment                   49.916925
## On.board.service                         20.414878
## Leg.room.service                         29.950656
## Baggage.handling                         15.465432
## Checkin.service                          17.674639
## Inflight.service                         21.602675
## Cleanliness                              25.392969
## Departure.Delay.in.Minutes               12.851447
## Arrival.Delay.in.Minutes                 13.183788
varImpPlot(RF)

prediction

pred=predict(RF, newdata = testd)
table(Real = testd$satisfaction, Predict = pred)
##     Predict
## Real   0   1
##    0 240   3
##    1   2 155

bagging:做完bagging後的test結果比原先的prediction好,錯誤率下降

library(ipred)
bag <- bagging(satisfaction ~ ., data = airline.1[,-(1:2)], coob=TRUE) #放model跟資料
print(bag)
## 
## Bagging classification trees with 25 bootstrap replications 
## 
## Call: bagging.data.frame(formula = satisfaction ~ ., data = airline.1[, 
##     -(1:2)], coob = TRUE)
## 
## Out-of-bag estimate of misclassification error:  0.0675
pred <- predict(bag, testd)
table(Real = testd$satisfaction, Predict = pred)
##     Predict
## Real   0   1
##    0 243   0
##    1   0 157

#2. 任選1種非監督式方法,將客戶分群,介紹你分出來的群,對於這些不同的客戶群集提出給該航空業的商業策略建議

library(tidyverse)
library(ggplot2)
library(factoextra)
## Welcome! Want to learn more? See two factoextra-related books at https://goo.gl/ve3WBa
library(dplyr)
airline.2<-airline.1[,-c(1:2)]
airline.2<-na.omit(airline.2)

找出最適合的k,選擇k=5 –> 方法一

fviz_nbclust(airline.2, #data
             FUNcluster = kmeans,# K-Means
             method = "wss",     # total within sum of square 組內變異最小 組間最大
             k.max = 20          # max number of clusters to consider
) +
  labs(title="Elbow Method for K-Means")+
  geom_vline(xintercept = 5, linetype = 2) #標出適合的線--> k=5

方法二

fviz_nbclust(airline.2, FUN = kmeans, method = "silhouette")#k=2

fviz_nbclust(airline.2, FUN = kmeans, method = "wss")#k=5

方法三: 用另一種方式再選一次,也是選擇k=5

E.dist <- dist(airline.2, method="euclidean") # 歐式距離
tree1 <- hclust(E.dist, method="ward.D2")
fviz_nbclust(airline.2, FUN = hcut, method = "wss") #運用Gap statistic找適合的分群數目

plot(tree1, xlab="Euclidean",h=-1) #h=-1 齊頭--分五組
rect.hclust(tree1,k=5,border="orange")#把5群畫出來

plot the result

cluster <- cutree(tree1, k=5)  # 分成5群
table(cluster)#看分群狀況
## cluster
##   1   2   3   4   5 
## 393 587 316 225 479
airline.2=cbind(airline.2,cluster)

畫圖看各變數分佈情況–> 繪製importance前10筆的資料: Oline.boarding, Inflight.wifi.service, Type.of.Travel, Class, Inflight.entertainment, Seat.comfort, Flight.Distance, Leg.room.service, Age, Ease.of.Online.booking

  1. Oline.boarding
ggplot( data= airline.2) +
  geom_bar( aes( x = Online.boarding)) + 
  facet_wrap( ~ cluster)

  1. Inflight.wifi.service
ggplot( data =airline.2) +
  geom_bar( aes( x = Inflight.wifi.service)) + 
  facet_wrap( ~ cluster)

  1. Type.of.Travel
ggplot( data =airline.2) +
  geom_bar( aes( x = Type.of.Travel)) + 
  facet_wrap( ~ cluster)

  1. Class
ggplot( data =airline.2) +
  geom_bar( aes( x = Class)) + 
  facet_wrap( ~ cluster)

  1. Inflight.entertainment
ggplot( data =airline.2) +
  geom_bar( aes( x = Inflight.entertainment)) + 
  facet_wrap( ~ cluster)

  1. Seat.comfort
ggplot( data =airline.2) +
  geom_bar( aes( x= Seat.comfort)) + 
  facet_wrap( ~ cluster)

  1. Flight.Distance
ggplot(airline.2, aes(x=as.factor(cluster), y=Flight.Distance)) + 
  geom_boxplot()

  1. Leg.room.service
ggplot( data =airline.2) +
  geom_bar( aes( x=  Leg.room.service)) + 
  facet_wrap( ~ cluster)

  1. Age
ggplot(airline.2, aes(x=as.factor(cluster), y=Age)) + 
  geom_boxplot()

  1. Ease.of.Online.booking
ggplot( data =airline.2) +
  geom_bar( aes( x=  Ease.of.Online.booking)) + 
  facet_wrap( ~ cluster)

由以上圖表可觀察出,最明顯分群的變數為Age,我們以此作為分群依據,並給予商業策略建議。

第一群為45~49歲的壯年。 商務旅行的需求較高,且因經濟能力較好坐商務艙的比例較高,對leg room service的滿意度也較高。 但從觀察的項目中可看出,壯年對機上娛樂的不滿意度有明顯突出,也許航空業者可增加機上娛樂的項目,如數獨、報紙、增加中年人會觀看的電影類別、免稅品品項更多元等,以增加其滿意度。

第二群為24~30歲的青年。 他們對機上娛樂的滿意度較高,因此可維持機上年輕人會觀看的電影類別。 但或許是因辦公需求他們重視機上網路,對機上網路的滿意度不高;online boarding、online booking的容易性、與seat comfort的滿意度跟其他族群比也都相對不滿意。 我們可猜想這是因青年經濟能力還不高,因此坐經濟艙的比例較高(位子較不舒適),而因他們為善於使用資訊產品的世代,對online service的要求也因此比較高。 航空業者可以試圖優化機上的網路速度與優化線上劃位&登機的系統,以增加其滿意度。

第三群為38~40歲的青壯年。 商務旅行的需求較高,且因經濟能力較好坐商務艙的比例較高,他們對leg room service的滿意度也不錯,可持續維持此服務品質。 但在觀察的項目中可看出青壯年對online booking的容易性稍較不滿意,航空業者可以優化網路訂位系統以增加其滿意度。

第四群為9~17歲的小孩與年輕人。 他們搭乘飛機多是與家人同行,且因經濟能力不高,乘坐的class多為經濟艙。 從圖表中可看出他們的分佈和成年人不同,對各項滿意度多為平均散佈,我們可以猜想這是因小孩不太了解這些滿意度變數,而按照當時的心情去填寫問卷所產生的結果。 但我們也可看出此族群對飛機上的網路服務不太滿意,因此若航空業者想提升小孩的滿意度以讓寵溺小孩的父母再次搭乘,他們可以試圖優化機上的網路速度以增加其滿意度。

第五群為54~62歲的中老年人。 他們online boarding的滿意度高,對leg room service的滿意度也高,可持續維持此服務品質。 但online booking的容易性跟其他族群比相對不滿意,也許是因這一族群不善於使用網路的緣故,航空業者可於網頁設立教學專區以提升其滿意度。