def evaluate(level, step, X):
    """Transform or predict according to the input level.

    This function uses the transform or the predict method on the input
    sklearn-like step according to its level (i.e. imputing, preproc, dimred,
    clustering, none).

    Parameters
    -----------
    level : {'imputing', 'preproc', 'dimred', 'clustering', 'None'}
        The step level.

    step : sklearn-like object
        This might be an Imputer, or a PCA, or a KMeans (and so on...)
        sklearn-like object.

    X : array of float, shape : n_samples x n_features
        The input data matrix.

    Returns
    -----------
    res : array of float
        A matrix projection in case of dimred, a label vector in case of
        clustering, and so on.
    """
    if level in ('imputing', 'preproc', 'dimred', 'None'):
        if hasattr(step, 'embedding_'):
            res = step.embedding_
        else:
            res = step.transform(X)
    elif level == 'clustering':
        if hasattr(step, 'labels_'):
            res = step.labels_
        elif hasattr(step, 'affinity') and step.affinity == 'precomputed':
            if not hasattr(step.estimator, 'labels_'):
                step.estimator.fit(X)
            res = step.estimator.labels_
        else:
            res = step.predict(X)
    return res
