Está en la página 1de 15

Tema 3 RSTUDIO.

Regresión lineal múltiple


#Utilizamos los datos liver

summary(liver)

#Observamos que la variable gender toma 0 y 1. La ponemos como factor

liver$gender=as.factor(liver$gender)

pairs(liver)

#En la base de datos aparecen 54 pacientes y 9 variables. Vamos a analizar graficos y


#relaciones usando las primeras 5 variables:

pairs(liver[,c(1:5,9)])

#Vamos a empezar ajustando un modelo de regresión con estas 5 primeras covariables, para
#examinar residuos y ver si la relacion es lineal:

lm.1=lm(survival~blood+prognostic+enzyme+liver+age+gender,data=liver)

summary(lm.1)

plot(lm.1)
#No parece homocedasticidad (grafico 1), parece problemas con los residuos en la de
#normalidad. En la siguiente, parece que hay una observación muy influyente: parece haber
#algun valor anomalo, gran leverage para dos valores y un valor de la distancia cook grande. Se
#observa en el ultimo grafico que parece que la relacion puede ser algo cuadrática y varianza
#no constante.

#Veamos el histograma de survival

hist(liver$survival)

#Para hacerlo simetrico, consideramos log. Para estabilizar estos problemas, probamos con la
#transformacion:

log.surv=log(liver$survival)

lm.2=lm(log.surv~blood+prognostic+enzyme+liver+age+gender,data=liver)

plot(lm.2)

#Se ha arreglado notablemente. Ya no tenemos los residuos influyentes del de normalidad. Las
#cotas del siguiente tampoco estan.

liver=cbind(liver, log.surv)
colnames(liver)[10]="log.surv"

pairs(liver[,c(1:5,10)])

#Parece que la varianza se estabiliza algo y que los residuos se hacen mas normales.

library(leaps)

#Cuidado cuando trabajamos con factores. En este caso hay que usar la funcion model.matrix

x <- model.matrix(~blood+prognostic+enzyme+liver+age+gender, data=liver)

#Si no quiero que aparezca la intercepta entre las variables a seleccionar:

reg.fit.selec <- regsubsets(x[,-1], y=liver$log.surv,nbest=1)

#Esto funcionaría si todas las variables fuesen cuantitativas:

#reg.fit.selec=regsubsets(x=liver[,1:6],y=liver$log.surv)

reg.summary=summary(reg.fit.selec)

summary(reg.fit.selec)

#Aqui se nos muestran cuales son los mejores modelos de dimension 1,2,3,...

#Por ej, el mejor modelo de dimension 1 es el que contiene enzyme, de dos seria enzyme y
#prognostic,... Los que pone asterisco son los que se añadirian

names(reg.summary)

#Estadisticos R^2:

reg.summary$rsq

#Estadistico R^2 ajustado. Me devuelve los R^2 ajustados para cuando solo me quedo con 1:
#enzima, para cuando me quedo con 2: pronostico y enzima… El numero es la variabilidad
#explicada.

reg.summary$adjr2

#Observamos que a partir de 3 variables, R2 aumenta muy poco.

#Segun el criterio del R^2 ajustado, el mejor pronostico seria el de 4 variables. Podria
#quedarme con varios modelos: entre 3, 4 y 5 variables.

par(mfrow=c(2,2))

plot(reg.summary$rss ,xlab="Numero de variables ",ylab="RSS", type="l")


plot(reg.summary$adjr2 ,xlab="Numero de variables ", ylab="Adjusted RSq",type="l")

#Me dice que posicion maximiza

which.max(reg.summary$adjr2)

points(4,reg.summary$adjr2[4], col="red",cex=2,pch=20)

#Usando el criterio R2 ajustado seleccionamos el modelo con 4 covariables:

mod.sele=lm(log.surv~ blood+prognostic+enzyme+age,data=liver)

summary(mod.sele)

#Grafico cp: el que se acerque a la linea tiene menor sesgo. Nos interesa menos error.
#Insesgado es mejor pero peudo elegir mas sesgados con menor error cuadratico medio. Se ve
#que en el 5 tengo menor error cuadratico medio pero es mas sesgado. Elegimos siempre
#menor error cuadratico medio. Si se llevan poco elegimos el mas insesgado

