在2.5节中介绍Alink在批式任务中定义了Lazy方式,本小节将通过示例演示一些常用使用方式。另外,在后面的2.6节重点介绍了使用Lazy方法显示模型信息;在模型评估阶段也常使用Lazy的方法,具体内容参见分类、回归、聚类等的评估章节。

选择演示的数据集为iris数据集,可以从HTTP链接直接读取。相关代码如下:

  1. CsvSourceBatchOp source = new CsvSourceBatchOp()
  2. .setFilePath("http://archive.ics.uci.edu/ml/machine-learning-databases"
  3. + "/iris/iris.data")
  4. .setSchemaStr("sepal_length double, sepal_width double, petal_length double, "
  5. + "petal_width double, category string");

批式组件间的输出

下面例子是对原始数据使用SelectBatchOp组件进行操作,在组件操作前后可以使用多种方式进行数据和统计结果的输出,帮助我们了解组件操作的效果。完整代码如下:

  1. source
  2. .lazyPrint()
  3. .lazyPrint(">>> print with title.")
  4. .lazyPrint(2)
  5. .lazyPrint(2, ">>> print 2 rows with title.")
  6. .lazyPrintStatistics()
  7. .lazyPrintStatistics(">>> summary of current data.")
  8. .lazyCollect(new Consumer <List <Row>>() {
  9. @Override
  10. public void accept(List <Row> rows) {
  11. System.out.println("number of rows : " + rows.size());
  12. }
  13. })
  14. .lazyCollectStatistics(new Consumer <TableSummary>() {
  15. @Override
  16. public void accept(TableSummary tableSummary) {
  17. System.out.println("number of valid values :"
  18. + tableSummary.numValidValue("sepal_length"));
  19. System.out.println("number of missing values :"
  20. + tableSummary.numMissingValue("sepal_length"));
  21. }
  22. })
  23. .link(
  24. new SelectBatchOp()
  25. .setClause("sepal_length, sepal_width, sepal_length/sepal_width AS ratio")
  26. )
  27. .lazyPrint(">>> final data")
  28. .lazyPrintStatistics(">>> summary of final data.");
  29. BatchOperator.execute();

可以看到,lazy系列组件在链式调用过程中,其输出数据与输入数据是一样的,所以可以随时嵌入链式调用过程,或者从链式调用中移除,但不会影响最终的结果,这就给我们调试程序,诊断问题,探索数据等带来了便利。下面将每个lazy操作对应到数据结果,对比了解各个功能。

lazyPrint

lazyPrint方法可以不输入参数,如下所示,当数据过多时,会只打印输出首尾的数据行。

  1. lazyPrint()

输出结果为:

  1. sepal_length|sepal_width|petal_length|petal_width|category
  2. ------------|-----------|------------|-----------|--------
  3. 5.1000|3.5000|1.4000|0.2000|Iris-setosa
  4. 4.9000|3.0000|1.4000|0.2000|Iris-setosa
  5. 4.7000|3.2000|1.3000|0.2000|Iris-setosa
  6. 4.6000|3.1000|1.5000|0.2000|Iris-setosa
  7. 5.0000|3.6000|1.4000|0.2000|Iris-setosa
  8. 5.4000|3.9000|1.7000|0.4000|Iris-setosa
  9. 4.6000|3.4000|1.4000|0.3000|Iris-setosa
  10. 5.0000|3.4000|1.5000|0.2000|Iris-setosa
  11. 4.4000|2.9000|1.4000|0.2000|Iris-setosa
  12. 4.9000|3.1000|1.5000|0.1000|Iris-setosa
  13. ......
  14. 6.7000|3.1000|5.6000|2.4000|Iris-virginica
  15. 6.9000|3.1000|5.1000|2.3000|Iris-virginica
  16. 5.8000|2.7000|5.1000|1.9000|Iris-virginica
  17. 6.8000|3.2000|5.9000|2.3000|Iris-virginica
  18. 6.7000|3.3000|5.7000|2.5000|Iris-virginica
  19. 6.7000|3.0000|5.2000|2.3000|Iris-virginica
  20. 6.3000|2.5000|5.0000|1.9000|Iris-virginica
  21. 6.5000|3.0000|5.2000|2.0000|Iris-virginica
  22. 6.2000|3.4000|5.4000|2.3000|Iris-virginica
  23. 5.9000|3.0000|5.1000|1.8000|Iris-virginica

