資料處理流程
- 資料前處理
- 簡單的Feature Engineering
- 只保留Cabin的艙位號(前面的字母)。
- 把Name中的有一定含義的 title 元素提取出來,並將比較少用的title合併到比較常用的tittle中,建立一個新的類別“Title”
- 把姓氏提取出來,創建新的類別“Surname”
- Missing Data
- NA值 & 空白值
- 減少資料量
- 屬性的篩選:刪掉不要的屬性
- 正規化處理
- 簡單的Feature Engineering
- 模型的建立
- 隨機森林(Random Forest)
- SVM(Support Vector Machines)
- GBM(Gradient Boosting Machine)
- 模型的解釋
- 預測及分析
- 混淆矩陣
- ROC
- AUC
資料前處理
簡單的Feature Engineering:
- 只保留Cabin的艙位號(前面的字母)。
- 把Name中的有一定含義的 title 元素提取出來,並將比較少用的title合併到比較常用的tittle中,建立一個新的類別“Title”
- 把姓氏提取出來,創建新的類別“Surname”
Missing data:
NA值主要來自Age和Cabin(Survived的缺失值,是test中填補的NA)
方法:這邊我們選擇用mice填補Age和Fare的缺失值
查看填補之後的結果:
空值:只來自Embarked
查看Embarked的類別及各個類別的資料筆數,選擇資料筆數最的類別(“S”)填補填補到Embarked的空值中
減少資料量:
屬性的篩選:刪掉不要的屬性
- Name & Surname:類別太多了,並且沒有什麼特別的用途。
- Ticket:裡面都是一些隨機的數字,沒有特多含義,並且是多值屬性不好處理。
- Cabin:有太多的NA值,並且為類別變數不好填充,如果給一個Ncabin的類別,會使得屬性非常unbalance。
- PassengerId:只是一個序列號,沒有太多的含義。
Data 正規化:
數值變量的range沒有特別的大,所以沒有做特別的正規化處理
模型的建立
因為test 資料集中沒有“Survuved”欄位,所以我們從train資料集中分出30%作為驗證集。
剩下的train中的70%資料用於訓練模型,訓練中也會做cross-validation。
下面建立了三個模型:
- 隨機森林(Random Forest)
- SVM(Support Vector Machines)
- GBM(Gradient Boosting Machine)
- ⚠️ KNN一般可以作為分類的baseline
隨機森林:
# 隨機森林
set.seed(100)
titanic_rf <- train(factor(Survived) ~ ., data=train_data, method='rf',
trControl=trainControl(method="cv", number=5))
titanic_rf
plot(titanic_rf)
我們可以看出選擇出的最好的模型是mtry = 3的時候。
SVM:
# SVM
set.seed(100)
titanic_svm <- train(factor(Survived) ~., data=SVMtrain_data, method='svmRadial', preProcess= c('center', 'scale'),
trControl= trainControl(method="cv", number=5, classProbs = T))
titanic_svm
plot(titanic_svm
我們可以看出最好的模型是 sigma=0.2828,C=0.25的時候。
GBM:
# (GBM) model
set.seed(100)
titanic_gbm <- train(factor(Survived) ~., data=train_data, method='gbm', preProcess= c('center', 'scale'),
trControl=trainControl(method="cv", number=7), verbose=FALSE)
print(titanic_gbm)
plot(titanic_gbm)
我們可以看出GBM選出的最好的模型是n.trees=200,且深度為3 interaction.depth = 3的模型。
模型的解釋
這裡直接利用library("DALEX")
包的解釋函數對三個模型進行解釋性分析
累積殘差分佈:
由上圖我們可以看,綠色的線在最上方,也就是SVM中大部分的樣本殘差都比較大。而紅色的線是RF模型,它的大部分的樣本殘差都比較小。可以看出樹的模型的殘差線對於SVM這類的模型都要來的比較小一些。
變數重要性分析:
可以看出三個模型中的變數重要性的排序基本上是一樣的。
測試訓練好的模型並分析結果
我們用之前從train的資料集中分出的valid資料來做各個模型的測試
# 使用不同的已經訓練好的模型分類預測:
rf_probs = predict(titanic_rf,valid_feature,type = "prob") # 訓練集中的預測情形
svm_probs = predict(titanic_svm,valid_feature,type = "prob")
gbm_probs = predict(titanic_gbm,valid_feature,type = "prob")
預測出來的結果(這邊僅以Random Forrest的處理過程為例):
如圖:
# 查看訓練集的預測情形
rf_summaryvalid <- rf_validDataPred %>%
filter(yes > 0.5) %>% # yes 為預測存活下來的機率
summarise(count = n(),
accuracy_rate = mean(Survived)) # 統計預測存活下來的人數與實際比較的準確率
rf_summaryvalid
# count accuracy_rate
# 106 0.6981132
我們將是否存活的機率的門檻設置為0.5,我們可以看到計算出來的準確率為:0.6981132
我們想了解不同門檻值的預測情況,所以就先粗略切了[0,0.5,0.55,0.6,0.65,0.7,0.8,1]這些區間來看看,是否有更好的門檻值設定。
# 查看測試集分類機率在不同門檻值下的預測情況
rf_summaryvalidCut <- rf_validDataPred %>%
# 看不同的分類機率做區間查看其準確率
mutate(interval = cut(yes,breaks = c(0,0.5,0.55,0.6,0.65,0.7,0.8,1),include.lowest = T)) %>%
group_by(interval) %>%
summarise(count = n(),
accuracy_rate = mean(Survived))
rf_summaryvalidCut
根據下表的分佈情況似乎切在0.8左右會更好
混淆矩陣 :
那麼我將預測結果依照分類機率大於0.8當成1來建立混淆矩陣,並對三個模型都建立了混淆矩陣來進行對比:
可以看出三個模型:
-
預測的準確率(Accuracy)以及F1 Score 最高的都是 Random Forrest
-
三個模型主要犯的都是FN(false negative)的錯誤,既將實際存活的人判斷為了死亡。
-
同時我們可以看到SVM在準確率(Accuracy)上和其他兩個模型相差的並不多,但是 F1 Score 的分數就要比其他兩個模型低很多。
- Accuracy = (TP+TN)/(TP+FP+FN+TN)
- Recall = TP/(TP+FN)
- Precision = TP/(TP+FP)
- F1-score = 2 * Precision * Recall / (Precision + Recall)
那麼我們可以根據F1-score 的公式看出他是Precision和Recall两者調和平均,而Precision和Recall两者可以比較好的度量分類錯誤的情況。所以我們可以推測出SVM的模型對於FP和FN的判斷不是很好,但對於TP和TN的預測效果還是可以的。
ROC:
上面的混淆矩陣我是透過比較粗糙的方式切出的 0.8 作為門檻來進行三個模型的比較的。
但是想進一步比較三個模型效果還是應該來看一個更為細緻的ROC曲線和AUC的值。
紅線為:Random Forest
- 最佳的切分值:0.835 or 0.737
綠線為:SVM
- 最佳的切分值:0.808 or 0.798
藍線為:GBM
- 最佳的切分值:0.885 or 0.717
在ROC的圖中越是靠近左上角的部分他的TPR越大而FPR越小,也就是模型的效果就越好。可以看出藍線和紅線都完全包裹在綠線的外面,所以我們可以認為Random Forest和GBM做為這個資料集的分類器效果都比SVM更好。而Random Forest和GBM的比較我們我們只從ROC不能看出哪一個模型比較好,所以我們需要進一步分析兩個模型的AUC值。
AUC:
AUC也就是ROC曲線下方的面積,AUC值越大的分類器,正確率越高。
根據 AUC 比較模型的效果也就是:Random Forest(0.844) > GBM(0.836) > SVM(0.795)