plot(reg.summary$cp ,xlab="Numero de variables ",ylab="Cp", type="l")

which.min(reg.summary$cp )

points(4,reg.summary$cp [4],col="red",cex=2,pch=20)

plot(4:7,reg.summary$cp[3:6],main="Valores de Cp frente a p")


reg.summary$cp
[1] 68.643691 21.772834 4.288921 3.885529 5.003213 7.000000

#Vemos ahora con bic

plot(reg.summary$bic ,xlab="Numero de variables ",ylab="BIC", type="l")

which.min(reg.summary$bic)

points(3,reg.summary$bic [3],col="red",cex=2,pch=20)
reg.summary$bic
[1] -22.11697 -46.79551 -60.48937 -59.14484 -56.16011 -52.17482

#El modelo con 3 covariables tiene mayor bic (en valor absoluto). No incluye edad

plot(reg.fit.selec,scale="adjr2")

reg.summary$adjr2

plot(reg.fit.selec,scale="bic")

reg.summary$bic

#Podemos ver los coeficientes estimados para este modelo seleccionado:


coef(reg.fit.selec ,3)

#El AIC y el BIC tambien aparecen implementados por defecto en R, solo que tendriamos que
#calcularlos para cada modelo:

AIC(lm(log.surv~enzyme,data=liver)) #51

AIC(lm(log.surv~prognostic+enzyme,data=liver)) #24

AIC(lm(log.surv~ blood+prognostic+enzyme,data=liver)) #9

AIC(lm(log.surv~ blood+prognostic+enzyme+liver,data=liver)) #10

AIC(lm(log.surv~ blood+prognostic+enzyme+liver+age,data=liver)) #10

AIC(lm(log.surv~ blood+prognostic+enzyme+liver+age+gender,data=liver)) #11

#El modelo con 3 covariables tiene menor AIC=> mas parsimonioso

#Calculamos los BIC;

BIC(lm(log.surv~ enzyme,data=liver)) #57

BIC(lm(log.surv~ prognostic+enzyme,data=liver)) #32

BIC(lm(log.surv~ blood+prognostic+enzyme,data=liver)) #19

BIC(lm(log.surv~ blood+prognostic+enzyme+liver,data=liver)) #22

BIC(lm(log.surv~ blood+prognostic+enzyme+liver+age,data=liver)) #24

BIC(lm(log.surv~ blood+prognostic+enzyme+liver+age+gender,data=liver)) #27

#El modelo con 3 covariables tiene menor BIC (en valor absoluto)

install.packages("DAAG")

library(DAAG)

#Para los mejores modelos seleccionados, de 1, 2, 3 ... covariables (los que me seleccionaba
#regsubset), calculamos PRESS

#Me da los errores de prediccion segun las variables que elija

press(lm(log.surv~ enzyme,data=liver)) #8

press(lm(log.surv~ prognostic+enzyme,data=liver)) #5

press(lm(log.surv~ blood+prognostic+enzyme,data=liver)) #3.9

press(lm(log.surv~ blood+prognostic+enzyme+liver,data=liver)) #4

press(lm(log.surv~ blood+prognostic+enzyme+liver+age,data=liver)) #4

press(lm(log.surv~ blood+prognostic+enzyme+liver+age+gender,data=liver)) #4.1

#Tambien el mejor modelo usando PRESS es el modelo con 3 covariables


#Y si uso las 8 covariables:

#En este caso tambien alc.mod y alc.heavy son factores:

x=model.matrix(~blood+prognostic+enzyme+liver+age+gender+alch.cons, data=liver)

reg.fit.selec=regsubsets(y=log.surv,x=x[,-1], data=liver)

reg.summary=summary(reg.fit.selec)

summary(reg.fit.selec)

reg.summary$cp

#Usando el criterio Cp, tendriamos que seleccionar las variables: blood, prognostic, enzyme,
#alc.heavy, alch.consNone y gender

reg.summary$bic

#Usando el criterio BIC, tendriamos que seleccionar las variables: blood, prognostic, enzyme,
#alc.heavy, alch.consNone.

#Tambien puedo verlo graficamente

