DEEPPRICE Procedure

A Demand-Price Example When the Price Is Not Endogenous

This example illustrates how the DEEPPRICE procedure enables you to estimate the parameters of interest and perform policy evaluation and policy comparison when the treatment variable is not endogenous. In this case, the instrumental variable is not needed. This example also demonstrates how you can save the model information and use it later to score other new data.

A simulated data set is generated, based on the following assumptions:

  • The treatment variable, scaled flight price (denoted by p), is continuous, and its value ranges from 0.01 to 75, inclusive.

  • The outcome variable, demand (denoted by y), is continuous and nonnegative.

  • There are two covariates:

    • The customer type (denoted by s), is discrete, and its value ranges from 1 to 10, inclusive.

    • The time (denoted by t) is continuous, and its value ranges from 0 to 12, exclusive.

  • The disturbance in the treatment model is independent of the disturbance in the outcome model; this implies that the treatment variable is not endogenous.

The treatment model is given as

StartLayout 1st Row 1st Column p 2nd Column equals eta 0 left parenthesis t right parenthesis plus eta comma eta tilde Overscript iid Endscripts upper N left parenthesis 0 comma 1 right parenthesis 2nd Row 1st Column eta 0 left parenthesis t right parenthesis 2nd Column equals 5 plus 0.3 psi left parenthesis t right parenthesis 3rd Row 1st Column psi left parenthesis t right parenthesis 2nd Column equals 2 left parenthesis StartFraction 50 Over 3 EndFraction left parenthesis StartFraction t minus 6 Over 12 EndFraction right parenthesis Superscript 4 Baseline plus normal e normal x normal p left parenthesis minus 400 left parenthesis StartFraction t minus 6 Over 12 EndFraction right parenthesis squared right parenthesis plus StartFraction t Over 12 EndFraction minus StartFraction 41 Over 20 EndFraction right parenthesis EndLayout

where psi left parenthesis period right parenthesis describes the seasonality.

The outcome model is given as

StartLayout 1st Row 1st Column y 2nd Column equals alpha left parenthesis s comma t right parenthesis plus beta left parenthesis s comma t right parenthesis p plus epsilon comma epsilon tilde Overscript iid Endscripts upper N left parenthesis 0 comma 0.25 right parenthesis 2nd Row 1st Column alpha left parenthesis s comma t right parenthesis 2nd Column equals 30 plus 0.1 s psi left parenthesis t right parenthesis 3rd Row 1st Column beta left parenthesis s comma t right parenthesis 2nd Column equals 0.1 s psi left parenthesis t right parenthesis minus 0.2 EndLayout

Note that epsilon and eta are uncorrelated, which implies that the scaled flight price is not endogenous.

The following statements simulate 12,500 samples that are based on the treatment and outcome models that were just presented:

%macro deepPriceGenerateData(n,rho,seed);
   data deepPriceDGP;
      call streaminit('pcg', &seed.);
      rho = &rho.;
      do i = 1 to &n.;
         s = floor(rand('Uniform')*10+1);
         t = rand('Uniform')*12;
         z = rand('Normal',0,1);
         eta = rand('Normal',0,1);
         psi = 2*((t-6)/12*(t-6)/12*(t-6)/12*(t-6)/12*50/3
             +exp(-400*(t-6)/12*(t-6)/12)+t/12-41/20);
         eta0 = 5+0.3*psi;
         eta1 = 0.1*psi;
         if(rho ^= 0) then p = eta0 + eta1*z + eta;
         else p = eta0 + eta;
         plb = 0.01;
         pub = 75;
         if(p<plb) then p=plb;
         if(p>pub) then p=pub;

         eps = rand('Normal',rho*eta,0.25);
         alpha = 30 + 0.1*s*psi;
         beta = 0.1*s*psi - 0.2;
         if(beta>0) then beta=0;
         y0 = alpha + beta*p;
         y = y0 + eps;
         if(y<0) then y = 0;

         * the realized revenue;
         R = y * p;
         R0 = y0 * p;

         * the best price to maximize the revenue,
           which cannot be obtained without knowing DGP;
         if(beta<0) then pstar = -alpha/beta/2;
         else pstar = pub;
         ystar = alpha + beta * pstar;
         * the maximized expected revenue;
         Rstar = ystar * pstar;

         output;
      end;
   run;
%mend;

%let n=12500;
%let rho = 0;
%let seed=12346;
%deepPriceGenerateData(&n.,&rho.,&seed.);

