<SYSTEM_TASK:>
Solve the following problem using Python, implementing the functions described below, one line at a time
<END_TASK>
<USER_TASK:>
Description:
 def predict_proba(self, data, ntree_limit=None, validate_features=True):
 """ Predict the probability of each `data` example being of a given class. .. note:: This function is not thread safe For each booster object, predict can only be called from one thread. If you want to run prediction using multiple thread, call ``xgb.copy()`` to make copies of model object and then call predict Parameters data : DMatrix The dmatrix storing the input. ntree_limit : int Limit number of trees in the prediction; defaults to best_ntree_limit if defined (i.e. it has been trained with early stopping), otherwise 0 (use all trees). validate_features : bool When this is True, validate that the Booster's and data's feature_names are identical. Otherwise, it is assumed that the feature_names are the same. Returns ------- prediction : numpy array a numpy array with the probability of each data example being of a given class. """

        test_dmatrix = DMatrix(data, missing=self.missing, nthread=self.n_jobs)
        if ntree_limit is None:
            ntree_limit = getattr(self, "best_ntree_limit", 0)
        class_probs = self.get_booster().predict(test_dmatrix,
                                                 ntree_limit=ntree_limit,
                                                 validate_features=validate_features)
        if self.objective == "multi:softprob":
            return class_probs
        classone_probs = class_probs
        classzero_probs = 1.0 - classone_probs
        return np.vstack((classzero_probs, classone_probs)).transpose()