def predict_instance()

in runtime/native/python/treelite_runtime/predictor.py [0:0]


  def predict_instance(self, inst, missing=None, pred_margin=False):
    """
    Perform single-instance prediction. Prediction is run by the calling thread.

    Parameters
    ----------
    inst: :py:class:`numpy.ndarray` / :py:class:`scipy.sparse.csr_matrix` /\
          :py:class:`dict <python:dict>`
        Data instance for which a prediction will be made. If ``inst`` is of
        type :py:class:`scipy.sparse.csr_matrix`, its first dimension must be 1
        (``shape[0]==1``). If ``inst`` is of type :py:class:`numpy.ndarray`,
        it must be one-dimensional. If ``inst`` is of type
        :py:class:`dict <python:dict>`, it must be a dictionary where the keys
        indicate feature indices (0-based) and the values corresponding
        feature values.
    missing : :py:class:`float <python:float>`, optional
        Value in the data instance that represents a missing value. If set to
        ``None``, ``numpy.nan`` will be used. Only applicable if ``inst`` is
        of type :py:class:`numpy.ndarray`.
    pred_margin: :py:class:`bool <python:bool>`, optional
        Whether to produce raw margins rather than transformed probabilities
    """
    entry = (PredictorEntry * self.num_feature_)()
    for i in range(self.num_feature_):
      entry[i].missing = -1

    if isinstance(inst, scipy.sparse.csr_matrix):
      if inst.shape[0] != 1:
        raise ValueError('inst cannot have more than one row')
      if inst.shape[1] > self.num_feature_:
        raise ValueError('Too many features. This model was trained with only '+\
                         '{} features'.format(self.num_feature_))
      for i in range(inst.nnz):
        entry[inst.indices[i]].fvalue = inst.data[i]
    elif isinstance(inst, scipy.sparse.csc_matrix):
      raise TypeError('inst must be csr_matrix')
    elif isinstance(inst, np.ndarray):
      if len(inst.shape) > 1:
        raise ValueError('inst must be 1D')
      if inst.shape[0] > self.num_feature_:
        raise ValueError('Too many features. This model was trained with only '+\
                         '{} features'.format(self.num_feature_))
      if missing is None or np.isnan(missing):
        for i in range(inst.shape[0]):
          if not np.isnan(inst[i]):
            entry[i].fvalue = inst[i]
      else:
        for i in range(inst.shape[0]):
          if inst[i] != missing:
            entry[i].fvalue = inst[i]
    elif isinstance(inst, dict):
      for k, v in inst.items():
        entry[k].fvalue = v
    else:
      raise TypeError('inst must be NumPy array, SciPy CSR matrix, or a dictionary')

    result_size = ctypes.c_size_t()
    _check_call(_LIB.TreelitePredictorQueryResultSizeSingleInst(
        self.handle,
        ctypes.byref(result_size)))
    out_result = np.zeros(result_size.value, dtype=np.float32, order='C')
    out_result_size = ctypes.c_size_t()
    _check_call(_LIB.TreelitePredictorPredictInst(
        self.handle,
        ctypes.byref(entry),
        ctypes.c_int(1 if pred_margin else 0),
        out_result.ctypes.data_as(ctypes.POINTER(ctypes.c_float)),
        ctypes.byref(out_result_size)))
    idx = int(out_result_size.value)
    res = out_result[0:idx].reshape((1, -1)).squeeze()
    if self.num_output_group_ > 1:
      res = res.reshape((-1, self.num_output_group_))
    return res