def fit(self, counts_df, val_set=None):
		"""
		Fit Hierarchical Poisson Model to sparse count data

		Fits a hierarchical Poisson model to count data using mean-field approximation with either
		full-batch coordinate-ascent or mini-batch stochastic coordinate-ascent.
		
		Note
		----
		DataFrames and arrays passed to '.fit' might be modified inplace - if this is a problem you'll
		need to pass a copy to them, e.g. 'counts_df=counts_df.copy()'.

		Note
		----
		Forcibly terminating the procedure should still keep the last calculated shape and rate
		parameter values, but is not recommended. If you need to make predictions on a forced-terminated
		object, set the attribute 'is_fitted' to 'True'.

		Note
		----
		Fitting in mini-batches is more prone to numerical instability and compared to full-batch
		variational inference, it is more likely that all your parameters will turn to NaNs (which
		means the optimization procedure failed).

		Parameters
		----------
		counts_df : pandas data frame (nobs, 3) or coo_matrix
			Input data with one row per non-zero observation, consisting of triplets ('UserId', 'ItemId', 'Count').
			Must containin columns 'UserId', 'ItemId', and 'Count'.
			Combinations of users and items not present are implicitly assumed to be zero by the model.
			Can also pass a sparse coo_matrix, in which case 'reindex' will be forced to 'False'.
		val_set : pandas data frame (nobs, 3)
			Validation set on which to monitor log-likelihood. Same format as counts_df.

		Returns
		-------
		self : obj
			Copy of this object
		"""

		## a basic check
		if self.stop_crit == 'val-llk':
			if val_set is None:
				raise ValueError("If 'stop_crit' is set to 'val-llk', must provide a validation set.")

		## running each sub-process
		if self.verbose:
			self._print_st_msg()
		self._process_data(counts_df)
		if self.verbose:
			self._print_data_info()
		if (val_set is not None) and (self.stop_crit!='diff-norm') and (self.stop_crit!='train-llk'):
			self._process_valset(val_set)
		else:
			self.val_set = None
			
		self._cast_before_fit()
		self._fit()
		
		## after terminating optimization
		if self.keep_data:
			if self.users_per_batch == 0:
				self._store_metadata()
			else:
				self._st_ix_user = self._st_ix_user[:-1]
		if self.produce_dicts and self.reindex:
			self.user_dict_ = {self.user_mapping_[i]:i for i in range(self.user_mapping_.shape[0])}
			self.item_dict_ = {self.item_mapping_[i]:i for i in range(self.item_mapping_.shape[0])}
		self.is_fitted = True
		del self.input_df
		del self.val_set
		
		return self
Fit Hierarchical Poisson Model to sparse count data

		Fits a hierarchical Poisson model to count data using mean-field approximation with either
		full-batch coordinate-ascent or mini-batch stochastic coordinate-ascent.
		
		Note
		----
		DataFrames and arrays passed to '.fit' might be modified inplace - if this is a problem you'll
		need to pass a copy to them, e.g. 'counts_df=counts_df.copy()'.

		Note
		----
		Forcibly terminating the procedure should still keep the last calculated shape and rate
		parameter values, but is not recommended. If you need to make predictions on a forced-terminated
		object, set the attribute 'is_fitted' to 'True'.

		Note
		----
		Fitting in mini-batches is more prone to numerical instability and compared to full-batch
		variational inference, it is more likely that all your parameters will turn to NaNs (which
		means the optimization procedure failed).

		Parameters
		----------
		counts_df : pandas data frame (nobs, 3) or coo_matrix
			Input data with one row per non-zero observation, consisting of triplets ('UserId', 'ItemId', 'Count').
			Must containin columns 'UserId', 'ItemId', and 'Count'.
			Combinations of users and items not present are implicitly assumed to be zero by the model.
			Can also pass a sparse coo_matrix, in which case 'reindex' will be forced to 'False'.
		val_set : pandas data frame (nobs, 3)
			Validation set on which to monitor log-likelihood. Same format as counts_df.

		Returns
		-------
		self : obj
			Copy of this object