Skip to content

Item prod 2vec#309

Open
michaelteboul wants to merge 2 commits intomainfrom
item_prod_2vec
Open

Item prod 2vec#309
michaelteboul wants to merge 2 commits intomainfrom
item_prod_2vec

Conversation

@michaelteboul
Copy link
Contributor

Description of the goal of the PR

Description:

Changes this PR introduces (fill it before implementation)

  • : Add Item2vec/Prod2vec to our pool of model

@gemini-code-assist
Copy link
Contributor

Summary of Changes

Hello @michaelteboul, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed!

This pull request expands the available basket recommendation models by introducing the Item2vec/Prod2vec model, enhancing the system's capability to generate item embeddings and predict purchases. Concurrently, an existing self-attention model has been refactored with a more concise name, improving clarity and organization within the model pool.

Highlights

  • New Model Introduction: A new Item2vec class has been added, implementing the Item/Prod_2vec model for basket recommendation, complete with methods for initialization, instantiation, utility computation, negative sampling, and loss calculation.
  • Model Renaming: The SelfAttentionModel class and its corresponding file self_attention_model.py have been renamed to AttRec and att_rec.py respectively, along with updates to its docstring.

🧠 New Feature in Public Preview: You can now enable Memory to help Gemini Code Assist learn from your team's feedback. This makes future code reviews more consistent and personalized to your project's style. Click here to enable Memory in your admin console.

Changelog
  • choice_learn/basket_models/att_rec.py
    • Renamed the file from self_attention_model.py to att_rec.py.
    • Updated the class name from SelfAttentionModel to AttRec.
    • Modified the class docstring to reflect the new AttRec name.
  • choice_learn/basket_models/item2vec_prod2vec.py
    • Added a new file item2vec_prod2vec.py.
    • Introduced the Item2vec class, implementing the Item/Prod_2vec model.
    • Implemented __init__ method for model configuration, including latent sizes, negative samples, and regularization.
    • Added instantiate method to initialize model variables like item and store embeddings.
    • Defined trainable_weights property to list all trainable parameters.
    • Set train_iter_method property to 'prod2vec' for data generation.
    • Implemented compute_batch_utility for calculating item utilities within a batch.
    • Added get_negative_samples_sgns for generating negative samples using a skip-gram approach.
    • Provided compute_basket_utility for calculating the utility of an unordered basket.
    • Implemented compute_batch_loss to calculate the log-likelihood and loss for a batch, incorporating binary cross-entropy and L2 regularization.
Activity
  • The pull request description indicates the explicit goal of adding Item2vec/Prod2vec to the pool of models, with a checklist item marked for this change.
Using Gemini Code Assist

The full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips.

Invoking Gemini

You can request assistance from Gemini at any point by creating a comment using either /gemini <command> or @gemini-code-assist <command>. Below is a summary of the supported commands on the current page.

Feature Command Description
Code Review /gemini review Performs a code review for the current pull request in its current state.
Pull Request Summary /gemini summary Provides a summary of the current pull request in its current state.
Comment @gemini-code-assist Responds in comments when explicitly tagged, both in pull request comments and review comments.
Help /gemini help Displays a list of available commands.

Customization

To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a .gemini/ folder in the base of the repository. Detailed instructions can be found here.

Limitations & Feedback

Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for Github and other Google products, sign up here.

You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension.

Footnotes

  1. Review the Privacy Notices, Generative AI Prohibited Use Policy, Terms of Service, and learn how to configure Gemini Code Assist in GitHub here. Gemini can make mistakes, so double check it and use code with caution.

Copy link
Contributor

@gemini-code-assist gemini-code-assist bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request introduces the Item2vec/Prod2vec model and renames SelfAttentionModel to AttRec. The new Item2vec model implementation appears to be a mix of new logic and code copied from other models, which has resulted in several critical issues. There are uninitialized attributes that will cause AttributeError at runtime, a potential crash from a nullable parameter that isn't checked, and significant amounts of dead or confusing code. My review focuses on fixing these critical bugs and improving code clarity by removing unused logic and correcting documentation.

momentum: float = 0.0,
epsilon_price: float = 1e-5,
l2_regularization: float = 0.0,
item_counts: list[int] = None,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

