/tpfinal/tp.R
https://gitlab.com/pr2016/aed · R · 133 lines · 83 code · 10 blank · 40 comment · 2 complexity · 7eef63811490680e684803ded137e69b MD5 · raw file
- library(Matrix)
- library(glmnet)
- library(randomForest)
- data <- read.table('titanic.txt', header=T, stringsAsFactors=F)
- set.seed(0); data <- data[sample(nrow(data)),] # Por las dudas, nunca esta de mas.
- # Descompongo Ticket en un prefijo categorico y un sufijo numerico. Si el
- # prefijo no existe, cae en la categoria NP (no prefix). Si el numero no existe,
- # lo dejo en cero bajo la categoria NN (no number).
- data$TicketPref <- as.factor(toupper(
- gsub('^$', 'NP',
- gsub('[./ ]', '',
- gsub('^(((.+) )?[0-9]+|(.*))$', '\\3\\4', data$Ticket)))))
- data$TicketNum <- as.numeric(gsub('^(.+ )?([^ ]+)$', '\\2', data$Ticket))
- data$TicketNumNN <- is.na(data$TicketNum)
- data$TicketNum <- ifelse(data$TicketNumNN, 0, data$TicketNum)
- # Del nombre solamente extraigo el titulo (MR, MRS, MISS). Cuando no aparece
- # ninguno de estos, la categoria por defecto es NT (no title).
- data$Title <- as.factor(toupper(
- gsub('^$', 'NT',
- gsub('^(.*(Mr|Mrs|Miss)\\..*|.*)$', '\\2', data$Name))))
- # Sexo es simplemente un factor bivaluado. No hay casos NA en la base.
- data$Sex <- as.factor(data$Sex)
- # Embarked es un factor con cuatro valors: C, Q, S y ''. En el caso vacio,
- # asigno la categoria NP (no port).
- data$Embarked <- as.factor(gsub('', 'NP', data$Embarked))
- # El tratamiento de las cabinas es mas complejo:
- #
- # 1. Algunas entradas tienen 0 y otras mas de 1.
- # 2. En general una cabina esta codificada como una letra seguida de un
- # numero, pero en ocasiones la letra aparece sola.
- # 3. Si aparece mas de una cabina, en general la letra es la misma para todas
- # y los numeros son muy cercanos. Hay dos excepciones a esta regla, en las
- # que la cabina F aparece seguida de G<num>.
- #
- # Teniendo todo esto en cuenta, procedo como sigue:
- #
- # 1. Descompongo cada cabina en una letra y un numero.
- # 2. Si el numero no existe, lo dejo en 0 y lo asigno a la categoria NN (no
- # number).
- # 3. Ademas del numero de cabina y su letra, creo una variable con la cuenta de
- # cabinas. Si hay 0 cabinas, la letra sera NL (no letter), el numero sera 0
- # en la categoria NN (no number) y la cuenta sera 0 en la categoria NC
- # (no count).
- # 4. Cuando hay mas de una cabina, informo el numero y la cuenta de la primera
- # solamente.
- # 5. Elimino los prefijos 'F '.
- data$Cabin <- gsub('^F ', '', data$Cabin)
- data$CabinCount <- sapply(strsplit(data$Cabin, ' '), length)
- data$CabinCountNC <- data$CabinCount == 0
- data$CabinLetter <- sapply(
- strsplit(data$Cabin, ' '), function(c) substr(c[1], 1, 1))
- data$CabinLetter <- as.factor(
- ifelse(is.na(data$CabinLetter), 'NL', data$CabinLetter))
- data$CabinNum <- as.numeric(sapply(
- strsplit(data$Cabin, ' '), function(c) substr(c[1], 2, nchar(c[1]))))
- data$CabinNumNN <- is.na(data$CabinNum)
- data$CabinNum <- ifelse(data$CabinNumNN, 0, data$CabinNum)
- # La edad es un numero cuando existe, cuando no es 0 bajo la categoria NA (no
- # age).
- data$AgeNA <- is.na(data$Age)
- data$Age <- ifelse(data$AgeNA, 0, data$Age)
- ######################### GlmNet
- form <- ~ 1 + (
- # Terminos simples e interacciones entre ellos
- Pclass +
- SibSp +
- Parch +
- Fare +
- TicketPref +
- TicketNum + TicketNumNN +
- Title +
- Sex +
- Embarked +
- CabinCount + CabinCountNC +
- CabinLetter +
- CabinNum + CabinNumNN +
- Age + AgeNA)^2 + (
- # Terminos cuadraticos para las variables numericas
- I(SibSp^2) +
- I(Parch^2) +
- I(Fare^2) +
- I(TicketNum^2) +
- I(CabinCount^2) +
- I(CabinNum^2) +
- I(Age^2)) - (
- # Elimino algunas interacciones espurias que dan siempre 0
- TicketNum : TicketNumNN +
- CabinCount : CabinCountNC +
- CabinNum : CabinNumNN)
- # La matriz de diseño es bastante dispersa, la proporcion de no-ceros a ceros es
- # menor al 10%.
- X <- sparse.model.matrix(form, data)
- y <- data$Survived
- gn.fit <- cv.glmnet(X, y, family='binomial', type.measure = "class",
- nlambda=100, alpha=0.2)
- cat('glmnet:', 1 - gn.fit$cvm[which(gn.fit$lambda == gn.fit$lambda.min)], '\n')
- # Random Forest
- data$Survived <- factor(data$Survived)
- form <- Survived ~ (
- # Terminos simples e interacciones entre ellos
- Pclass +
- SibSp +
- Parch +
- Fare +
- TicketPref +
- TicketNum + TicketNumNN +
- Title +
- Sex +
- Embarked +
- CabinCount + CabinCountNC +
- CabinLetter +
- CabinNum + CabinNumNN +
- Age + AgeNA) + (
- # Terminos cuadraticos para las variables numericas
- I(SibSp^2) +
- I(Parch^2) +
- I(Fare^2) +
- I(TicketNum^2) +
- I(CabinCount^2) +
- I(CabinNum^2) +
- I(Age^2))
- rf.fit <- randomForest(form, data)
- cat('random forest:', 1 - tail(rf.fit$err.rate[,1], 1), '\n')