H2O AI Machine Learning

By Laura Whiting · Published 23 September 2026
Programmingstata

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.

8 views 0 found this useful