Model Specification¶
In the following, we discuss the model specification in greater detail. In case the model specification is used to simulate a data set, the data generation is based on the chosen parameters. As soon as the estimation procedure is invoked, the values specified in the model specification are used as starting values for the optimization.
The model is specified in two separate files as we differentiate between the parameters of the model and other options. As an example we take the first parametrization of Keane and Wolpin (1994).
Parameter specification¶
The following table shows a parameter specification for respy. The first two columns,
category
and name
, can be used for indexing. para
contains the parameter
value. fixed
indicates whether the parameter is held constant during optimization.
lower
and upper
indicate lower and upper bounds for the parameter which are used
in conjunction with a constrained optimizer. In this example the discount factor is
bounded between 0.7 and 1.0. comment
contains a short description of the parameter.
category |
name |
para |
fixed |
lower |
upper |
comment |
---|---|---|---|---|---|---|
delta |
delta |
0.95 |
False |
0.7 |
1.0 |
discount factor |
coeffs_common |
return_hs_degree |
0.0 |
False |
return to high school degree (non pecuniary) |
||
coeffs_common |
return_col_degree |
0.0 |
False |
return to college degree (non pecuniary) |
||
coeffs_a |
skill_price |
9.21 |
False |
skill rental price if the base skill endowment of type 1 is normalized to 0 (wage) |
||
coeffs_a |
return_schooling |
0.038 |
False |
linear return to an additional year of schooling (wage) |
||
coeffs_a |
exp_a |
0.033 |
False |
return to experience, same sector, linear (wage) |
||
coeffs_a |
exp_a_square |
-0.0005 |
False |
return to experience, same sector, quadratic (divided by 100) (wage) |
||
coeffs_a |
exp_b |
0.0 |
False |
return to experience, other civilian sector, linear (wage) |
||
coeffs_a |
exp_b_square |
-0.0 |
False |
return to experience, other civilian sector, quadratic (divided by 100) (wage) |
||
coeffs_a |
premium_hs |
0.0 |
False |
skill premium of having finished high school (wage) |
||
coeffs_a |
premium_col |
-0.0 |
False |
skill premium of having finished college (wage) |
||
coeffs_a |
age |
0.0 |
False |
linear age effect (wage) |
||
coeffs_a |
minor |
0.0 |
False |
effect of being a minor (wage) |
||
coeffs_a |
not_first |
0.0 |
False |
gain of having worked in the same occupation at least once before (wage) |
||
coeffs_a |
no_switch |
0.0 |
False |
gain of remaining in the same occupation as previous period (wage) |
||
coeffs_a |
constant |
0.0 |
False |
constant (non pecuniary) |
||
coeffs_a |
first |
0.0 |
False |
reward of switching to a from other occupation (non pecuniary) |
||
coeffs_a |
switch |
0.0 |
False |
reward of working in a for the first time (non pecuniary) |
||
coeffs_b |
skill_price |
8.48 |
False |
skill rental price if the base skill endowment of type 1 is normalized to 0 (wage) |
||
coeffs_b |
return_schooling |
0.07 |
False |
linear return to an additional year of schooling (wage) |
||
coeffs_b |
exp_a |
0.022 |
False |
return to experience, other civilian sector, linear (wage) |
||
coeffs_b |
exp_a_square |
-0.0005 |
False |
return to experience, other civilian sector, quadratic (divided by 100) (wage) |
||
coeffs_b |
exp_b |
0.067 |
False |
return to experience, same sector, linear (wage) |
||
coeffs_b |
exp_b_square |
-0.001 |
False |
return to experience, same sector, quadratic (divided by 100) (wage) |
||
coeffs_b |
premium_hs |
0.0 |
False |
skill premium of having finished high school (wage) |
||
coeffs_b |
premium_col |
-0.0 |
False |
skill premium of having finished college (wage) |
||
coeffs_b |
age |
0.0 |
False |
linear age effect (wage) |
||
coeffs_b |
minor |
0.0 |
False |
effect of being a minor (wage) |
||
coeffs_b |
not_first |
0.0 |
False |
gain of having worked in the same occupation at least once before (wage) |
||
coeffs_b |
no_switch |
0.0 |
False |
gain of remaining in the same occupation as previous period (wage) |
||
coeffs_b |
constant |
0.0 |
False |
constant (non pecuniary) |
||
coeffs_b |
first |
0.0 |
False |
reward of switching to a from other occupation (non pecuniary) |
||
coeffs_b |
switch |
0.0 |
False |
reward of working in a for the first time (non pecuniary) |
||
coeffs_edu |
constant |
0.0 |
False |
consumption value of school attendance for type 1 |
||
coeffs_edu |
value_col |
-0.0 |
False |
consumption value of college |
||
coeffs_edu |
value_grad |
0.0 |
False |
consumption value of graduate school |
||
coeffs_edu |
reenroll_col |
-4000.0 |
False |
reward for going back to college |
||
coeffs_edu |
reenroll_hs |
-4000.0 |
False |
reward for going back to high school |
||
coeffs_edu |
age |
0.0 |
False |
linear age effect |
||
coeffs_edu |
minor |
0.0 |
False |
effect of being a minor |
||
coeffs_home |
constant |
17750.0 |
False |
mean value of non-market alternative for type 1 |
||
coeffs_home |
18_to_20 |
0.0 |
False |
additional value of staying home if aged 18-20 |
||
coeffs_home |
21_plus |
0.0 |
False |
additional value of staying home if 21 or older |
||
shocks |
chol_sigma_1 |
0.2 |
False |
Element 1,1 of cholesky factor of shock covariance matrix |
||
shocks |
chol_sigma_21 |
0.0 |
False |
Element 2,1 of cholesky factor of shock covariance matrix |
||
shocks |
chol_sigma_2 |
0.25 |
False |
Element 2,2 of cholesky factor of shock covariance matrix |
||
shocks |
chol_sigma_31 |
0.0 |
False |
Element 3,1 of cholesky factor of shock covariance matrix |
||
shocks |
chol_sigma_32 |
0.0 |
False |
Element 3,2 of cholesky factor of shock covariance matrix |
||
shocks |
chol_sigma_3 |
1500.0 |
False |
Element 3,3 of cholesky factor of shock covariance matrix |
||
shocks |
chol_sigma_41 |
0.0 |
False |
Element 4,1 of cholesky factor of shock covariance matrix |
||
shocks |
chol_sigma_42 |
0.0 |
False |
Element 4,2 of cholesky factor of shock covariance matrix |
||
shocks |
chol_sigma_43 |
0.0 |
False |
Element 4,3 of cholesky factor of shock covariance matrix |
||
shocks |
chol_sigma_4 |
1500.0 |
False |
Element 4,4 of cholesky factor of shock covariance matrix |
||
type_shares |
base_share_2 |
-1.6094379124341 |
False |
share_of_agents_of_type_2 |
||
type_shares |
ten_years_2 |
0.0 |
False |
effect of more than ten years of schooling on probability of being type 2 |
||
type_shares |
base_share_3 |
-0.22314355131421 |
False |
share_of_agents_of_type_3 |
||
type_shares |
ten_years_3 |
0.0 |
False |
effect of more than ten years of schooling on probability of being type 3 |
||
type_shift |
type_2_in_occ_a |
0.1 |
False |
deviation for type 2 from type 1 in occ_a |
||
type_shift |
type_2_in_occ_b |
-0.15 |
False |
deviation for type 2 from type 1 in occ_b |
||
type_shift |
type_2_in_edu |
-1000.0 |
False |
deviation for type 2 from type 1 in edu |
||
type_shift |
type_2_in_home |
1000.0 |
False |
deviation for type 2 from type 1 in home |
||
type_shift |
type_3_in_occ_a |
-0.1 |
False |
deviation for type 3 from type 1 in occ_a |
||
type_shift |
type_3_in_occ_b |
0.15 |
False |
deviation for type 3 from type 1 in occ_b |
||
type_shift |
type_3_in_edu |
1000.0 |
False |
deviation for type 3 from type 1 in edu |
||
type_shift |
type_3_in_home |
-1000.0 |
False |
deviation for type 3 from type 1 in home |
In alignment to Keane and Wolpin (1994), the error terms of the model are set to follow a multivariate normal distribution, allowing for cross-correlation are admissible, and excluding serial correlation. In the parameter specification, the shock parameters have to be specified as the lower triangular Cholesky factor of the covariance matrix. In the implementation, the requested number of realizations is drawn from the standard normal distribution. The draws are then multiplied by the shock parameters implied by the Cholesky factor in order to generate the desired variance-covariance structure.
In this example specification the model implementation implies three types of
heterogeneous agents. The current version of the code works both with more than three
types, as well as with homogeneous agents (only one type). In order to add a type, a
block of two and a block of four coefficients need to be specified in the categories
type_shares
and type_shifts
”, respectively.
Warning
There are two small differences compared to Keane and Wolpin (1997). First, all coefficients enter the return function with a positive sign, while the squared terms enter with a minus in the original paper. Second, the order of covariates is fixed across the two occupations. In the original paper, own experience always comes before other experience.
Warning
Again, there is a small difference between this setup and Keane and Wolpin (1997). There is no automatic change in sign for the costs. Thus, e.g. a $1,000 tuition cost must be specified as -1000.
Options specification¶
In addition to the model parameters, other model options are kept in another
specification file in the json
format.
{
"estimation": {
"file": "data.respy.dat",
"maxfun": 1000,
"agents": 1000,
"draws": 200,
"optimizer": "FORT-BOBYQA",
"seed": 500,
"tau": 500.0
},
"simulation": {
"file": "data",
"agents": 1000,
"seed": 132
},
"program": {
"debug": false,
"procs": 1,
"threads": 1,
"version": "fortran"
},
"interpolation": {
"flag": false,
"points": 200
},
"solution": {
"store": true,
"seed": 456,
"draws": 500
},
"preconditioning": {
"minimum": 1e-05,
"type": "magnitudes",
"eps": 0.0001
},
"derivatives": "forward-differences",
"edu_spec": {
"lagged": [
1.0,
1.0
],
"start": [
10,
9
],
"share": [
0.5,
0.5
],
"maxiter": 10,
"stpmx": 100.0
},
"FORT-BOBYQA": {
"maxfun": 1000000,
"npt": 1,
"maxiter": 1,
"xtol": 0.0001
},
"SCIPY-LBFGSB": {
"eps": 4.41037423e-07,
"factr": 30.401091854739622,
"m": 5,
"maxiter": 2,
"maxls": 2,
"pgtol": 8.6554171164e-05
}
}
Note that in order to implement the model based on agents with different initial levels of schooling the three integer values - start, share, and lagged - have to be specified together as a block.
SOLUTION
Key |
Value |
Interpretation |
---|---|---|
draws |
int |
number of draws for \(E\max\) |
store |
bool |
persistent storage of results |
seed |
int |
random seed for \(E\max\) |
SIMULATION
Key |
Value |
Interpretation |
---|---|---|
agents |
int |
number of simulated agents |
file |
str |
file to print simulated sample |
seed |
int |
random seed for agent experience |
ESTIMATION
Key |
Value |
Interpretation |
---|---|---|
agents |
int |
number of agents to read from sample |
draws |
int |
number of draws for choice probabilities |
file |
str |
file to read observed sample |
maxfun |
int |
maximum number of function evaluations |
optimizer |
str |
optimizer to use |
seed |
int |
random seed for choice probability |
tau |
float |
scale parameter for function smoothing |
DERIVATIVES
Key |
Value |
Interpretation |
---|---|---|
version |
str |
approximation scheme |
The computed derivatives are calculated numerically and are used in the standard error calculation.
PRECONDITIONING
Key |
Value |
Interpretation |
---|---|---|
eps |
int |
step size |
minimum |
int |
minimum admissible value |
type |
str |
preconditioning type |
The inputs in the Preconditioning block are employed in reaching a (faster) solution in the optimization step. The coefficients are transformed for better handling by the optimizer. Three different types of transformations can be selected via the preconditioning type:
identity - no transformation
magnitude - divison by the number of digits
gradient based - weighting by the inverse contribution to the likelihood function
PROGRAM
Key |
Value |
Interpretation |
---|---|---|
debug |
bool |
debug mode |
procs |
int |
number of processors |
threads |
int |
number of threads |
version |
str |
program version |
INTERPOLATION
Key |
Value |
Interpretation |
---|---|---|
flag |
bool |
flag to use interpolation |
points |
int |
number of interpolation points |
The implemented optimization algorithms vary with the program’s version. If you request
the Python version of the program, you can choose from the scipy
implementations of
the BFGS (Norcedal and Wright, 2006), LBFGSB, and POWELL (Powell, 1964) algorithms. In
essense, POWELL is a conjugate direction method, which performs sequential
one-dimentional minimizations, does not require that the functions be differentiable and
no derivatives are taken. The BFGS algorythm is a quasi-Newton type of optimizer, which
uses first derivatives only, but performs reasonably well even in non-smooth
optimizations. The LBFGS algorithm can use simple box contraints to potentially improve
accuracy. Further implementation details are available here.
For Fortran, we implemented the BFGS, BOBYQA and NEWUOA (Powell, 2004) algorithms.
NEWUOA is a gradient-free algorythm which performs unconstrained optimiztion. In a
similar fashion, BOBYQA performs gradient-free bound constrained optimization.
FORT-NEWUOA
Key |
Value |
Interpretation |
---|---|---|
maxfun |
float |
maximum number of function evaluations |
npt |
int |
number of points for approximation model |
rhobeg |
float |
starting value for size of trust region |
rhoend |
float |
minimum value of size for trust region |
FORT-BFGS
Key |
Value |
Interpretation |
---|---|---|
eps |
int |
value to use for step size if fprime is approximated |
gtol |
float |
gradient norm must be less than gtol before successful termination |
maxiter |
int |
maximum number of iterations |
stpmx |
int |
maximum step size |
FORT-BOBYQA
Key |
Value |
Interpretation |
---|---|---|
maxfun |
float |
maximum number of function evaluations |
npt |
int |
number of points for approximation model |
rhobeg |
float |
starting value for size of trust region |
rhoend |
float |
minimum value of size for trust region |
SCIPY-BFGS
Key |
Value |
Interpretation |
---|---|---|
eps |
value to use for step size if fprime is approximated |
|
gtol |
float |
gradient norm must be less than gtol before successful termination |
maxiter |
int |
maximum number of iterations |
stpmx |
int |
maximum step size |
SCIPY-POWELL
Key |
Value |
Interpretation |
---|---|---|
ftol |
float |
relative error in func(xopt) acceptable for convergence |
maxfun |
int |
maximum number of function evaluations to make |
maxiter |
int |
maximum number of iterations |
xtol |
float |
line-search error tolerance |
SCIPY-LBFGSB
Key |
Value |
Interpretation |
---|---|---|
eps |
float |
Step size used when approx_grad is True, for numerically calculating the gradient |
factr |
float |
Multiple of the default machine precision used to determine the relative error in func(xopt) acceptable for convergence |
m |
int |
Maximum number of variable metric corrections used to define the limited memory matrix. |
maxiter |
int |
maximum number of iterations |
maxls |
int |
Maximum number of line search steps (per iteration). Default is 20. |
pgtol |
float |
gradient norm must be less than gtol before successful termination |
Helper functions¶
We provide some helper functions to write a model specification. You can use the following function to output a template of the parameter specification.
-
respy.pre_processing.specification_helpers.
csv_template
(num_types=1, save_path=None, initialize_coeffs=True)[source]¶ Creates a template for the parameter specification.
- Parameters
num_types (int, optional) – Number of types in the model. Default is one.
save_path (str, pathlib.Path, optional) – The template is saved to this path. Default is
None
.initialize_coeffs (bool, optional) – Whether coefficients are initialized with values or not. Default is
True
.
Dataset¶
To use respy, you need a dataset with the following columns:
Identifier: identifies the different individuals in the sample
Period: identifies the different rounds of observation for each individual
Choice: an integer variable that indicates the labor market choice
1 = Occupation A
2 = Occupation B
3 = Education
4 = Home
Earnings: a float variable that indicates how much people are earning. This variable is missing (indicated by a dot) if individuals don’t work.
Experience_A: labor market experience in sector A
Experience_B: labor market experience in sector B
Years_Schooling: years of schooling
Lagged_Choice: choice in the period before the model starts. Codes are the same as in Choice.
The information in the data file should be first sorted by individual and then by period as visualized below:
ID. |
Priod |
Choice |
Earnings |
Exp_A |
Exp_B |
sch_y |
choice_lag |
---|---|---|---|---|---|---|---|
0 |
0 |
4 |
0 |
0 |
0 |
10 |
1 |
0 |
1 |
4 |
0 |
0 |
0 |
10 |
0 |
0 |
2 |
4 |
0 |
0 |
0 |
10 |
0 |
1 |
0 |
4 |
0 |
0 |
0 |
10 |
1 |
1 |
1 |
4 |
0 |
0 |
0 |
10 |
0 |
1 |
2 |
4 |
0 |
0 |
0 |
10 |
0 |
2 |
0 |
4 |
0 |
0 |
0 |
10 |
1 |
2 |
1 |
4 |
0 |
0 |
0 |
10 |
0 |
2 |
1 |
4 |
0 |
0 |
0 |
10 |
0 |
Datasets for respy are stored in simple text files, where columns are separated by spaces. The easiest way to write such a text file in Python is to create a pandas DataFrame with all relevant columns and then storing it in the following way:
with open("my_data.respy.dat", "w") as file:
df.to_string(file, index=False, header=True, na_rep=".")