critical

The item_counts parameter defaults to None, but it's used on line 102 without a null check, which will cause a TypeError at runtime. Since this parameter is essential for negative sampling, it should be a required argument.

Suggested change
item_counts: list[int] = None,
item_counts: list[int],

Comment on lines +143 to +147
if n_stores == 0 and self.price_effects:
# To take into account the price effects, the number of stores must be > 0
# to have a delta embedding
# (By default, the store id is 0)
n_stores = 1
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

critical

self.price_effects is used here but is not initialized in __init__, which will cause an AttributeError. Since price effects are not implemented in this model, this check is incorrect. The logic should be adjusted to ensure n_stores is at least 1, as it's needed for the theta embedding.

Suggested change
if n_stores == 0 and self.price_effects:
# To take into account the price effects, the number of stores must be > 0
# to have a delta embedding
# (By default, the store id is 0)
n_stores = 1
if n_stores == 0:
# To have a theta embedding, the number of stores must be > 0
# (By default, the store id is 0)
n_stores = 1

Comment on lines +185 to +192
if self.item_intercept:
weights.append(self.alpha)
if self.price_effects:
weights.extend([self.beta, self.delta])

if self.seasonal_effects:
weights.extend([self.mu, self.nu])

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

critical

This code accesses uninitialized attributes self.item_intercept, self.price_effects, and self.seasonal_effects, which will cause an AttributeError. The weights these blocks would add (alpha, beta, etc.) are also not defined. Since these features are not part of the model, this logic should be removed.

        return weights

Comment on lines +43 to +49
item_intercept: bool, optional
Whether to include item intercept in the model, by default True
Corresponds to the item intercept
price_effects: bool, optional
Whether to include price effects in the model, by default True
seasonal_effects: bool, optional
Whether to include seasonal effects in the model, by default False
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

high

The parameters item_intercept, price_effects, and seasonal_effects are mentioned in the docstring but are not part of the function signature, nor are they implemented in the model. This is misleading and contributes to AttributeErrors in other methods. Please remove this part of the docstring to align with the model's actual implementation.

Comment on lines +55 to +67
by default {"preferences": 4, "price": 4, "season": 4}
n_negative_samples: int, optional
Number of negative samples to draw for each positive sample for the training,
by default 2
Must be > 0
optimizer: str, optional
Optimizer to use for training, by default "adam"
callbacks: tf.keras.callbacks.Callbacklist, optional
List of callbacks to add to model.fit, by default None and only add History
lr: float, optional
Learning rate, by default 1e-3
epochs: int, optional
Number of epochs, by default 100
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

high

The docstrings for latent_sizes and epochs are inconsistent with their default values in the function signature.

  • latent_sizes: The docstring default is {"preferences": 4, "price": 4, "season": 4}, but the code default is {"preferences": 4}.
  • epochs: The docstring default is 100, but the code default is 10.

Please update the docstrings to match the code.

Comment on lines +456 to +458
price_batch: np.ndarray
Batch of prices (floats) for each purchased item
Shape must be (batch_size,)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

high

The docstring for price_batch states its shape is (batch_size,). However, based on its usage (e.g., line 492) and how batches are generated, the shape is actually (batch_size, n_items). Please correct the docstring here and in compute_batch_utility.

        price_batch: np.ndarray
            Batch of prices for all items, for each purchased item.
            Shape must be (batch_size, n_items)