reg.summary$bic

reg.summary$adjr2

#Usando el criterio R2 ajustado, tendriamos que seleccionar las variables: blood, prognostic,
#enzyme, alc.heavy, alch.consNone, gender y age.

#Y usando el criterio PRESS:

library(DAAG)

#Para los mejores modelos seleccionados, de 1, 2, 3 ... covariables, calculamos PRESS

press(lm(log.surv~ enzyme,data=liver)) #8
press(lm(log.surv~ prognostic+enzyme,data=liver)) #5

press(lm(log.surv~ blood+prognostic+enzyme,data=liver)) #3.9

press(lm(log.surv~ prognostic+enzyme+alch.cons,data=liver)) #3.5

press(lm(log.surv~ blood+prognostic+enzyme+alch.cons,data=liver)) #2.794987, modelo que


#incluye 5 covariables porque alch.cons tiene dos dummies. Coincide con el seleccionado por
#BIC

press(lm(log.surv~ blood+prognostic+enzyme+alch.cons+gender,data=liver)) #2.83

press(lm(log.surv~ blood+prognostic+enzyme+alch.cons+gender+age,data=liver)) #2.8

press(lm(log.surv~ blood+prognostic+enzyme+alch.cons+gender+age+liver,data=liver)) #2.93

#Se selecciona el modelo con blood, prognostic, enzyme y alch.cons.

#Vamos a analizar el ajuste con el modelo mas parsimonioso, es decir el que incluye
#blood+prognostic+enzyme+alch.cons, y el modelo que elegiría por ejemplo Cp que contendría
#6 cov: blood+prognostic+enzyme+alch.cons+gender

lm.4=lm(log.surv~ blood+prognostic+enzyme+alch.cons,data=liver)

lm.5=lm(log.surv~ blood+prognostic+enzyme+alch.cons+gender,data=liver)

#Valoramos lo bien que se ajusta cada modelo:

summary(lm.4)

summary(lm.5)

#El consumo de alcohol es un factor: me sale heavy, mode y none. No puedo poner 1, 2 y 3
#porque no es numerica. Si ajusto un modelo con esa variable y hago summary me salen dos
#coeficientes: uno de consumo moderado y uno de sin alcohol. Como es una variable con 3
#factores, saca dos dummies (la 3ª se explica con las otras dos). Lo hace por orden alfabetico.
#Se restaran los valores de alch.mod y alch.None (bajara la recta porque es negativo). Se
#obtiene un hiperplano para consumo elevado de alcohol y luego se sumara o restara la
#cantidad de alcohol moderado o no alcohol, según al grupo al que pertenezca. Veo el
#coeficiente de consumo moderado y no consumo frente a consumo elevado.
plot(lm.4)

plot(lm.5)

#viendo los graficos de los residuos, el ajuste es muy parecido en ambos modelos, en cuanto a
#bondad residual. No hay mucha mejoria en las posibles observaciones influyentes incluyendo
#blood o no incluyendola. Por otro gender no parece significativa. Si parece que el paciente del
#17 tiene valores influyentes. No parece haber heterocedasticidad. Desde este punto de vista
#nos quedamos con el 4 porque parece que en el otro hay valores mas influyentes.

#Si comparamos los modelos usando una comparacion con la F para comparar las sumas
#residuales con uno y otro modelo. Hay diferencia de 1 grado de libertad

anova(lm.4,lm.5)

#Nos quedamos con el modelo 4, ya que el p-valor es grande, lo que quiere decir que se puede
#asumir que el beta asociado a gender es 0. Sale 2.19 en el test de la F: probabilidad de 0.14 de
#ser compatible. El p-valor no es significativo=> los dos modelos explican parecido=> me
#quedo con el de menor variables (menos grados de libertad).

#Analizamos si hay problemas con observaciones o posible colinealidad en las variables


#seleccionadas:

library(olsrr)

library(car)

n=length(liver$log.surv)

stud.del.resids=rstudent(lm.4)

stud.del.resids

range(stud.del.resids)

#Miramos si estos residuos eliminados estudentizados son mayores que, para un alpa=0.01

qt(1-0.01/(2*n),df= n-4-1) #4

