더북(TheBook)

교차 검증 준비

테스트 데이터를 분리한 뒤 남은 데이터로부터 교차 검증을 수행하기로 한다. 10겹 교차 검증을 수행하기로 하고 caret 패키지의 createFolds( )를 사용해 데이터를 분리해보자.

> createFolds(titanic.train$survived, k=10)
$Fold01
  [1]    2   34   39   41   49   50   66   67   72   86   89   92  108
 [14]  116  143  148  151  172  201  211  214  216  224  245  247  250
 [27]  259  268  270  277  289  304  308  321  351  370  375  407  420
 [40]  422  434  441  446  447  448  457  460  462  467  490  501  502
 [53]  515  522  538  551  554  562  589  592  601  602  618  624  628
 [66]  632  654  676  708  710  713  716  717  719  720  744  751  755
 [79]  759  770  774  782  807  814  827  847  862  864  899  916  922
 [92]  937  944  947  952  958  959  960  978  989  993 1003 1007 1010
[105] 1020 1024 1026 1043 1045 1063 1082 1084 1089 1117 1142 1157 1160
[118] 1165

$Fold02
  [1]   15   21   35   38   40   57   60   85  101  103  113  128  141
 [14]  142  145  156  161  177  182  193  199  209  230  252  263  309
 [27]  324  328  359  361  372  391  402  412  414  435  458  472  483
 [40]  485  492  498  506  511  521  525  527  539  545  552  561  567
 [53]  573  578  585  631  649  656  660  666  669  673  677  682  684
 [66]  687  688  690  701  702  703  730  740  742  762  764  767  773
 [79]  799  810  839  840  849  876  897  911  914  920  933  936  942
 [92]  954  975  981  992  994 1001 1004 1009 1019 1031 1061 1076 1078
[105] 1095 1102 1107 1108 1111 1114 1118 1120 1132 1138 1143 1150 1152
[118] 1176

...

$Fold10
  [1]    5    9   27   33   51   54   65   69   76   77   91   97  100
 [14]  105  109  125  131  132  139  146  154  174  218  226  238  253
 [27]  265  281  282  288  293  300  307  323  330  332  334  336  344
 [40]  363  366  378  379  396  404  405  408  418  423  439  442  463
 [53]  468  478  523  530  532  537  563  564  565  576  577  583  597
 [66]  663  674  691  694  725  728  733  736  746  775  777  787  792
 [79]  795  802  821  831  838  848  855  857  866  880  883  889  896
 [92]  905  926  946  961  967  995 1013 1017 1025 1039 1040 1055 1057
[105] 1066 1079 1086 1105 1116 1125 1130 1131 1156 1158 1166 1171 1174
[118] 1177

코드 수행 결과 10개의 폴드Fold가 만들어져서 리스트에 Fold01, Fold02, …, Fold10이라는 이름으로 저장됨을 알 수 있다. 각 폴드에는 검증 데이터로 사용할 데이터 번호가 저장되어 있다. 따라서 데이터 번호를 보고 훈련 데이터와 검증 데이터를 분리하면 된다. 다음은 10겹 교차 테스트 데이터를 만드는 함수다. 앞서 설명한 것처럼 set.seed( )는 해당 함수를 반복해서 호출해도 매번 같은 결과가 나오게 할 목적으로 사용했다.

create_ten_fold_cv <- function() {
  set.seed(137)
  lapply(createFolds(titanic.train$survived, k=10), function(idx) {
    return(list(train=titanic.train[-idx, ],
                validation=titanic.train[idx, ]))
  })
}

이 함수는 Fold01, Fold02, …, Fold10을 포함하는 리스트를 반환하며, 각 폴드에는 train과 validation이라는 이름에 훈련 데이터와 검증 데이터가 저장된다. 이 함수의 실제 실행 결과를 살펴보자.

> x <- create_ten_fold_cv()
> str(x)
List of 10
 $ Fold01:List of 2
  ..$ train :'data.frame': 1061 obs. of 11 variables:
  .. ..$ pclass  : Factor w/ 3 levels "1","2","3": 1 1 1 1 1 1 1 1 ...
  .. ..$ survived: Factor w/ 2 levels "dead","survived": 2 1 1 2 2 ...
  .. ..$ name    : chr [1:1061] "Allen, Miss. Elisabeth Walton" ...
  .. ..$ sex     : Factor w/ 2 levels "female","male": 1 2 1 2 1 ...
  .. ..$ age     : num [1:1061] 29 30 25 48 63 39 53 71 47 18 ...
  .. ..$ sibsp   : int [1:1061] 0 1 1 0 1 0 2 0 1 1 ...
  .. ..$ parch   : int [1:1061] 0 2 2 0 0 0 0 0 0 0 ...
  .. ..$ ticket  : chr [1:1061] "24160" "113781" "113781" "19952" ...
  .. ..$ fare    : num [1:1061] 211.3 151.6 151.6 26.6 78 ...
  .. ..$ cabin   : chr [1:1061] "B5" "C22 C26" "C22 C26" "E12" ...
  .. ..$ embarked: Factor w/ 3 levels "C","Q","S": 3 3 3 3 3 3 ...
  ..$ validation:'data.frame': 117 obs. of 11 variables:
  .. ..$ pclass  : Factor w/ 3 levels "1","2","3": 1 1 1 1 1 1 ...
  .. ..$ survived: Factor w/ 2 levels "dead","survived": 1 1 2 ...
  .. ..$ name    : chr [1:117] "Allison, Miss. Helen Loraine" ...
  .. ..$ sex     : Factor w/ 2 levels "female","male": 1 2 1 1 ...
  .. ..$ age     : num [1:117] 2 24 47 60 41 39 38 38 NA 30 ...
  .. ..$ sibsp   : int [1:117] 1 0 1 0 0 1 1 0 0 0 ...
  .. ..$ parch   : int [1:117] 2 1 1 0 0 0 0 0 0 0 ...
  .. ..$ ticket  : chr [1:117] "113781" "PC 17558" "11751" "11813" ...
  .. ..$ fare    : num [1:117] 151.6 247.5 52.6 76.3 134.5 ...
  .. ..$ cabin   : chr [1:117] "C22 C26" "B58 B60" "D35" "D15" ...
  .. ..$ embarked: Factor w/ 3 levels "C","Q","S": 3 1 3 1 1 1 1 ...

...

결과가 길어 예에서는 Fold01의 내용만 보였다. Fold01에서 훈련 데이터를 가져오려면 다음과 같이 하면 된다.

> head(x$Fold01$train)
  pclass survived                                            name
1      1 survived                   Allen, Miss. Elisabeth Walton
4      1     dead            Allison, Mr. Hudson Joshua Creighton
5      1     dead Allison, Mrs. Hudson J C (Bessie Waldo Daniels)
6      1 survived                             Anderson, Mr. Harry
7      1 survived               Andrews, Miss. Kornelia Theodosia
8      1     dead                          Andrews, Mr. Thomas Jr

     sex age sibsp parch ticket     fare   cabin embarked
1 female  29     0     0  24160 211.3375      B5        S
4   male  30     1     2 113781 151.5500 C22 C26        S
5 female  25     1     2 113781 151.5500 C22 C26        S
6   male  48     0     0  19952  26.5500   E12 S
7 female  63     1     0  13502  77.9583    D7 S
8   male  39     0     0 112050   0.0000   A36 S

또는 x[[1]]$train으로 첫 번째 폴드를 가져올 수도 있다.

신간 소식 구독하기
뉴스레터에 가입하시고 이메일로 신간 소식을 받아 보세요.