Jak mogę zadzwonić do scikit-poznaj klasyfikatory z Javy?

Mam klasyfikator, który trenowałem używając Pythona scikit-learn. Jak Mogę używać klasyfikatora z programu Java? Czy Mogę używać Jython? Czy jest jakiś sposób, aby zapisać klasyfikator w Pythonie i załadować go w Javie? Jest jakiś inny sposób, by go użyć?

Author: Thomas Johnson, 2012-10-05

5 answers

Nie możesz używać jythona jako scikit-learn w dużym stopniu opiera się na numpy i scipy, które mają wiele skompilowanych rozszerzeń C i Fortran, dlatego nie mogą działać w jython.

Najprostszym sposobem użycia scikit-learn w środowisku java byłoby:

  • Wyświetlanie klasyfikatora jako usługi HTTP / Json, na przykład za pomocą mikroframeworku, takiego jak flask lub bottle lub cornice i wywołaj go z Javy za pomocą biblioteki klienta HTTP

  • Napisz a aplikacja wrapper wiersza poleceń w Pythonie, która odczytuje dane na stdin i prognozy wyjściowe na stdout przy użyciu jakiegoś formatu, takiego jak CSV lub JSON (lub jakiejś reprezentacji binarnej niższego poziomu) i wywołuje program Pythona z Javy na przykład za pomocą Apache Commons Exec.

  • Spraw, aby program Pythona wypisywał surowe parametry numeryczne poznane w czasie dopasowania (zazwyczaj jako tablica wartości zmiennoprzecinkowych) i ponownie zaimplementował funkcję predict w Javie (jest to zwykle łatwe dla predykcyjne modele liniowe, gdzie PREDYKCJA jest często tylko progowym produktem kropkowym).

Ostatnie podejście będzie dużo więcej pracy, jeśli trzeba ponownie zaimplementować ekstrakcję funkcji w Javie, jak również.

Wreszcie możesz użyć biblioteki Javy, takiej jak Weka lub Mahout, która implementuje algorytmy, których potrzebujesz, zamiast próbować używać scikit-ucz się z Javy.

 37
Author: ogrisel,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-10-05 09:05:29

Istnieje jpmml projekt do tego celu.

Najpierw możesz serializować model scikit-learn do PMML (który jest wewnętrznie XML) za pomocą biblioteki sklearn2pmml bezpośrednio z Pythona lub najpierw zrzucić go w Pythonie i przekonwertować za pomocą jpmml-sklearn w Javie lub z wiersza poleceń dostarczonego przez tę bibliotekę. Następnie możesz załadować plik pmml, deserializować i wykonać załadowany model za pomocą jpmml-evaluator w kodzie Java.

Ten sposób działa z nie wszystkimi scikit-ucz się modeli, ale z wielu z nich.

 14
Author: Dmitry Spikhalskiy,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-08-10 16:39:01

Możesz użyć Portera, przetestowałem sklearn-porter ( https://github.com/nok/sklearn-porter ) i działa dobrze w Javie.

Mój kod jest następujący:

import pandas as pd
from sklearn import tree
from sklearn_porter import Porter

train_dataset = pd.read_csv('./result2.csv').as_matrix()

X_train = train_dataset[:90, :8]
Y_train = train_dataset[:90, 8:]

X_test = train_dataset[90:, :8]
Y_test = train_dataset[90:, 8:]

print X_train.shape
print Y_train.shape


clf = tree.DecisionTreeClassifier()
clf = clf.fit(X_train, Y_train)

porter = Porter(clf, language='java')
output = porter.export(embed_data=True)
print(output)

W moim przypadku używam DecisionTreeClassifier, A Wyjście

Print (output)

To następujący kod jako tekst w konsoli:

class DecisionTreeClassifier {

  private static int findMax(int[] nums) {
    int index = 0;
    for (int i = 0; i < nums.length; i++) {
        index = nums[i] > nums[index] ? i : index;
    }
    return index;
  }


  public static int predict(double[] features) {
    int[] classes = new int[2];

    if (features[5] <= 51.5) {
        if (features[6] <= 21.0) {

            // HUGE amount of ifs..........

        }
    }

    return findMax(classes);
  }

  public static void main(String[] args) {
    if (args.length == 8) {

        // Features:
        double[] features = new double[args.length];
        for (int i = 0, l = args.length; i < l; i++) {
            features[i] = Double.parseDouble(args[i]);
        }

        // Prediction:
        int prediction = DecisionTreeClassifier.predict(features);
        System.out.println(prediction);

    }
  }
}
 3
Author: gustavoresque,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-03-04 19:16:07

Oto kod do rozwiązania JPMML:

--PYTHON PART--

# helper function to determine the string columns which have to be one-hot-encoded in order to apply an estimator.
def determine_categorical_columns(df):
    categorical_columns = []
    x = 0
    for col in df.dtypes:
        if col == 'object':
            val = df[df.columns[x]].iloc[0]
            if not isinstance(val,Decimal):
                categorical_columns.append(df.columns[x])
        x += 1
    return categorical_columns

categorical_columns = determine_categorical_columns(df)
other_columns = list(set(df.columns).difference(categorical_columns))


#construction of transformators for our example
labelBinarizers = [(d, LabelBinarizer()) for d in categorical_columns]
nones = [(d, None) for d in other_columns]
transformators = labelBinarizers+nones

mapper = DataFrameMapper(transformators,df_out=True)
gbc = GradientBoostingClassifier()

#construction of the pipeline
lm = PMMLPipeline([
    ("mapper", mapper),
    ("estimator", gbc)
])

--JAVA PART --

//Initialisation.
String pmmlFile = "ScikitLearnNew.pmml";
PMML pmml = org.jpmml.model.PMMLUtil.unmarshal(new FileInputStream(pmmlFile));
ModelEvaluatorFactory modelEvaluatorFactory = ModelEvaluatorFactory.newInstance();
MiningModelEvaluator evaluator = (MiningModelEvaluator) modelEvaluatorFactory.newModelEvaluator(pmml);

//Determine which features are required as input
HashMap<String, Field>() inputFieldMap = new HashMap<String, Field>();
for (int i = 0; i < evaluator.getInputFields().size();i++) {
  InputField curInputField = evaluator.getInputFields().get(i);
  String fieldName = curInputField.getName().getValue();
  inputFieldMap.put(fieldName.toLowerCase(),curInputField.getField());
}


//prediction

HashMap<String,String> argsMap = new HashMap<String,String>();
//... fill argsMap with input

Map<FieldName, ?> res;
// here we keep only features that are required by the model
Map<FieldName,String> args = new HashMap<FieldName, String>();
Iterator<String> iter = argsMap.keySet().iterator();
while (iter.hasNext()) {
  String key = iter.next();
  Field f = inputFieldMap.get(key);
  if (f != null) {
    FieldName name =f.getName();
    String value = argsMap.get(key);
    args.put(name, value);
  }
}
//the model is applied to input, a probability distribution is obtained
res = evaluator.evaluate(args);
SegmentResult segmentResult = (SegmentResult) res;
Object targetValue = segmentResult.getTargetValue();
ProbabilityDistribution probabilityDistribution = (ProbabilityDistribution) targetValue;
 1
Author: Volokh,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-02-16 13:05:25

Znalazłem się w podobnej sytuacji. Polecam wyrzeźbić mikroserwis klasyfikatora. Możesz mieć mikrousługę klasyfikatora, która działa w Pythonie, a następnie ujawniać wywołania do tej usługi przez jakiś RESTFul API dając format wymiany danych JSON / XML. Myślę, że to czystsze podejście.

 0
Author: Josh Uzo,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-05-11 12:50:16