概述: 我有两个项目A和B. 项目A必须使用L库/ API的版本v1。 项目B,必须使用L库/ API的版本v2。 项目A依赖于项目B(在项目A中,我需要调用B中包含的方法)。
具体说明: 项目A实际上是一个机器学习器,它有一组使用旧版本spark-mllib的算法。 我想在项目A中集成XGBOOST-spark算法。
问题是XGBOOST api,特别是:ml.dmlc.xgboost4j.scala.spark.XGBoost.train()方法,需要RDD<org.apache.spark.ml.feature.LabeledPoint>
。但是org.apache.spark.ml.feature.LabeledPoint仅在较新版本的spark-mllib中可用。从项目A(使用较旧版本的spark-mllib),我只能访问org.apache.spark.mllib.regression.LabeledPoint。因此,如果不升级项目A的spark-mllib版本,我无法直接在项目A中集成XGBOOST。
幸运的是,较新版本的spark-mllib有一种从旧的LabeledPoint(org.apache.spark.mllib.regression.LabeledPoint)转换为新的LabeledPoint(org.apache.spark.ml.feature.LabeledPoint)的方法。 )。方法是:org.apache.spark.mllib.regression.LabeledPoint.asML()。
所以,问题是:是否有任何聪明的方法使用仅在较新版本的spark中可用的方法.asML()
,以便我可以转换LabeledPoint并将其传递给XGBOOST API?< / p>
我不熟悉maven如何处理依赖关系,但我想到的是:
创建一个项目B,它使用较新版本的spark-mllib和XGBOOST-API,并且我们有一个类和一个接收参数的方法(来自项目A),将旧的LabeledPoint转换为新的LabeledPoint调用生成模型的XGBoost.train()方法,然后将模型传回项目A.我们在项目A中导入该类(来自项目B),调用它的方法,得到模型,我们照常继续我们的业务。
当然,我试图这样做。但它不起作用。我认为这是因为我们在整个依赖树中只能有一个版本的spark-mllib。由于项目B中的类抛出java.lang.NoSuchMethodError: org.apache.spark.mllib.regression.LabeledPoint.asML()Lorg/apache/spark/ml/feature/LabeledPoint;
,似乎在整个依赖关系树中,我们实际上使用了旧版本的spark-mllib(这是因为旧版本更接近依赖关系树的根) 。即使在项目B中,我们使用较新版本的spark-mllib,它具有asML()方法。
所以,实际的问题是:有没有聪明的方法使这项工作?没有在项目A上升级spark-mllib版本?升级不是一个可行的选择。项目A很大,如果我升级那个版本,我就搞砸了一切。
[更新] 我甚至尝试使用ClassLoader(URLClassLoader)来直接从spark-mllib_2.11-2.3.0.jar加载类并打印所有可用的方法。代码在这里:
URLClassLoader clsLoader = URLClassLoader.newInstance(new URL[] {
new URL("file:///home/myhome/spark-mllib_2.11-2.3.0.jar")
});
Class cls = clsLoader.loadClass("org.apache.spark.mllib.regression.LabeledPoint");
Method[] m = cls.getDeclaredMethods();
for (int i = 0; i < m.length; i++)
System.out.println(m[i].toString());
在我的.pom文件中,如果我添加依赖项:
<dependency>
<groupId>org.apache.spark</groupId>
<artifactId>spark-mllib_2.11</artifactId>
<version>2.3.0</version>
</dependency>
如果我使用2.3.0版本,方法public org.apache.spark.ml.feature.LabeledPoint org.apache.spark.mllib.regression.LabeledPoint.asML()
会出现结果。
但是当我使用spark-mllib的1.6.2版本时,它就不再存在了。 尽管asML()方法在spark-mllib的jar中。这有点奇怪。