lazyPrint方法可以支持字符串类型参数作为打印内容的标题,如下所示:

  1. lazyPrint(">>> print with title.")

输出结果如下,注意最上一行为设置的标题。

  1. >>> print with title.
  2. sepal_length|sepal_width|petal_length|petal_width|category
  3. ------------|-----------|------------|-----------|--------
  4. 5.1000|3.5000|1.4000|0.2000|Iris-setosa
  5. 4.9000|3.0000|1.4000|0.2000|Iris-setosa
  6. 4.7000|3.2000|1.3000|0.2000|Iris-setosa
  7. 4.6000|3.1000|1.5000|0.2000|Iris-setosa
  8. 5.0000|3.6000|1.4000|0.2000|Iris-setosa
  9. 5.4000|3.9000|1.7000|0.4000|Iris-setosa
  10. 4.6000|3.4000|1.4000|0.3000|Iris-setosa
  11. 5.0000|3.4000|1.5000|0.2000|Iris-setosa
  12. 4.4000|2.9000|1.4000|0.2000|Iris-setosa
  13. 4.9000|3.1000|1.5000|0.1000|Iris-setosa
  14. ......
  15. 6.7000|3.1000|5.6000|2.4000|Iris-virginica
  16. 6.9000|3.1000|5.1000|2.3000|Iris-virginica
  17. 5.8000|2.7000|5.1000|1.9000|Iris-virginica
  18. 6.8000|3.2000|5.9000|2.3000|Iris-virginica
  19. 6.7000|3.3000|5.7000|2.5000|Iris-virginica
  20. 6.7000|3.0000|5.2000|2.3000|Iris-virginica
  21. 6.3000|2.5000|5.0000|1.9000|Iris-virginica
  22. 6.5000|3.0000|5.2000|2.0000|Iris-virginica
  23. 6.2000|3.4000|5.4000|2.3000|Iris-virginica
  24. 5.9000|3.0000|5.1000|1.8000|Iris-virginica

lazyPrint方法可以指定要输出的数据行数,下面代码为输出2行数据,注意参数“-1”表示输出全部数据。

  1. lazyPrint(2)

输出结果如下,2行数据。

  1. sepal_length|sepal_width|petal_length|petal_width|category
  2. ------------|-----------|------------|-----------|--------
  3. 5.1000|3.5000|1.4000|0.2000|Iris-setosa
  4. 4.9000|3.0000|1.4000|0.2000|Iris-setosa

lazyPrint方法也可以同时指定输出行数和标题,如下所示

  1. lazyPrint(2, ">>> print 2 rows with title.")

输出结果为:

  1. >>> print 2 rows with title.
  2. sepal_length|sepal_width|petal_length|petal_width|category
  3. ------------|-----------|------------|-----------|--------
  4. 5.1000|3.5000|1.4000|0.2000|Iris-setosa
  5. 4.9000|3.0000|1.4000|0.2000|Iris-setosa

上面的输出操作都在SelectBatchOp组件之前,在该组件后面再接一个输出,代码如下

  1. lazyPrint(">>> final data")

运行结果如下,可以看到数据列数发生了变换,保留了sepal_length和sepal_width列,增加了ratio列。

  1. >>> final data
  2. sepal_length|sepal_width|ratio
  3. ------------|-----------|-----
  4. 5.1000|3.5000|1.4571
  5. 4.9000|3.0000|1.6333
  6. 4.7000|3.2000|1.4688
  7. 4.6000|3.1000|1.4839
  8. 5.0000|3.6000|1.3889
  9. 5.4000|3.9000|1.3846
  10. 4.6000|3.4000|1.3529
  11. 5.0000|3.4000|1.4706
  12. 4.4000|2.9000|1.5172
  13. 4.9000|3.1000|1.5806
  14. ......
  15. 6.7000|3.1000|2.1613
  16. 6.9000|3.1000|2.2258
  17. 5.8000|2.7000|2.1481
  18. 6.8000|3.2000|2.1250
  19. 6.7000|3.3000|2.0303
  20. 6.7000|3.0000|2.2333
  21. 6.3000|2.5000|2.5200
  22. 6.5000|3.0000|2.1667
  23. 6.2000|3.4000|1.8235
  24. 5.9000|3.0000|1.9667

