R語言機器學習框架h2o基礎學習教程

h2o高性能機器學習框架教程

本文爲2016年H2O Open Chicago上的內容。html

譯者注:

在使用H2O前你須要:java

  1. 安裝java環境(需下載64位JDK,否則在R中不能控制經過h2o.init()函數來控制 內存)
  2. install.packages("h2o")

h2o相似於python中的sklearn,提供各類機器學習算法接口,咱們須要此類框架的理由:python

  1. 提供統一的接口,代碼更加清晰簡單
  2. 不須要一個模型一個數據格式
  3. 計算速度較快

在R中推薦使用data.table包進行數據清洗,而後使用as.h2o變成h2o包所接受的格式 ,再用h2o包進行數據建模。ios

上面都是個人廢話我的經驗R使用經驗git

下面開始教程:

首先加載h2o包,並在你本地機器上開啓h2o集羣github

library(h2o)
h2o.init(nthreads = -1, #-1表示使用你機器上全部的核
         max_mem_size = "8G")  #max_mem_size參數表示容許h2o使用的最大內存

下面咱們來導入一個已經通過數據清理的關於貸款的一個數據集,咱們的目的是來預測這個貸款是否能按時償還(二分類問題),響應變量bad_loan,1表示未能償還,0表示已經償還。算法

loan_csv <- "https://raw.githubusercontent.com/h2oai/app-consumer-loan/master/data/loan.csv"
data <- h2o.importFile(loan_csv)   #能夠直接從一個URL中導入數據
dim(data) # 163,987 rows x 15 columns

因爲咱們是一個二分類問題,咱們必須指定響應變量爲一個因子類型(factor),若響應變量爲0/1,H2O會認爲他是一個數值,那將意味着H2O會訓練一個迴歸模型網絡

data$bad_loan <- as.factor(data$bad_loan)  #編碼爲因子類型
h2o.levels(data$bad_loan)  #查看因子levels

下面我將數據拆分紅爲訓練集,驗證集與測試集,app

splits <- h2o.splitFrame(data = data, 
                         ratios = c(0.7, 0.15),  #訓練集,驗證集與測試集比例分別爲70%, 15%, 15%
                         seed = 1)  #setting a seed will guarantee reproducibility
train <- splits[[1]]
valid <- splits[[2]]
test <- splits[[3]]

咱們來看下數據各部分的大小,注意h2o.splitFrame函數爲了運行效率採用的是近似拆分方法而不是精確拆分,故你會發現數據大小不是精確的70%, 15%與15%框架

nrow(train)  # 114908
nrow(valid) # 24498
nrow(test)  # 24581

指定因變量與自變量

y <- "bad_loan"
x <- setdiff(names(data), c(y, "int_rate"))  
print(x)
# [1] "loan_amnt"             "term"                 
# [3] "emp_length"            "home_ownership"       
# [5] "annual_inc"            "verification_status"  
# [7] "purpose"               "addr_state"           
# [9] "dti"                   "delinq_2yrs"          
# [11] "revol_util"            "total_acc"            
# [13] "longest_credit_length"

咱們已經將數據準備工做完成(譯者注:在實際應用中咱們須要大量的時間進行特徵工程工做,因爲本文是爲了教授如何建模,故直接使用原始數據),下面咱們將訓練幾個模型,主要的模型包括H20監督算法的:

  1. 廣義線性迴歸模型 (GLM)
  2. 隨機森林模型(RF)
  3. GBM(也稱GBDT)
  4. 深度學習(DL)
  5. 樸素貝葉斯(NB)

1.廣義線性迴歸模型 (GLM)

讓咱們從一個基本的二元廣義線性迴歸開始:默認狀況下h2o.glm採用一個帶正則項的彈性網模型(elastic net model)

glm_fit1 <- h2o.glm(x = x, 
                    y = y, 
                    training_frame = train,
                    model_id = "glm_fit1",
                    family = "binomial")  #與R中`glm`相似,`h2o.glm`有一個family參數

