Обычно перенос длинной кодовой базы с одного языка программирования на другой является сложной задачей, а иногда это даже не имеет смысла. Если вы используете Java и вам нужно применить модель машинного обучения из scikit-learn, это руководство может вам помочь.
Для этой цели мы будем использовать 3 библиотеки: scikit-learn, sklearn2pmml и pllm4s. Для облегчения управления данными мы также используем другие библиотеки, но при необходимости вы можете заменить их.
Как выглядит код
Чтобы экспортировать модель, у нас есть простые шаги, как описано ниже. В этом примере мы используем регрессор в классе PMMLPipeline, но вы можете использовать классификатор, если хотите. Не забудьте добавить scikit-learn и sklearn2pmml в зависимости вашего проекта Python.
from sklearn.datasets import load_diabetes from sklearn.tree import DecisionTreeRegressor from sklearn2pmml import PMMLPipeline, sklearn2pmml import pandas as pd # fetching data example df = load_diabetes() X = pd.DataFrame(columns = df.feature_names, data = df.get('data')) y = pd.DataFrame(columns = ['target'], data = df.get('target')) # here you can use the key classifier, if suitable pipeline = PMMLPipeline([ ('regressor', DecisionTreeRegressor()) ]) #training the model pipeline.fit(X, y) # exporting the model sklearn2pmml(pipeline, 'model.pmml', with_repr = True)
Обязательно добавьте имена столбцов в свой набор данных, иначе вы не сможете идентифицировать функции в коде Java. Также этот пример очень простой, но если у вас сложная задача, вы всегда можете использовать больше функционала библиотеки, заглянув в документацию SkLearn2PMML.
В коде Java также очень просто делать свои прогнозы. Мы показываем пример ниже. В этом примере мы используем библиотеку pmml4s, поэтому не забудьте добавить свои зависимости.
import org.pmml4s.model.Model; import java.util.*; public class Main { private final Model model = Model.fromFile(Main.class.getClassLoader().getResource("model.pmml").getFile()); public Double getRegressionValue(Map<String, Double> values) { Object[] valuesMap = Arrays.stream(model.inputNames()) .map(values::get) .toArray(); Object[] result = model.predict(valuesMap); return (Double) result[0]; } public static void main(String[] args) { Main main = new Main(); Map<String, Double> values = Map.of( "age", 20d, "sex", 1d, "bmi", -100d, "bp", -200d, "s1", 1d, "s2", 2d, "s3", 3d, "s4", 4d, "s5", 5d, "s6", 6d ); double predicted = main.getRegressionValue(values); System.out.println(predicted); } }
Для этого java-кода основным методом, который нам нужен, является predict, и вы можете просто передать ему массив. Упростите код настолько, насколько хотите, но просто обратите внимание на порядок, в котором вы добавляете эти функции в этот массив, и именно поэтому мы использовали карту. Метод inputNames показывает именно тот порядок ввода объектов, которому необходимо следовать.
Проверка того, что это работает
В целях тестирования я экспортировал те же тестовые данные, которые использовал в коде Python, и импортировал их в код Java. Существует множество показателей, которые мы можем использовать для оценки наших моделей машинного обучения, и здесь используется MAE (Mean Absolute Error), потому что он очень прост и интуитивно понятен.
Глядя на рисунок выше, мы видим, что MAE одинаков в обоих кодах. Это означает, что мы предсказываем одни и те же значения, и это просто идея проверить, правильно ли вы экспортировали свою модель. Вы также можете использовать любую другую метрику, чтобы убедиться в этом.
Коды, используемые в этом тесте, доступны по адресу:
- Python: https://colab.research.google.com/drive/1OFdBfKQrqRpRb0jWZtq7kgv7M3JRfs-o?usp=sharing#scrollTo=DuJq1np-ln1q
- Java: https://replit.com/@JhonatanSilva3/MachineLearningPipeline#Main.java
Надеюсь, это вам как-то поможет (: