Все уровни фактора в модельной Матрице в R
у меня есть data.frame состоит из числовых и факторных переменных, как показано ниже.
testFrame <- data.frame(First=sample(1:10, 20, replace=T),
           Second=sample(1:20, 20, replace=T), Third=sample(1:10, 20, replace=T),
           Fourth=rep(c("Alice","Bob","Charlie","David"), 5),
           Fifth=rep(c("Edward","Frank","Georgia","Hank","Isaac"),4))
Я хочу построить matrix который присваивает фиктивные переменные фактору и оставляет числовые переменные в покое.
model.matrix(~ First + Second + Third + Fourth + Fifth, data=testFrame)
как и ожидалось при запуске lm это оставляет один уровень каждого фактора в качестве опорного уровня.  Тем не менее, я хочу построить matrix С фиктивной / индикаторной переменной для каждого уровня всех факторов.  Я строю эту матрицу glmnet поэтому я не беспокоюсь о мультиколлинеарности.
есть ли способ, чтобы иметь model.matrix создать манекен для каждого уровня фактора?
8 ответов
вам нужно сбросить contrasts для факторных переменных:
model.matrix(~ Fourth + Fifth, data=testFrame, 
        contrasts.arg=list(Fourth=contrasts(testFrame$Fourth, contrasts=F), 
                Fifth=contrasts(testFrame$Fifth, contrasts=F)))
или, с немного меньшим набором текста и без собственных имен:
model.matrix(~ Fourth + Fifth, data=testFrame, 
    contrasts.arg=list(Fourth=diag(nlevels(testFrame$Fourth)), 
            Fifth=diag(nlevels(testFrame$Fifth))))
(пытается искупить свою вину...) В ответ на комментарий Джареда на @Fabians ответ об автоматизации, обратите внимание, что все, что вам нужно предоставить, это именованный список контрастных матриц. contrasts() принимает вектор / фактор и создает из него матрицу контрастов. Для этого мы можем использовать lapply() для выполнения contrasts() по каждому фактору в нашем наборе данных, например для testFrame пример:
> lapply(testFrame[,4:5], contrasts, contrasts = FALSE)
$Fourth
        Alice Bob Charlie David
Alice       1   0       0     0
Bob         0   1       0     0
Charlie     0   0       1     0
David       0   0       0     1
$Fifth
        Edward Frank Georgia Hank Isaac
Edward       1     0       0    0     0
Frank        0     1       0    0     0
Georgia      0     0       1    0     0
Hank         0     0       0    1     0
Isaac        0     0       0    0     1
какие слоты красиво в @fabians ответ:
model.matrix(~ ., data=testFrame, 
             contrasts.arg = lapply(testFrame[,4:5], contrasts, contrasts=FALSE))
dummyVars с caret также можно использовать. http://caret.r-forge.r-project.org/preprocess.html
caret реализована хорошая функция dummyVars чтобы достичь этого с помощью 2 строк:
library(caret)
dmy <- dummyVars(" ~ .", data = testFrame)
testFrame2 <- data.frame(predict(dmy, newdata = testFrame))
проверка последних столбцов:
colnames(testFrame2)
"First"  "Second"         "Third"          "Fourth.Alice"   "Fourth.Bob"     "Fourth.Charlie" "Fourth.David"   "Fifth.Edward"   "Fifth.Frank"   "Fifth.Georgia"  "Fifth.Hank"     "Fifth.Isaac"   
самая приятная точка здесь-вы получаете исходный фрейм данных, плюс фиктивные переменные, исключив исходные, используемые для преобразования.
Подробнее: http://amunategui.github.io/dummyVar-Walkthrough/
Ok. Просто читаю вышесказанное и складываю все воедино. Предположим, вам нужна матрица, например "X. факторы", которая умножается на ваш вектор коэффициентов, чтобы получить ваш линейный предиктор. Есть еще пара дополнительных шагов:
X.factors = 
  model.matrix( ~ ., data=X, contrasts.arg = 
    lapply(data.frame(X[,sapply(data.frame(X), is.factor)]),
                                             contrasts, contrasts = FALSE))
(обратите внимание, что вам нужно превратить X[*] обратно в фрейм данных, если у вас есть только один столбец факторов.)
тогда скажите, что вы получаете что-то вроде этого:
attr(X.factors,"assign")
[1]  0  1  **2**  2  **3**  3  3  **4**  4  4  5  6  7  8  9 10 #emphasis added
мы хотим избавиться от * * ' D ссылочных уровней каждого фактор
att = attr(X.factors,"assign")
factor.columns = unique(att[duplicated(att)])
unwanted.columns = match(factor.columns,att)
X.factors = X.factors[,-unwanted.columns]
X.factors = (data.matrix(X.factors))
использование пакета R 'CatEncoders'
library(CatEncoders)
testFrame <- data.frame(First=sample(1:10, 20, replace=T),
           Second=sample(1:20, 20, replace=T), Third=sample(1:10, 20, replace=T),
           Fourth=rep(c("Alice","Bob","Charlie","David"), 5),
           Fifth=rep(c("Edward","Frank","Georgia","Hank","Isaac"),4))
fit <- OneHotEncoder.fit(testFrame)
z <- transform(fit,testFrame,sparse=TRUE) # give the sparse output
z <- transform(fit,testFrame,sparse=FALSE) # give the dense output
model.matrix(~ First + Second + Third + Fourth + Fifth - 1, data=testFrame)
или
model.matrix(~ First + Second + Third + Fourth + Fifth + 0, data=testFrame)
должно быть самым простым
F
в настоящее время я изучаю модель лассо и glmnet::cv.glmnet(), model.matrix() и Matrix::sparse.model.matrix()(для матрицы больших размеров, используя model.matrix будет убивать наше время, как предположил автор glmnet.).
просто обмен там имеет аккуратное кодирование, чтобы получить тот же ответ, что и @fabians и ответ @Gavin. Между тем, @asdf123 представил еще один пакет library('CatEncoders') как хорошо.
> require('useful')
> # always use all levels
> build.x(First ~ Second + Fourth + Fifth, data = testFrame, contrasts = FALSE)
> 
> # just use all levels for Fourth
> build.x(First ~ Second + Fourth + Fifth, data = testFrame, contrasts = c(Fourth = FALSE, Fifth = TRUE))
источник : R для всех: расширенная аналитика и графики (page273)
