使用 H2O、R 和 MinIO 进行机器学习

我从80年代后期就开始接触神经网络和机器学习了。没错,我确实这么老。我买的第一款产品是加州科学软件公司的BrainMaker Professional。我喜欢这款产品,因为它让我开始接触神经网络。我到现在还留着它。

它是一款三层神经网络产品,附带了用C语言编写的源代码,用于执行它训练的模型。我买它是为了获取源代码。我当时并不知道代码里充满了bug,而且没有包含训练模型的代码。因为懂C语言,我开始根据当时可用的数学文献添加训练模型的功能。我还把它做成了一个带线程和分布式执行功能的DCE RPC服务器,可以在多个节点上运行。当我向人们描述我的工作,并解释使用梯度下降进行收敛时,他们看着我的眼神就像我长了两个脑袋一样。机器学习的发展已经走了很长一段路。现在,在杂货店里也能买到ML平台了。好吧,不完全是,但你明白我的意思。
现在有如此多的AI/ML平台可供选择。我个人比较喜欢H2O。我发现它速度很快,易于管理和使用,并且功能非常完善。我也喜欢用R语言。我发现R语言在我处理数据和机器学习时最直观。将这两个与MinIO对象存储结合起来,就可以为数据科学家创建一个非常强大的平台。
如果您不熟悉H2O,这里有一个总结(来自官网)
开源、面向所有人的分布式机器学习。H2O是一个完全开源的、分布式的内存机器学习平台,具有线性可扩展性。H2O支持最广泛使用的统计和机器学习算法,包括梯度提升机、广义线性模型、深度学习等等。H2O还拥有业界领先的AutoML功能,可以自动运行所有算法及其超参数,并生成最佳模型的排行榜。H2O平台被全球超过18,000家组织使用,在R和Python社区中非常受欢迎。
如果您不熟悉R(来自维基百科)
“R是一种用于统计计算和图形的编程语言,由R核心团队和R统计计算基金会提供支持。R是由统计学家Ross Ihaka和Robert Gentleman创建的,被数据挖掘人员和统计学家用于数据分析和开发统计软件。用户创建了包来增强R语言的功能。”
我发现R语言在我处理数据、数据分析和机器学习时最直观。
如果您不熟悉MinIO,它是一个100%兼容的Amazon S3替代品: https://min-io.cn
在这篇文章中,我将设置H2O、R和MinIO,以使用H2O AutoML功能来训练模型。R语言有一个配套的IDE叫做RStudio,我将用它来进行开发:https://www.rstudio.com/。如果您想跟着一起操作,请安装R和RStudio,并能够访问一个H2O集群。
R studio为R开发提供了一个强大的IDE。它通常看起来像这样
使用非常大的训练和执行数据集的一个挑战是,它们根本无法放入内存中。H2O通过从H2O集群中的节点创建一个分布式计算平台来解决这个问题。如果给定的数据集对于您的集群来说太大,只需添加更多具有更大RAM的节点即可。这太棒了。这意味着那些卑微的数据科学家不需要在他们桌子上摆满拥有海量RAM的机器,而是可以利用大型H2O集群的集体RAM能力。
MinIO提供了高性能的对象存储来持久化大型训练和执行数据集,而H2O能够直接读写MinIO。非常简单。我有一个MinIO集群正在运行,我通常用来读写集群的节点是“HP-Z230”,端口为9000。
我们首先将一个.csv文件加载到MinIO中的S3存储桶中。这可以通过MinIO的“mc”客户端或通过MinIO控制台来完成。
我在这里使用的是来自H2O教程的发电厂数据:"https://github.com/h2oai/h2o-tutorials/raw/master/h2o-world-2017/automl/data/powerplant_output.csv"
我已将该文件加载到MinIO中名为test-data
的存储桶中。您会注意到这个文件并不大,但这种方法也适用于非常大的文件——只是需要更长时间。
将数据放入MinIO存储桶是我们的过程的起点。下一步是配置H2O,使其能够读写MinIO s3存储。需要执行一些配置步骤。
首先,我们需要创建一个core-site.xml
文件,该文件指定H2O在访问MinIO s3存储时应使用的AccessKeyId
和SecretAccessKey
(凭据)。这是一个示例
bcosta@bcosta-HP-Z230-Tower-Workstation:~/h2o/h2o-3.36.0.3$ more core-site.xml
<?xml version="1.0"?>
<?xml-stylesheet type="text/xsl" href="configuration.xsl"?>
<!-- Put site-specific property overrides in this file. -->
<configuration>
<!--
<property>
<name>fs.default.name</name>
<value>s3://<your s3 bucket></value>
</property>
-->
<property>
<name>fs.s3.awsAccessKeyId</name>
<value>minioadmin</value>
</property>
<property>
<name>fs.s3.awsSecretAccessKey</name>
<value>minioadmin</value>
</property>
</configuration>
然后,需要在命令行上使用一些参数启动H2O程序,指示在哪里访问对象存储。这是一个示例。我的MinIO运行在一台名为“HP-Z230”的机器上,端口为9000。此外,还引用了core-site.xml
文件
java -Dsys.ai.h2o.persist.s3.endPoint=http://HP-Z230:9000 -Dsys.ai.h2o.persist.s3.enable.path.style=true -jar h2o.jar -hdfs_config core-site.xml
H2O应该能够成功启动。如果有多个H2O节点形成一个集群,则应在每个节点上执行这些步骤。如果在您的环境中,您更希望不将凭据硬编码到H2O配置文件中,则有一种方法可以从R动态设置它们,但通常情况下,由于MinIO集群和H2O集群都是基础设施的一部分,因此静态地将它们绑定在一起并不罕见。
接下来是代码!第一步是加载所需的库并测试我们的连接。在此代码块中,我加载了aws.s3和h2o库,设置了一些凭据以便R能够看到MinIO s3集群,并对其进行测试以查看是否正常工作。由于MinIO与Amazon s3完全兼容,因此我们可以使用AWS库或MinIO库——这无关紧要。H2O提供了一个与R兼容的库,可以使用下载方式获取,并且应该使用它来访问H2O服务器。R库和H2O服务器的版本必须匹配,否则下面的init
调用将失败并显示相应的错误信息。
library(aws.s3)
library(h2o)
# set the credentials this r instances uses to access minio
Sys.setenv("AWS_ACCESS_KEY_ID" = "minioadmin", # enter your credentials
"AWS_SECRET_ACCESS_KEY" = "minioadmin", # enter your credentials
"AWS_S3_ENDPOINT" = "HP-Z230:9000") # change it to your specific minio IP and port to override default aws s3
# initialise the h2o server
h2o.init(ip="HP-Z230", port=54321,startH2O=FALSE)
#make a call from this r instance (ssl is off)
bucketlist(region = "", verbose = TRUE, use_https = FALSE)
在R Studio中执行此代码应导致H2O服务器成功初始化,以及成功连接到MinIO集群并返回存储桶列表。这测试了从R到H2O和MinIO的连接。
下一步测试H2O直接访问MinIO集群的能力。请记住——我们将加载的文件太大,无法通过运行在我的笔记本电脑上的R环境传递。H2O需要能够直接从MinIO读取大型文件到其分布式计算环境中。
# set the data_path for the object we will read
data_path <- "s3://test-data/powerplant_output.csv"
#import the file from minio directly into h2o and return a pointer to it
df <- h2o.importFile(path = data_path)
h2o.describe(df)
请注意h2o.importFile()
调用。它在R中执行,但指示H2O服务器直接从MinIO S3存储将文件加载到集群的内存中。如果这可以正常工作,那么您现在就有R与H2O通信、R与MinIO通信以及H2O与MinIO通信。世界任你驰骋!
接下来,我们将数据转换为H2O喜欢的格式,并使用对服务器的调用进行拆分——我们实际上是在远程对大型数据集执行数据操作调用。
#convert the raw dataframe on the server to a hex file and return a pointer to it
data.hex <- as.h2o(df)
y <- "HourlyEnergyOutputMW"
splits <- h2o.splitFrame(data.hex, ratios = 0.8, seed = 1)
train <- splits[[1]]
test <- splits[[2]]
现在我们有一些训练和测试数据,我们就可以对训练集执行一些AutoML来构建和比较一些模型了。我在这里使用了一些默认值,并将下面的探索时间限制为60秒,但H2O AutoML功能可以设置大量参数——这里无法一一介绍。完成后,代码会打印排行榜。
## Run AutoML stopping after 60 seconds. The `max_runtime_secs` argument provides a way to limit the AutoML run by time. When using a time-limited stopping criterion, the number of models train will vary between runs. If different hardware is used or even if the same machine is used but the available compute resources on that machine are not the same between runs, then AutoML may be able to train more models on one run vs another.
aml <- h2o.automl(y = y,
training_frame = train,
leaderboard_frame = test,
max_runtime_secs = 60,
seed = 1,
project_name = "powerplant_lb_frame")
## Leaderboard
print(aml@leaderboard)
接下来,我们将测试数据通过主模型发送以查看一些预测结果。这是测试数据的前几行。该模型将预测最后一列——“HourlyEnergyOutputMW”
## Predict Using Leader Model
pred <- h2o.predict(aml, test) # predict(aml, test) and h2o.predict(aml@leader, test) also work
head(pred)
同样,请注意,对于预测,H2O直接从MinIO S3存储访问测试数据。假设H2O集群很大,则测试文件可以非常大。
这些看起来很合理,最后我们可以评估模型的性能并将模型保存回MinIO s3存储
perf <- h2o.performance(aml@leader, test)
perf
# save leader as bin
h2o.saveModel(aml@leader, path = "s3://bin-models/powerplant_output_model_bin")
我已经将模型保存到一个名为bin-models
的存储桶中,如果查看控制台,可以看到该模型存储在MinIO中。
使用R和MinIO的H20
这是一个使用H2O、R和MinIO快速创建AI/ML平台的示例,该平台可以处理大型文件,并使用AutoML训练模型、测试模型、评估leader模型的性能,并最终将模型保存到MinIO S3对象存储中以供将来使用。我希望它对您有所帮助,我很享受编写它。