def __init__(
self,
latent_sizes: dict[str] = {"preferences": 4},
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

The type hint for latent_sizes is dict[str], which is incomplete. It should be dict[str, int] to reflect that it's a mapping from string keys to integer values.

Suggested change
latent_sizes: dict[str] = {"preferences": 4},
latent_sizes: dict[str, int] = {"preferences": 4},

n_items: int,
n_stores: int = 0,
) -> None:
"""Instantiate the Shopper model.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

The docstring refers to the "Shopper model", which appears to be a copy-paste error. It should refer to the Item2vec model.

Suggested change
"""Instantiate the Shopper model.
"""Instantiate the Item2vec model.

Comment on lines +480 to +484
# --- NOUVEAU CODE (VECTORISÉ) ---
negative_samples = self.get_negative_samples_sgns(
item_batch=item_batch, basket_batch=basket_batch, n_samples=self.n_negative_samples
) # Shape: (batch_size, n_negative_samples)
# ----------------------------------------------
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

This comment is in French and appears to be a temporary developer note. It should be removed.

        # Negative sampling
        negative_samples = self.get_negative_samples_sgns(
            item_batch=item_batch, basket_batch=basket_batch, n_samples=self.n_negative_samples
        )  # Shape: (batch_size, n_negative_samples)

Comment on lines +526 to +539
# ----------------Loss computation----------------#
bce = tf.keras.backend.binary_crossentropy(
# Target: 1 for positive samples, 0 for negative samples
target=tf.concat(
[
tf.ones_like(positive_samples_utilities),
tf.zeros_like(negative_samples_utilities),
],
axis=1,
),
output=tf.nn.sigmoid(all_utilities),
) # Shape: (batch_size * (n_negative_samples + 1),)

# --------------------------------------------------#
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

These comments appear to be temporary developer notes and should be removed from the final code.

        )  # Shape of loglikelihood: (1,))
        bce = tf.keras.backend.binary_crossentropy(
            # Target: 1 for positive samples, 0 for negative samples
            target=tf.concat(
                [
                    tf.ones_like(positive_samples_utilities),
                    tf.zeros_like(negative_samples_utilities),
                ],
                axis=1,
            ),
            output=tf.nn.sigmoid(all_utilities),
        )  # Shape: (batch_size * (n_negative_samples + 1),)

@github-actions
Copy link
Contributor

Coverage

Coverage Report for Python 3.10
FileStmtsMissCoverMissing
choice_learn
   __init__.py20100% 
   tf_ops.py62198%283
choice_learn/basket_models
   __init__.py40100% 
   alea_carta.py1482285%86–90, 92–96, 98–102, 106, 109, 131, 159, 308, 431–455
   att_rec.py1331330%3–651
   base_basket_model.py2352789%111–112, 123, 141, 185, 255, 377, 485, 585–587, 676, 762, 772, 822–830, 891–894, 934–935
   basic_attention_model.py89496%424, 427, 433, 440
   item2vec_prod2vec.py1281280%3–544
   shopper.py184995%130, 159, 325, 345, 360, 363, 377, 489, 618
choice_learn/basket_models/data
   __init__.py20100% 
   basket_dataset.py1903383%74–77, 294–298, 331, 407, 540–576, 636, 658–661, 700–705, 790–801, 849
   preprocessing.py947817%43–45, 128–364
choice_learn/basket_models/datasets
   __init__.py30100% 
   bakery.py38392%47, 51, 61
   synthetic_dataset.py811186%62, 112–113, 152–158, 194–199, 247
choice_learn/basket_models/utils
   __init__.py00100% 
   permutation.py22195%37
choice_learn/data
   __init__.py30100% 
   choice_dataset.py6493395%198, 250, 283, 421, 463–464, 589, 724, 738, 840, 842, 937, 957–961, 1140, 1159–1161, 1179–1181, 1209, 1214, 1223, 1240, 1281, 1293, 1307, 1346, 1361, 1366, 1395, 1408, 1443–1444
   indexer.py2412390%20, 31, 45, 60–67, 202–204, 219–230, 265, 291, 582
   storage.py161696%22, 33, 51, 56, 61, 71
   store.py72720%3–275
choice_learn/datasets
   __init__.py40100% 
   base.py400599%42–43, 153–154, 714
   expedia.py1028319%37–301
   tafeng.py490100% 
choice_learn/datasets/data
   __init__.py00100% 
choice_learn/models
   __init__.py14286%15–16
   base_model.py3353590%145, 187, 289, 297, 303, 312, 352, 356–357, 362, 391, 395–396, 413, 426, 434, 475–476, 485–486, 587, 589, 605, 609, 611, 734–735, 935, 939–953
   baseline_models.py490100% 
   conditional_logit.py2692690%49, 52, 54, 85, 88, 91–95, 98–102, 136, 206, 212–216, 351, 388, 445, 520–526, 651, 685, 822, 826
   halo_mnl.py1241885%186, 341, 360, 364–380
   latent_class_base_model.py2863986%55–61, 273–279, 288, 325–330, 497–500, 605, 624, 665–701, 715, 720, 751–752, 774–775, 869–870, 974
   latent_class_mnl.py62690%257–261, 296
   learning_mnl.py67396%157, 182, 188
   nested_logit.py2911296%55, 77, 160, 269, 351, 484, 530, 600, 679, 848, 900, 904
   reslogit.py132695%285, 360, 369, 374, 382, 432
   rumnet.py236399%748–751, 982
   simple_mnl.py139696%167, 275, 347, 355, 357, 359
   tastenet.py94397%142, 180, 188
choice_learn/toolbox
   __init__.py00100% 
   assortment_optimizer.py27678%28–30, 93–95, 160–162
   gurobi_opt.py2382380%3–675
   or_tools_opt.py2301195%103, 107, 296–305, 315, 319, 607, 611
choice_learn/utils
   metrics.py854349%74, 126–130, 147–166, 176, 190–199, 211–232, 242
TOTAL5774112980% 

Tests Skipped Failures Errors Time
217 0 💤 1 ❌ 1 🔥 7m 55s ⏱️

@github-actions
Copy link
Contributor

Coverage

Coverage Report for Python 3.11
FileStmtsMissCoverMissing
choice_learn
   __init__.py20100% 
   tf_ops.py62198%283
choice_learn/basket_models
   __init__.py40100% 
   alea_carta.py1482285%86–90, 92–96, 98–102, 106, 109, 131, 159, 308, 431–455
   att_rec.py1331330%3–651
   base_basket_model.py2352789%111–112, 123, 141, 185, 255, 377, 485, 585–587, 676, 762, 772, 822–830, 891–894, 934–935
   basic_attention_model.py89496%424, 427, 433, 440
   item2vec_prod2vec.py1281280%3–544
   shopper.py184995%130, 159, 325, 345, 360, 363, 377, 489, 618
choice_learn/basket_models/data
   __init__.py20100% 
   basket_dataset.py1903383%74–77, 294–298, 331, 407, 540–576, 636, 658–661, 700–705, 790–801, 849
   preprocessing.py947817%43–45, 128–364
choice_learn/basket_models/datasets
   __init__.py30100% 
   bakery.py38392%47, 51, 61
   synthetic_dataset.py811186%62, 112–113, 152–158, 194–199, 247
choice_learn/basket_models/utils
   __init__.py00100% 
   permutation.py22195%37
choice_learn/data
   __init__.py30100% 
   choice_dataset.py6493395%198, 250, 283, 421, 463–464, 589, 724, 738, 840, 842, 937, 957–961, 1140, 1159–1161, 1179–1181, 1209, 1214, 1223, 1240, 1281, 1293, 1307, 1346, 1361, 1366, 1395, 1408, 1443–1444
   indexer.py2412390%20, 31, 45, 60–67, 202–204, 219–230, 265, 291, 582
   storage.py161696%22, 33, 51, 56, 61, 71
   store.py72720%3–275
choice_learn/datasets
   __init__.py40100% 
   base.py400599%42–43, 153–154, 714
   expedia.py1028319%37–301
   tafeng.py490100% 
choice_learn/datasets/data
   __init__.py00100% 
choice_learn/models
   __init__.py14286%15–16
   base_model.py3353590%145, 187, 289, 297, 303, 312, 352, 356–357, 362, 391, 395–396, 413, 426, 434, 475–476, 485–486, 587, 589, 605, 609, 611, 734–735, 935, 939–953
   baseline_models.py490100% 
   conditional_logit.py2692690%49, 52, 54, 85, 88, 91–95, 98–102, 136, 206, 212–216, 351, 388, 445, 520–526, 651, 685, 822, 826
   halo_mnl.py124298%186, 374
   latent_class_base_model.py2863986%55–61, 273–279, 288, 325–330, 497–500, 605, 624, 665–701, 715, 720, 751–752, 774–775, 869–870, 974
   latent_class_mnl.py62690%257–261, 296
   learning_mnl.py67396%157, 182, 188
   nested_logit.py2911296%55, 77, 160, 269, 351, 484, 530, 600, 679, 848, 900, 904
   reslogit.py132695%285, 360, 369, 374, 382, 432
   rumnet.py236399%748–751, 982
   simple_mnl.py139696%167, 275, 347, 355, 357, 359
   tastenet.py94397%142, 180, 188
choice_learn/toolbox
   __init__.py00100% 
   assortment_optimizer.py27678%28–30, 93–95, 160–162
   gurobi_opt.py2382380%3–675
   or_tools_opt.py2301195%103, 107, 296–305, 315, 319, 607, 611
choice_learn/utils
   metrics.py854349%74, 126–130, 147–166, 176, 190–199, 211–232, 242
TOTAL5774111381% 

Tests Skipped Failures Errors Time
217 0 💤 1 ❌ 1 🔥 8m 7s ⏱️

@github-actions
Copy link
Contributor

Coverage

Coverage Report for Python 3.9
FileStmtsMissCoverMissing
choice_learn
   __init__.py20100% 
   tf_ops.py62198%283
choice_learn/basket_models
   __init__.py40100% 
   alea_carta.py1482285%86–90, 92–96, 98–102, 106, 109, 131, 159, 308, 431–455
   att_rec.py1331330%3–651
   base_basket_model.py2352789%111–112, 123, 141, 185, 255, 377, 485, 585–587, 676, 762, 772, 822–830, 891–894, 934–935
   basic_attention_model.py89496%424, 427, 433, 440
   item2vec_prod2vec.py1281280%3–544
   shopper.py184995%130, 159, 325, 345, 360, 363, 377, 489, 618
choice_learn/basket_models/data
   __init__.py20100% 
   basket_dataset.py1903383%74–77, 294–298, 331, 407, 540–576, 636, 658–661, 700–705, 790–801, 849
   preprocessing.py947817%43–45, 128–364
choice_learn/basket_models/datasets
   __init__.py30100% 
   bakery.py38392%47, 51, 61
   synthetic_dataset.py811186%62, 112–113, 152–158, 194–199, 247
choice_learn/basket_models/utils
   __init__.py00100% 
   permutation.py22195%37
choice_learn/data
   __init__.py30100% 
   choice_dataset.py6493395%198, 250, 283, 421, 463–464, 589, 724, 738, 840, 842, 937, 957–961, 1140, 1159–1161, 1179–1181, 1209, 1214, 1223, 1240, 1281, 1293, 1307, 1346, 1361, 1366, 1395, 1408, 1443–1444
   indexer.py2412390%20, 31, 45, 60–67, 202–204, 219–230, 265, 291, 582
   storage.py161696%22, 33, 51, 56, 61, 71
   store.py72720%3–275
choice_learn/datasets
   __init__.py40100% 
   base.py400599%42–43, 153–154, 714
   expedia.py1028319%37–301
   tafeng.py490100% 
choice_learn/datasets/data
   __init__.py00100% 
choice_learn/models
   __init__.py14286%15–16
   base_model.py3353590%145, 187, 289, 297, 303, 312, 352, 356–357, 362, 391, 395–396, 413, 426, 434, 475–476, 485–486, 587, 589, 605, 609, 611, 734–735, 935, 939–953
   baseline_models.py490100% 
   conditional_logit.py2692690%49, 52, 54, 85, 88, 91–95, 98–102, 136, 206, 212–216, 351, 388, 445, 520–526, 651, 685, 822, 826
   halo_mnl.py124298%186, 374
   latent_class_base_model.py2863986%55–61, 273–279, 288, 325–330, 497–500, 605, 624, 665–701, 715, 720, 751–752, 774–775, 869–870, 974
   latent_class_mnl.py62690%257–261, 296
   learning_mnl.py67396%157, 182, 188
   nested_logit.py2911296%55, 77, 160, 269, 351, 484, 530, 600, 679, 848, 900, 904
   reslogit.py132695%285, 360, 369, 374, 382, 432
   rumnet.py236399%748–751, 982
   simple_mnl.py139696%167, 275, 347, 355, 357, 359
   tastenet.py94397%142, 180, 188
choice_learn/toolbox
   __init__.py00100% 
   assortment_optimizer.py27678%28–30, 93–95, 160–162
   gurobi_opt.py2362360%3–675
   or_tools_opt.py2301195%103, 107, 296–305, 315, 319, 607, 611
choice_learn/utils
   metrics.py854349%74, 126–130, 147–166, 176, 190–199, 211–232, 242
TOTAL5772111181% 

Tests Skipped Failures Errors Time
217 0 💤 0 ❌ 1 🔥 6m 54s ⏱️

@github-actions
Copy link
Contributor

Coverage

Coverage Report for Python 3.12
FileStmtsMissCoverMissing
choice_learn
   __init__.py20100% 
   tf_ops.py62198%283
choice_learn/basket_models
   __init__.py40100% 
   alea_carta.py1482285%86–90, 92–96, 98–102, 106, 109, 131, 159, 308, 431–455
   att_rec.py1331330%3–651
   base_basket_model.py2352789%111–112, 123, 141, 185, 255, 377, 485, 585–587, 676, 762, 772, 822–830, 891–894, 934–935
   basic_attention_model.py89496%424, 427, 433, 440
   item2vec_prod2vec.py1281280%3–544
   shopper.py184995%130, 159, 325, 345, 360, 363, 377, 489, 618
choice_learn/basket_models/data
   __init__.py20100% 
   basket_dataset.py1903383%74–77, 294–298, 331, 407, 540–576, 636, 658–661, 700–705, 790–801, 849
   preprocessing.py947817%43–45, 128–364
choice_learn/basket_models/datasets
   __init__.py30100% 
   bakery.py38392%47, 53, 61
   synthetic_dataset.py811186%62, 112–113, 152–158, 194–199, 247
choice_learn/basket_models/utils
   __init__.py00100% 
   permutation.py22195%37
choice_learn/data
   __init__.py30100% 
   choice_dataset.py6493395%198, 250, 283, 421, 463–464, 589, 724, 738, 840, 842, 937, 957–961, 1140, 1159–1161, 1179–1181, 1209, 1214, 1223, 1240, 1281, 1293, 1307, 1346, 1361, 1366, 1395, 1408, 1443–1444
   indexer.py2412390%20, 31, 45, 60–67, 202–204, 219–230, 265, 291, 582
   storage.py161696%22, 33, 51, 56, 61, 71
   store.py72720%3–275
choice_learn/datasets
   __init__.py40100% 
   base.py400599%42–43, 153–154, 714
   expedia.py1028319%37–301
   tafeng.py490100% 
choice_learn/datasets/data
   __init__.py00100% 
choice_learn/models
   __init__.py14286%15–16
   base_model.py3353590%145, 187, 289, 297, 303, 312, 352, 356–357, 362, 391, 395–396, 413, 426, 434, 475–476, 485–486, 587, 589, 605, 609, 611, 734–735, 935, 939–953
   baseline_models.py490100% 
   conditional_logit.py2692690%49, 52, 54, 85, 88, 91–95, 98–102, 136, 206, 212–216, 351, 388, 445, 520–526, 651, 685, 822, 826
   halo_mnl.py124298%186, 374
   latent_class_base_model.py2863986%55–61, 273–279, 288, 325–330, 497–500, 605, 624, 665–701, 715, 720, 751–752, 774–775, 869–870, 974
   latent_class_mnl.py62690%257–261, 296
   learning_mnl.py67396%157, 182, 188
   nested_logit.py2911296%55, 77, 160, 269, 351, 484, 530, 600, 679, 848, 900, 904
   reslogit.py132695%285, 360, 369, 374, 382, 432
   rumnet.py236399%748–751, 982
   simple_mnl.py139696%167, 275, 347, 355, 357, 359
   tastenet.py94397%142, 180, 188
choice_learn/toolbox
   __init__.py00100% 
   assortment_optimizer.py27678%28–30, 93–95, 160–162
   gurobi_opt.py2382380%3–675
   or_tools_opt.py2301195%103, 107, 296–305, 315, 319, 607, 611
choice_learn/utils
   metrics.py854349%74, 126–130, 147–166, 176, 190–199, 211–232, 242
TOTAL5774111381% 

Tests Skipped Failures Errors Time
217 0 💤 0 ❌ 1 🔥 8m 44s ⏱️

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant