Multiple regression is no oracle, but only a golem. It is logical, but the relationships it describes are conditional associations, not causal influences. Therefore additional information, from outside the model, is needed to make sense of it. This chapter presented introductory examples of some common frustrations: multicollinearity, post-treatment bias, and collider bias. Solutions to these frustrations can be organized under a coherent framework in which hypothetical causal relations among variables are analyzed to cope with confounding. In all cases, causal models exist outside the statistical model and can be difficult to test. However, it is possible to reach valid causal inferences in the absence of experiments. This is good news, because we often cannot perform experiments, both for practical and ethical reasons.
Place each answer inside the code chunk (grey box). The code chunks should contain a text response or a code that completes/answers the question or activity requested. Make sure to include plots if the question requests them. Problems are labeled Easy (E), Medium (M), and Hard(H).
Finally, upon completion, name your final output .html file as: YourName_ANLY505-Year-Semester.html and publish the assignment to your R Pubs account and submit the link to Canvas. Each question is worth 5 points.
6E1. List three mechanisms by which multiple regression can produce false inferences about causal effects.
# Multicollinearity, Post-treatment bias and Collider bias.
6E2. For one of the mechanisms in the previous problem, provide an example of your choice, perhaps from your own research.
# Post-treatment bias: For example that I am thinking of a market campaign to put some advertisement banner on the client's website. I want to know the difference in the client enrollments under different types of "click-propensity" online advertisement banners, because clicking the online ad-banners tend to increase the likelihood of client to enroll into the campaign. The DAG could be: Online Ad Banner treatment -> Banner Click -> Client Interest in the campaign enrollment. If my goal is to make a causal inference about the Ad Banner treatment, I should not include the "Banner click", because it is a post-treatment effect.
6E3. List the four elemental confounds. Can you explain the conditional dependencies of each?
library(dagitty)
library(rethinking)
library(dplyr)
# 1) Fork
# Draw DAG of Forks
dag_fork <- dagitty( "dag {
X <- Z -> Y
}")
coordinates(dag_fork)<-list(
x=c(X=0,Y=2,Z=1),
y=c(X=0,Y=0,Z=1)
)
dag_fork %>% drawdag
# conditional dependencies of Forks
impliedConditionalIndependencies(dag_fork)
## X _||_ Y | Z
# 2) Pipe
# Draw DAG of Pipe
dag_pipe <- dagitty( "dag {
X -> Z -> Y
}")
coordinates(dag_pipe)<-list(
x=c(X=0,Y=2,Z=1),
y=c(X=0,Y=2,Z=1)
)
dag_pipe %>% drawdag
# conditional dependencies of Pipe
impliedConditionalIndependencies(dag_pipe)
## X _||_ Y | Z
# 3) Collider
# Draw DAG of Collider
dag_collider <- dagitty( "dag {
X -> Z <- Y
}")
coordinates(dag_collider)<-list(
x=c(X=0,Y=2,Z=1),
y=c(X=1,Y=1,Z=0)
)
dag_collider %>% drawdag
# conditional dependencies of Collider
impliedConditionalIndependencies(dag_collider)
## X _||_ Y
\[X \not\!\perp\!\!\!\perp Y |Z\]
# 4) Descendant
# Draw DAG of Descendant
dag_desc <- dagitty( "dag {
X -> Z <- Y
Z -> D
}")
coordinates(dag_desc)<-list(
x=c(X=0,Y=2,Z=1, D=1),
y=c(X=1,Y=1,Z=0, D=0.8)
)
dag_desc %>% drawdag
# We can notice that conditional on the Descendent D is like conditioning on its parent Z.
impliedConditionalIndependencies(dag_desc)
## D _||_ X | Z
## D _||_ Y | Z
## X _||_ Y
6E4. How is a biased sample like conditioning on a collider? Think of the example at the open of the chapter.
# In the example that started the chapter, there was no association between the trustworthiness and newsworthiness, but both of them influence the selection for funding. The causal DAG is presented as newsworthiness -> Selection <- trustworthiness. Here, the Selection variable is the collider. However, when we condition on the selection, it mislead us into believing that there is a negative association between newsworthiness and trustworthiness. In details, when we learn that a proposal has been selected(S), then learning its trustworthiness (T) also provides information about its newsworthiness(N). Because if a selected proposal has low trustworthiness, then it must have high newsworthiness. Otherwise it wouldn’t have been funded. The same works in reverse: If a proposal has low newsworthiness, we’d infer that it must have higher than average trustworthiness. Otherwise it would not have been selected for funding. Overall, after we condition on the collider "selection", it creates a statistical association , but not necessary casual assocoation.
# The biased sample in this case, is like only including the population of selected proposals into the sample. It is equivalent to condition on selection (S=1) as I described above, which distorts the associations among the variables and will generate a misleading association inside a statistical model, as well as make an errorneous causal inference.
6M1. Modify the DAG on page 186 to include the variable V, an unobserved cause of C and Y: C ← V → Y. Reanalyze the DAG. Draw the DAG. How many paths connect X to Y? Which must be closed? Which variables should you condition on now?
dag_6m1 <- dagitty( "dag {
U [unobserved]
V [unobserved]
X -> Y
X <- U <- A -> C -> Y
U -> B <- C
C <- V -> Y
}")
coordinates(dag_6m1)<-list(
x=c(X=0,Y=2,U=0,A=1,B=1,C=2,V=2.5),
y=c(X=2,Y=2,U=1,A=0.2,B=1.5,C=1,V=1.5)
)
dag_6m1 %>% drawdag
# There are four paths connect X to Y:
# 1) X <- U <- A -> C -> Y
# 2) X <- U -> B <- C -> Y
# 3) X <- U <- A -> C <- V -> Y
# 4) X <- U -> B <- C <- V -> Y
# Path 2), 4) are closed, because B is a collider. Path 1) is open, because there is no collider within it. There is just a fork A at the top and two pipes, one on each side. Information will flow through this path, confounding X → Y. It is a backdoor and we should close it. To shut this backdoor, we need to condition on A or C. However, from the Path 3) we know that C is also a collider, which we should not condition on it. Therefore, we should only condition on variable A now. The adjustmentSets function also provides the same answer.
adjustmentSets( dag_6m1 , exposure="X" , outcome="Y" )
## { A }
6M2. Sometimes, in order to avoid multicollinearity, people inspect pairwise correlations among predictors before including them in a model. This is a bad procedure, because what matters is the conditional association, not the association before the variables are included in the model. To highlight this, consider the DAG X → Z → Y. Simulate data from this DAG so that the correlation between X and Z is very large. Then include both in a model prediction Y. Do you observe any multicollinearity? Why or why not? What is different from the legs example in the chapter?
n<- 1000
b_xz<- 0.9
b_zy<- -0.7
set.seed(100)
x<- rnorm(n)
z<- rnorm(n,x*b_xz)
y<- rnorm(n,z*b_zy)
d <- data.frame(x,y,z)
cor(d)
## x y z
## x 1.0000000 -0.4734962 0.6924074
## y -0.4734962 1.0000000 -0.7057048
## z 0.6924074 -0.7057048 1.0000000
pairs( ~ x+y+z, data = d, col = rangi2)
# We can observed that X and Z are strongly positive correlated.
m_6m2<- quap( alist(
y ~ dnorm( mu , sigma ),
mu <- a + b_xz*x + b_zy*z,
a ~ dnorm( 0 , 100 ),
c(b_xz,b_zy) ~ dnorm( 0 , 100 ),
sigma ~ dexp( 1 ) ),
data=d )
precis(m_6m2)
## mean sd 5.5% 94.5%
## a -0.01390048 0.03305837 -0.06673415 0.03893318
## b_xz 0.04170468 0.04447459 -0.02937431 0.11278367
## b_zy -0.78879067 0.03371364 -0.84267158 -0.73490975
## sigma 1.04525021 0.02335453 1.00792516 1.08257526
plot(precis(m_6m2))
# The posterior mean of b_zy is negative and it has a narrow posterior distribution that lies entirely on the left side of zero. It presents a strong association of Z with Y. Also, the posterior mean of b_zy is quite close to the true b_zy we defined in the simulation. On the other hand, though the posterior mean of b_xz also has a narrow posterior distribution, it is very close to zero and is not lying entirely to any side of zero.
# I did not observe the multicolinearity in this case. It is in contrast to the example of legs in the book, where the estimated standard deviations of parameters beta are much larger, and the posterior distributions of two leg parameters have significant overlap. Therefore, this simulated example does not seem to be a case of multicollinearity.
# Also, according to the DAG, we could notice that the relationship is actually a "Pipe". Just as how we simulate, X influences Z which influence the final outcome Y. If we condition on Z now, we block the path from X to Y: There's no extra information of X to inluence Y, conditional on Z, please see "X_||_Y|Z". That's also why we see the posterior mean of b_xz in the model is nearly 0.
# Therefore, pairwise correlation are not the problem. It is the conditional associations - not correlations- that matter.