Fit the model.

        Fit the model. Unlike fit, repeated calls to this method will
        cause training to resume from the current model state.

        For details on how to use feature matrices, see the documentation
        on the :class:`lightfm.LightFM` class.

        Arguments
        ---------

        interactions: np.float32 coo_matrix of shape [n_users, n_items]
             the matrix containing
             user-item interactions. Will be converted to
             numpy.float32 dtype if it is not of that type.
        user_features: np.float32 csr_matrix of shape [n_users, n_user_features], optional
             Each row contains that user's weights over features.
        item_features: np.float32 csr_matrix of shape [n_items, n_item_features], optional
             Each row contains that item's weights over features.
        sample_weight: np.float32 coo_matrix of shape [n_users, n_items], optional
             matrix with entries expressing weights of individual
             interactions from the interactions matrix.
             Its row and col arrays must be the same as
             those of the interactions matrix. For memory
             efficiency its possible to use the same arrays
             for both weights and interaction matrices.
             Defaults to weight 1.0 for all interactions.
             Not implemented for the k-OS loss.
        epochs: int, optional
             number of epochs to run
        num_threads: int, optional
             Number of parallel computation threads to use. Should
             not be higher than the number of physical cores.
        verbose: bool, optional
             whether to print progress messages.
             If `tqdm` is installed, a progress bar will be displayed instead.

        Returns
        -------

        LightFM instance
            the fitted model

def fit_partial(
        self,
        interactions,
        user_features=None,
        item_features=None,
        sample_weight=None,
        epochs=1,
        num_threads=1,
        verbose=False,
    ):
        """
        Fit the model.

        Fit the model. Unlike fit, repeated calls to this method will
        cause training to resume from the current model state.

        For details on how to use feature matrices, see the documentation
        on the :class:`lightfm.LightFM` class.

        Arguments
        ---------

        interactions: np.float32 coo_matrix of shape [n_users, n_items]
             the matrix containing
             user-item interactions. Will be converted to
             numpy.float32 dtype if it is not of that type.
        user_features: np.float32 csr_matrix of shape [n_users, n_user_features], optional
             Each row contains that user's weights over features.
        item_features: np.float32 csr_matrix of shape [n_items, n_item_features], optional
             Each row contains that item's weights over features.
        sample_weight: np.float32 coo_matrix of shape [n_users, n_items], optional
             matrix with entries expressing weights of individual
             interactions from the interactions matrix.
             Its row and col arrays must be the same as
             those of the interactions matrix. For memory
             efficiency its possible to use the same arrays
             for both weights and interaction matrices.
             Defaults to weight 1.0 for all interactions.
             Not implemented for the k-OS loss.
        epochs: int, optional
             number of epochs to run
        num_threads: int, optional
             Number of parallel computation threads to use. Should
             not be higher than the number of physical cores.
        verbose: bool, optional
             whether to print progress messages.
             If `tqdm` is installed, a progress bar will be displayed instead.

        Returns
        -------

        LightFM instance
            the fitted model
        """

        # We need this in the COO format.
        # If that's already true, this is a no-op.
        interactions = interactions.tocoo()

        if interactions.dtype != CYTHON_DTYPE:
            interactions.data = interactions.data.astype(CYTHON_DTYPE)

        sample_weight_data = self._process_sample_weight(interactions, sample_weight)

        n_users, n_items = interactions.shape
        (user_features, item_features) = self._construct_feature_matrices(
            n_users, n_items, user_features, item_features
        )

        for input_data in (
            user_features.data,
            item_features.data,
            interactions.data,
            sample_weight_data,
        ):
            self._check_input_finite(input_data)
        if self.item_embeddings is None:
            # Initialise latent factors only if this is the first call
            # to fit_partial.
            self._initialize(
                self.no_components, item_features.shape[1], user_features.shape[1]
            )

        # Check that the dimensionality of the feature matrices has
        # not changed between runs.
        if not item_features.shape[1] == self.item_embeddings.shape[0]:
            raise ValueError("Incorrect number of features in item_features")

        if not user_features.shape[1] == self.user_embeddings.shape[0]:
            raise ValueError("Incorrect number of features in user_features")

        if num_threads < 1:
            raise ValueError("Number of threads must be 1 or larger.")

        for _ in self._progress(epochs, verbose=verbose):
            self._run_epoch(
                item_features,
                user_features,
                interactions,
                sample_weight_data,
                num_threads,
                self.loss,
            )

            self._check_finite()

        return self