Showing posts with label Qreg. Show all posts
Showing posts with label Qreg. Show all posts

Saturday, June 23, 2012

Quantile Regression (qreg) is invariant to non-decreasing transformations


* That is med(f(x))=f(med(x)) so long as f' > = 0

* LAD is  is invariant to non-decreasing transformations.
set seed 110

clear
set obs 10000

gen x = rnormal()*8+6
* Because x is symetric around 1 we know the median is 1

sum x, detail

gen fx = sign(x)*x^2+500
* fx is a non-decreasing function we can see this by ploting fx against x

line fx x, sort

* Likewise the median of fx is now easy to find med(f(x))=f(med(x))

* med(f(x))=f(med(x))=f(x=6) = sign(1)*6^2+50 = 536
* We can confirm this:

sum fx, detail

* also: med(f(x))=f(med(x)) so long as f' <= 0 by the symetry of the rank function around 50%
* med(g(x))=g(med(x))=g(x=6) = (-1)*(sign(1)*6^2+5) = -536
gen gx = (-1)*(sign(x)*x^2+500)
sum gx, detail

* Notice that while the medians are mirrors of each other (and equal) despite g' < 0.  However the quantile have now reversed order thus quantile(.25)=-quantile(.75).

* This is because of the mirror nature of the generated data.
two (hist  fx, color(blue)) (hist  gx, color(red)), legend(label(1 "fx") label(2 "gx")) title(Mirror quantiles)

* But what is more interesting to us how well LAD does at estimating the conditional median.

* First let us specify:

gen u = rnormal()*20

gen y = x*10 + u*10

* The conditional median is clearly 10

qreg y x
* And qreg is pretty good at identifying the conditional coefficient as 10.

* Also, because E(u|x)=med(u|x)=0, OLS also identifies the median.
* Thus the following also provides a good estimate
reg y x

* Now let us transform y so that it has larger tails using f(y)=fy:

gen fy = sign(y)*y^2+5

* Let's see how well LAD (least absolute deviations) works

qreg fy x
* But what does this mean?
* How well is the quantile regression working?

* Remember fy = sign(y)*y^2+500
* If fy>0: fy(x) = y(x)^2+500 = (x*10 + u)^2 + 500
* And the conditional effect of x on y is

* fy'(x) = 20*(x*10 + u)
* med(fy'(y)|x) = fy'(med(y|x)) =
* 20*(med(x|x)*10 + med(u|x)) =
* 20*(med(x)*10) =
* 20*(6*10) = 1200

* Alternatively:
reg fy x

graph twoway (lfitci fy x) ///
             (scatter fy x)

* This regression does not work very well even though it has a higher r2.

Wednesday, June 6, 2012

2SQreg IVqreg Cfqreg - zombies


* The following simulation is testing how well a 2 stage quantile regression can work.  The example is a little unlikely but the methods should still be good.

* In the first stage we will assume the coefficient on the instrument is constant.

* In the second stage we will assume that the coefficient on the endogenous variable w is changing in y.

* That is we want to estimate quantile(Y|w)=wB + u   med(u|z)=0
  * w = gamma0 + z*gamma1 + v
  * E(w|z) = gamma0 + z*gamma1

  * w_hat = gamma0_hat + z*gamma1_hat

  * quantile(Y|w_hat)=w_hat B + u   med(u|w_hat)=0   or something like that
  * but that med(u|w)!=0

* The properties of quantile regression are difficult because of the non-linearities involved in median maximization.

* However, we can test the properties of 2 stage quantile regression through simulation!

* Imagine we would like to estimate how good are weapons are at killing zombies.

* However you are afraid that people who own weapons might also be more militaristic people and in general might be more effective at killing zombies.

* Therefore, you would like to instrument for the likelihood of owning a weapons.

* You would like to know three things.

* 1. For the bottom 25% zombie killer how much does owning weapons improve their ability to kill zombies?

* 2. For the median person (typical person), how much does owning weapons improve zombie killing ability?

* 3. For the top 75% zombie killer how much does owning weapons improve their ability to kill zombies?

* Let us first generate the data

set seed 101
clear
local num_obs = 10000
set obs `num_obs'

gen fitness = runiform()

gen militarism = runiform()

* Your instrument is that some people live in areas that are more weapon friendly prior to the zombie outbreak.

gen weapon_ease = runiform()
  label var weapon_ease "The ease by which people can purchase weapons in the area"
* Assume the likelihood of people being militaristic is unrelated to the area the live (unlikely).

gen weapons = weapon_ease + militarism

gen error = 5*rnormal()

* Let's get a general estimate of the effectiveness of weapons
gen weapon_coef = 1
gen zombie_kills = fitness + militarism + weapon_coef*weapons + rnormal()

forv i=1(1)10 {
  sort zombie_kills
  replace weapon_coef=4*(_n/`num_obs')
  replace zombie_kills = 5*fitness + 7* militarism + weapon_coef*weapons + error + 15
  * Note partial kills are possible because assists do not count as full kills.
}

* We know the true coefficient on weapons at 25% is 1 at 50% is 2 and at 75% is 3
scatter  weapon_coef zombie_kills, sort