#Los valores maximo y minimos no son mayores en valor absoluto del correspondiente cuantil,
#aunque el residuo de la observacion 17 se queda con un valor muy grande.

ols_plot_resid_stud_fit(lm.4)

hatvalues(lm.4) #get the leverage values (hi)

#Tendriamos que comparar estos valores con:

2*4/n

#parece que el leverage de varias observaciones es mayor

ols_leverage(lm.4)
dffits(lm.4) #dffits.

#Dffits de la observacion 17 es mayor que 1

ols_plot_dffits(lm.4) #Mejor usar como valor umbral 1, -1 para tamaños moderados

cooks.distance(lm.4) #get Cook's distance

ols_plot_cooksd_chart(lm.4)

#Si comparamos los valores de la distancia de Cook con

qf(0.2,df1=4,df2=n-4)

#No parece que haya problema con las distancias de Cook

dfbetas(lm.4) #print all dfbetas

ols_plot_dfbetas(lm.4) #Mejor considerar como valor umbral 1 y -1 para tamaños moderados y


#2/sqrt(n) para bancos de datos mas grandes.

#Tampoco parece haber valores que excedan 1 o -1

influence(lm.4)

#Panel de graficos para analizar las diferentes cuestiones que hemos ido comentando:

ols_plot_diagnostics(lm.4)

vif(lm.4) #variance inflation factors

ols_coll_diag(lm.4)

avPlots(lm.4) #added variable plots

#Usamos Forward selection en el ejemplo de la cirugia de higado:

#Y si uso las 8 covariables:

x=model.matrix(~blood+prognostic+enzyme+liver+age+gender+alch.cons, data=liver)

reg.fit.selec.forward=regsubsets(y=log.surv,x=x[,-1], data=liver, method=c("forward"))

reg.summary.forward=summary(reg.fit.selec.forward)

summary(reg.fit.selec.forward)

names(reg.summary.forward)

#Estadisticos R^2:
reg.summary.forward$rsq

#Estadisticos R^2 ajustado:

reg.summary.forward$adjr2

#Estadisticos Cp ajustado:

reg.summary.forward$cp

#Estadisticos bic ajustado:

reg.summary.forward$bic

#Usamos backward selection en el ejemplo de la cirugia de higado:

#Y si uso las 8 covariables:

reg.fit.selec.back=regsubsets(y=log.surv,x=x[,-1], data=liver, method=c("backward"))

reg.summary.back=summary(reg.fit.selec.back)

summary(reg.fit.selec.back)

names(reg.summary.back)

#Estadisticos R^2:

reg.summary.back$rsq

#Estadisticos R^2 ajustado:

reg.summary.back$adjr2

#Estadisticos Cp ajustado:
reg.summary.back$cp

#Estadisticos bic ajustado:

reg.summary.back$bic

reg.fit.selec.seq=regsubsets(y=log.surv,x=x[,-1], data=liver, method=c("seqrep"))

reg.summary.seq=summary(reg.fit.selec.seq)

summary(reg.fit.selec.seq)

#Estadisticos R^2:

reg.summary.seq$rsq

#Estadisticos R^2 ajustado:

reg.summary.seq$adjr2

#Estadisticos Cp ajustado:

reg.summary.seq$cp

#Estadisticos bic ajustado:

reg.summary.seq$bic

#Notar que en este caso no se llega a seleccionar el mejor modelo al que llegaba bic por
busqueda exhaustiva o por stepwise (hacia atras y hacia adelante)
#Hemos considerado todo el rato alcohol como dummy. Ahora vamos a considerarla

#como factor

setwd("~/Dropbox/docencia/ModelosPrediccion/Tema3/datos")

#liver <-
#read.delim("~/Dropbox/docencia/ModelosPrediccion/Tema2/datos/UnidadQuirur.txt",
#header=FALSE)

#colnames(liver)=c("blood", "prognostic",
#"enzyme","liver","age","gender","alc.mod","alc.heavy","survival")

#write.table(liver[,1:9],file="liver.csv",row.names = FALSE, sep=";")

setwd("C:/Users/maria/Dropbox/docencia/ModelosPrediccion/Tema3/datos")

