H2O AI Machine Learning
H2O AI is a scalable, open-source, and distributed in-memory machine learning platform. You can learn more about it here: H2O Open Source Machine Learning Platform
StataCorp is experimenting with integrating H2O into Stata. Ordinarily experimental features like this are kept in-house until ready for release, but in this instance StataCorp believes the feedback it can get from the community will be greatly beneficial to further development.
In order to use H2O you first need to install it. For instructions on how to do this check out our H2O Installation Guide
Starting an H2O Cluster
Once H2O is installed, you need to either initialise a new H2O cluster or connect to an existing one. It is possible to use the command h2o connect to connect to an existing cluster that has been made accessible across a network. For this introduction we will focus on initialising a cluster using the command h2o init. When you initialise a cluster in Stata, one will be created on your local machine and external access to it will be limited. Stata will automatically connect you to it.
. h2o init
Connecting to the H2O cluster running at http://127.0.0.1:54321.....not found.
Starting a new cluster running at http://127.0.0.1:54321.
Connecting to the H2O cluster running at http://127.0.0.1:54321... Successful.
------------------------------------------------------------------------------
H2O cluster uptime: 2 secs
H2O cluster timezone: Australia/Sydney
H2O data parsing timezone: UTC
H2O cluster version: 3.46.0.9
H2O cluster version age: 3 months and 14 days
H2O cluster total nodes: 1
H2O cluster free memory: 3.819 Gb
H2O cluster total cores: 6
H2O cluster allowed cores: 6
H2O cluster status: accepting new members, healthy
H2O connection url: http://127.0.0.1:54321
------------------------------------------------------------------------------
Moving Data Into the Cluster
Once our cluster has been created we need to feed it our dataset. While Stata is able to talk to the cluster, the cluster itself is not directly able to see the data that Stata holds. It needs to be transferred from Stata into an H2O data frame. It is important to note here that you are essentially duplicating your data at a single moment in time. This means once your data has been transferred into an H2O data frame, any subsequent changes you make to the dataset in Stata will not be duplicated in H2O. They become two separate datasets. So make sure that any additional variables and changes to names are made before the dataset is loaded into the cluster.
To load your dataset into an H2O frame, use the _h2oframe put command. You will then need to set your newly created H2O frame as active with the _h2oframe change command. Note the underscore at the beginning of the command names. This signifies an experimental or programming command in Stata and there will be no documentation for it in the help system. However, for Stata’s H2O integration there is a separate set of documentation that can be found here: Experimental Documentation.
. sysuse nlsw88, clear
(NLSW, 1988 extract)
. describe
Contains data from C:\Users\UserName\Documents\Stata19\StataNow19\ado\base/n/nlsw88.dta
Observations: 2,246 NLSW, 1988 extract
Variables: 17 1 May 2024 22:52
(_dta has notes)
------------------------------------------------------------------------------------------------------
Variable Storage Display Value
name type format label Variable label
------------------------------------------------------------------------------------------------------
idcode int %8.0g NLS ID
age byte %8.0g Age in current year
race byte %8.0g racelbl Race
married byte %8.0g marlbl Married
never_married byte %16.0g nev_mar Never married
grade byte %8.0g Current grade completed
collgrad byte %16.0g gradlbl College graduate
south byte %9.0g southlbl Lives in the south
smsa byte %9.0g smsalbl Lives in SMSA
c_city byte %16.0g ccitylbl Lives in a central city
industry byte %23.0g indlbl Industry
occupation byte %22.0g occlbl Occupation
union byte %8.0g unionlbl Union worker
wage float %9.0g Hourly wage
hours byte %8.0g Usual hours worked
ttl_exp float %9.0g Total work experience (years)
tenure float %9.0g Job tenure (years)
------------------------------------------------------------------------------------------------------
Sorted by: idcode
. _h2oframe put, into(nlsw)
Progress (%): 0 100
. _h2oframe change nlsw
Perform Statistical Analysis using Machine Learning Algorithms
At the moment Stata’s H2O integration supports gradient boosted machines and random forests. There is also a range of post-estimations and diagnostics that can be run after running a model. Use the help h2oml command in Stata to find all the currently available commands.
Let’s run a simple gradient boosting regression on our NLSW dataset.
. h2oml gbregress wage age race grade industry occupation ttl_exp tenure
Progress (%): 0 100
Gradient boosting regression using H2O
Response: wage
Loss: Gaussian
Frame: Number of observations:
Training: nlsw Training = 2,246
Model parameters
Number of trees = 50 Learning rate = .1
actual = 50 Learning rate decay = 1
Tree depth: Pred. sampling rate = 1
Input max = 5 Sampling rate = 1
min = 5 No. of bins cat. = 1,024
avg = 5.0 No. of bins root = 1,024
max = 5 No. of bins cont. = 20
Min. obs. leaf split = 10 Min. split thresh. = .00001
Metric summary
-----------------------
Metric | Training
-----------+-----------
Deviance | 18.39375
MSE | 18.39375
RMSE | 4.288793
RMSLE | .3436352
MAE | 2.397088
R-squared | .4444872
-----------------------
The output gives us an overview of the model. Because I gave no additional options, the model was run on the training dataset alone and evaluation metrics were reported.
If you want to cross-validate the model you need to specify the cv() option. This option requires you to specify the number of folds and choose a method of cross-validation. The default is random, or you can specify either a modulo or stratify method for cross-validation. The help file for h2oml gbregress describes each of these methods.
. h2oml gbregress wage age race grade industry occupation ttl_exp tenure, cv(3)
Progress (%): 0 81.0 100
Gradient boosting regression using H2O
Response: wage
Loss: Gaussian
Frame: Number of observations:
Training: nlsw Training = 2,246
Cross-validation = 2,246
Cross-validation: Random Number of folds = 3
Model parameters
Number of trees = 50 Learning rate = .1
actual = 50 Learning rate decay = 1
Tree depth: Pred. sampling rate = 1
Input max = 5 Sampling rate = 1
min = 5 No. of bins cat. = 1,024
avg = 5.0 No. of bins root = 1,024
max = 5 No. of bins cont. = 20
Min. obs. leaf split = 10 Min. split thresh. = .00001
Metric summary
-----------------------------------
| Cross-
Metric | Training validation
-----------+-----------------------
Deviance | 18.39375 27.64066
MSE | 18.39375 27.64066
RMSE | 4.288793 5.257439
RMSLE | .3436352 .4265271
MAE | 2.397088 2.968854
R-squared | .4444872 .1652195
-----------------------------------
. h2oml gbregress wage age race grade industry occupation ttl_exp tenure, cv(3, modulo)
Progress (%): 0 100
Gradient boosting regression using H2O
Response: wage
Loss: Gaussian
Frame: Number of observations:
Training: nlsw Training = 2,246
Cross-validation = 2,246
Cross-validation: Modulo Number of folds = 3
Model parameters
Number of trees = 50 Learning rate = .1
actual = 50 Learning rate decay = 1
Tree depth: Pred. sampling rate = 1
Input max = 5 Sampling rate = 1
min = 5 No. of bins cat. = 1,024
avg = 5.0 No. of bins root = 1,024
max = 5 No. of bins cont. = 20
Min. obs. leaf split = 10 Min. split thresh. = .00001
Metric summary
-----------------------------------
| Cross-
Metric | Training validation
-----------+-----------------------
Deviance | 18.39375 27.97831
MSE | 18.39375 27.97831
RMSE | 4.288793 5.289453
RMSLE | .3436352 .4333191
MAE | 2.397088 2.998854
R-squared | .4444872 .1550221
-----------------------------------
The random and modulo options can be run without any other changes, but the stratify option can only be used with a categorical or factor variable as the dependent variable. Additionally, this variable must be stored as an int type and not an enum type. The enum type is H2O’s version of a factor variable storage type. Even though an enum type is technically correct, H2O still needs it to be stored as a numeric variable in order for the model to run.
To find out the current storage type of your variables you use the command _h2oframe describe. To change the storage type of your variable use either _h2oframe toenum, or _h2oframe tonumeric, or _h2oframe tostring with either generate or replace options. For example, if I wanted to run a model testing the effect of being a college graduate on wage, I would first need to convert the collgrad variable as it was loaded as an enum type.
. _h2oframe describe
Rows: 2246
Cols: 17
------------------------------------------------------------------------------
Column Type Missing Zeros +Inf -Inf Cardinality
------------------------------------------------------------------------------
idcode int 0 0 0 0
age int 0 0 0 0
race enum 0 583 0 0 3
married enum 0 1442 0 0 2
never_married enum 0 2012 0 0 2
grade int 2 2 0 0
collgrad enum 0 532 0 0 2
south enum 0 1304 0 0 2
smsa enum 0 665 0 0 2
c_city enum 0 655 0 0 2
industry enum 14 17 0 0 12
occupation enum 9 102 0 0 13
union enum 368 1417 0 0 2
wage real 0 0 0 0
hours int 4 0 0 0
ttl_exp real 0 0 0 0
tenure real 15 51 0 0
------------------------------------------------------------------------------
. _h2oframe tonumeric collgrad, replace
. h2oml gbregress collgrad wage grade age, cv(3, stratify)
Progress (%): 0 100
Gradient boosting regression using H2O
Response: collgrad
Loss: Gaussian
Frame: Number of observations:
Training: nlsw Training = 2,246
Cross-validation = 2,246
Cross-validation: Stratify Number of folds = 3
Model parameters
Number of trees = 50 Learning rate = .1
actual = 50 Learning rate decay = 1
Tree depth: Pred. sampling rate = 1
Input max = 5 Sampling rate = 1
min = 5 No. of bins cat. = 1,024
avg = 5.0 No. of bins root = 1,024
max = 5 No. of bins cont. = 20
Min. obs. leaf split = 10 Min. split thresh. = .00001
Metric summary
-----------------------------------
| Cross-
Metric | Training validation
-----------+-----------------------
Deviance | .0062261 .0089356
MSE | .0062261 .0089356
RMSE | .0789058 .0945283
RMSLE | .0561176 .0647799
MAE | .016547 .0200545
R-squared | .9655559 .9505666
-----------------------------------
Finally, if you want to perform validation using a separate dataset, you use the validframe() option. You need to provide the frame name of another H2O frame within the cluster that contains your validation dataset, not a Stata frame.
For this example I will create two new H2O frames called train and valid which will contain 80% and 20% respectively of the data from the NSLW dataset. I can do this using the _h2oframe split command. Once split, I must change the active H2O frame to the train dataset to run the regression.
. _h2oframe split nlsw, into(train valid) split(0.8 0.2) rseed(194119)
. _h2oframe change train
. h2oml gbregress wage age race grade industry occupation ttl_exp tenure, validframe(valid)
Progress (%): 0 100
Gradient boosting regression using H2O
Response: wage
Loss: Gaussian
Frame: Number of observations:
Training: train Training = 1,784
Validation: valid Validation = 462
Model parameters
Number of trees = 50 Learning rate = .1
actual = 50 Learning rate decay = 1
Tree depth: Pred. sampling rate = 1
Input max = 5 Sampling rate = 1
min = 5 No. of bins cat. = 1,024
avg = 5.0 No. of bins root = 1,024
max = 5 No. of bins cont. = 20
Min. obs. leaf split = 10 Min. split thresh. = .00001
Metric summary
-----------------------------------
Metric | Training Validation
-----------+-----------------------
Deviance | 17.67406 24.63134
MSE | 17.67406 24.63134
RMSE | 4.204053 4.962997
RMSLE | .3340099 .4230132
MAE | 2.333324 2.94512
R-squared | .4792486 .1763648
-----------------------------------
The output gives an overview as before, however now we see two dataset names and the number of observations contained in each. We are also given metrics for both datasets.
Closing an H2O Cluster
Once you are finished, you will need to extract your results and dataset (if needed) from the H2O cluster. You can use the _h2oframe export or _h2oframe get commands to extract your data as either a csv file or a Stata frame. The export to csv command will only work on the currently loaded H2O frame. The get command will work on any frame you specify and will load it into your currently selected Stata frame. For results, the collect command works on all appropriate h2oml commands.
Once you have all the results and data you want to keep, you then either disconnect from or shut down the H2O cluster. If the cluster is external simply disconnect with h2o disconnect. If you do this, all your resources and data will remain in the cluster so you may need to delete these before disconnecting depending on your circumstances. If you have initialised the cluster within Stata like we have done in this article, you can shut it down and destroy its resources with the h2o shutdown, force command. This command is also run automatically when you exit Stata.
. _h2oframe export h2odata.csv, replace
(file h2odata.csv not found)
file h2odata.csv saved
. frame create h2odata
. frame change h2odata
. _h2oframe get nlsw
. save h2odata.dta, replace
(file h2odata.dta not found)
file h2odata.dta saved
. h2o shutdown, force
The cluster running at http://127.0.0.1:54321 shut down successfully.
For more information on H2O and the features available, check out Stata’s Experimental H2O Documentation.