lazyPrintStatistics

lazyPrintStatistics方法可以将数据的基本统计结果打印输出。代码如下所示:

  1. lazyPrintStatistics()

输出结果为:

  1. Summary:
  2. | colName|count|missing| sum| mean|variance|min|max|
  3. |------------|-----|-------|-----|------|--------|---|---|
  4. |sepal_length| 150| 0|876.5|5.8433| 0.6857|4.3|7.9|
  5. | sepal_width| 150| 0|458.1| 3.054| 0.188| 2|4.4|
  6. |petal_length| 150| 0|563.8|3.7587| 3.1132| 1|6.9|
  7. | petal_width| 150| 0|179.8|1.1987| 0.5824|0.1|2.5|
  8. | category| 150| 0| NaN| NaN| NaN|NaN|NaN|

lazyPrintStatistics也可以指定标题内容,代码如下:

  1. lazyPrintStatistics(">>> summary of current data.")

输出结果为:

  1. >>> summary of current data.
  2. Summary:
  3. | colName|count|missing| sum| mean|variance|min|max|
  4. |------------|-----|-------|-----|------|--------|---|---|
  5. |sepal_length| 150| 0|876.5|5.8433| 0.6857|4.3|7.9|
  6. | sepal_width| 150| 0|458.1| 3.054| 0.188| 2|4.4|
  7. |petal_length| 150| 0|563.8|3.7587| 3.1132| 1|6.9|
  8. | petal_width| 150| 0|179.8|1.1987| 0.5824|0.1|2.5|
  9. | category| 150| 0| NaN| NaN| NaN|NaN|NaN|

在在SelectBatchOp组件之后再接一个输出统计结果,代码如下

  1. lazyPrintStatistics(">>> summary of final data.")

运行结果如下,可以看到当前数据的统计结果,保留了sepal_length和sepal_width列,增加了ratio列。对比SelectBatchOp组件前后的统计结果,有助于理解和验证操作的影响。

  1. >>> summary of final data.
  2. Summary:
  3. | colName|count|missing| sum| mean|variance| min| max|
  4. |------------|-----|-------|--------|------|--------|------|------|
  5. |sepal_length| 150| 0| 876.5|5.8433| 0.6857| 4.3| 7.9|
  6. | sepal_width| 150| 0| 458.1| 3.054| 0.188| 2| 4.4|
  7. | ratio| 150| 0|293.2717|1.9551| 0.159|1.2683|2.9615|

lazyCollect

lazyCollect方法可以获取当前的数据,用户能自定义更多的操作,下面代码演示了获取数据总行数并打印输出。

  1. .lazyCollect(new Consumer <List <Row>>() {
  2. @Override
  3. public void accept(List <Row> rows) {
  4. System.out.println("number of rows : " + rows.size());
  5. }
  6. })

运行结果为:

  1. number of rows : 150

lazyCollectStatistics方法提供了对统计结果TableSummary的自定义操作,下面代码演示了从统计信息中获取sepal_length列数据中,有效数据的行数及空值的行数。

  1. .lazyCollectStatistics(new Consumer <TableSummary>() {
  2. @Override
  3. public void accept(TableSummary tableSummary) {
  4. System.out.println("number of valid values :"
  5. + tableSummary.numValidValue("sepal_length"));
  6. System.out.println("number of missing values :"
  7. + tableSummary.numMissingValue("sepal_length"));
  8. }
  9. })

输出结果为:

  1. number of valid values :150
  2. number of missing values :0

Pipeline中的输出

