def METHOD_NAME(self, train_set, val_set=None):
    """Fit the model to observations.
    Parameters
    ----------
    train_set: :obj:`cornac.data.Dataset`, required
        User-Item preference data as well as additional modalities.
    val_set: :obj:`cornac.data.Dataset`, optional, default: None
        User-Item preference data for model selection purposes (e.g., early stopping).
    Returns
    -------
    self : object
    """
    Recommender.METHOD_NAME(self, train_set, val_set)
    X = self.train_set.matrix
    X = sp.csr_matrix(X)
    # Skmeans requires rows of X to have a unit L2 norm. We therefore need to make a copy of X as we should not modify the latter.
    X1 = X.copy()
    X1 = X1.multiply(
        sp.csc_matrix(1.0 / (np.sqrt(X1.multiply(X1).sum(1).A1) + 1e-20)).T
    )
    if self.trainable:
        from .skmeans import skmeans
        res = skmeans(
            X1,
            k=self.k,
            max_iter=self.max_iter,
            tol=self.tol,
            verbose=self.verbose,
            seed=self.seed,
            init_par=getattr(self, "final_par", self.init_par),
        )
        self.centroids = res["centroids"]
        self.final_par = res["partition"]
    else:
        print("%s is trained already (trainable = False)" % (self.name))
    self.user_center_sim = (
            X1 * self.centroids.T
    )  # user-centroid cosine similarity matrix
    del X1
    return self