\(H_2 O\) 헬로 월드를 찍고, \(H_2 O\) 클러스터로 데이터를 가져오는 작업과 \(H_2 O\) 클러스터와 R 협업 과정을 이해한다. 일반화 선형모형을 \(H_2 O\) 클러스터 내 데이터프레임 데이터로 예측모형으로 적용하는 것을 목표로 한다.
R에서 \(H_2 O\) 설치는 install.packages
명령어를 통해 간단히 구현된다. 만약 기존 \(H_2 O\) 팩키지가 설치되어 있다면 제거하고, install.packages
명령어로 설치한다. 단순히 install.packages("h2o")
설치하고 h2o.getVersion()
명령어로 최신 버전이 설치된 것을 확인한다.
##=========================================================================
## 01. H2O 설치:
##=========================================================================
# 기존 H2O 제거
# The following two commands remove any previously installed H2O packages for R.
if ("package:h2o" %in% search()) { detach("package:h2o", unload=TRUE) }
if ("h2o" %in% rownames(installed.packages())) { remove.packages("h2o") }
# 새로 깔끔하게 H2O 설치
install.packages("h2o", repos=(c("http://s3.amazonaws.com/h2o-release/h2o/master/1497/R", getOption("repos"))))
library(h2o)
만약 자바가 설치되지 않는 경우 다음 명령어를 통해 자바를 설치한다. 64비트 버젼이 필요하다. 32비트 자바가 설치되어 있다면 64비트 버젼으로 새로 설치해야만 된다. 추가로 스파크 의존성이 있기 때문에 단독형 스파크 설치 - PC/노트북, EC2 원격 컴퓨터 설치내용도 참조한다.
로컬 컴퓨터, 아마존 EC2, 하둡 서버 위 어디든 다음 명령어로 \(H_2 O\) 인스턴스를 띄울 수 있다.
\(H_2 O\) 클러스터가 생성되면, 클러스터 노드 하나를 잡아서 h2o.init
명령어로 IP 주소와 포트를 인자로 넘겨 연결을 초기화한다.
library(h2o)
localH2O <- h2o.init(ip = 'localhost', port = 54321, max_mem_size = '4g', nthreads = -1)
Connection successful!
R is connected to the H2O cluster:
H2O cluster uptime: 13 minutes 7 seconds
H2O cluster timezone: Asia/Seoul
H2O data parsing timezone: UTC
H2O cluster version: 3.20.0.8
H2O cluster version age: 3 months and 13 days !!!
H2O cluster name: H2O_started_from_R_victorlee_lyi311
H2O cluster total nodes: 1
H2O cluster total memory: 3.54 GB
H2O cluster total cores: 4
H2O cluster allowed cores: 4
H2O cluster healthy: TRUE
H2O Connection ip: localhost
H2O Connection port: 54321
H2O Connection proxy: NA
H2O Internal Security: FALSE
H2O API Extensions: Algos, AutoML, Core V3, Core V4
R Version: R version 3.5.1 (2018-07-02)
[1] "3.20.0.8"
Are you sure you want to shutdown the H2O instance running at http://localhost:54321/ (Y/N)?
웹브라우저를 열ㄹ고 http://localhost:54321/flow/index.html
주소창에 입력하게 되면 \(H_2 O\) FLOW를 사용해서 GUI 방식으로 데이터 분서과 기계학습모형을 제작할 수 있다.
h2o.clusterInfo()
혹은 h2o.clusterInfo(localH2O)
명령어를 통해 구성된 클러스터 정보를 확인한다.
R is connected to the H2O cluster:
H2O cluster uptime: 13 minutes 8 seconds
H2O cluster timezone: Asia/Seoul
H2O data parsing timezone: UTC
H2O cluster version: 3.20.0.8
H2O cluster version age: 3 months and 13 days !!!
H2O cluster name: H2O_started_from_R_victorlee_lyi311
H2O cluster total nodes: 1
H2O cluster total memory: 3.54 GB
H2O cluster total cores: 4
H2O cluster allowed cores: 4
H2O cluster healthy: TRUE
H2O Connection ip: localhost
H2O Connection port: 54321
H2O Connection proxy: NA
H2O Internal Security: FALSE
H2O API Extensions: Algos, AutoML, Core V3, Core V4
R Version: R version 3.5.1 (2018-07-02)
\(H_2 O\) 클러스터를 h2o.shutdown
명령어로 종료시킨다.
h2o.importFile
명령어를 HTTP REST API를 통해 \(H_2 O\) 클러스터에 전송을 하게 되면 \(H_2 O\) 클러스터는 데이터저장소를 찾아 데이터를 요청하게 된다.
다른 특별한 사항이 없다면 데이터 저장소에서 \(H_2 O\) 클러스터로 데이터가 공급되고, \(H_2 O\) 분산 데이터프레임
이 \(H_2 O\) 클러스터에 생성되고, 작업 실행결과가 REST API JSON 응답으로 반환되고, R 내부에는 h2o_df
데이터프레임이 생성된다. 하지만, 로컬 컴퓨터 R에는 클러스터 IP, 클러스터 포트, \(H_2 O\) 분산 데이터프레임을 지시하는 포인터정보가 보관된다.
\(H_2 O\) 데이터를 가져오는 경우 \(H_2 O\)에 나온 설명과 차이가 나서 돌아가지 않는 경우가 있다. 활발히 성능개선이 꾸준히 일어나다 보니 문서와 코드가 맞지 않으니 가장 최신 \(H_2 O\) 도움말을 참조하거나, 가장 최신 코드를 뜯어보고 사용하면 된다. 늘 오픈소스 소프트웨어를 사용하면 발생되는 사항이니 절대로 당황하지 않는다.
##=========================================================================
## 02. Data import
##=========================================================================
irisPath <- system.file("extdata", "iris.csv", package="h2o")
iris.hex <- h2o.importFile(path = irisPath, destination_frame = "iris.hex")
|
| | 0%
|
|=================================================================| 100%
C1 C2 C3 C4
Min. :4.300 Min. :2.000 Min. :1.000 Min. :0.100
1st Qu.:5.100 1st Qu.:2.800 1st Qu.:1.600 1st Qu.:0.300
Median :5.800 Median :3.000 Median :4.350 Median :1.300
Mean :5.843 Mean :3.054 Mean :3.759 Mean :1.199
3rd Qu.:6.400 3rd Qu.:3.300 3rd Qu.:5.100 3rd Qu.:1.800
Max. :7.900 Max. :4.400 Max. :6.900 Max. :2.500
C5
Iris-setosa :50
Iris-versicolor:50
Iris-virginica :50
[1] "C:/Program Files/R/R-3.5.1/library/h2o/extdata/iris.csv"
C1 C2 C3 C4
Min. :4.300 Min. :2.000 Min. :1.000 Min. :0.100
1st Qu.:5.100 1st Qu.:2.800 1st Qu.:1.600 1st Qu.:0.300
Median :5.800 Median :3.000 Median :4.350 Median :1.300
Mean :5.843 Mean :3.054 Mean :3.759 Mean :1.199
3rd Qu.:6.400 3rd Qu.:3.300 3rd Qu.:5.100 3rd Qu.:1.800
Max. :7.900 Max. :4.400 Max. :6.900 Max. :2.500
C5
Iris-setosa :50
Iris-versicolor:50
Iris-virginica :50
항공사 데이터셋(allyear2k.csv) 파일을 다운로드 받아 로컬 컴퓨터 원하는 디렉토리에 저장을 한 후, h2o.importFile
명령어로 데이터를 불러온다.
#-------------------------------------------------------------------------
# 2.2. 외부 CSV 데이터 불러오기
#-------------------------------------------------------------------------
# download.file(url="https://s3.amazonaws.com/h2o-airlines-unpacked/allyears2k.csv", destfile = "data/allyears2k.csv")
pathToAirlines <- normalizePath("data/allyears2k.csv")
airlines.hex <- h2o.importFile(path = pathToAirlines, destination_frame = "airlines.hex")
|
| | 0%
|
|============================================= | 69%
|
|=================================================================| 100%
Year Month DayofMonth DayOfWeek
Min. :1987 Min. : 1.000 Min. : 1.0 Min. :1.000
1st Qu.:1992 1st Qu.: 1.000 1st Qu.: 6.0 1st Qu.:2.000
Median :1998 Median : 1.000 Median :14.0 Median :4.000
Mean :1998 Mean : 1.409 Mean :14.6 Mean :3.821
3rd Qu.:2003 3rd Qu.: 1.000 3rd Qu.:23.0 3rd Qu.:5.000
Max. :2008 Max. :10.000 Max. :31.0 Max. :7.000
DepTime CRSDepTime ArrTime CRSArrTime UniqueCarrier
Min. : 1 Min. : 0 Min. : 1 Min. : 0 US:18729
1st Qu.: 929 1st Qu.: 910 1st Qu.:1118 1st Qu.:1109 UA: 9434
Median :1330 Median :1320 Median :1527 Median :1516 WN: 6170
Mean :1346 Mean :1313 Mean :1505 Mean :1485 HP: 3451
3rd Qu.:1735 3rd Qu.:1720 3rd Qu.:1917 3rd Qu.:1903 PS: 3212
Max. :2400 Max. :2359 Max. :2400 Max. :2359 DL: 935
NA's :1086 NA's :1195
FlightNum TailNum ActualElapsedTime CRSElapsedTime
Min. : 1.0 UNKNOW : 179 Min. : 16.0 Min. : 17
1st Qu.: 204.0 000000 : 124 1st Qu.: 71.0 1st Qu.: 71
Median : 557.0 <0xE4>NKNO<0xE6>: 114 Median :101.0 Median :102
Mean : 818.8 0 : 66 Mean :124.8 Mean :125
3rd Qu.:1242.0 N912UA : 59 3rd Qu.:151.0 3rd Qu.:151
Max. :3949.0 N316AW : 56 Max. :475.0 Max. :437
NA :16024 NA's :1195 NA's :13
AirTime ArrDelay DepDelay Origin Dest
Min. : 14.0 Min. :-63.000 Min. :-16.00 DEN:3558 PHX:9317
1st Qu.: 61.0 1st Qu.: -6.000 1st Qu.: -2.00 PIT:3241 PHL:4482
Median : 91.0 Median : 2.000 Median : 1.00 ORD:2246 PIT:3020
Mean :114.3 Mean : 9.317 Mean : 10.01 BUR:2021 ORD:2103
3rd Qu.:140.0 3rd Qu.: 14.000 3rd Qu.: 10.00 CLT:1781 CLT:1542
Max. :402.0 Max. :475.000 Max. :473.00 PHL:1632 DEN:1470
NA's :16649 NA's :1195 NA's :1086
Distance TaxiIn TaxiOut Cancelled
Min. : 11.0 Min. : 0.000 Min. : 0.00 Min. :0.00000
1st Qu.: 326.0 1st Qu.: 3.000 1st Qu.: 9.00 1st Qu.:0.00000
Median : 541.0 Median : 5.000 Median : 12.00 Median :0.00000
Mean : 730.2 Mean : 5.381 Mean : 14.17 Mean :0.02469
3rd Qu.: 920.0 3rd Qu.: 6.000 3rd Qu.: 16.00 3rd Qu.:0.00000
Max. :3365.0 Max. :128.000 Max. :254.00 Max. :1.00000
NA's :35 NA's :16026 NA's :16024
CancellationCode Diverted CarrierDelay WeatherDelay
B : 93 Min. :0.000000 Min. : 0.000 Min. : 0.0000
A : 81 1st Qu.:0.000000 1st Qu.: 0.000 1st Qu.: 0.0000
C : 47 Median :0.000000 Median : 0.000 Median : 0.0000
NA:43757 Mean :0.002479 Mean : 4.048 Mean : 0.2894
3rd Qu.:0.000000 3rd Qu.: 0.000 3rd Qu.: 0.0000
Max. :1.000000 Max. :369.000 Max. :201.0000
NA's :35045 NA's :35045
NASDelay SecurityDelay LateAircraftDelay IsArrDelayed
Min. : 0.000 Min. : 0.00000 Min. : 0.00 YES:24441
1st Qu.: 0.000 1st Qu.: 0.00000 1st Qu.: 0.00 NO :19537
Median : 0.000 Median : 0.00000 Median : 0.00
Mean : 4.855 Mean : 0.01702 Mean : 7.62
3rd Qu.: 0.000 3rd Qu.: 0.00000 3rd Qu.: 0.00
Max. :323.000 Max. :14.00000 Max. :373.00
NA's :35045 NA's :35045 NA's :35045
IsDepDelayed
YES:23091
NO :20887
lubridate
팩키지의 정확한 시간 계산 함수를 사용해서 비행기 출발시간과 도착시간을 계산하여야 하나 편의상 데이터 전처리과정만을 맛보기로 보여주는 \(H_2 O\) R 코드는 다음과 같다.
DepTime
, ArrTime
변수에서 나머지를 구하는 연산자 %%
을 사용하여 전체를 분으로 환산하고, 총합을 빼는 로직으로 비행기 이동시간을 산출한다.
##=========================================================================
## 03. H2O 데이터 정제 과정
##=========================================================================
## 비행기 출발시간
depHour <- airlines.hex$DepTime %/% 100
depMin <- airlines.hex$DepTime %% 100 ## R 나머지 연산자
depTime <- depHour*60 + depMin
## 비행기 도착시간
arrHour <- airlines.hex$ArrTime %/% 100
arrMin <- airlines.hex$ArrTime %% 100 ## R 나머지 연산자
arrTime <- arrHour*60 + arrMin
## 비행기 이동시간을 계산하여 데이터프레임에 변수로 추가
airlines.hex$airliner_duration <- arrTime - depTime
summary(airlines.hex$airliner_duration, exact_quantiles=TRUE)
airliner_duration
Min. :-1408.00
1st Qu.: 67.00
Median : 95.00
Mean : 94.94
3rd Qu.: 140.00
Max. : 570.00
NA's :1195
비행기 연착에 대한 예측모형을 개발 할 때 일반화 선형모형 h2o.glm
함수를 사용할 경우, REST API를 통해 JSON을 통해 POST
요청을 HTTP, TCP/IP 요청을 보내면 \(H_2 O\) 클러스터에서 이를 받아 맵리듀스 작업을 통해 GLM 모형을 분산해서 작업처리하고 이 결과값을 K/V 스토어 프레임워크에서 그대로 HTTP, TCP/IP 네트워크 계층을 통해 REST API JSON 응답으로 반환한다.
GLM 모형 적합 과정이 끝났기 때문에 GET
요청을 통해 GLM 예측모형 결과를 반환해서 볼 수 있다. 이와 같이 \(H_2 O\)는 계층으로 구분되고 API 호출을 통해 작업이 이루어지는 것을 쉽게 확인할 수 있다.
h2o.glm
함수를 통해 일반화 선형모형 적합을 한다.
y <- "IsArrDelayed"
X <- c("Year", "Month", "DayofMonth", "DayOfWeek", "CRSDepTime", "UniqueCarrier", "Origin", "Dest", 'Distance')
airlines.glm <- h2o.glm(y=y, x=X, training_frame = airlines.hex, family = "binomial", nfolds = 1)
|
| | 0%
|
|===== | 8%
|
|=================================================================| 100%
Model Details:
==============
H2OBinomialModel: glm
Model Key: GLM_model_R_1546566305096_167
GLM Model: summary
family link regularization
1 binomial logit Elastic Net (alpha = 0.5, lambda = 1.286E-4 )
number_of_predictors_total number_of_active_predictors
1 282 174
number_of_iterations training_frame
1 6 RTMP_sid_ab5b_97
H2OBinomialMetrics: glm
** Reported on training data. **
MSE: 0.2292239
RMSE: 0.4787734
LogLoss: 0.6494671
Mean Per-Class Error: 0.4635289
AUC: 0.6531433
Gini: 0.3062866
R^2: 0.07155948
Residual Deviance: 57124.52
AIC: 57474.52
Confusion Matrix (vertical: actual; across: predicted) for F1-optimal threshold:
NO YES Error Rate
NO 2254 17283 0.884629 =17283/19537
YES 1037 23404 0.042429 =1037/24441
Totals 3291 40687 0.416572 =18320/43978
Maximum Metrics: Maximum metrics at their respective thresholds
metric threshold value idx
1 max f1 0.384441 0.718708 330
2 max f2 0.218280 0.862275 391
3 max f0point5 0.547815 0.650912 204
4 max accuracy 0.479810 0.614307 261
5 max precision 0.905358 0.920635 5
6 max recall 0.171626 1.000000 398
7 max specificity 0.923419 0.999898 0
8 max absolute_mcc 0.562560 0.220240 191
9 max min_per_class_accuracy 0.547815 0.609971 204
10 max mean_per_class_accuracy 0.551838 0.610573 200
Gains/Lift Table: Extract with `h2o.gainsLift(<model>, <data>)` or `h2o.gainsLift(<model>, valid=<T/F>, xval=<T/F>)`
Scoring History:
timestamp duration iterations negative_log_likelihood
1 2019-01-04 10:58:27 0.000 sec 0 30209.23396
2 2019-01-04 10:58:27 0.024 sec 1 28613.08490
3 2019-01-04 10:58:27 0.036 sec 2 28584.52677
4 2019-01-04 10:58:27 0.047 sec 3 28584.22829
5 2019-01-04 10:58:27 0.079 sec 4 28569.76940
6 2019-01-04 10:58:27 0.091 sec 5 28562.73042
7 2019-01-04 10:58:27 0.115 sec 6 28562.26209
objective
1 0.68692
2 0.65412
3 0.65366
4 0.65366
5 0.65346
6 0.65344
7 0.65344
Variable Importances: (Extract with `h2o.varimp`)
=================================================
Standardized Coefficient Magnitudes: standardized coefficient magnitudes
names coefficients sign
1 Origin.HPN 0.998666 POS
2 Dest.HNL 0.966070 NEG
3 Origin.BOI 0.948073 NEG
4 Origin.MDW 0.932842 POS
5 Origin.ERI 0.913336 POS
---
names coefficients sign
278 Origin.TLH 0.000000 POS
279 Origin.TUL 0.000000 POS
280 Origin.TYS 0.000000 POS
281 Origin.UCA 0.000000 POS
282 UniqueCarrier.DL 0.000000 POS
283 NA NA