下面咱們將經過驗證集來進行一些自動調參工做,須要設置lambda_search = True。由於咱們的GLM模型是帶正則項的,因此咱們須要找到一個合適的正則項大小來防止過擬合。這個模型參數lambda是控制GLM模型的正則項大小,經過設定lambda_search = TRUE 咱們能自動找到一個lambda 的最優值,這個自動尋找的方法是經過在驗證集上指定一個lambda,驗證集上的最優lambda即咱們要找的lambda

glm_fit2 <- h2o.glm(x = x, 
                    y = y, 
                    training_frame = train,
                    model_id = "glm_fit2",
                    family = "binomial",
                    validation_frame = valid,
                    lambda_search = TRUE)

讓咱們在測試集上看下2個GLM模型的表現:

glm_perf1 <- h2o.performance(model = glm_fit1,
                             newdata = test)
glm_perf2 <- h2o.performance(model = glm_fit2,
                             newdata = test)

若是你不想輸出模型所有的評測對象,咱們也只輸出你想要的那個評測

h2o.auc(glm_perf1)  
h2o.auc(glm_perf2)

比較測試集訓練集驗證集上的AUC

h2o.auc(glm_fit2, train = TRUE)  
h2o.auc(glm_fit2, valid = TRUE)  
glm_fit2@model$validation_metrics

2.隨機森林模型(RF)

H2O的隨機森林算法實現了標準隨機森林算法的分佈式版本和變量重要性的度量,首先咱們使用一個默認參數來訓練一個基礎的隨機森林模型。隨機森林模型將從因變量編碼推斷因變量分佈。

rf_fit1 <- h2o.randomForest(x = x,
                            y = y,
                            training_frame = train,
                            model_id = "rf_fit1",
                            seed = 1) # 設置隨機數以便結果復現.

下面咱們經過設置參數ntrees = 100來增長樹的大小,在H2O中樹的默認大小爲50。一般來講增長樹的大小RF的表現會更好。相比較GBM模型,RF一般更加不易過擬合。在下面的GBM例子中你將會看到咱們須要額外的設置early stopping來防止過擬合。

rf_fit2 <- h2o.randomForest(x = x,
                            y = y,
                            training_frame = train,
                            model_id = "rf_fit2",
                            #validation_frame = valid,  #only used if stopping_rounds > 0
                            ntrees = 100,
                            seed = 1)

# 比較2個RF模型的性能
rf_perf1 <- h2o.performance(model = rf_fit1,
                            newdata = test)
rf_perf2 <- h2o.performance(model = rf_fit2,
                            newdata = test)
rf_perf1
rf_perf2

# 提取測試集AUC
h2o.auc(rf_perf1)  
h2o.auc(rf_perf2)

交叉驗證

有時咱們會不設定驗證集,而直接使用交叉驗證來看模型的表現。下面咱們將使用隨機森林做爲例子,來展現使用H2O進行交叉驗證。你不須要自定義代碼或循環,您只需在nfolds參數中指定所需折的數量。注意k-折交叉驗證將會訓練k個模型,故時間是原來額k倍

rf_fit3 <- h2o.randomForest(x = x,
                            y = y,
                            training_frame = train,
                            model_id = "rf_fit3",
                            seed = 1,
                            nfolds = 5)

# 評估交叉訓練的auc
h2o.auc(rf_fit3, xval = TRUE)

3. Gradient Boosting Machine(gbdt/gbm)

H2O的GBM提供了一個隨機GBM,向較原始的GBM會有一點性能上的提高。如今咱們來訓練一個基礎的GBM模型。

若是沒有經過distribution參數明確指定,則GBM模型將從因變量編碼推斷因變量分佈。

gbm_fit1 <- h2o.gbm(x = x,
                    y = y,
                    training_frame = train,
                    model_id = "gbm_fit1",
                    seed = 1)# 設置隨機數以便結果復現.

