jeffgortmaker / pyblp

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

How to construct a separate pair of micro moments for each market #138

Closed ryosaka55 closed 1 year ago

ryosaka55 commented 1 year ago

Hi Jeff and Chris,

Thank you so much for this wonderful package. I am now working on incorporating micro moments in my estimation. Your paper suggests that matching a separate micro moment for each market may be helpful, but I could not figure out how to do this.

For instance, the codes below are from your tutorial about Petrin's paper. These codes construct a micro moment by pooling all markets (all years in this case). Could you show how to code for constructing micro moments for each market (year)?

I would like to consider separate moments for each market because my estimation with pooling moments could not converge. I guess this may be due to the fact that the observed values of moments are significantly different across geographic markets and the pooling moments have little power to identify parameters.

Thanks for your help!

[Petrin tutorial] age_mi_part = pyblp.MicroPart( name="E[age_i * mi_j]", dataset=micro_dataset, computevalues=lambda t, p, a: np.outer(a.demographics[:, 5], np.r[0, p.X2[:, 7]]), )

mi_part = pyblp.MicroPart( name="E[mi_j]", dataset=micro_dataset, computevalues=lambda t, p, a: np.outer(a.demographics[:, 0], np.r[0, p.X2[:, 7]]), )

micro_moments = [ pyblp.MicroMoment( name="E[age_i | mi_j]", value=0.783, parts=[age_mi_part, mi_part], compute_value=compute_ratio, compute_gradient=compute_ratio_gradient, ) ]

jeffgortmaker commented 1 year ago

The easiest way is probably to treat micro data from each separate market (or group of similar markets as we usually suggest) as a separate micro dataset with the market_ids argument.

ryosaka55 commented 1 year ago

Thank you so much for your suggestion. I am still struggling with setting up a separate micro data set with the market_ids argument...

In the Petrin example, there is no market_ids argument in the code of micro_dataset below. If I want to construct a micro data set only with the data of market_ids==0, how to code this?

micro_dataset = pyblp.MicroDataset( name="CEX", observations=29125, compute_weights=lambda t, p, a: np.ones((a.size, 1 + p.size)), )

The same question is applied to the coding of micropart. It seems to me that The code automatically uses the full set of product_data and agent_data. How to designate market_ids==0?

age_mi_part = pyblp.MicroPart( name="E[age_i * mi_j]", dataset=micro_dataset, computevalues=lambda t, p, a: np.outer(a.demographics[:, 5], np.r[0, p.X2[:, 7]]), )

I am so sorry for bothering you with such an elementary question... Any advice or suggestion will be very helpful to me.

Thanks.

jeffgortmaker commented 1 year ago

Ah, you need to look at the docs, not just the tutorial!

https://pyblp.readthedocs.io/en/stable/_api/pyblp.MicroDataset.html

You would set the market_ids argument with market_ids=[0]. Then all micro parts that derive from this dataset would also be restricted to just market ID 0.

ryosaka55 commented 1 year ago

Ah, I finally understand now. Thank you so much!! I really appreciate your support.