In this example, we will train an XGBoost regression model and convert it to CoreML. For more details on all the different ways to convert these models, see the coremltools XGBoost documentation.
For this example, we will follow a regression example in the XGBoost repository. For this example, we are predicting the performance of a computer system based on some features. This data comes from the UCI Machine Learning Repository Compute Hardware Data Set.
import xgboost as xgb
import matplotlib.pyplot as plt
First, we load the train and test data (already split):
dtrain = xgb.DMatrix('machine.txt.train')
dtest = xgb.DMatrix('machine.txt.test')
Train the model using parameters from the example:
param = {
'objective': 'reg:squarederror',
'eta': '1.0',
'gamma': 1.0,
'min_child_weight': 1,
'max_depth': 3,
}
bst_model = xgb.train(param, dtrain, num_boost_round=2)
And plot the tree:
xgb.plot_tree(bst_model, 'machine.featmap.txt')
fig = plt.gcf()
fig.set_size_inches(20, 40)
plt.show()
Next we can test the accuracy of the model on the training data:
prediction = bst_model.predict(dtrain)
actual = dtrain.get_label()
error = prediction - actual
print('mean error:', error.mean(), 'stdev error:', error.std())
plt.hist(error)
plt.xlabel('prediction - actual')
plt.show()
Converting an XGBoost model to CoreML format is much simpler than PyTorch or TensorFlow. However, if we want to use the proper feature names for model inputs, we need to load them and pass them to the convert
method.
feature_names = []
with open('machine.featmap.txt') as f:
for line in f.readlines():
feature_name = line.split()[1]
feature_names.append(feature_name)
feature_names
We can then use the desired feature names and the name of the model target (the output) during model conversion:
import coremltools as ct
cml_model = ct.converters.xgboost.convert(bst_model, feature_names=feature_names, target='perf', mode='regressor')
We can see the feature names in the metadata describing this model by looking at the string representation:
cml_model
Note that the vendor
categorical input is represented in the model as a one-hot-encoded value.
Finally, we can write the model to disk in the CoreML format.
cml_model.save('machine.mlmodel')
As with other CoreML model types, if we are on a macOS system, we can use the predict method to run the model. We can pass our input in the form of a dictionary with the feature values.
example = {
'MYCT': 125,
'MMIN': 256,
'MMAX': 6000,
'CACH': 256,
'CHMIN': 16,
'CHMAX': 128,
}
# Set the one-hot-encoded vendor feature
for feature_name in feature_names:
if feature_name == 'vendor:ibm':
example[feature_name] = 1
elif feature_name.startswith('vendor'):
example[feature_name] = 0
import sys
IS_MACOS = sys.platform == 'darwin'
if IS_MACOS:
loaded_model = ct.models.MLModel('machine.mlmodel')
prediction = loaded_model.predict(example)
print('prediction:', prediction)
else:
prediction = 'Skipping prediction on non-macOS system'