liver <- read.table("liver.csv", header=TRUE,sep=";")

summary(liver)

liver$gender=as.factor(liver$gender)

names(liver)

#alc.mod and alc.heavy son dummys de la misma variable, vamos a redefinir un factor:

indi.none=(1-liver$alc.heavy-liver$alc.mod)

indi.mod=liver$alc.mod

indi.heavy=liver$alc.heavy

aux=cbind(indi.none,indi.mod,indi.heavy)

colSums(aux)

rowSums(aux)

alch.cons=1*indi.none+2*indi.mod+3*indi.heavy

alch.cons

table(alch.cons)

alch.cons=factor(alch.cons,levels=c(1,2,3),labels=c("None","Mod","Heav"))

liver.new=data.frame(liver[,c(1:6)],alch.cons,liver$survival)

names(liver.new)[8]="survival"

write.csv(liver.new,file="liver.csv")

#Vamos ahora a hitters

#Comparando diferentes metodos de seleccion de variables automaticos:

library(ISLR)

fix(Hitters)
#Queremos predecir el salario de los jugadores de baloncesto

names(Hitters)

dim(Hitters)

sum(is.na(Hitters$Salary))

Hitters=na.omit(Hitters)

dim(Hitters)

sum(is.na(Hitters))

library(leaps)

regfit.full=regsubsets(log(Salary)~.,Hitters)

summary(regfit.full)

#En este caso hemos probado los diferentes modelos hasta un numero maximo de 8
#covariables, incrementamos este numero hasta 19:

regfit.full=regsubsets(log(Salary)~.,Hitters,nvmax=19)

summary(regfit.full)

reg.summary.full=summary(regfit.full)

reg.summary.full$adjr2

par(mfrow=c(2,2))

plot(reg.summary.full$rss ,xlab="Numero de variables ",ylab="RSS", type="l")

plot(reg.summary.full$adjr2 ,xlab="Numero de variables ", ylab="Adjusted RSq",type="l")

which.max(reg.summary.full$adjr2)

points(13,reg.summary.full$adjr2[11], col="red",cex=2,pch=20)

plot(reg.summary.full$cp ,xlab="Numero de variables ",ylab="Cp", type="l")


which.min(reg.summary.full$cp )

points(9,reg.summary.full$cp[10],col="red",cex=2,pch=20)

plot(5:19,reg.summary.full$cp[4:18],main="Valores de Cp frente a p")

abline(1,1)

plot(reg.summary.full$bic ,xlab="Numero de variables ",ylab="BIC", type="l")

which.min(reg.summary.full$bic)

points(3,reg.summary.full$bic[6],col="red",cex=2,pch=20)

regfit.forw=regsubsets(log(Salary)~.,Hitters,nvmax=19,method="forward")

summary(regfit.forw)

reg.summary.forw=summary(regfit.forw)

reg.summary.forw$adjr2

reg.summary.forw$bic

which.max(reg.summary.forw$adjr2) #13

which.min(reg.summary.forw$bic) #4

which.min(reg.summary.forw$cp) #9

regfit.bac=regsubsets(log(Salary)~.,Hitters,nvmax=19,method="backward")

summary(regfit.bac)
reg.summary.bac=summary(regfit.bac)

reg.summary.bac$adjr2

which.max(reg.summary.bac$adjr2) #13

which.min(reg.summary.bac$bic) #3

which.min(reg.summary.forw$cp) #9

names(coef(regfit.bac,3))

names(coef(regfit.full,3))

fit.3=lm(log(Salary)~Hits+Walks+Years,data=Hitters)

plot(fit.3)

summary(fit.3)

fit.9=lm(log(Salary)~AtBat+Hits+Walks+Years+CRuns+CWalks+League+Division+PutOuts,data=
Hitters)

summary(fit.9)

plot(fit.9)

#Cross Validation, para comparar varios posibles modelos.

library(DAAG)

#Para el modelo que le digo, parte el data.set en train y predice los los del test. Lo hace varias
#veces

library(lattice)

cv.lm(data=Hitters,form.lm=fit.3,seed=231)

cv.lm(data=Hitters,form.lm=fit.9,seed=191)

También podría gustarte