Очень часто при анализе статистических моделей аналитики уделяют большое
внимание p-значениям коэффиентов. Например, при анализе:
lmfit <- lm (mpg ~ ., data=mtcars)
summary(lmfit)
## ## Call: ## lm(formula = mpg ~ ., data = mtcars) ## ## Residuals: ## Min 1Q Median 3Q Max ## -3.4506 -1.6044 -0.1196 1.2193 4.6271 ## ## Coefficients: ## Estimate Std. Error t value Pr(>|t|) ## (Intercept) 12.30337 18.71788 0.657 0.5181 ## cyl -0.11144 1.04502 -0.107 0.9161 ## disp 0.01334 0.01786 0.747 0.4635 ## hp -0.02148 0.02177 -0.987 0.3350 ## drat 0.78711 1.63537 0.481 0.6353 ## wt -3.71530 1.89441 -1.961 0.0633 . ## qsec 0.82104 0.73084 1.123 0.2739 ## vs 0.31776 2.10451 0.151 0.8814 ## am 2.52023 2.05665 1.225 0.2340 ## gear 0.65541 1.49326 0.439 0.6652 ## carb -0.19942 0.82875 -0.241 0.8122 ## --- ## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1 ## ## Residual standard error: 2.65 on 21 degrees of freedom ## Multiple R-squared: 0.869, Adjusted R-squared: 0.8066 ## F-statistic: 13.93 on 10 and 21 DF, p-value: 3.793e-07
можно услышать такой вывод:
т.к. p-значение для
wt
(вес автомобиля) близко к 0, скорее всего вес автомобиля является статистически значимым в определенииmpg
(miles per gallon или пробег в милях на галлон топлива).
В принципе, такой вывод близок к истине, но иногда низкие p-значения можно получить случайно, благодаря большому количеству переменных.
Рассмотрим пример линейной регрессии для 100 случайно сгенерированных переменных, по 1000 наблюдений для каждой, и поинтересуемся 10-ю наименьшими p-значениями:
set.seed(1)
df <- as.data.frame(do.call(rbind, lapply(rep(100,1000), rnorm)))
lmfit2 <- lm (V1 ~ ., data = df)
head(summary(lmfit2)$coef)
## Estimate Std. Error t value Pr(>|t|) ## (Intercept) -0.011058620 0.03422017 -0.3231609 0.7466485 ## V2 -0.005615463 0.03330244 -0.1686202 0.8661333 ## V3 -0.039832076 0.03447283 -1.1554631 0.2482075 ## V4 0.011818246 0.03490221 0.3386102 0.7349823 ## V5 0.035375402 0.03495254 1.0120982 0.3117631 ## V6 -0.041390874 0.03358092 -1.2325710 0.2180577
data.frame("p-value"= sort(summary(lmfit2)$coef[,"Pr(>|t|)"])[1:10])
## p.value ## V89 0.01085061 ## V26 0.02000810 ## V22 0.02218768 ## V56 0.04985120 ## V35 0.07203533 ## V61 0.07951660 ## V11 0.11630999 ## V17 0.12247078 ## V27 0.17635340 ## V82 0.19592635
Как мы видим, даже среди случайных данных, которые представляют собой сгенерированный шум, мы нашли 4 “статистически-значимых” переменных. Причем этот результат не случаен: всегда, при заданном уровне значимости в n%
и р
переменных, n*p
переменных могут показать статистическую значимость просто случайно.
Для того, чтобы сделать поправку на количество переменных и получить ответ на вопрос “Является ли хотя бы одна переменная статистически значимой”, существует F-статистика, с соответствующим р-значением.
library(broom)
glance(lmfit)[, c(4,5)]
## statistic p.value ## 1 13.93246 3.793152e-07
glance(lmfit2)[, c(4,5)]
## statistic p.value ## 1 0.8432571 0.8581062
Во втором случае р-значение для F-статистики говорит о том, что 99 переменных НЕ СВЯЗАНЫ с величиной V1, несмотря на наличие 4-ех “статистически-значимых” переменных. Что и требовалось доказать, принимая во внимание то, что данные являются сгенерированным шумом.