sum weapon_coef if _n==`num_obs'*1/4
sum weapon_coef if _n==`num_obs'*2/4
sum weapon_coef if _n==`num_obs'*3/4

* Let us see how well we can recover the coefficients:

* First: militarism is unobservable

drop militarism

* Let us first try the nieve regression
qreg zombie_kills fitness weapons, quantile(.25)
qreg zombie_kills fitness weapons, quantile(.50)
qreg zombie_kills fitness weapons, quantile(.75)

* We can see that at all levels weapons appear far more effective than they actually are.

* Let us try 2SQReg

reg weapons weapon_ease
* Looks like a pretty good estimate

predict weapons_hat
predict uhat, resid

qreg zombie_kills fitness weapons_hat, quantile(.25)
qreg zombie_kills fitness weapons_hat, quantile(.50)
qreg zombie_kills fitness weapons_hat, quantile(.75)

* It appears that 2SQreg while not perfect is much better than qreg.

* Let us try a control function formulation

qreg zombie_kills fitness weapons uhat, quantile(.25)
qreg zombie_kills fitness weapons uhat, quantile(.50)
qreg zombie_kills fitness weapons uhat, quantile(.75)

* We can see that while the estimates of 2SQreg is identical to that of the control function they both appear to be effective methods.

* Let us do a monte Carlo Simulation of the who thing again:

cap program drop s2qreg
program define s2qreg, rclass

  clear
  local num_obs = 10000
  set obs `num_obs'

  gen fitness = runiform()

  gen militarism = runiform()

  * Your instrument is that some people live in areas that are more weapon friendly prior to the zombie outbreak.

  gen weapon_ease = runiform()
    label var weapon_ease "The ease by which people can purchase weapons in the area"
  * Assume the likelihood of people being militaristic is unrelated to the area the live (unlikely).
 
  gen weapons = weapon_ease + militarism

  gen error = 5*rnormal()

  * Let's get a general estimate of the effectiveness of weapons
  gen weapon_coef = 1
  gen zombie_kills = fitness + militarism + weapon_coef*weapons + rnormal()

  forv i=1(1)10 {
    sort zombie_kills
    replace weapon_coef=4*(_n/`num_obs')
    replace zombie_kills = 5*fitness + 7* militarism + weapon_coef*weapons + error + 15
  }

  qreg zombie_kills fitness weapons, quantile(.25)
    return scalar qreg25=_b[weapons]
  qreg zombie_kills fitness weapons, quantile(.50)
    return scalar qreg5=_b[weapons]
  qreg zombie_kills fitness weapons, quantile(.75)
    return scalar qreg75=_b[weapons]

  reg weapons weapon_ease

  predict weapons_hat
  predict uhat, resid

  qreg zombie_kills fitness weapons_hat, quantile(.25)
    return scalar s2qreg25=_b[weapons]
  qreg zombie_kills fitness weapons_hat, quantile(.50)
    return scalar s2qreg5=_b[weapons]
  qreg zombie_kills fitness weapons_hat, quantile(.75)
    return scalar s2qreg75=_b[weapons]

  qreg zombie_kills fitness weapons uhat, quantile(.25)
    return scalar cfqreg25=_b[weapons]
  qreg zombie_kills fitness weapons uhat, quantile(.50)
    return scalar cfqreg5=_b[weapons]
  qreg zombie_kills fitness weapons uhat, quantile(.75)
    return scalar cfqreg75=_b[weapons]

end

s2qreg

return list

simulate qreg25=r(qreg25) s2qreg25=r(s2qreg25) cfqreg25=r(cfqreg25)  ///
         qreg5=r(qreg5)   s2qreg5=r(s2qreg5)   cfqreg5=r(cfqreg5)    ///
qreg75=r(qreg75) s2qreg75=r(s2qreg75) cfqreg75=r(cfqreg75), ///
reps(500): s2qreg
sum

Tuesday, May 8, 2012

Quantile Regression Fail


* Stata simulation to estimate performance of quantile regression at
* different quantiles

clear
set obs 10000
set seed 101

gen x1 = runiform()
* Single exogenous x

gen u = rnormal()
* Single uncorrelated error u

gen beta=1
  label var beta "True Beta"
* At first beta is = 1

gen y0 = u

gen y = beta*x1 + y0
* Generate a starting point for y

forv i=1/20 {
  cap drop ytile
  * Removes old ytile from the data
  xtile ytile=y, nq(100)
  * Generates a variable that orders all of the
  * y variables into 100 quantiles
  qui replace beta = 4-((ytile+30)/20)^.5
  * beta goes from  4-31/20)^.5 to 4-(133/20)^.5 which is
  * a range of 1.25 to 2.6 ish.
  replace y = beta*x1 + u + 190

  di "`i'"
}
* This repetitive routine makes it so that beta is smoothly related to y

  replace y = y-190
* Make y closer a small range so that the beta hat seems more effective

line beta y, sort
* We can see the beta function is changing effect accross the different
* quantiles of y.  We can see that if x1 is a policy variable then because
* x1 is greater for lower ys and smaller for higher ys.  Then the effect of
* sign of the betas is to keep the variance in y constant or even decrease
* it.  It is possible for the variance in y to still be larger if the
* variances of the xs are larger since in effect we are adding two random
* variables together.

sum y y0

gen beta_hat=.
  label var beta_hat "Estimated Beta"
forv i =1/100 {
  cap qreg y x1, quantile(`=`i'/100')
  * This tells stata to do a quantile regression at every point
  * the 'cap' tells it not to stop if there is an error.
 
  if _rc==0 qui replace beta_hat=_b[x1] if ytile==`i'
  * _rc==0 then it means there was no error in the previous quantile regression
 
  di _continue " `i'"
}

two (line beta y, sort) (line beta_hat y, sort), title(Results of Qreg)

two (line beta ytile, sort) (line beta_hat ytile, sort), title(Results of Qreg)

* The quantile regression seems to be working mediocre
* at picking up some of the shape of the beta distribution.
* However, near the edges which people are often interested in
* it is failing.

* One might say that this is due to the tails having too few observations.
* However, increasing the sample size to 100,000 gives almost identical results!

* Ah, but hope is not lost.  Stay tuned for future releases of semi-parametric
* estimators!