<jupyter_start><jupyter_text>Building Differentiation Instruments Example<jupyter_code>import pyblp
import numpy as np
import pandas as pd

np.set_printoptions(precision=3)
pyblp.__version__<jupyter_output><empty_output><jupyter_text>In this example, we'll load the automobile product data from :ref:`references:Berry, Levinsohn, and Pakes (1995)`, build some very simple excluded demand-side instruments for the problem in the spirit of :ref:`references:Gandhi and Houde (2017)`, and demonstrate how to update the problem data to use these instrument instead of the default ones.<jupyter_code>product_data = pd.read_csv(pyblp.data.BLP_PRODUCTS_LOCATION)
product_data.head()<jupyter_output><empty_output><jupyter_text>We'll first build "local" differentiation instruments, which are constructed by default, and which consist of counts of "close" rival and non-rival products in each market. Note that we're excluding the constant column because it yields collinear constant columns of differentiation instruments.<jupyter_code>formulation = pyblp.Formulation('0 + hpwt + air + mpd')
local_instruments = pyblp.build_differentiation_instruments(
    formulation, 
    product_data
)
local_instruments<jupyter_output><empty_output><jupyter_text>Next, we'll build a more continuous "quadratic" version of the instruments, which consist of sums over squared differences between rival and non-rival products in each market.<jupyter_code>quadratic_instruments = pyblp.build_differentiation_instruments(
    formulation, 
    product_data,
    version='quadratic'
)
quadratic_instruments<jupyter_output><empty_output><jupyter_text>We could also use `interact=True` to include interaction terms in either version of instruments, which would help capture covariances between different product characteristics.To use these instruments when setting up a :class:`Problem`, the existing product data has to be updated or new product data has to be constructed. Since the existing product data is a Pandas `DataFrame`, it does not support matrices, so each column of instruments has to be added individually after deleting the existing instruments.<jupyter_code>for i in range(8):
    del product_data[f'demand_instruments{i}']

for i, column in enumerate(local_instruments.T):
    product_data[f'demand_instruments{i}'] = column

product_data<jupyter_output><empty_output><jupyter_text>Any data type that has fields can be used as product data. An alternative way to specify `problem_data` for :class:`Problem` initialization is to simply use a `dict`, where fields can be matrices. For example, we could use the following `dict`, which includes both the new demand instruments as well as a few other variables that might be used when setting up the problem.<jupyter_code>product_data_dict = {k: product_data[k] for k in ['market_ids', 'firm_ids', 'shares', 'prices', 'hpwt', 'air', 'mpd']}
product_data_dict['demand_instruments'] = local_instruments<jupyter_output><empty_output>
{'fraction_non_alphanumeric': 0.07181389076196898, 'fraction_numerical': 0.0037086985839514496, 'mean_word_length': 6.870026525198939, 'pattern_counts': {'":': 0, '<': 25, '<?xml version=': 0, '>': 25, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'chain_length': '6', 'dir': 'jupyter-structured-clean-dedup', 'id': '268875', 'license': 'MIT', 'n_tokens_mistral': 855, 'n_tokens_neox': 818, 'n_words': 309, 'path': 'docs/notebooks/api/build_differentiation_instruments.ipynb', 'repo_name': 'Asquidy/pyblp_alt', 'size': '2966'}