Я провел несколько экспериментов на смоделированных данных, чтобы увидеть, какой метод работает лучше всего. Пожалуйста, прочитайте мои выводы ниже.
Давайте рассмотрим два разных сценария: во-первых, где нет прямой связи между DUI и ликерными магазинами, и во-вторых, где у нас есть прямые отношения. Затем изучите каждый из методов, чтобы увидеть, какой метод работает лучше всего.
Случай 1: Нет прямых отношений, но оба связаны с населением
library(rmutil)
############
## Simulating Data
set.seed(111)
# Simulating city populations
popln <- rpareto(n=10000,m=10000,s=1.2)
# Simulating DUI numbers
e1 <- rnorm(10000,mean=0,sd=15)
DUI = 100 + popln * 0.04 + e1
summary(DUI)
truehist(log(DUI))
# Simulating Nbr of Liquor stores
e2 <- rnorm(100,mean=0,sd=5)
Nbr_Liquor_Stores = 20 + popln * 0.009 + e2
summary(Nbr_Liquor_Stores)
truehist(log(Nbr_Liquor_Stores))
dat <- data.frame(popln,DUI,Nbr_Liquor_Stores)
Теперь, когда данные смоделированы, давайте посмотрим, как работает каждый из методов.
## Method 0: Simple OLS
fit0 <- lm(DUI~Nbr_Liquor_Stores,data=dat)
summary(fit0)
Coefficients:
Estimate Std. Error t value Pr(>|t|)
(Intercept) 9.4353630 0.2801544 33.68 <2e-16 ***
Nbr_Liquor_Stores 4.4444207 0.0001609 27617.49 <2e-16 ***
Nbr_Liquor_Stores очень значительный, как и ожидалось. Хотя отношения косвенные.
## Method 1: Divide Liquor Stores by population and then regress
fit1 <- lm( I(DUI/popln) ~ Nbr_Liquor_Stores, data=dat)
summary(fit1)
Estimate Std. Error t value Pr(>|t|)
(Intercept) 4.981e-01 4.143e-02 12.022 <2e-16 ***
Nbr_Liquor_Stores -1.325e-05 2.380e-05 -0.557 0.578
Nbr_Liquor_Stores не имеет значения. Вроде работает, но пока не будем спешить с выводами.
## Method 2: Divide Liquor Stores by population and then regress
fit2 <- lm( DUI ~ Nbr_Liquor_Stores + popln, data=dat)
summary(fit2)
Estimate Std. Error t value Pr(>|t|)
(Intercept) 1.003e+02 6.022e-01 166.569 <2e-16 ***
Nbr_Liquor_Stores -1.603e-02 3.042e-02 -0.527 0.598
popln 4.014e-02 2.738e-04 146.618 <2e-16 ***
Nbr_Liquor_Stores не имеет значения, значение p также довольно близко к методу 1.
## Method 3: "DUI per capita" on "liquer stores per capita" and "population size"
fit3 <- lm( I(DUI/popln) ~ I(Nbr_Liquor_Stores/popln) + popln, data=dat)
summary(fit3)
Estimate Std. Error t value Pr(>|t|)
(Intercept) 2.841e-02 1.300e-02 2.187 0.0288 *
I(Nbr_Liquor_Stores/popln) 4.886e+00 1.603e-02 304.867 <2e-16 ***
popln -8.426e-09 6.675e-08 -0.126 0.8996
(Nbr_Liquor_Stores / popln) очень важно! Не ожидал, что, возможно, этот метод не самый лучший для вашей задачи.
Случай 2: Прямые отношения как с населением, так и с Nbr_Liquor_Stores
### Simulating Data
set.seed(111)
# Simulating city populations
popln <- rpareto(n=10000,m=10000,s=1.2)
# Simulating Nbr of Liquor stores
e2 <- rnorm(100,mean=0,sd=5)
Nbr_Liquor_Stores = 20 + popln * 0.009 + e2
summary(Nbr_Liquor_Stores)
truehist(log(Nbr_Liquor_Stores))
# Simulating DUI numbers
e1 <- rnorm(10000,mean=0,sd=15)
DUI = 100 + popln * 0.021 + Nbr_Liquor_Stores * 0.01 + e1
summary(DUI)
truehist(log(DUI))
dat <- data.frame(popln,DUI,Nbr_Liquor_Stores)
Давайте посмотрим производительность каждого из методов в этом сценарии.
## Method 0: Simple OLS
fit0 <- lm(DUI~Nbr_Liquor_Stores,data=dat)
summary(fit0)
Estimate Std. Error t value Pr(>|t|)
(Intercept) 5.244e+01 1.951e-01 268.8 <2e-16 ***
Nbr_Liquor_Stores 2.343e+00 1.121e-04 20908.9 <2e-16 ***
Ожидаемый, но не отличный способ сделать причинные выводы.
## Method 1: Divide Liquor Stores by population and then regress
fit1 <- lm( I(DUI/popln) ~ Nbr_Liquor_Stores, data=dat)
summary(fit1)
Estimate Std. Error t value Pr(>|t|)
(Intercept) 4.705e-01 4.005e-02 11.747 <2e-16 ***
Nbr_Liquor_Stores -1.294e-05 2.301e-05 -0.562 0.574
Для меня это сюрприз, я ожидал, что этот метод захватит отношения, но он их не поднимает. Таким образом, этот метод не работает в этом сценарии!
## Method 2: Divide Liquor Stores by population and then regress
fit2 <- lm( DUI ~ Nbr_Liquor_Stores + popln, data=dat)
summary(fit2)
Estimate Std. Error t value Pr(>|t|)
(Intercept) 1.013e+02 5.945e-01 170.391 <2e-16 ***
Nbr_Liquor_Stores -5.484e-02 2.825e-02 -1.941 0.0523 .
popln 2.158e-02 2.543e-04 84.875 <2e-16 ***
Nbr_Liquor_Stores является значимым, р-значение имеет большой смысл. Явный победитель для меня.
## Method 3: "DUI per capita" on "liquer stores per capita" and "population size"
fit3 <- lm( I(DUI/popln) ~ I(Nbr_Liquor_Stores/popln) + popln, data=dat)
summary(fit3)
Estimate Std. Error t value Pr(>|t|)
(Intercept) 6.540e-02 1.485e-02 4.405 1.07e-05 ***
I(Nbr_Liquor_Stores/popln) 3.915e+00 1.553e-02 252.063 < 2e-16 ***
popln -2.056e-08 7.635e-08 -0.269 0.788
TLDR; Метод 2 дает наиболее точные значения p в разных сценариях.