熱線電話:13121318867

登錄
首頁精彩閱讀模型驗證的常用武器
模型驗證的常用武器
2016-04-03
收藏
模型驗證的常用武器


分類模型是數據挖掘中應用非常廣泛的算法之一,常用的分類算法有Logistic模型、決策樹、隨機森林、神經網絡、Boosting等。針對同一個數據集,可以有這么多的算法進行分析,那何評估什么樣的模型比較合理呢?本文就講講常用的模型驗證武器,主要包括混淆矩陣、ROC曲線、提升度、增益法和KS統計量。

一、混淆矩陣

混淆矩陣就是如下圖所示的那樣,也是最簡單的一種模型驗證方法:


QQ截圖20160324114443.png


通過混淆矩陣可以算出模型預測精度((a+d)/(a+b+c+d))、正例覆蓋率(b/(c+d))、負例覆蓋率(a/(a+b))等。通過這么些指標綜合考慮模型的預測準確率。

二、ROC曲線

在講解ROC曲線之前,我們先看看幾個定義:


Sensitivity:正確預測到的正例數/實際正例總數,即b/(c+d)

Specificity:正確預測到的負例數/實際負例總數,即a/(a+b)


ROC曲線就是根據這兩個指標值繪制出來的,其中x軸為1-Specificity,y軸為Sensitivity。

通過比較ROC曲線與45°直線可以直觀的反映模型的好壞,但并不能從定量的角度反饋模型好是好到什么程度或模型差是差到什么程度。那么就引申出了AUC的概念,即ROC曲線下的面積。當曲線偏離45°直線越遠,則AUC越大,模型相應就會越好。一般認為AUC在0.75以上,模型就可以接受了。

三、提升度Lift

在講解提升度曲線之前,我們先看看幾個定義:

Pi:測試集中正例的比例,即(c+d)/(a+b+c+d)

Ptp:正確預測到的正例個數占總觀測值的比例,即d/a+b+c+d=Pi1* Sensitivity

Pfp:把負例錯誤地預測成正例的個數占總數的比例,即b/a+b+c+d=(1-Pi1)*(1- Specificity) 

Depth:預測成正例的比例,即b+d/a+b+c+d=Ptp+Pfp

PV_Plus:正確預測到的正例數/預測正例總數,即d/(b+d)=Ptp/depth

提升度Lift=(d/b+d)/(c+d/a+b+c+d)=PV_plus/Pi1


Lift曲線就是根據Depth和Lift兩個指標繪制而成,它反映了預測正例的正真準確率。

四、增益法Gain

其實增益法Gain與提升度是一個事物的兩種說法,從公式中就可以看出:

Gain=d/(b+d)=PV_plus

Gain與提升度相比并沒有除以Pi值。

五、K-S統計量

統計學中,對于單樣本的K-S檢驗就是利用樣本數據來推斷其是否服從某種分布,對于兩樣本的K-S檢驗主要推測的是兩個樣本是否具有相同的分布,對于模型的評估,希望正例的累積概率分布與負例的累積概率分布存在顯著差異。


所以我們使用K-S統計量刻畫模型的優劣,即使正例與負例的累積概率差達到最大。這是一個定量的判斷規則,如下圖所示,為傳統的評價準則

QQ截圖20160324114451.png

通常要求模型KS值在0.4以上。

廢話不多說,下面我們看看如何使用R語言實現這些評估模型的方法。

實例操作:

```{r}

#讀取數據

dmagecr <- read.table(file = file.choose(), head = TRUE, sep = '')


#數據結構

str(dmagecr)

```

QQ截圖20160324114502.png


其中,二分變量good_bad為目標變量,Logistic模型默認將good水平作為感興趣的水平,很顯然對于客戶是否為優質客戶的問題,這里選擇good作為關注對象是錯誤的,下面指定bad水平為興趣水平。


```{r}

#指定感興趣的水平為bad

dmagecr$good_bad <- factor(dmagecr$good_bad, levels = c('good','bad'),ordered = TRUE)


#創建訓練集和測試集

set.seed(1234)

index <- sample(c(1,2), size = nrow(dmagecr), replace = TRUE, prob = c(0.7,0.3))

train <- dmagecr[index == 1,]

test <- dmagecr[index == 2,] 


#構建Logistic模型

model <- glm(formula = good_bad ~ checking+history+duration+savings+property, family = binomial(link = "logit"), data = train)


#模型結果查看

summary(model)

```

QQ截圖20160324114515.png


從上圖的結果可知,模型的預測變量均為顯著,即認為這些變量是模型的重要變量。光有模型的預測變量顯著還不夠,還需要檢測模型是否顯著:


```{r}

#模型的顯著性檢驗

anova(object = model, test = 'Chisq')

```

QQ截圖20160324114524.png


從第一個變量到最后一個變量,逐步加入模型后,模型的偏差檢驗均為顯著,即認為整個模型是通過檢驗的。下面我們再看看模型的擬合優度如何,即模型的預測與實際情況是否吻合或相近,這里使用H-L檢驗:


```{r}

#模型的擬合優度檢驗--HL檢驗

library(sjmisc)

HL_test <- hoslem_gof(x = model)

HL_test

```

QQ截圖20160324114533.png


H-L的P值顯著大于0.05,即接受實際值與預測值相吻合的原假設,再次說明模型是比較理想的。接下來我們就用這個訓練集得到的模型來預測測試集:


```{r}

#模型預測

probility <- predict(object = model, newdata = test[,-21], type = 'response')

predict <- ifelse(probility > 0.5, 'bad', 'good')

#轉型為因子

predict <- factor(predict, levels = c('good','bad'), order = TRUE)

#模型評估混淆矩陣

Freq <- table(test[,21], predict)

#預測精度

Accuracy <- sum(diag(Freq))/sum(Freq)

Freq;Accuracy

```

