Обычно перенос длинной кодовой базы с одного языка программирования на другой является сложной задачей, а иногда это даже не имеет смысла. Если вы используете 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 одинаков в обоих кодах. Это означает, что мы предсказываем одни и те же значения, и это просто идея проверить, правильно ли вы экспортировали свою модель. Вы также можете использовать любую другую метрику, чтобы убедиться в этом.

Коды, используемые в этом тесте, доступны по адресу:

Надеюсь, это вам как-то поможет (: