wake-up-neo.net

So codieren Sie mehrere kategoriale Variablen in R

Ich arbeite an einem Vorhersageproblem und erstelle in R einen Entscheidungsbaum. Ich habe mehrere kategoriale Variablen und möchte sie in meinem Trainings- und Testset konsistent per One-Hot-Codierung codieren. Ich habe es mit meinen Trainingsdaten geschafft:

temps <- X_train
tt <- subset(temps, select = -output)
oh <- data.frame(model.matrix(~ . -1, tt), CLASS = temps$output)

Ich kann jedoch nicht die gleiche Codierung auf meinem Testset anwenden. Wie kann ich das tun?

9
xeco

Ich empfehle die Verwendung der dummyVars-Funktion im Caret-Paket:

customers <- data.frame(
  id=c(10, 20, 30, 40, 50),
  gender=c('male', 'female', 'female', 'male', 'female'),
  mood=c('happy', 'sad', 'happy', 'sad','happy'),
  outcome=c(1, 1, 0, 0, 0))
customers
id gender  mood outcome
1 10   male happy       1
2 20 female   sad       1
3 30 female happy       0
4 40   male   sad       0
5 50 female happy       0


# dummify the data
dmy <- dummyVars(" ~ .", data = customers)
trsf <- data.frame(predict(dmy, newdata = customers))
trsf
id gender.female gender.male mood.happy mood.sad outcome
1 10             0           1          1        0       1
2 20             1           0          0        1       1
3 30             1           0          1        0       0
4 40             0           1          0        1       0
5 50             1           0          1        0       0

beispiel Quelle

Sie wenden das gleiche Verfahren auf die Trainings- und Validierungssätze an.

23
Esteban PS

Code

library(data.table)
library(mltools)
customers_1h <- one_hot(as.data.table(customers))

Ergebnis

> customers_1h
id gender_female gender_male mood_happy mood_sad outcome
1: 10             0           1          1        0       1
2: 20             1           0          0        1       1
3: 30             1           0          1        0       0
4: 40             0           1          0        1       0
5: 50             1           0          1        0       0

Daten

customers <- data.frame(
  id=c(10, 20, 30, 40, 50),
  gender=c('male', 'female', 'female', 'male', 'female'),
  mood=c('happy', 'sad', 'happy', 'sad','happy'),
  outcome=c(1, 1, 0, 0, 0))
11
Roman

Hier ist eine einfache Lösung, um Ihre Kategorie mit nur einem Tastendruck ohne Pakete zu kodieren.

Lösung

model.matrix(~0+category)

Ihre kategoriale Variable muss ein Faktor sein. Die Faktorstufen müssen in Ihren Trainings- und Testdaten gleich sein, prüfen Sie mit levels(train$category) und levels(test$category). Es spielt keine Rolle, ob einige Level in Ihrem Test-Set nicht vorkommen.

Beispiel

Hier ist ein Beispiel mit dem Iris-Datensatz.

data(iris)
#Split into train and test sets.
train <- sample(1:nrow(iris),100)
test <- -1*train

iris[test,]

    Sepal.Length Sepal.Width Petal.Length Petal.Width   Species
34           5.5         4.2          1.4         0.2    setosa
106          7.6         3.0          6.6         2.1 virginica
112          6.4         2.7          5.3         1.9 virginica
127          6.2         2.8          4.8         1.8 virginica
132          7.9         3.8          6.4         2.0 virginica

model.matrix() erstellt eine Spalte für jede Ebene des Faktors, auch wenn sie nicht in den Daten vorhanden ist. Null zeigt an, dass es nicht dieses Niveau ist, man zeigt an, dass es ist. Das Hinzufügen der Null gibt an, dass Sie keinen Schnittpunkt oder Referenzpegel möchten, und entspricht -1.

oh_train <- model.matrix(~0+iris[train,'Species'])
oh_test <- model.matrix(~0+iris[test,'Species'])

#Renaming the columns to be more concise.
attr(oh_test, "dimnames")[[2]] <- levels(iris$Species)


  setosa versicolor virginica
1      1          0         0
2      0          0         1
3      0          0         1
4      0          0         1
5      0          0         1

P.S. Im Allgemeinen ist es vorzuziehen, alle Kategorien in die Trainings- und Testdaten aufzunehmen. Aber das geht mich nichts an.

3
D A Wells

Hallo, hier ist meine Version derselben, diese Funktion codiert alle kategorialen Variablen, die 'Faktoren' sind, und entfernt eine der Dummy-Variablen, um Dummy-Variablen-Trap zu vermeiden, und gibt ein zurück neuer Datenrahmen mit der Kodierung: -

onehotencoder <- function(df_orig) {
  df<-cbind(df_orig)
  df_clmtyp<-data.frame(clmtyp=sapply(df,class))
  df_col_typ<-data.frame(clmnm=colnames(df),clmtyp=df_clmtyp$clmtyp)
  for (rownm in 1:nrow(df_col_typ)) {
    if (df_col_typ[rownm,"clmtyp"]=="factor") {
      clmn_obj<-df[toString(df_col_typ[rownm,"clmnm"])] 
      dummy_matx<-data.frame(model.matrix( ~.-1, data = clmn_obj))
      dummy_matx<-dummy_matx[,c(1,3:ncol(dummy_matx))]
      df[toString(df_col_typ[rownm,"clmnm"])]<-NULL
      df<-cbind(df,dummy_matx)
      df[toString(df_col_typ[rownm,"clmnm"])]<-NULL
    }  }
  return(df)
}
1
Shubham Joshi