jeffgortmaker / pyblp

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

Supply-side moments for subset of markets #151

Closed JulianHidalgoRodriguez closed 8 months ago

JulianHidalgoRodriguez commented 9 months ago

Hi,

To estimate a demand model, I would like to know if it is possible to add the supply side for only a subset of markets. The reason is that for those markets I have (external) information on the marginal cost which I would like to use to discipline the demand parameters.

In practice, I need to compute the supply-side moment conditions for the subset of markets and stack them to the demand moments. For the subset of markets, I can parametrize the marginal cost as a linear function of the external marginal cost variable (with the parameter in gamma fixed to one) and without constant.

Is there a way to implement this in pyblp or a workaround?

Thanks for your time.

jeffgortmaker commented 9 months ago

If your supply-side specification is c_{jt} = \hat{c}_{jt} + \omega_{jt} for all t \in \hat{T} where you observe your external information \hat{c}_{jt} and your desired moment condition is E[\omega_{jt}] = 0 for t \in \hat{T}, then I think you can implement this by having a single supply-side instrument z_{jt} = 1\{t \in \hat{T}\}, i.e. a dummy for being in these markets. Let me know if you think that would work.

To implement this, you'd have to set pyblp.Problem(..., add_exogenous=False) and manually specify your full set of demand- and supply-side instruments. The default behavior of add_exogenous=True would be to have your supply-side instrument be \hat{c}_{jt}, which isn't exactly what you want (although it'll do something similar if \hat{c}_{jt} is zero for all t \in \hat{T}).

One caveat is that this approach might bias your standard errors downward. If asymptotically the share of markets with external marginal cost information is some fixed \hat{T} / T \to \lambda < 1, then you should scale the supply-side block of your moments' asymptotic VCV by an estimate of something like 1 / \lambda, i.e. the number of total markets T divided by the number of markets \hat{T} for which you have external information on marginal cost. I'm less sure about the off-diagonal part of this VCV matrix (i.e. the covariance between \omega_{jt} and your demand-side moments), since I'm not sure about the DGP for your external cost information. Maybe you can just assume that \omega_{jt} is measurement error uncorrelated with your demand-side moments -- then this off-diagonal would be zero.

JulianHidalgoRodriguez commented 8 months ago

Thank you for the guidance. I have implemented the supply-side moments together with a nested logit demand model. Everything seems to be working well (i.e. the predicted average marginal cost is in line with the moment I impose) although the estimation time increases by a lot. Moving forward, I tried to estimate the random coefficients nested logit model. The code was running for almost 48 hours and didn't converge. I carefully followed the optimization process and it was working (not stuck) but very slowly.

I think that I need to explore different optimization algorithms (with alternative options) to see whether I can speed up the process. I will let you know if I come across anything related to this issue.

Good point you made on the adjustment of the VCV matrix.

Thanks again for your support!

jeffgortmaker commented 8 months ago

Glad it's working! Adding a supply side does take significantly more compute, so that's expected. Adding random coefficients also takes significantly more time. A couple of quick suggestions to help speed stuff up:

  1. If a lot of the time for RCNL is spent on the contraction, you may want to try a Jacobian-based iteration routine (e.g. LM) instead of the default (SQUAREM). With a high nesting parameter (e.g. close to 1), the contraction needs to be very dampened, and Jacobian-based routines are relatively more unaffected by this dampening.
  2. When adding random coefficients, the main thing that will slow you down is the number of draws/agents per market. Using quadrature or scrambled Halton draws instead of simple Monte Carlo draws can help speed things up.

I'm going to close this for now, but please do re-open/keep commenting, either here or in another issue, if you have other questions.