/tpfinal/tp.R

https://gitlab.com/pr2016/aed · R · 133 lines · 83 code · 10 blank · 40 comment · 2 complexity · 7eef63811490680e684803ded137e69b MD5 · raw file

  1. library(Matrix)
  2. library(glmnet)
  3. library(randomForest)
  4. data <- read.table('titanic.txt', header=T, stringsAsFactors=F)
  5. set.seed(0); data <- data[sample(nrow(data)),] # Por las dudas, nunca esta de mas.
  6. # Descompongo Ticket en un prefijo categorico y un sufijo numerico. Si el
  7. # prefijo no existe, cae en la categoria NP (no prefix). Si el numero no existe,
  8. # lo dejo en cero bajo la categoria NN (no number).
  9. data$TicketPref <- as.factor(toupper(
  10. gsub('^$', 'NP',
  11. gsub('[./ ]', '',
  12. gsub('^(((.+) )?[0-9]+|(.*))$', '\\3\\4', data$Ticket)))))
  13. data$TicketNum <- as.numeric(gsub('^(.+ )?([^ ]+)$', '\\2', data$Ticket))
  14. data$TicketNumNN <- is.na(data$TicketNum)
  15. data$TicketNum <- ifelse(data$TicketNumNN, 0, data$TicketNum)
  16. # Del nombre solamente extraigo el titulo (MR, MRS, MISS). Cuando no aparece
  17. # ninguno de estos, la categoria por defecto es NT (no title).
  18. data$Title <- as.factor(toupper(
  19. gsub('^$', 'NT',
  20. gsub('^(.*(Mr|Mrs|Miss)\\..*|.*)$', '\\2', data$Name))))
  21. # Sexo es simplemente un factor bivaluado. No hay casos NA en la base.
  22. data$Sex <- as.factor(data$Sex)
  23. # Embarked es un factor con cuatro valors: C, Q, S y ''. En el caso vacio,
  24. # asigno la categoria NP (no port).
  25. data$Embarked <- as.factor(gsub('', 'NP', data$Embarked))
  26. # El tratamiento de las cabinas es mas complejo:
  27. #
  28. # 1. Algunas entradas tienen 0 y otras mas de 1.
  29. # 2. En general una cabina esta codificada como una letra seguida de un
  30. # numero, pero en ocasiones la letra aparece sola.
  31. # 3. Si aparece mas de una cabina, en general la letra es la misma para todas
  32. # y los numeros son muy cercanos. Hay dos excepciones a esta regla, en las
  33. # que la cabina F aparece seguida de G<num>.
  34. #
  35. # Teniendo todo esto en cuenta, procedo como sigue:
  36. #
  37. # 1. Descompongo cada cabina en una letra y un numero.
  38. # 2. Si el numero no existe, lo dejo en 0 y lo asigno a la categoria NN (no
  39. # number).
  40. # 3. Ademas del numero de cabina y su letra, creo una variable con la cuenta de
  41. # cabinas. Si hay 0 cabinas, la letra sera NL (no letter), el numero sera 0
  42. # en la categoria NN (no number) y la cuenta sera 0 en la categoria NC
  43. # (no count).
  44. # 4. Cuando hay mas de una cabina, informo el numero y la cuenta de la primera
  45. # solamente.
  46. # 5. Elimino los prefijos 'F '.
  47. data$Cabin <- gsub('^F ', '', data$Cabin)
  48. data$CabinCount <- sapply(strsplit(data$Cabin, ' '), length)
  49. data$CabinCountNC <- data$CabinCount == 0
  50. data$CabinLetter <- sapply(
  51. strsplit(data$Cabin, ' '), function(c) substr(c[1], 1, 1))
  52. data$CabinLetter <- as.factor(
  53. ifelse(is.na(data$CabinLetter), 'NL', data$CabinLetter))
  54. data$CabinNum <- as.numeric(sapply(
  55. strsplit(data$Cabin, ' '), function(c) substr(c[1], 2, nchar(c[1]))))
  56. data$CabinNumNN <- is.na(data$CabinNum)
  57. data$CabinNum <- ifelse(data$CabinNumNN, 0, data$CabinNum)
  58. # La edad es un numero cuando existe, cuando no es 0 bajo la categoria NA (no
  59. # age).
  60. data$AgeNA <- is.na(data$Age)
  61. data$Age <- ifelse(data$AgeNA, 0, data$Age)
  62. ######################### GlmNet
  63. form <- ~ 1 + (
  64. # Terminos simples e interacciones entre ellos
  65. Pclass +
  66. SibSp +
  67. Parch +
  68. Fare +
  69. TicketPref +
  70. TicketNum + TicketNumNN +
  71. Title +
  72. Sex +
  73. Embarked +
  74. CabinCount + CabinCountNC +
  75. CabinLetter +
  76. CabinNum + CabinNumNN +
  77. Age + AgeNA)^2 + (
  78. # Terminos cuadraticos para las variables numericas
  79. I(SibSp^2) +
  80. I(Parch^2) +
  81. I(Fare^2) +
  82. I(TicketNum^2) +
  83. I(CabinCount^2) +
  84. I(CabinNum^2) +
  85. I(Age^2)) - (
  86. # Elimino algunas interacciones espurias que dan siempre 0
  87. TicketNum : TicketNumNN +
  88. CabinCount : CabinCountNC +
  89. CabinNum : CabinNumNN)
  90. # La matriz de diseño es bastante dispersa, la proporcion de no-ceros a ceros es
  91. # menor al 10%.
  92. X <- sparse.model.matrix(form, data)
  93. y <- data$Survived
  94. gn.fit <- cv.glmnet(X, y, family='binomial', type.measure = "class",
  95. nlambda=100, alpha=0.2)
  96. cat('glmnet:', 1 - gn.fit$cvm[which(gn.fit$lambda == gn.fit$lambda.min)], '\n')
  97. # Random Forest
  98. data$Survived <- factor(data$Survived)
  99. form <- Survived ~ (
  100. # Terminos simples e interacciones entre ellos
  101. Pclass +
  102. SibSp +
  103. Parch +
  104. Fare +
  105. TicketPref +
  106. TicketNum + TicketNumNN +
  107. Title +
  108. Sex +
  109. Embarked +
  110. CabinCount + CabinCountNC +
  111. CabinLetter +
  112. CabinNum + CabinNumNN +
  113. Age + AgeNA) + (
  114. # Terminos cuadraticos para las variables numericas
  115. I(SibSp^2) +
  116. I(Parch^2) +
  117. I(Fare^2) +
  118. I(TicketNum^2) +
  119. I(CabinCount^2) +
  120. I(CabinNum^2) +
  121. I(Age^2))
  122. rf.fit <- randomForest(form, data)
  123. cat('random forest:', 1 - tail(rf.fit$err.rate[,1], 1), '\n')