Predictionio 评估失败,出现 empty.maxBy 异常,训练失败 java.lang.OutOfMemoryError

Predictionio evaluation fails with empty.maxBy exception and training with java.lang.OutOfMemoryError

我已经下载了 text classification 模板的最新更新。我创建了一个新应用并通过指定应用 ID

导入了 stopwords.json 和 emails.json
$ pio import --appid <appID> --input data/stopwords.json
$ pio import --appid <appID> --input data/emails.json

然后我更改了 engine.json 并在其中提供了我的应用程序名称。

{
   "id": "default",
   "description": "Default settings",
   "engineFactory":   "org.template.textclassification.TextClassificationEngine",
   "datasource": {
   "params": {
   "appName": "<myapp>",
   "evalK": 3
}

但是下一步,即评估失败并出现错误 empty.maxBy。下面贴出部分错误

[INFO] [Engine$] Preparator:  org.template.textclassification.Preparator@79a13920
[INFO] [Engine$] AlgorithmList: List(org.template.textclassification.LRAlgorithm@420a8042)
[INFO] [Engine$] Serving: org.template.textclassification.Serving@faea4da
Exception in thread "main" java.lang.UnsupportedOperationException:  empty.maxBy
at scala.collection.TraversableOnce$class.maxBy(TraversableOnce.scala:223)
at scala.collection.AbstractTraversable.maxBy(Traversable.scala:105)
at org.template.textclassification.PreparedData.<init> (Preparator.scala:160)
at org.template.textclassification.Preparator.prepare(Preparator.scala:39)
at org.template.textclassification.Preparator.prepare(Preparator.scala:35)
at io.prediction.controller.PPreparator.prepareBase(PPreparator.scala:34)
at io.prediction.controller.Engine$$anonfun.apply(Engine.scala:758)
at scala.collection.MapLike$MappedValues.get(MapLike.scala:249)
at scala.collection.MapLike$MappedValues.get(MapLike.scala:249)
at scala.collection.MapLike$class.apply(MapLike.scala:140)
at scala.collection.AbstractMap.apply(Map.scala:58)

然后我尝试了 pio train 但在显示一些观察结果后训练也失败了。显示的错误是 java.lang.OutOfMemoryError: Java heap space。错误的一部分粘贴在下面。

[INFO] [Engine$] Data santiy check is on.
[INFO] [Engine$] org.template.textclassification.TrainingData supports data sanity check. Performing check.

Observation 1 label: 1.0
Observation 2 label: 0.0
Observation 3 label: 0.0
Observation 4 label: 1.0
Observation 5 label: 1.0

[INFO] [Engine$] org.template.textclassification.PreparedData does not support data sanity check. Skipping check.
[WARN] [BLAS] Failed to load implementation from: com.github.fommil.netlib.NativeSystemBLAS
[WARN] [BLAS] Failed to load implementation from: com.github.fommil.netlib.NativeRefBLAS
[INFO] [Engine$] org.template.textclassification.NBModel does not support data sanity check. Skipping check.
[INFO] [Engine$] EngineWorkflow.train completed
[INFO] [Engine] engineInstanceId=AU3g4XyhTrUUakX3xepP
[INFO] [CoreWorkflow$] Inserting persistent model
Exception in thread "main" java.lang.OutOfMemoryError: Java heap space
at java.util.Arrays.copyOf(Arrays.java:3236)
at java.io.ByteArrayOutputStream.grow(ByteArrayOutputStream.java:118)
at  java.io.ByteArrayOutputStream.ensureCapacity(ByteArrayOutputStream.java:93)
at java.io.ByteArrayOutputStream.write(ByteArrayOutputStream.java:153)
at com.esotericsoftware.kryo.io.Output.flush(Output.java:155)
at com.twitter.chill.Tuple2Serializer.write(TupleSerializers.scala:36)
at com.twitter.chill.Tuple2Serializer.write(TupleSerializers.scala:33)
at com.esotericsoftware.kryo.Kryo.writeClassAndObject(Kryo.java:568)
at  com.twitter.chill.TraversableSerializer$$anonfun$write.apply(Traversable.scala:29)

这是不是内存不足?我有 运行 相同模板的先前版本,文本分类数据大于 40mb,没有问题。评估是培训的必要条件吗?也请您解释一下评估是如何进行的?

所以我只是能够运行评估没有前一个问题,后一个问题与内存使用有关。

同样,当您的数据未通过 DataSource 读入时,会出现 empty.maxBy 错误。我的第一个猜测是,如果您使用 appName 而不是 MyTextApp,请确保您也在 Evaluation.scala 脚本中的 EngineParamsList 对象中反映了该更改.您会看到您正在那里创建一个 DataSourceParams 对象用于评估。

对于 OutofMemoryError,您应该在训练/评估之前增加您的驾驶员记忆。这是通过执行以下操作完成的:

pio train -- --driver-memory xG --executor-memory yG pio eval org.template.textclassification.AccuracyEvaluation org.template.textclassification.EngineParamsList -- --driver-memory xG --executor-memory yG

将 --driver-memory 设置为 1G 或 2G 应该就足够了。

至于如何进行评估,PredictionIO默认进行k折交叉验证。为此,您的数据被分成大小大致相等的部分。为了便于说明,假设 k 为 3。然后在2/3的数据上训练一个模型,另外1/3的数据作为测试集来估计预测性能。对每 1/3 的数据重复此过程,然后将获得的 3 个性能估计值的平均值用作预测性能的最终估计值(在一般设置中,您必须自己决定什么是衡量此指标的合适指标) .对每个参数设置和您指定用于测试的模型重复此过程。

评估不是训练和部署的必要步骤,但是,它是 select 的一种方法,parameters/algorithms 应该用于训练和部署。它在机器学习/统计中被称为模型 selection。


编辑:至于文本向量化,每个文档按以下方式向量化:

假设我的文档是:

"I am Marco."

第一步是对其进行标记化,这将导致以下 Array/List 输出:

["I", "am", "Marco"]

然后,您进行双字母提取,其中存储以下标记集 arrays/lists:

["I", "am"], ["am", "Marco"], ["I"], ["am"], [ "Marco"]

其中每一个都用作构建二元组和单词计数向量的特征,然后应用 tf-idf 转换。请注意,要构建一个向量,我们必须从每个文档中提取二元组,这样这些特征向量就会变得非常大。您可以通过 increasing/decreasing 准备阶段的 inverseIdfMin/inverseIdfMax 值来减少很多。