def METHOD_NAME(self, X, y=None):
    """Fit LSI model to X and perform dimensionality reduction on X.
    Parameters
    ----------
    X : {array-like, sparse matrix}, shape (n_samples, n_features)
        Training data.
    Returns
    -------
    X_new : array, shape (n_samples, n_components)
        Reduced version of X. This will always be a dense array.
    """
    X = as_float_array(X, copy=False)
    random_state = check_random_state(self.random_state)
    # If sparse and not csr or csc, convert to csr
    if sp.issparse(X) and X.getformat() not in ["csr", "csc"]:
        X = X.tocsr()
    if self.algorithm == "arpack":
        U, Sigma, VT = svds(X, k=self.n_components, tol=self.tol)
        # svds doesn't abide by scipy.linalg.svd/randomized_svd
        # conventions, so reverse its outputs.
        Sigma = Sigma[::-1]
        U, VT = svd_flip(U[:, ::-1], VT[::-1])
    elif self.algorithm == "randomized":
        k = self.n_components
        n_features = X.shape[1]
        if k >= n_features:
            raise ValueError("n_components must be < n_features;"
                             " got %d >= %d" % (k, n_features))
        U, Sigma, VT = randomized_svd(X, self.n_components,
                                      n_iter=self.n_iter,
                                      random_state=random_state)
    else:
        raise ValueError("unknown algorithm %r" % self.algorithm)
    self.components_ = VT
    # Calculate explained variance & explained variance ratio
    X_transformed = U * Sigma
    self.explained_variance_ = exp_var = np.var(X_transformed, axis=0)
    if sp.issparse(X):
        _, full_var = mean_variance_axis(X, axis=0)
        full_var = full_var.sum()
    else:
        full_var = np.var(X, axis=0).sum()
    self.explained_variance_ratio_ = exp_var / full_var
    return X_transformed