scikit-learn:将多输出决策树转换为 CoreML 模型

Posted

技术标签:

【中文标题】scikit-learn:将多输出决策树转换为 CoreML 模型【英文标题】:scikit-learn: Convert multi-output decision tree to CoreML model 【发布时间】:2017-12-30 15:49:42 【问题描述】:

我有一个训练有素的 scikit-learn 模型,它使用多输出决策树(作为 RandomForestRegressor)。没有明确对随机森林回归模型进行自定义配置以启用多输出行为,因为内置了多输出行为。基本上,只要将多输出训练数据拟合到模型中,模型就会在后台切换到多输出模式。

此外,RandomForestRegressor 是 CoreML 转换脚本提供的受支持的转换器。但是,在转换过程中,我收到了带有堆栈跟踪的此错误:

ValueError:预计 scikit-learn 树中只有 1 个输出。

Traceback (most recent call last):
  File "/Users/user0/Desktop/model_convert.py", line 7, in <module>
    coreml_model = sklearn_to_ml.convert(model)
  File "/Library/Python/2.7/site-packages/coremltools/converters/sklearn/_converter.py", line 146, in convert
    sk_obj, input_features, output_feature_names, class_labels = None)
  File "/Library/Python/2.7/site-packages/coremltools/converters/sklearn/_converter_internal.py", line 297, in _convert_sklearn_model
    last_spec = last_sk_m.convert(last_sk_obj, current_input_features, output_features)._spec
  File "/Library/Python/2.7/site-packages/coremltools/converters/sklearn/_random_forest_regressor.py", line 53, in convert
    return _MLModel(_convert_tree_ensemble(model, feature_names, target))
  File "/Library/Python/2.7/site-packages/coremltools/converters/sklearn/_tree_ensemble.py", line 195, in convert_tree_ensemble
    scaling = scaling, mode = mode, n_classes = n_classes, tree_index = tree_index)
  File "/Library/Python/2.7/site-packages/coremltools/converters/sklearn/_tree_ensemble.py", line 68, in _recurse
    _recurse(coreml_tree, scikit_tree, tree_id, left_child_id, scaling, mode, n_classes, tree_index)
  File "/Library/Python/2.7/site-packages/coremltools/converters/sklearn/_tree_ensemble.py", line 68, in _recurse
    _recurse(coreml_tree, scikit_tree, tree_id, left_child_id, scaling, mode, n_classes, tree_index)
  File "/Library/Python/2.7/site-packages/coremltools/converters/sklearn/_tree_ensemble.py", line 68, in _recurse
    _recurse(coreml_tree, scikit_tree, tree_id, left_child_id, scaling, mode, n_classes, tree_index)
  File "/Library/Python/2.7/site-packages/coremltools/converters/sklearn/_tree_ensemble.py", line 68, in _recurse
    _recurse(coreml_tree, scikit_tree, tree_id, left_child_id, scaling, mode, n_classes, tree_index)
  File "/Library/Python/2.7/site-packages/coremltools/converters/sklearn/_tree_ensemble.py", line 68, in _recurse
    _recurse(coreml_tree, scikit_tree, tree_id, left_child_id, scaling, mode, n_classes, tree_index)
  File "/Library/Python/2.7/site-packages/coremltools/converters/sklearn/_tree_ensemble.py", line 68, in _recurse
    _recurse(coreml_tree, scikit_tree, tree_id, left_child_id, scaling, mode, n_classes, tree_index)
  File "/Library/Python/2.7/site-packages/coremltools/converters/sklearn/_tree_ensemble.py", line 68, in _recurse
    _recurse(coreml_tree, scikit_tree, tree_id, left_child_id, scaling, mode, n_classes, tree_index)
  File "/Library/Python/2.7/site-packages/coremltools/converters/sklearn/_tree_ensemble.py", line 68, in _recurse
    _recurse(coreml_tree, scikit_tree, tree_id, left_child_id, scaling, mode, n_classes, tree_index)
  File "/Library/Python/2.7/site-packages/coremltools/converters/sklearn/_tree_ensemble.py", line 68, in _recurse
    _recurse(coreml_tree, scikit_tree, tree_id, left_child_id, scaling, mode, n_classes, tree_index)
  File "/Library/Python/2.7/site-packages/coremltools/converters/sklearn/_tree_ensemble.py", line 68, in _recurse
    _recurse(coreml_tree, scikit_tree, tree_id, left_child_id, scaling, mode, n_classes, tree_index)
  File "/Library/Python/2.7/site-packages/coremltools/converters/sklearn/_tree_ensemble.py", line 68, in _recurse
    _recurse(coreml_tree, scikit_tree, tree_id, left_child_id, scaling, mode, n_classes, tree_index)
  File "/Library/Python/2.7/site-packages/coremltools/converters/sklearn/_tree_ensemble.py", line 68, in _recurse
    _recurse(coreml_tree, scikit_tree, tree_id, left_child_id, scaling, mode, n_classes, tree_index)
  File "/Library/Python/2.7/site-packages/coremltools/converters/sklearn/_tree_ensemble.py", line 68, in _recurse
    _recurse(coreml_tree, scikit_tree, tree_id, left_child_id, scaling, mode, n_classes, tree_index)
  File "/Library/Python/2.7/site-packages/coremltools/converters/sklearn/_tree_ensemble.py", line 68, in _recurse
    _recurse(coreml_tree, scikit_tree, tree_id, left_child_id, scaling, mode, n_classes, tree_index)
  File "/Library/Python/2.7/site-packages/coremltools/converters/sklearn/_tree_ensemble.py", line 75, in _recurse
    raise ValueError('Expected only 1 output in the scikit-learn tree.')
ValueError: Expected only 1 output in the scikit-learn tree.

简单的转换代码如下:

from coremltools.converters import sklearn as sklearn_to_ml
from sklearn.externals import joblib

model = joblib.load("ms5000.pkl")

print("Converting model")
coreml_model = sklearn_to_ml.convert(model)

print("Saving CoreML model")
coreml_model.save("ms5000.mlmodel")

如何使 CoreML 转换脚本能够处理多输出决策树?我可以对现有脚本进行更改,而无需完全重新发明***吗?

【问题讨论】:

【参考方案1】:

CoreML(现在)是一个全新的事物,因此目前没有任何已知的第三方转换脚本来源。

coremltools documentation 的“模型”部分提供了有关如何使用 Python 生成 CoreML 模型的大量文档。话虽如此,您可以使用文档中提供的模型接口将任何机器学习模型转换为 CoreML 模型。

目前,coremltools 不支持多输出回归模型。如果您不想重新发明***,则需要通过引入与当前预测所针对的输出相对应的新输入,将模型转换为单一输出模型。

无论哪种方式,文档都在那里,可以帮助您入门。

【讨论】:

以上是关于scikit-learn:将多输出决策树转换为 CoreML 模型的主要内容,如果未能解决你的问题,请参考以下文章

是否可以使用 scikit-learn 指定决策树中的拆分顺序?

为决策树中的每个数据点找到对应的叶节点(scikit-learn)

是否可以在 scikit-learn 中打印决策树?

来自多种数据类型特征的决策树

来自多种数据类型特征的决策树

如何控制scikit-learn决策树算法的精度