下面咱們將經過設置ntrees=500來增長GBM中樹的數量。H2O中默認樹的數量爲50,因此此次GBM的運行時間會是默認狀況的10倍。增長樹的個數是一般會提升模型的性能,可是你必須當心,使用那麼多樹有可能會致使過擬合。你能夠經過設置

early stopping來自動尋找最優的樹的個數。在後面的例子中咱們會討論 early stopping.

gbm_fit2 <- h2o.gbm(x = x,
                    y = y,
                    training_frame = train,
                    model_id = "gbm_fit2",
                    #validation_frame = valid,  #only used if stopping_rounds > 0
                    ntrees = 500,
                    seed = 1)

下面咱們仍然會設置ntrees = 500,但此次咱們會設置early stopping來防止過擬合。全部的H2O算法都提供early stopping然而在默認狀況下是不啓用的(除了深度學習算法)。這裏有幾個參數設置來控制early stopping,全部參數共有以下3個參數:stopping_rounds, stopping_metric and stopping_tolerance.

stopping_metric參數是你的評測函數,在這裏咱們使用AUC。

score_tree_interval參數是隨機森林和GBM的特有參數。設置score_tree_interval = 5將在每五棵樹以後計算得分。

咱們下面設置的參數指定模型將在三次評分間隔後中止訓練,若AUC增長沒有超過0.0005。

因爲咱們指定了一個驗證集,因此將在驗證集上計算AUC的stopping_tolerance,而不是訓練集AUC

gbm_fit3 <- h2o.gbm(x = x,
                    y = y,
                    training_frame = train,
                    model_id = "gbm_fit3",
                    validation_frame = valid,  #only used if stopping_rounds > 0
                    ntrees = 500,
                    score_tree_interval = 5,      #used for early stopping
                    stopping_rounds = 3,          #used for early stopping
                    stopping_metric = "AUC",      #used for early stopping
                    stopping_tolerance = 0.0005,  #used for early stopping
                    seed = 1)


# GBM性能比較
gbm_perf1 <- h2o.performance(model = gbm_fit1,
                             newdata = test)
gbm_perf2 <- h2o.performance(model = gbm_fit2,
                             newdata = test)
gbm_perf3 <- h2o.performance(model = gbm_fit3,
                             newdata = test)
gbm_perf1
gbm_perf2
gbm_perf3

# 提取測試集AUC
h2o.auc(gbm_perf1)  
h2o.auc(gbm_perf2)  
h2o.auc(gbm_perf3)

爲了檢查評分歷史,請在已經訓練的模型上使用scoring_history方法,若不指定,它會計算不一樣間隔的得分,請參閱下面h2o.scoreHistory()gbm_fit2只使用了訓練集沒有使用驗證集,故只對訓練集來計算模型的歷史得分。

只有使用訓練集(無驗證集)對「gbm_fit2」進行訓練,所以僅爲訓練集績效指標計算得分記錄。

h2o.scoreHistory(gbm_fit2)

當使用early stopping時,咱們發現咱們只使用了95棵樹而不是所有的500棵。因爲咱們在gbm_fit3中使用了驗證集,訓練集與驗證集的歷史得分都被存儲了下來。咱們來觀察驗證集的AUC,以確認stopping tolerance是否被強制執行。

h2o.scoreHistory(gbm_fit3)
# 查看下這個模型的歷史得分
plot(gbm_fit3, 
     timestep = "number_of_trees", 
     metric = "AUC")
plot(gbm_fit3, 
     timestep = "number_of_trees", 
     metric = "logloss")

4.深度學習(DL)

H2O的深度學習算法是多層前饋人工神經網絡,它也能夠用於訓練自動編碼器。 在這個例子中,咱們將訓練一個標準的監督預測模型。

首先咱們將使用默認參數訓練一個基礎深度學習模型,若是沒有經過distribution參數明確指定,則DL模型將從因變量編碼推斷因變量分佈。若H2O的DL算法運行在多核上,那麼H2O的DL算法將沒法重現。因此在這個例子中,下面的性能指標可能與你在機器上看到的不一樣。在H2O的DL中,默認狀況下啓用early stopping,因此下面的訓練集中將會默認使用early stopping參數來 進行early stopping

