jeffgortmaker / pyblp

BLP Demand Estimation with Python
https://pyblp.readthedocs.io
MIT License
228 stars 82 forks source link

Nested Logit with Micro Moments #120

Closed andrew-heinzman closed 1 year ago

andrew-heinzman commented 1 year ago

Is there a way to incorporate micro moments into a nested logit model without random coefficients? In a nested logit model rho needs to be optimized and micro moments should help with identification.

As currently written I believe the package does not accept micro moments unless agent data is provided and agent data cannot be provided without formulating X2. A hacky workaround specifies a formulation for X2 and then sets sigma to 0 when solving the problem. However, this likely causes its own issues such as integrating when not necessary.

Thank you for all the hard work that's gone into the package it's a fantastic service!

jeffgortmaker commented 1 year ago

Right, so the correct way to do this is actually the hacky workaround that you suggested! You should specify a formulation for X2, probably including any characteristics that your micro moments will depend on. If your micro moments also depend on demographics, you'll have to specify a formulation for them as well.

Then you'll need to specify agent data. If you don't have any demographics (and you're just matching, for example, some second choice statistics, which should absolutely be informative about rho), you can just specify a single row per market with some arbitrary column of nodes, and set sigma to zero. This is actually what PyBLP does in the background for the simple nested logit model, so you won't be slowing anything down. If you do have demographics, you'll have to specify those.

Since you're using micro moments, I'll also note that they're under active development, so you should probably use the "dev" version by cloning this repo and adding it to your PYTHONPATH (and looking at the dev docs), instead of using the "stable" version via pip. I've changed up the micro moments interface a bit in the last few weeks, so if you use the stable version you'll have to modify your code for future versions.

andrew-heinzman commented 1 year ago

That's great and makes a lot of sense. The one drawback to the workaround is that I don't believe the package will take advantage of the closed form solution for rho (because X2 is specified). Is there a way to force the solver to avoid iterating over delta and instead use the closed form solution?

Good tip about the new micro moment interface. I really like the added functionality that comes with the changes (for example the added ability to use covariances helps a lot in the nested logit setting).

jeffgortmaker commented 1 year ago

Ah that's a good point. In b16345ab87a8e0997603579f6a6e749e2c586909, I just added support for a new delta_behavior='logit' that starts your delta at the solution to the nested logit model for the current rho. If you also set iteration=pyblp.Iteration('return'), iteration will be skipped and delta will just be set equal to the closed form solution. Let me know if this works / if you run into any issues!

FWIW I don't particularly like that this solution is sort of hackish, but I'm okay with it for now because adding informative micro moments to a nested logit model without any demographics seems like a pretty niche edge-case. If others start asking about this too I can think about a less hackish solution that wouldn't mess up the API too much.

andrew-heinzman commented 1 year ago

I've given it a shot and this solution seems to work great. Thank you!

jeffgortmaker commented 1 year ago

Great, glad to hear it! Thanks for the feedback.