QQ截圖20160324114546.png


從模型的預測精度來看,準確率為74.2%,模型預測并不理想。除了使用混淆矩陣來評估模型,還可以使用ROC曲線下的面積AUC、提升度Lift、增益法Gain和K-S統計量。下面就深入介紹這幾種方法:


```{r}

#ROC曲線

library(pROC)

roc_curve <- roc(test[,21],probility)

names(roc_curve)

Specificity <- roc_curve$specificities

Sensitivity <- roc_curve$sensitivities

library(ggplot2)

p <- ggplot(data = NULL, mapping = aes(x= 1-Specificity, y = Sensitivity))

p + geom_line(colour = 'red') +geom_abline(intercept = 0, slope = 1)+ annotate('text', x = 0.4, y = 0.5, label=paste('AUC=',round(roc_curve$auc,2)))+ labs(x = '1-Specificity',y = 'Sensitivity', title = 'ROC Curve')

```

QQ截圖20160324114555.png


結果顯示,AUC為0.79,相比于0.75,模型馬馬虎虎還能說的過去。


```{r}

#Lift曲線

Pi <- table(test$good_bad)[2]/sum(table(test$good_bad))

Ptp <- Pi*Sensitivity

Pfp <- (1-Pi)*(1-Specificity)

Depth <- Ptp + Pfp

PV_Plus <- Ptp/Depth

Lift <- PV_Plus/Pi


p <- ggplot(data = NULL, mapping = aes(x= Depth, y = Lift))

p + geom_line(colour = 'blue') + labs(x = 'Depth',y = 'Lift', title = 'Lift Curve')

```

QQ截圖20160324114605.png


提升度一般是這樣使用的:如果某項營銷活動受成本的限制,又想使營銷活動取得非常成功,一般通過Lift曲線進行人員的篩選,即給定某個Lift閾值,反過來確定Depth值。如提升度相比于不作任何模型,使其達到2倍以上的響應,需要設置Depth在前25%以內。同樣,我們還可以繪制Gain曲線:


```{r}

#Gain曲線

p <- ggplot(data = NULL, mapping = aes(x= Depth, y = PV_Plus))

p + geom_line(colour = 'blue')  + labs(x = 'Depth',y = 'PV_Plus', title = 'Gain Curve')

```

QQ截圖20160324114613.png


實際上,Lift曲線與Gain曲線長的一模一樣,只不過是縱坐標不同而已。

胡江堂的基于SAS模型評估系列文章中沒有涉及到K-S統計量的講解,本文就對其作一個拓展,R中還沒有找到直接繪制兩個連續變量的K-S曲線統計量函數,故這里自定義繪制曲線所需數據的函數:

```{r}

#準備K-S數據

ks_data <- as.data.frame(cbind(good_bad=test[,21], probility))

good_ks <- ks_data[which(ks_data$good_bad==1),'probility']

bad_ks <- ks_data[which(ks_data$good_bad==2),'probility']


#自定義計算累計分布函數值

KS_Data <- function(x, y){

  gaps_x <- seq(min(x), max(x), length=1000)

  cauculate_x <- numeric()

for(i in 1:length(gaps_x)){

  cauculate_x[i] <- sum(x<=gaps_x[i])/length(x)

}

  gaps_x <- sort((gaps_x-min(gaps_x))/(max(gaps_x)-min(gaps_x)))

  

  gaps_y <- seq(min(y), max(y), length=1000)

  cauculate_y <- numeric()

for(i in 1:length(gaps_y)){

  cauculate_y[i] <- sum(y<=gaps_y[i])/length(y)

}

  gaps_y <- sort((gaps_y-min(gaps_y))/(max(gaps_y)-min(gaps_y)))

  return(list(df = data.frame(rbind(data.frame(Gaps = gaps_x,Cauculate = cauculate_x,Type = 'Positive'),data.frame(Gaps = gaps_y,Cauculate = cauculate_y,Type = 'Negtive'))), KS = max(abs(cauculate_y-cauculate_x)), x = gaps_y[which.max(abs(cauculate_y-cauculate_x))],y = abs(cauculate_x[which.max(abs(cauculate_y-cauculate_x))]-cauculate_y[which.max(abs(cauculate_y+cauculate_x))])/2))

}


#繪制K-S曲線

ggplot(data = KS_Data(bad_ks,good_ks)$df, mapping = aes(x = Gaps, y = Cauculate, colour = Type)) + geom_line() + theme(legend.position='none') + annotate(geom = 'text', x = KS_Data(bad_ks,good_ks)$x, y = KS_Data(bad_ks,good_ks)$y, label = paste('K-S Value: ', round(KS_Data(bad_ks,good_ks)$KS,2))) + labs(x = 'Probility', y = 'CDF')

QQ截圖20160324114624.png


上圖結果顯示,K-S統計量的值為0.43,根據傳統的評價準則,也說明該模型還是基本行得通的。

數據挖掘實際過程中,需要橫向的比較多個模型評估結果,還需要縱向的比較同一個模型不同參數調整的評估結果。通過上面所說的這些評估方法,終能夠選出一個最理想的模型。


數據分析咨詢請掃描二維碼

若不方便掃碼,搜微信號:CDAshujufenxi

數據分析師資訊
更多

OK
客服在線
立即咨詢
日韩人妻系列无码专区视频,先锋高清无码,无码免费视欧非,国精产品一区一区三区无码
客服在線
立即咨詢