dl_fit1 <- h2o.deeplearning(x = x,
                            y = y,
                            training_frame = train,
                            model_id = "dl_fit1",
                            seed = 1)

用新的結構和更多的epoch訓練DL。下面咱們經過設置epochs=20來增長epochs,默認爲10。

一般來講增長epochs深度神經網絡的表現會更好。相比較GBM模型,RF一般更加不易過擬合。在下面的GBM例子中你將會看到咱們須要額外的設置early stopping來防止過擬合。可是你必須當心,不要過擬合你的數據。你能夠經過設置

early stopping來自動尋找最優的epochs數。與其餘H2O中的算法不一樣,H2O的深度學習算法會默認使用early stopping 因此爲了比較咱們先不使用 early stopping,經過設置stopping_rounds=0

dl_fit2 <- h2o.deeplearning(x = x,
                            y = y,
                            training_frame = train,
                            model_id = "dl_fit2",
                            #validation_frame = valid,  #only used if stopping_rounds > 0
                            epochs = 20,
                            hidden= c(10,10),
                            stopping_rounds = 0,  # 禁用 early stopping
                            seed = 1)

使用 early stopping來訓練DL模型。

此次咱們會使用跟 dl_fit2相同的參數,並在這基礎上加上early stopping。經過驗證集來進行early stopping

dl_fit3 <- h2o.deeplearning(x = x,
                            y = y,
                            training_frame = train,
                            model_id = "dl_fit3",
                            validation_frame = valid,  #in DL, early stopping is on by default
                            epochs = 20,
                            hidden = c(10,10),
                            score_interval = 1,           #used for early stopping
                            stopping_rounds = 3,          #used for early stopping
                            stopping_metric = "AUC",      #used for early stopping
                            stopping_tolerance = 0.0005,  #used for early stopping
                            seed = 1)


#比較一下這3個模型
dl_perf1 <- h2o.performance(model = dl_fit1,
                            newdata = test)
dl_perf2 <- h2o.performance(model = dl_fit2,
                            newdata = test)
dl_perf3 <- h2o.performance(model = dl_fit3,
                            newdata = test)
dl_perf1
dl_perf2
dl_perf3
# 提取驗證集AUC
h2o.auc(dl_perf1)  
h2o.auc(dl_perf2)  
h2o.auc(dl_perf3)  
# 計算曆史得分
h2o.scoreHistory(dl_fit3)
# 查看第三個DL模型的歷史得分
plot(dl_fit3, 
     timestep = "epochs", 
     metric = "AUC")

5. 樸素貝葉斯(NB)

樸素貝葉斯算法(NB)在效果上一般會比RF與GBM差,但它仍然是一個受歡迎的算法,尤爲在文本領域(例如,當您的輸入文本被編碼爲「詞袋」時"Bag of Words")。樸素貝葉斯算法只能用做二分類與多分類任務,不能用做迴歸。所以響應變量必須是因子類型,不能是數值類型。

首先咱們使用默認參數來訓練一個基礎的NB模型。

nb_fit1 <- h2o.naiveBayes(x = x,
                          y = y,
                          training_frame = train,
                          model_id = "nb_fit1")

下面咱們使用拉普拉斯平滑來訓練NB模型。樸素貝葉斯算法的幾個可調模型參數之一是拉普拉斯平滑的量。默認狀況下不會使用拉普拉斯平滑。

nb_fit2 <- h2o.naiveBayes(x = x,
                          y = y,
                          training_frame = train,
                          model_id = "nb_fit2",
                          laplace = 6)

# 比較2個NB模型
nb_perf1 <- h2o.performance(model = nb_fit1,
                            newdata = test)
nb_perf2 <- h2o.performance(model = nb_fit2,
                            newdata = test)
nb_perf1
nb_perf2
# 提取測試集 AUC
h2o.auc(nb_perf1)  
h2o.auc(nb_perf2)
相關文章
相關標籤/搜索