The following DATA steps load the first 10,000 observations of the data set deepPriceDGP into the data table simPrice_train and the next 2,500 observations into the data table simPrice_test in your session that is associated with the mylib libref. The DATA steps assume that your libref is named mylib, but you can substitute any appropriately defined libref.

data mylib.simPrice_train;
   set deepPriceDGP(obs=10000 keep=i s t p y R pstar);
run;

data mylib.simPrice_test;
   set deepPriceDGP(firstobs=10001 keep=i s t p y R pstar);
run;

The unknown functions eta 0 left parenthesis dot right parenthesis, alpha left parenthesis dot right parenthesis, and beta left parenthesis dot right parenthesis are estimated through two DNNs by using the data set simPrice_train. The parameters of interest are then estimated, and policy evaluation and policy comparison are performed. The following statements use PROC DEEPPRICE to perform these tasks and store the model information and parameter learning results:

proc deepprice data=mylib.simPrice_train;
   id i;
   tmodel p=s t / dnn=(nodes=(32 32 32 32)
         train=(optimizer=(miniBatchSize=2000 regL1=0.001 maxEpochs=2000
         algorithm=adam) nthreads=5 seed=12346 recordseed=12346));
   model y=s t / dnn=(nodes=(32 32 32 32)
         train=(optimizer=(miniBatchSize=2000 regL1=0.001 maxEpochs=4000
         algorithm=adam) nthreads=5 seed=12346 recordseed=12346));
   infer policy=(pstar) policyComparison=(base=(p) compare=(pstar))
      out=mylib.oest outdetails=mylib.odetails;
   score outt=mylib.outtdata outa=mylib.outadata outb=mylib.outbdata;
run;

Note that specifying the SEED= and RECORDSEED= option values does not guarantee that you get identical results each time you run the DEEPPRICE procedure in single-machine or distributed computing mode. This is because the execution environment is the combination of the operating environment and the number of threads (single-machine mode) or the number of worker nodes, together with the number of threads that are used for execution on each worker node (distributed computing mode).

The OUTT= option writes the treatment model information to the data table outtdata, the OUTA= option writes the alpha left parenthesis dot right parenthesis estimation information to the data table outadata, and the OUTB= option writes the beta left parenthesis dot right parenthesis estimation information to the data table outbdata. The number of observations is shown in Figure 1.

Figure 1: Number of Observations

The DEEPPRICE Procedure

Number of Observations10000
Observations with Missing Covariates0
Observations with Missing Covariates for Treatment Model0
Observations with Missing Covariates for Outcome Model0
Observations with Missing Outcome0
Observations with Missing Treatment0


The estimates of parameters of interest are shown in Figure 2.

Figure 2: Parameters of Interest

Parameter Estimates
ParameterEstimateStandard
Error
95% Confidence LimitsZPr > |Z|
Average Intercept28.4427370.03255828.37892528.506549873.61<.0001
Average Slope-1.5152710.011544-1.537896-1.492646-131.27<.0001


The policy evaluation estimates the expected demand of a policy. The policy evaluation results are shown in Figure 3.

Figure 3: Policy Evaluation

Policy Evaluation
PolicyEstimateStandard
Error
95% Confidence LimitsZPr > |Z|
pstar14.6718260.10764614.46084514.882808136.30<.0001


The policy comparison estimates the difference in expected demand of two policies. The policy comparison results are shown in Figure 4.

Figure 4: Policy Comparison

Policy Comparison
Comparison
Policy
Base
Policy
EstimateStandard
Error
95% Confidence LimitsZPr > |Z|
pstarp-7.2735720.111963-7.493016-7.054129-64.96<.0001


According to the comparison of the two policies, the policy p in the observed data generates more demand on average than the policy pstar; however, this does not mean that p generates more revenue than pstar! In fact, in the real world, although pstar is theoretically the best policy to maximize revenue, it cannot be available because it requires the unknown functions alpha left parenthesis dot right parenthesis and beta left parenthesis dot right parenthesis. Because of the availability of the true data generating process (DGP), the revenue that the optimized policies generate that is suggested by the plug-in estimator and influence-function estimator can be compared to that of the best-in-theory infeasible policy pstar. The following statements compare the actual function values in the true DGP to the estimates of eta 0 left parenthesis dot right parenthesis, alpha left parenthesis dot right parenthesis, and beta left parenthesis dot right parenthesis, which are _that_, _alpha_, and _beta_, respectively, in the oDetails data table in your session; compare the revenues that are generated through different policies; and use PROC MEANS to get the bias and variance of each estimator:

proc sort data=mylib.odetails out=odetails_tmp;
   by i;
run;

data odetails;
   merge odetails_tmp(in=a) deepPriceDGP(in=b where=(i<=10000));
   by i;
   diff_eta0 = _that_ - eta0;
   diff_alpha = _alpha_-alpha;
   diff_beta  = _beta_ -beta;
   * revenue difference between observed policy and best policy;
   diff_R = R0 - Rstar;
   * pipstar, the optimized policy suggested by plug-in estimator;
   if(_beta_<0) then pipstar = -_alpha_/_beta_/2;
   else pipstar = pub;
   if(pipstar>pub) then pipstar = pub;
   if(pipstar<plb) then pipstar = plb;
   piystar = alpha + beta * pipstar;
   if(piystar<0) then piystar=0;
   piRstar = piystar * pipstar;
   * revenue difference between plug-in optimized policy and best policy;
   diff_piR = piRstar - Rstar;
   * ifpstar, the optimized policy suggested by influence-function
     estimator;
   if(_if_beta_<0) then ifpstar = -_if_alpha_/_if_beta_/2;
   else ifpstar = pub;
   if(ifpstar>pub) then ifpstar = pub;
   if(ifpstar<plb) then ifpstar = plb;
   ifystar = alpha + beta * ifpstar;
   if(ifystar<0) then ifystar=0;
   ifRstar = ifystar * ifpstar;
   * revenue difference between influence-function optimized policy and
     best policy;
   diff_ifR = ifRstar - Rstar;
run;

proc means data=odetails;
   var diff_eta0 diff_alpha diff_beta diff_R diff_ifR diff_piR;
run;

The results are displayed in Figure 5, which shows that all three estimated functions are unbiased.

Figure 5: Summary Statistics of Difference between Actual Value and Estimate

The MEANS Procedure

VariableNMeanStd DevMinimumMaximum
diff_eta0
diff_alpha
diff_beta
diff_R
diff_ifR
diff_piR
10000
10000
10000
10000
10000
10000
0.0513895
-0.1021674
0.0683319
-115.4171558
-44.9515312
-24.8457316
0.1463623
0.6435525
0.1840845
154.0205778
100.6869697
80.2110640
-0.4907291
-2.4314195
-0.4170375
-996.2989116
-653.3786359
-554.8558027
0.2826009
1.5739562
0.8771066
-7.750115E-6
-3.722889E-9
-1.849463E-8


You can apply the previously saved treatment model, the alpha left parenthesis dot right parenthesis estimation information, and the beta left parenthesis dot right parenthesis estimation information to a new data set by specifying the INT=, INA=, and INB= options, respectively, in the SCORE statement. The following statements use the outtdata, outadata, and outbdata data tables as input data tables and then estimate the parameters of interest and perform the policy evaluation and comparison by using the simPrice_test data table:

proc deepprice data=mylib.simPrice_test;
   id i;
   infer policy=(pstar) policyComparison=(base=(p) compare=(pstar))
      out=mylib.oest2 outdetails=mylib.odetails2;
   score int=mylib.outtdata ina=mylib.outadata inb=mylib.outbdata;
run;

When you specify the INT=, INA=, and INB= options in the SCORE statement, you do not need to specify the TMODEL or MODEL statement. The estimates of the parameters of interest and the results of the policy evaluation and policy comparison are shown in Figure 6.

Figure 6: Parameters of Interest, Policy Evaluation, and Policy Comparison

The DEEPPRICE Procedure

Parameter Estimates
ParameterEstimateStandard
Error
95% Confidence LimitsZPr > |Z|
Average Intercept28.3489280.07167228.20845328.489403395.53<.0001
Average Slope-1.5077690.024143-1.555090-1.460449-62.45<.0001

Policy Evaluation
PolicyEstimateStandard
Error
95% Confidence LimitsZPr > |Z|
pstar14.6624680.16688614.33537714.98956087.86<.0001

Policy Comparison
Comparison
Policy
Base
Policy
EstimateStandard
Error
95% Confidence LimitsZPr > |Z|
pstarp-7.2226890.178589-7.572718-6.872660-40.44<.0001


For more information about the estimates of parameters of interest, policy evaluation, and policy comparison, see the sections Average Intercept and Slope Parameters and Policy Evaluation and Comparison.

Last updated: November 24, 2025