在Pipeline中也可以输出中间的数据,统计信息和模型信息,便于我们了解Pipeline执行的过程。
还是以iris数据集为例,Pipeline中有两个操作:首先是使用Select组件,选取两列sepal_length和sepal_width,并将这两列的比值作为一个新的数据列,列名为ratio;然后使用StandardScaler组件,对sepal_length和sepal_width列执行标准化操作。具体代码如下:

  1. new Pipeline()
  2. .add(
  3. new Select()
  4. .setClause("sepal_length, sepal_width, sepal_length/sepal_width AS ratio")
  5. .enableLazyPrintTransformData(5, ">>> output data after Select")
  6. .enableLazyPrintTransformStat(">>> summary of data after Select ")
  7. )
  8. .add(
  9. new StandardScaler()
  10. .setSelectedCols("sepal_length", "sepal_width")
  11. .enableLazyPrintModelInfo(">>> model info")
  12. .enableLazyPrintTransformData(5, ">>> output data after StandardScaler")
  13. .enableLazyPrintTransformStat(">>> summary of data after StandardScaler")
  14. )
  15. .fit(source)
  16. .transform(source)
  17. .lazyPrint(">>> output data after the whole pipeline");
  18. BatchOperator.execute();

enableLazyPrintTransformData

Pipeline Select阶段的运行结果,可以使用下面方法输出

  1. enableLazyPrintTransformData(5, ">>> output data after Select")

输出内容为:

  1. >>> output data after Select
  2. sepal_length|sepal_width|ratio
  3. ------------|-----------|-----
  4. 5.1000|3.5000|1.4571
  5. 4.9000|3.0000|1.6333
  6. 4.7000|3.2000|1.4688
  7. 4.6000|3.1000|1.4839
  8. 5.0000|3.6000|1.3889

Pipeline StandardScaler阶段的运行结果,可以使用下面方法输出

  1. enableLazyPrintTransformData(5, ">>> output data after StandardScaler")

运行结果如下,可以看到左边两列经过标准化操作后的变化。

  1. >>> output data after StandardScaler
  2. sepal_length|sepal_width|ratio
  3. ------------|-----------|-----
  4. -0.8977|1.0286|1.4571
  5. -1.1392|-0.1245|1.6333
  6. -1.3807|0.3367|1.4688
  7. -1.5015|0.1061|1.4839
  8. -1.0184|1.2592|1.3889

enableLazyPrintTransformStat

使用下面的方法输出Pipeline Select阶段的统计结果,

  1. enableLazyPrintTransformStat(">>> summary of data after Select ")

运行结果为:

  1. >>> summary of data after Select
  2. Summary:
  3. | colName|count|missing| sum| mean|variance| min| max|
  4. |------------|-----|-------|--------|------|--------|------|------|
  5. |sepal_length| 150| 0| 876.5|5.8433| 0.6857| 4.3| 7.9|
  6. | sepal_width| 150| 0| 458.1| 3.054| 0.188| 2| 4.4|
  7. | ratio| 150| 0|293.2717|1.9551| 0.159|1.2683|2.9615|

使用下面的方法输出Pipeline StandardScaler阶段的统计结果,

  1. enableLazyPrintTransformStat(">>> summary of data after StandardScaler")

输出统计结果如下,注意:经过标准化操作,sepal_length和sepal_width两列的均值都为0,方差都为1.

  1. >>> summary of data after StandardScaler
  2. Summary:
  3. | colName|count|missing| sum| mean|variance| min| max|
  4. |------------|-----|-------|--------|------|--------|-------|------|
  5. |sepal_length| 150| 0| -0| -0| 1|-1.8638|2.4837|
  6. | sepal_width| 150| 0| -0| -0| 1|-2.4308|3.1043|
  7. | ratio| 150| 0|293.2717|1.9551| 0.159| 1.2683|2.9615|

enableLazyPrintModelInfo

还可以使用Lazy方法打印输出模型信息,Pipeline StandardScaler阶段的模型打印输出代码如下:

  1. enableLazyPrintModelInfo(">>> model info")

运行结果如下,模型中包含了各列的均值和标准差信息。

  1. >>> model info
  2. ------------------------- StandardScalerModelInfo -------------------------
  3. ============================ means information ============================
  4. [5.8433, 3.054]
  5. ===================== standard deviation information =====================
  6. [0.8281, 0.4336]