порядковая логистическая регрессия с непрерывными переменными - масштабирование - PullRequest
1 голос
/ 12 апреля 2019

Я узнал о логистической регрессии и наткнулся на этот великий пост с примером анализа данных R.Я адаптировал код для своего анализа, и до сих пор все работало нормально.

У меня есть непрерывный предиктор.Я использовал команды для получения таблицы, которая отображает (линейные) предсказанные значения, которые мы получили бы, если бы мы регрессировали нашу зависимую переменную по нашим переменным предиктора по одному.Однако команда, кажется, преобразовывает непрерывную переменную в категориальную.

> ## Ordinal logistic regression (OLR) ## 
> # https://stats.idre.ucla.edu/r/dae/ordinal-logistic-regression/
> mod_OLRfull <- polr(Percentage_f ~ Gender + SE_track + Total_testscore, data = mydata, Hess=TRUE)

> # calculate essential metrics
> ctable <- coef(summary(mod_OLRfull))
> p <- pnorm(abs(ctable[, "t value"]), lower.tail = FALSE) * 2
> ctable <- cbind(ctable, "p value" = p)

> # check if assumption holds: proportional odds
> sf <- function(y) {
+   c('Y>=1' = qlogis(mean(y >= 1)),
+     'Y>=2' = qlogis(mean(y >= 2)),
+     'Y>=3' = qlogis(mean(y >= 3)))#,
+ #    'Y>=4' = qlogis(mean(y >= 4)))
+ }
> s <- with(mydata, summary(as.numeric(Percentage_f) ~ Gender + SE_track + Total_testscore, fun=sf))
> s
as.numeric(Percentage_f)     N= 286 

+---------------+-------+---+----+---------+----------+
|               |       |N  |Y>=1|Y>=2     |Y>=3      |
+---------------+-------+---+----+---------+----------+
|Gender         |male   | 97|Inf |1.2862109|-1.1685709|
|               |female |189|Inf |1.5170646|-0.8397507|
+---------------+-------+---+----+---------+----------+
|SE_track       |KSO    | 39|Inf |1.0647107|-1.3545457|
|               |TSO    | 40|Inf |0.7308875|-1.7346011|
|               |ASO    |207|Inf |1.6990501|-0.7591051|
+---------------+-------+---+----+---------+----------+
|Total_testscore|[ 2, 8)| 74|Inf |0.8602013|-1.6422277|
|               |[ 8,11)|104|Inf |1.6326948|-1.3156768|
|               |[11,13)| 58|Inf |1.3437347|-0.5663955|
|               |[13,16]| 50|Inf |2.4423470| 0.0000000|
+---------------+-------+---+----+---------+----------+
|Overall        |       |286|Inf |1.4350845|-0.9458495|
+---------------+-------+---+----+---------+----------+
> glm(I(as.numeric(Percentage_f) >= 2) ~ Gender + SE_track + Total_testscore, family = "binomial", data = mydata)

Call:  glm(formula = I(as.numeric(Percentage_f) >= 2) ~ Gender + SE_track + 
    Total_testscore, family = "binomial", data = mydata)

> glm(I(as.numeric(Percentage_f) >= 3) ~ Gender + SE_track + Total_testscore, family = "binomial", data = mydata)

> glm(I(as.numeric(Percentage_f) >= 4) ~ Gender + SE_track + Total_testscore, family = "binomial", data = mydata)


> s[, 4] <- s[, 4] - s[, 3]
> s[, 3] <- s[, 3] - s[, 3]
> s
as.numeric(Percentage_f)     N= 286 

