SystemML 是一种用 Java 编写的灵活、可扩展的机器学习 (ML) 语言。SystemML 的显着特点是:(1)算法的可定制性,(2)多种执行模式,包括 Standalone、Hadoop Batch 和 Spark Batch,以及(3)自动优化。
最新的文档可以在 SystemML 文档网站上找到。
SystemML 中的 ML 算法以高级声明式机器学习 (DML) 语言指定。算法可以用类似 R 的语法或类似 Python 的语法表示。DML 包括线性代数基元、统计函数和其他结构。
[hidecontent type="logged" desc="隐藏内容:登录后可查看"]
这种高级语言显着提高了数据科学家的生产力,因为它提供 (1) 表达自定义分析的完全灵活性和 (2) 数据独立于底层输入格式和物理数据表示。
SystemML 计算可以在各种不同的模式下执行。首先,SystemML 可以在单机上以独立模式运行,允许数据科学家在本地开发算法而不需要分布式集群。算法可以跨 Hadoop 或 Spark 分布。这种灵活性允许利用组织的现有资源和专业知识。此外,SystemML 可以通过 Java、Scala 和 Python 运行。SystemML 还具有用于对模型进行评分的嵌入式 API。
DML 中指定的算法是基于数据和集群特征使用基于规则和基于成本的优化技术动态编译和优化的。优化器自动生成混合运行时执行计划,范围从内存中单节点执行到 Spark 或 Hadoop 上的分布式计算。这确保了效率和可扩展性。自动优化减少或消除了手动调整分布式运行时执行计划和系统配置的需要。
SystemML 是使用Apache Maven构建的。SystemML 将在 Windows、Linux 或 MacOS 上构建,并且需要 Maven 3 和 Java 7(或更高版本)。要构建 SystemML,请运行:
mvn clean package
SystemML 具有一套全面的集成测试。要执行这些测试,请运行:
cd system-ml
mvn verify
注意:这些测试要求在运行这些测试的机器上安装R并将其作为 PATH 变量的一部分提供。
如果需要,请在 R 中安装以下软件包:
install.packages(c("batch", "bitops", "boot", "caTools", "data.table", "doMC", "doSNOW", "ggplot2", "glmnet", "lda", "Matrix", "matrixStats", "moments", "plotrix", "psych", "reshape", "topicmodels", "wordcloud"), dependencies=TRUE)
SystemML 可以在分布式模式下运行,也可以在本地独立模式下运行。我们将在本指南中以独立模式运行。从源 ( mvn clean package
) 构建 SystemML 后,可以在 Mac/Unix 上使用./bin/systemml
脚本或在 Windows 上使用.\bin\systemml.bat
批处理文件执行独立模式。
如果您从项目根文件夹./
或文件夹中的脚本运行./bin
,则运行 SystemML 的输出文件将在该./temp
文件夹内创建,以将它们与 Git 管理的 SystemML 源文件分开。本指南中所有示例的输出文件都将在该./temp
文件夹下创建。
SystemML 的运行时行为和日志记录行为可以通过编辑文件./conf/SystemML-config.xml
和./conf/log4j.properties
. 这两个文件将*.template
在 SystemML 可执行脚本的第一次执行期间从它们的相应文件创建。
当调用./bin/systemml
或.\bin\systemml.bat
使用任何预先打包的 DML 脚本时,您可以省略 DML 脚本文件的相对路径。以下两个命令是等价的:
./bin/systemml ./system-ml/scripts/datagen/genLinearRegressionData.dml -nvargs numSamples=1000 numFeatures=50 maxFeatureValue=5 maxWeight=5 addNoise=FALSE b=0 sparsity=0.7 output=linRegData.csv format=csv perc=0.5
./bin/systemml genLinearRegressionData.dml -nvargs numSamples=1000 numFeatures=50 maxFeatureValue=5 maxWeight=5 addNoise=FALSE b=0 sparsity=0.7 output=linRegData.csv format=csv perc=0.5
在本指南中,我们使用相对文件夹调用命令,以便更轻松地查找 DML 脚本的源代码。
SystemML 具有一套算法,可分为五大类:描述性统计、分类、聚类、回归和矩阵分解。这些算法的详细描述可以在 SystemML 打包的算法参考中找到。
作为 SystemML 和 DML 的功能和强大功能的示例,让我们考虑一下线性回归算法。我们需要数据集来训练和测试我们的模型。要获取此数据,我们可以使用真实数据或为我们的算法生成数据。UCI 机器学习存储库数据集 是真实数据的一个位置。使用真实数据通常涉及某种程度的数据争论。在下面的示例中,我们将使用 SystemML 生成随机数据来训练和测试我们的模型。
本示例由以下部分组成:
SystemML 分布在多个包中,包括一个独立包。在此示例中,我们将以独立模式运行。
genLinearRegressionData.dml
我们可以使用systemml
或systemml.bat
文件以独立模式执行脚本。在本例中,我们将生成一个包含 1000 行 50 列测试数据的矩阵,稀疏度为 0.7。除此之外,由标签组成的第 51列将附加到矩阵中。
./bin/systemml ./system-ml/scripts/datagen/genLinearRegressionData.dml -nvargs numSamples=1000 numFeatures=50 maxFeatureValue=5 maxWeight=5 addNoise=FALSE b=0 sparsity=0.7 output=linRegData.csv format=csv perc=0.5
这会在文件夹中生成以下文件./temp
:
linRegData.csv # 1000 rows of 51 columns of doubles (50 data columns and 1 label column), csv format
linRegData.csv.mtd # metadata file
接下来,我们将创建生成数据的两个子集,每个子集的大小约为 50%。我们可以使用sample.dml
脚本完成此操作。此脚本将从linRegData.csv
文件中随机抽取行并将它们放入 2 个文件中。
为此,我们需要为sv
命名参数创建一个 csv 文件(sample.dml
更多详细信息请参见 参考资料),我将其命名为perc.csv
. 该文件是在上一步中生成的,如下所示:
0.5
0.5
这将创建两个样本组,每个样本组大约占 50%。
现在,sample.dml
可以运行脚本了。
./bin/systemml ./system-ml/scripts/utils/sample.dml -nvargs X=linRegData.csv sv=perc.csv O=linRegDataParts ofmt=csv
此脚本创建原始数据的两个分区并将它们放在一个linRegDataParts
文件夹中。创建的文件如下:
linRegDataParts/1 # first partition of data, ~50% of rows of linRegData.csv, csv format
linRegDataParts/1.mtd # metadata
linRegDataParts/2 # second partition of data, ~50% of rows of linRegData.csv, csv format
linRegDataParts/2.mtd # metadata
文件包含第1
一个分区的数据,2
文件包含第二个分区的数据。关联的元数据文件描述了每个数据分区的性质。如果我们打开1
并2
查看行数,我们可以看到通常分区不完全是 50%,而是接近 50%。但是,我们发现原始数据文件中的总行数等于 和 中的行数之1
和2
。
下一个任务是从第一个样本中拆分标签列。我们可以使用splitXY.dml
脚本来做到这一点。
./bin/systemml ./system-ml/scripts/utils/splitXY.dml -nvargs X=linRegDataParts/1 y=51 OX=linRegData.train.data.csv OY=linRegData.train.labels.csv ofmt=csv
这会将第 51 列(标签列)从数据中分离出来。完成后,已创建以下文件。
linRegData.train.data.csv # training data of 50 columns, csv format
linRegData.train.data.csv.mtd # metadata
linRegData.train.labels.csv # training labels of 1 column, csv format
linRegData.train.labels.csv.mtd # metadata
我们还需要从第二个样本中拆分标签列。
./bin/systemml ./system-ml/scripts/utils/splitXY.dml -nvargs X=linRegDataParts/2 y=51 OX=linRegData.test.data.csv OY=linRegData.test.labels.csv ofmt=csv
这会将第 51 列从数据中拆分出来,从而生成以下文件:
linRegData.test.data.csv # test data of 50 columns, csv format
linRegData.test.data.csv.mtd # metadata
linRegData.test.labels.csv # test labels of 1 column, csv format
linRegData.test.labels.csv.mtd # metadata
现在,我们可以根据第一个样本训练我们的模型。为此,我们使用LinearRegDS.dml
(线性回归直接求解)脚本。请注意,SystemML 还包括一个LinearRegCG.dml
(线性回归共轭梯度)算法,用于特征数量较多的情况。
./bin/systemml ./system-ml/scripts/algorithms/LinearRegDS.dml -nvargs X=linRegData.train.data.csv Y=linRegData.train.labels.csv B=betas.csv fmt=csv
这将生成以下文件:
betas.csv # betas, 50 rows of 1 column, csv format
betas.csv.mtd # metadata
LinearRegDS.dml 脚本生成类似于以下内容的标准输出统计信息。
BEGIN LINEAR REGRESSION SCRIPT
Reading X and Y...
Calling the Direct Solver...
Computing the statistics...
AVG_TOT_Y,-2.160284487670675
STDEV_TOT_Y,66.86434576808432
AVG_RES_Y,-3.3127468704080085E-10
STDEV_RES_Y,1.7231785003947183E-8
DISPERSION,2.963950542926297E-16
PLAIN_R2,1.0
ADJUSTED_R2,1.0
PLAIN_R2_NOBIAS,1.0
ADJUSTED_R2_NOBIAS,1.0
PLAIN_R2_VS_0,1.0
ADJUSTED_R2_VS_0,1.0
Writing the output matrix...
END LINEAR REGRESSION SCRIPT
现在我们有了betas.csv
,我们可以用第二组数据测试我们的模型。
要在第二个样本上测试我们的模型,我们可以使用GLM-predict.dml
脚本。此脚本可用于预测和评分。在这里,我们使用它进行评分,因为我们包含了Y
命名参数。我们的betas.csv
文件被指定为B
命名参数。
./bin/systemml ./system-ml/scripts/algorithms/GLM-predict.dml -nvargs X=linRegData.test.data.csv Y=linRegData.test.labels.csv B=betas.csv fmt=csv
这会向标准输出生成以下统计信息。
LOGLHOOD_Z,,FALSE,NaN
LOGLHOOD_Z_PVAL,,FALSE,NaN
PEARSON_X2,,FALSE,1.895530994504798E-13
PEARSON_X2_BY_DF,,FALSE,4.202951207327712E-16
PEARSON_X2_PVAL,,FALSE,1.0
DEVIANCE_G2,,FALSE,0.0
DEVIANCE_G2_BY_DF,,FALSE,0.0
DEVIANCE_G2_PVAL,,FALSE,1.0
LOGLHOOD_Z,,TRUE,NaN
LOGLHOOD_Z_PVAL,,TRUE,NaN
PEARSON_X2,,TRUE,1.895530994504798E-13
PEARSON_X2_BY_DF,,TRUE,4.202951207327712E-16
PEARSON_X2_PVAL,,TRUE,1.0
DEVIANCE_G2,,TRUE,0.0
DEVIANCE_G2_BY_DF,,TRUE,0.0
DEVIANCE_G2_PVAL,,TRUE,1.0
AVG_TOT_Y,1,,1.0069397725436522
STDEV_TOT_Y,1,,68.29092137526905
AVG_RES_Y,1,,-4.1450397073455047E-10
STDEV_RES_Y,1,,2.0519206226041048E-8
PRED_STDEV_RES,1,TRUE,1.0
PLAIN_R2,1,,1.0
ADJUSTED_R2,1,,1.0
PLAIN_R2_NOBIAS,1,,1.0
ADJUSTED_R2_NOBIAS,1,,1.0
我们看到测试阶段的 STDEV_RES_Y 值与从模型训练阶段获得的值大小相似。
为了方便起见,我们可以将 DML 调用封装在一个脚本中:
#!/bin/bash
./bin/systemml ./system-ml/scripts/datagen/genLinearRegressionData.dml -nvargs numSamples=1000 numFeatures=50 maxFeatureValue=5 maxWeight=5 addNoise=FALSE b=0 sparsity=0.7 output=linRegData.csv format=csv perc=0.5
./bin/systemml ./system-ml/scripts/utils/sample.dml -nvargs X=linRegData.csv sv=perc.csv O=linRegDataParts ofmt=csv
./bin/systemml ./system-ml/scripts/utils/splitXY.dml -nvargs X=linRegDataParts/1 y=51 OX=linRegData.train.data.csv OY=linRegData.train.labels.csv ofmt=csv
./bin/systemml ./system-ml/scripts/utils/splitXY.dml -nvargs X=linRegDataParts/2 y=51 OX=linRegData.test.data.csv OY=linRegData.test.labels.csv ofmt=csv
./bin/systemml ./system-ml/scripts/algorithms/LinearRegDS.dml -nvargs X=linRegData.train.data.csv Y=linRegData.train.labels.csv B=betas.csv fmt=csv
./bin/systemml ./system-ml/scripts/algorithms/GLM-predict.dml -nvargs X=linRegData.test.data.csv Y=linRegData.test.labels.csv B=betas.csv fmt=csv
在这个例子中,我们看到了 SystemML 的一小部分功能。有关更多详细信息,请参阅 SystemML 算法参考和 SystemML 语言参考。
[/hidecontent]