本文爲2016年H2O Open Chicago上的內容。html
在使用H2O前你須要:java
h2o.init()
函數來控制 內存)install.packages("h2o")
h2o
相似於python中的sklearn
,提供各類機器學習算法接口,咱們須要此類框架的理由:python
在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監督算法的:
讓咱們從一個基本的二元廣義線性迴歸開始:默認狀況下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
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)
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")
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")
樸素貝葉斯算法(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)