+---------------+-------+---+----+----+---------+
|               |       |N  |Y>=1|Y>=2|Y>=3     |
+---------------+-------+---+----+----+---------+
|Gender         |male   | 97|Inf |0   |-2.454782|
|               |female |189|Inf |0   |-2.356815|
+---------------+-------+---+----+----+---------+
|SE_track       |KSO    | 39|Inf |0   |-2.419256|
|               |TSO    | 40|Inf |0   |-2.465489|
|               |ASO    |207|Inf |0   |-2.458155|
+---------------+-------+---+----+----+---------+
|Total_testscore|[ 2, 8)| 74|Inf |0   |-2.502429|
|               |[ 8,11)|104|Inf |0   |-2.948372|
|               |[11,13)| 58|Inf |0   |-1.910130|
|               |[13,16]| 50|Inf |0   |-2.442347|
+---------------+-------+---+----+----+---------+
|Overall        |       |286|Inf |0   |-2.380934|
+---------------+-------+---+----+----+---------+

ВОПРОС:

Как изменить, что моя переменная Total_testscore разбита на интервалы [ 2, 8), [ 8,11), [11,13), [13,16]?Я хотел бы изменить их на [ 0, 5), [ 5,10), [10,13), [13,16]

Ответы [ 2 ]

1 голос
/ 12 апреля 2019

Решение состоит в том, чтобы масштабировать непрерывную переменную перед ее использованием в регрессии, используя:

starters$Total_testscore_f <- cut(starters$Total_testscore, breaks = c(0,5,10,13,16))

s <- with(mydata, summary(as.numeric(Percentage_f) ~ Gender + SE_track + Total_testscore_f, fun=sf))
glm(I(as.numeric(Percentage_f) >= 2) ~ Gender + SE_track + Total_testscore_f, family = "binomial", data = mydata)
glm(I(as.numeric(Percentage_f) >= 3) ~ Gender + SE_track + Total_testscore_f, family = "binomial", data = mydata)
glm(I(as.numeric(Percentage_f) >= 4) ~ Gender + SE_track + Total_testscore_f, family = "binomial", data = mydata)
s[, 4] <- s[, 4] - s[, 3]
s[, 3] <- s[, 3] - s[, 3]
s

# plot 
par(mfrow = c(1,1))
plot(s, which=1:3, pch=1:3, xlab='logit', main=' ', xlim = c(-3,0))#xlim=range(s[,3:4]))
#  suggesting that the proportional odds assumption may not hold

as.numeric(Percentage_f)     N= 286 , 2 Missing 

+-----------------+-------+---+----+----+---------+
|                 |       |N  |Y>=1|Y>=2|Y>=3     |
+-----------------+-------+---+----+----+---------+
|Gender           |male   | 97|Inf |0   |-2.454782|
|                 |female |189|Inf |0   |-2.356815|
+-----------------+-------+---+----+----+---------+
|SE_track         |KSO    | 39|Inf |0   |-2.419256|
|                 |TSO    | 40|Inf |0   |-2.465489|
|                 |ASO    |207|Inf |0   |-2.458155|
+-----------------+-------+---+----+----+---------+
|Total_testscore_f|(0,5]  | 25|Inf |0   |-1.912387|
|                 |(5,10] |153|Inf |0   |-2.956124|
|                 |(10,13]| 81|Inf |0   |-2.096264|
|                 |(13,16]| 27|Inf |0   |-2.151035|
+-----------------+-------+---+----+----+---------+
|Overall          |       |286|Inf |0   |-2.380934|
+-----------------+-------+---+----+----+---------+
0 голосов
/ 12 апреля 2019

Вы можете создать нужные интервалы во фрейме данных перед запуском модели. Возможно, есть лучший способ, но, не глядя на данные, что-то вроде этого должно работать.

library(dplyr)

mydata = mydata %>% 
  mutate(
    `Total_testscore_[0,5)` = ifelse(Total_testscore>= 0 & Total_testscore < 5,1,0),
    `Total_testscore_[5,10)` = ifelse(Total_testscore>= 5 & Total_testscore < 10,1,0),
    `Total_testscore_[10,13)` = ifelse(Total_testscore>= 10 & Total_testscore < 13,1,0),
    `Total_testscore_[13,16)` = ifelse(Total_testscore>= 13 & Total_testscore < 16,1,0)) %>% 
  select(.,-Total_testscore)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...