'Transform new points into embedding space.
Parameters
X : array-like, shape = [n_samples, n_features]
Returns
X_new : array, shape = [n_samples, n_components]
Notes
Because of scaling performed by this method, it is discouraged to use
it together with methods that are not scale-invariant (like SVMs)'

def transform(self, X):

    check_is_fitted(self, 'nbrs_')
    X = check_array(X)
    ind = self.nbrs_.kneighbors(X, n_neighbors=self.n_neighbors, return_distance=False)
    weights = barycenter_weights(X, self.nbrs_._fit_X[ind], reg=self.reg)
    X_new = np.empty((X.shape[0], self.n_components))
    for i in range(X.shape[0]):
        X_new[i] = np.dot(self.embedding_[ind[i]].T, weights[i])
    return X_new
