def test_shape_ignore_msg_in_constructor(self): """ Ensures that a UserWarning is raised when the 'shape_ref_pos' keyword argument is passed to the Scobit model constructor. This warns people against expecting the shape parameters of the Scobit model to suffer from identification problems. It also alerts users that they are using a Scobit model when they might have been expecting to instantiate a different choice model. """ # Create a variable for the kwargs being passed to the constructor kwargs = deepcopy(self.constructor_kwargs) kwargs["shape_ref_pos"] = 2 # Test to ensure that the shape ignore message is printed when using # either of these two kwargs with warnings.catch_warnings(record=True) as context: # Use this filter to always trigger the UserWarnings warnings.simplefilter('always', UserWarning) # Create a Scobit model object with the irrelevant kwargs. # This should trigger a UserWarning scobit_obj = scobit.MNSL(*self.constructor_args, **kwargs) # Check that the warning has been created. self.assertEqual(len(context), 1) self.assertIsInstance(context[-1].category, type(UserWarning)) self.assertIn(scobit._shape_ref_msg, str(context[-1].message)) return None
def setUp(self): # The set up being used is one where there are two choice situations, # The first having three alternatives, and the second having only two # alternatives. There is one generic variable. Two alternative # specific constants and all three shape parameters are used. # Create the betas to be used during the tests self.fake_betas = np.array([-0.6]) # Create the fake outside intercepts to be used during the tests self.fake_intercepts = np.array([1, 0.5]) # Create names for the intercept parameters self.fake_intercept_names = ["ASC 1", "ASC 2"] # Record the position of the intercept that is not being estimated self.fake_intercept_ref_pos = 2 # Create the shape parameters to be used during the tests. Note that # these are the reparameterized shape parameters, thus they will be # exponentiated in the fit_mle process and various calculations. self.fake_shapes = np.array([-1, 0, 1]) # Create names for the intercept parameters self.fake_shape_names = ["Shape 1", "Shape 2", "Shape 3"] # Create an array of all model parameters self.fake_all_params = np.concatenate( (self.fake_shapes, self.fake_intercepts, self.fake_betas)) # The mapping between rows and alternatives is given below. self.fake_rows_to_alts = csr_matrix( np.array([[1, 0, 0], [0, 1, 0], [0, 0, 1], [1, 0, 0], [0, 0, 1]])) # Create the fake design matrix with columns denoting X # The intercepts are not included because they are kept outside the # index in the scobit model. self.fake_design = np.array([[1], [2], [3], [1.5], [3.5]]) # Create the index array for this set of choice situations self.fake_index = self.fake_design.dot(self.fake_betas) # Create the needed dataframe for the Scobit constructor self.fake_df = pd.DataFrame({ "obs_id": [1, 1, 1, 2, 2], "alt_id": [1, 2, 3, 1, 3], "choice": [0, 1, 0, 0, 1], "x": self.fake_design[:, 0], "intercept": [1 for i in range(5)] }) # Record the various column names self.alt_id_col = "alt_id" self.obs_id_col = "obs_id" self.choice_col = "choice" # Create the index specification and name dictionaryfor the model self.fake_specification = OrderedDict() self.fake_names = OrderedDict() self.fake_specification["x"] = [[1, 2, 3]] self.fake_names["x"] = ["x (generic coefficient)"] # Bundle the args and kwargs used to construct the Scobit model. self.constructor_args = [ self.fake_df, self.alt_id_col, self.obs_id_col, self.choice_col, self.fake_specification ] # Create a variable for the kwargs being passed to the constructor self.constructor_kwargs = { "intercept_ref_pos": self.fake_intercept_ref_pos, "names": self.fake_names, "intercept_names": self.fake_intercept_names, "shape_names": self.fake_shape_names } # Initialize a basic scobit model. # Create the scobit model object whose coefficients will be estimated. self.model_obj = scobit.MNSL(*self.constructor_args, **self.constructor_kwargs) return None
def make_uneven_and_scobit_models(self): # The set up being used is one where there are two choice situations, # The first having three alternatives, and the second having only two # alternatives. There is one generic variable. Two alternative # specific constants and all three shape parameters are used. # Create the betas to be used during the tests fake_betas = np.array([-0.6]) # Create the fake outside intercepts to be used during the tests fake_intercepts = np.array([1, 0.5]) # Create names for the intercept parameters fake_intercept_names = ["ASC 1", "ASC 2"] # Record the position of the intercept that is not being estimated fake_intercept_ref_pos = 2 # Create the shape parameters to be used during the tests. Note that # these are the reparameterized shape parameters, thus they will be # exponentiated in the fit_mle process and various calculations. fake_shapes = np.array([-1, 1, 2]) # Create names for the intercept parameters fake_shape_names = ["Shape 1", "Shape 2", "Shape 3"] # Create an array of all model parameters fake_all_params = np.concatenate( (fake_shapes, fake_intercepts, fake_betas)) # Get the mappping between rows and observations fake_rows_to_obs = csr_matrix( np.array([[1, 0], [1, 0], [1, 0], [0, 1], [0, 1]])) # Create the fake design matrix with columns denoting X # The intercepts are not included because they are kept outside the # index in the scobit model. fake_design = np.array([[1], [2], [3], [1.5], [3.5]]) # Create the index array for this set of choice situations fake_index = fake_design.dot(fake_betas) # Create the needed dataframe for the model constructor fake_df = pd.DataFrame({ "obs_id": [1, 1, 1, 2, 2], "alt_id": [1, 2, 3, 1, 3], "choice": [0, 1, 0, 0, 1], "x": fake_design[:, 0], "intercept": [1 for i in range(5)] }) # Record the various column names alt_id_col = "alt_id" obs_id_col = "obs_id" choice_col = "choice" # Create the index specification and name dictionary for the model fake_specification = OrderedDict() fake_names = OrderedDict() fake_specification["x"] = [[1, 2, 3]] fake_names["x"] = ["x (generic coefficient)"] # Bundle args and kwargs used to construct the choice models. constructor_args = [ fake_df, alt_id_col, obs_id_col, choice_col, fake_specification ] # Create a variable for the kwargs being passed to the constructor constructor_kwargs = { "intercept_ref_pos": fake_intercept_ref_pos, "names": fake_names, "intercept_names": fake_intercept_names, "shape_names": fake_shape_names } # Initialize the various choice models uneven_obj = uneven.MNUL(*constructor_args, **constructor_kwargs) scobit_obj = scobit.MNSL(*constructor_args, **constructor_kwargs) for model_obj in [uneven_obj, scobit_obj]: model_obj.coefs = pd.Series(fake_betas, index=fake_names["x"]) model_obj.intercepts =\ pd.Series(fake_intercepts, index=fake_intercept_names) model_obj.shapes = pd.Series(fake_shapes, index=fake_shape_names) model_obj.nests = None model_obj.params =\ pd.concat([model_obj.shapes, model_obj.intercepts, model_obj.coefs], axis=0, ignore_index=False) return uneven_obj, scobit_obj