我有一个分类,我使用Python的scikit学习培训。我如何使用Java程序中的分类器?我可以使用Jython吗?有没有办法在Python中保存分类器并使用Java加载它?有没有其他的方式来使用它?如何从Java调用scikit-learn分类器?
回答
不能用Jython作为scikit学习在很大程度上依赖于numpy的和SciPy的有许多编译C和Fortran扩展,因此可以用Jython无法工作。
使用最简单的方法在Java环境scikit学习将是:
使用microframework暴露分类为HTTP/Json的服务,例如,如flask或bottle或cornice和使用HTTP客户端库
在python写一个命令行包装应用的是使用一些格式诸如CSV或JSON(或一些较低级别的二进制表示)在stdout上stdin和输出预测读取数据从Java调用它,并调用python程序f rom java例如使用Apache Commons Exec。
使python程序输出在拟合时学习的原始数值参数(通常作为浮点值的数组),并重新实现java中的预测函数(对于预测通常只是预测线性模型一个阈值点积)。
如果您还需要在Java中重新实现特征提取,最后一种方法将会有更多的工作。
最后,你可以使用Java库,如Weka的或亨利马乌实现你需要的,而不是试图用从Java scikit学习算法。
有这个目的JPMML项目。首先,您可以直接使用sklearn2pmml库将pyikit-learn模型序列化为PMML(内部是XML),或者先使用python将其转储为python,然后使用java中的jpmml-sklearn或该库提供的命令行进行转换。接下来,你可以加载PMML文件,反序列化,并在Java代码中使用jpmml-evaluator执行加载的模型。
这种工作方式与不是所有scikit学习机型,但与他们的many。
如何确保功能转换部分在用于培训的Python和用Java完成的功能(使用pmml)之间保持一致? –
下面是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;
您可以使用一个搬运工,我已经测试了sklearn-porter(https://github.com/nok/sklearn-porter),并且它适用于Java。
我的代码如下:
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)
就我而言,我使用的是DecisionTreeClassifier,和
打印输出(输出)
是以下代码作为控制台中的文本:
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);
}
}
}
- 1. 使用Scikitlearn为音乐流派分类创建kNN分类器
- 2. 使用Scikitlearn和kNearestNeighbor分类器对音乐进行故障分类
- 3. 如何从java类调用javafx类?
- 4. 如何从jmeter调用java类?
- 5. 如何调用从普通的java类
- 6. 如何从Android活动调用Java类
- 7. 如何从JSP调用Java类
- 8. 如何从OnItemClick()调用java类?
- 9. 如何调用Java类从JSP文件
- 10. 如何从onClick Java调用一个类
- 11. 如何从Adobe调用Java类空气
- 12. 分层抽样的python scikitlearn
- 13. 从Java类调用C#类
- 14. 如何从java控制器调用JSP
- 15. 如何从java类调用xtend2生成器?
- 16. 从MATLAB调用WEKA Ridor分类器
- 17. 使用scikitlearn检索错误分类的文档
- 18. 如何调用Java类 - Eclipse
- 19. 从perl调用java类
- 20. 从javascript调用java类
- 21. 调用子类从Java中
- 22. 从Java类调用Acceleo Generator
- 23. 从IzPack调用Java类
- 24. 如何从Java调用Perl?
- 25. 如何从Java调用
- 26. 如何从java调用DLL?
- 27. 如何从Java调用C++?
- 28. 如何从asp调用java?
- 29. 如何从Java调用
- 30. 如何从java类中分离方法
我的一位同事刚刚建议Jepp ...是否会为此付出努力? –
也许,我不知道jepp。它确实看起来适合这项任务。 – ogrisel
对于一个网络应用程序,我个人更喜欢http曝光方法。然后,@ user939259可以为各种应用程序使用分类池并更轻松地进行扩展(根据需求调整池大小)。我只考虑Jepp的桌面应用程序。尽管我喜欢python,但除非scikit-lear比Weka或Mahout有更好的表现,否则我会选择单一语言的解决方案。拥有多种语言/框架应被视为技术性债务。 – rbanffy