Общее описание:
У меня есть два проекта A и B.
Проект A, должен использовать версию v1 библиотеки L / API.
Проект B, должен использовать версию v2 библиотеки L / API.
Проект A зависит от проекта B (В проекте A мне нужно вызвать метод, содержащийся в B).
Конкретное описание:
Проект A на самом деле является машинным учеником, у которого есть набор алгоритмов, использующих более старую версию spark-mllib.
Я хочу интегрировать алгоритм XGBOOST-spark в проект A.
Проблема в том, что API XGBOOST, а именно: 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. Поэтому я не могу напрямую интегрировать XGBOOST в проект A без обновления версии spark-mllib проекта A.
К счастью, в новой версии spark-mllib есть метод преобразования из старой LabeledPoint (org.apache.spark.mllib.regression.LabeledPoint) в новую LabeledPoint (org.apache.spark.ml.feature.LabeledPoint. ). Метод: org.apache.spark.mllib.regression.LabeledPoint.asML ().
Итак, вопрос: есть ли какой-нибудь умный способ использования этого метода .asML()
, который доступен только в более новой версии spark, чтобы я мог преобразовать LabeledPoint и передать его в API-интерфейс XGBOOST?
Я не знаком с тем, как 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 ().
Итак, актуальный вопрос: есть ли какой-нибудь умный способ заставить эту работу? Без обновления версии 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>
Метод public org.apache.spark.ml.feature.LabeledPoint org.apache.spark.mllib.regression.LabeledPoint.asML()
представляет результаты, если я использую версию 2.3.0.
Но когда я использую версию 1.6.2 из spark-mllib, ее там больше нет.
Хотя метод asML () находится в банке spark-mllib. Что странно.