Carga de Librerías, Lectura del dataset y su estructura

# leo el archivo ar_properties 
library(tidyverse) # entorno tidy
library(dplyr) # manejo de datos
library(GGally) # scatterplots multiples
library(rgl) # para graficos 3D
datos1a <- read_csv("/home/andresfaral/Dropbox/Labo de Datos/ar_properties.csv") # Acá completen con su propio PATH al archivo

── Column specification ──────────────────────────────────────────────────────────────────────
cols(
  .default = col_character(),
  start_date = col_date(format = ""),
  end_date = col_date(format = ""),
  created_on = col_date(format = ""),
  lat = col_double(),
  lon = col_double(),
  l6 = col_logical(),
  rooms = col_double(),
  bedrooms = col_double(),
  bathrooms = col_double(),
  surface_total = col_double(),
  surface_covered = col_double(),
  price = col_double()
)
ℹ Use `spec()` for the full column specifications.
datos1a

Aplicando filtros

datos1d <- datos1a %>% 
                   # Me quedo con los que pertenecen a Argentina, Capital Federal y Boedo
            filter(l1 == "Argentina", 
                   l2 == "Capital Federal",
                   l3=="Boedo",
                   # cuyo precio este en dolares 
                   currency == "USD", 
                   # propiedad tipo Casa
                   property_type %in% c("Casa"),
                   # operaciones de venta
                   operation_type == "Venta") %>% 
            dplyr::select(id, l3, surface_total, surface_covered, price) %>% mutate(Precio=price,Sup=surface_covered,Fondo=surface_total-surface_covered) %>% dplyr::select(Sup,Fondo,Precio) %>%  filter(Fondo>=0) %>% na.omit()
datos1d
NA

Modelado de Datos

# Boedo
summary(datos1d)
      Sup            Fondo            Precio      
 Min.   : 35.0   Min.   :  0.00   Min.   : 90000  
 1st Qu.:136.5   1st Qu.:  7.00   1st Qu.:261250  
 Median :190.0   Median : 37.00   Median :300000  
 Mean   :190.1   Mean   : 85.47   Mean   :347997  
 3rd Qu.:251.0   3rd Qu.:180.00   3rd Qu.:450000  
 Max.   :332.0   Max.   :368.00   Max.   :590000  
ggpairs(datos1d)

# ajuste
ajusM2<-lm(Precio~Sup+Fondo,data=datos1d) # modelo lineal multiple
coe<-coef(ajusM2) # coeficientes
coe
(Intercept)         Sup       Fondo 
133400.9620    863.4824    590.5066 
summary(ajusM2)

Call:
lm(formula = Precio ~ Sup + Fondo, data = datos1d)

Residuals:
    Min      1Q  Median      3Q     Max 
-174199  -44261   11610   41648  230873 

Coefficients:
            Estimate Std. Error t value Pr(>|t|)    
(Intercept) 133401.0    27584.3   4.836 8.47e-06 ***
Sup            863.5      152.3   5.671 3.53e-07 ***
Fondo          590.5      108.7   5.434 8.85e-07 ***
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

Residual standard error: 78620 on 65 degrees of freedom
Multiple R-squared:  0.6426,    Adjusted R-squared:  0.6316 
F-statistic: 58.43 on 2 and 65 DF,  p-value: 3.01e-15
plot3d(ajusM2,size=15,col="blue")
# Defino las variables
Sup<-datos1d$Sup
Fondo<-datos1d$Fondo
Precio<-datos1d$Precio

grafico bueno

predichos2<-fitted.values(ajusM2)
coefs <- coef(ajusM2)
a <- coefs["Sup"]
b <- coefs["Fondo"]
cc <- -1
d<- coefs["(Intercept)"]

par3d(windowRect = c(0, 0, 800, 800)) # make the window large
par3d(zoom = 1.1) # larger values make the image smaller
#plot3d(datos,col=colores[clases],size=2)
plot3d(Sup,Fondo,Precio, 
       type="s", size=1,col="red",pch="16", xlab="Sup", 
       ylab="Fondo", zlab="Precio")
planes3d(a, b, cc, d,  col = 'red', alpha = 0.2)
rgl.snapshot('/home/andresfaral/Dropbox/Labo de Datos/foto1.png')
plot3d(Sup,Fondo,predichos2, type="s", size=1,
       col="pink",pch="16",  xlab="Sup", 
       ylab="Fondo", zlab="Precio",add=T)
rgl.snapshot('/home/andresfaral/Dropbox/Labo de Datos/foto2.png')
segments3d(x=as.vector(rbind(Sup,Sup)),y=as.vector(rbind(Fondo,Fondo)),z=as.vector(rbind(Precio,predichos2)),col="darkred")
rgl.snapshot('/home/andresfaral/Dropbox/Labo de Datos/foto3.png')

Funcion de Evaluacion

# Perdida cuadratica
Eval <- function(mu, alfa, beta) {
  salida<-mean((Precio-mu-alfa*Sup-beta*Fondo)^2)
  return(t(salida))
}
Eval(100000,2000,1000)
            [,1]
[1,] 64555965000

Optimizacion Aleatoria

facred<-0.9999 # factor de reduccion de la ventana
facred.acu<-1 # factor de reduccion acumulado
toler<-1/1e5 # umbral de tolerancia
# rangos
rango.mu<- 50000 # rango inicial de mu
rango.alfa<- 500 # rango inicial de alfa
rango.beta<- 500 # rango inicial de beta
# parametros iniciales
mu<- 100000 # valor inicial de mu
alfa<- 1000 # valor inicial de alfa
beta<- 1000 # valor inicial de beta
# parametros mejores
mejor.mu<-mu
mejor.alfa<-alfa
mejor.beta<-beta
mejor.eval<-Eval(mu,alfa,beta) # el mejor valor
mejores<-matrix(c(mejor.eval,mu,alfa,beta,1),1,5)
k<-0 # indice de iteracion
actu<-0 # indice de actualizacion
set.seed(1) # Fijamos semilla para que siempre retorne el mismo resultado
plot(alfa,beta,xlim=c(0,2000),ylim=c(0,2000),type="n",xlab="alfa",ylab="beta",main = paste("Act:",actu,"Mejor alfa=",round(alfa,2),"Mejor beta=",round(beta,2)))
points(alfa,beta,cex=10,col="red",pch=3)

while (facred.acu>toler)
{
  k<-k+1
  # Genero nuevos valores aleatorios
  mu<-runif(1,mejor.mu-rango.mu*facred.acu,mejor.mu+rango.mu*facred.acu)
  alfa<-runif(1,mejor.alfa-rango.alfa*facred.acu,mejor.alfa+rango.alfa*facred.acu)
  beta<-runif(1,mejor.beta-rango.beta*facred.acu,mejor.beta+rango.beta*facred.acu)
  # Evaluacion de los nuevos valores
  valor<-Eval(mu,alfa,beta)
  if (valor<mejor.eval) # SI encuentro algo mejor -> Actualizacion
  {
    invisible(readline(prompt="Presione [enter] para seguir:"))
        actu<-actu+1
    # grafico
    plot(alfa,beta,xlim=c(0,2000),ylim=c(0,2000),type="n",xlab="alfa",ylab="beta",main =paste("Act:",actu,"Mejor alfa=",round(alfa,2),"Mejor beta=",round(beta,2)))
    points(alfa,beta,cex=10,col="red",pch=3)
    mejor.eval<-valor
    mejor.mu<-mu
    mejor.alfa<-alfa
    mejor.beta<-beta
    mejores<-rbind(mejores,c(mejor.eval,mu,alfa,beta,k))
  }
  else # SI NO encuentro algo mejor -> Reduzco rango de busqueda
  {
    facred.acu<-facred.acu*facred
  }
  points(alfa,beta,cex=0.1,col="blue") # puntos evalyados
}

NA

NA

NA

NA

NA

NA

NA

NA

NA

NA

NA

NA

NA

NA

NA

NA

NA

NA

NA

NA

NA

NA

NA

NA

NA

NA

NA

NA

NA

NA

NA

NA

NA

NA

NA

NA

NA

NA

NA

NA

c(mu,alfa,beta)
[1] 133400.6267    863.4835    590.5030
dim(mejores)
[1] 43  5

graficacion

plot((mejores[,1]),type="l",col="blue",xlab="Actualizacion",ylab="Valor de Perdida")
#lines(evol2[subconj,2],col="green")
abline(coe[1],0,lty=3)
title("Convergencia de la Perdida")

#
plot(mejores[,2],type="l",col="blue",xlab="Actualizacion",ylab="Valor de mu")
#lines(evol2[subconj,2],col="green")
abline(coe[1],0,lty=3)
title("Convergencia del Parametro mu")

#
#
plot(mejores[,3],type="l",col="blue",xlab="Actualizacion",ylab="Valor de alfa")
#lines(evol2[subconj,3],col="green")
abline(coe[2],0,lty=3)
title("Convergencia del Parametro alfa")

#
#
plot(mejores[,4],type="l",col="blue",xlab="Actualizacion",ylab="Valor de beta")
#lines(evol2[subconj,4],col="green")
abline(coe[3],0,lty=3)
title("Convergencia del Parametro beta")

#
#
plot(mejores[,5],type="l",col="blue",xlab="Actualizacion",ylab="Iteraciones")
#lines(evol2[subconj,4],col="green")
title("Evolucion de los Iteraciones")

#

¿ Cuanbueno es el ajuste ?

predichos<-predict(ajusM2)
mean(abs(Precio-predichos))
[1] 60757.25
pmaeM2<-mean(abs(Precio-predichos))/mean(Precio)
pmaeM2
[1] 0.1745913

Medida del error por Validacion Cruzada

n<-length(Precio)
predichos.oos<-rep(NA,n) # predichos out of sample
plot3d(ajusM2,size=15,col="blue")
invisible(readline(prompt="Presione [enter] para seguir:"))

for (i in 1:n)
{
  ajus.cv<-lm(Precio~Sup+Fondo,data=datos1d[-i,])
  predichos.oos[i]<-predict(ajus.cv,newdata=datos1d[i,])
  plot3d(ajus.cv,size=15,col="green",add=T,alpha=0.1)
}

# MAE
mean(abs(Precio-predichos.oos))
[1] 64086.7
# PMAE
pmaeM2.cv<-mean(abs(Precio-predichos.oos))/mean(Precio)
pmaeM2.cv
[1] 0.1841587

¿ Cuán certeras (creibles/estables/repetibles) son las relaciones halladas ? El Bootstrap

B<-1000 # cantidad de muestras bootstrap
mues<-rep(NA,B) # vector para guardar los mu estimados
alfas<-rep(NA,B) # vector para guardar los alfa estimados
betas<-rep(NA,B) # vector para guardar los beta estimados
set.seed(1)
for (b in 1:B)
{
  indices<-sample(1:68,68,replace = TRUE)
  ajus.boot<-lm(Precio~Sup+Fondo,data=datos1d[indices,])
  coe<-coef(ajus.boot)
  mues[b]<-coe[1]
  alfas[b]<-coe[2]
  betas[b]<-coe[3]
}
resul<-cbind(mues,alfas,betas)
head(resul)
         mues     alfas    betas
[1,] 150778.5  572.0181 910.9515
[2,] 144559.6  704.4977 764.7104
[3,] 142702.9  729.8691 606.0145
[4,] 172381.2  602.5592 679.1868
[5,] 115306.3  988.1902 660.7135
[6,] 109073.9 1023.9048 411.6738

Grafico de resultados

plot(alfas,betas)
# parametros estimados en el modelo inicial
segments(863,0,863,2000,col="green",lty = 1,lwd=3)
segments(0,591,2000,591,col="green",lty = 1,lwd=3)
# cuantiles bootstrap
segments(quantile(alfas,0.05),0,quantile(alfas,0.05),2000,col="red",lty = 3,lwd=3)
segments(quantile(alfas,0.5),0,quantile(alfas,0.5),2000,col="red",lty = 3,lwd=3)
segments(quantile(alfas,0.95),0,quantile(alfas,0.95),2000,col="red",lty = 3,lwd=3)
segments(0,quantile(betas,0.05),2000,quantile(betas,0.05),2000,col="red",lty = 3,lwd=3)
segments(0,quantile(betas,0.5),2000,quantile(betas,0.5),2000,col="red",lty = 3,lwd=3)
segments(0,quantile(betas,0.95),2000,quantile(betas,0.95),2000,col="red",lty = 3,lwd=3)
abline(0,1,col="blue")
title("Estimaciones Bootstrap de los Parametros")

mean(betas>alfas)
[1] 0.167

Modelo simple con Sup

ajusM1<-lm(Precio~Sup,data=datos1d)
coe<-coef(ajusM1)
coe
(Intercept)         Sup 
 109601.840    1254.226 
summary(ajusM1)

Call:
lm(formula = Precio ~ Sup, data = datos1d)

Residuals:
    Min      1Q  Median      3Q     Max 
-217225  -49083     603   75104  190740 

Coefficients:
            Estimate Std. Error t value Pr(>|t|)    
(Intercept) 109601.8    32593.3   3.363  0.00129 ** 
Sup           1254.2      160.6   7.808 5.83e-11 ***
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

Residual standard error: 94100 on 66 degrees of freedom
Multiple R-squared:  0.4802,    Adjusted R-squared:  0.4723 
F-statistic: 60.97 on 1 and 66 DF,  p-value: 5.832e-11
plot(ajusM1)

plot(Sup,Precio)
abline(ajusM1)
title("Regresion Lineal Simple Precio Vs. Sup")

¿ Cuan bueno es el ajuste ?

predichos<-predict(ajusM1)
mean(abs(Precio-predichos))
[1] 76741.89
pmaeM1<-mean(abs(Precio-predichos))/mean(Precio)
pmaeM1
[1] 0.2205245
# cv
n<-length(Precio)
predichos.oos<-rep(NA,n) # predichos out of sample
for (i in 1:n)
{
  ajus.cv<-lm(Precio~Sup,data=datos1d[-i,])
  predichos.oos[i]<-predict(ajus.cv,newdata=datos1d[i,])
}
mean(abs(Precio-predichos.oos))
[1] 79186.78
pmaeM1.cv<-mean(abs(Precio-predichos.oos))/mean(Precio)
pmaeM1.cv
[1] 0.2275501

Modelo mas complejo

# agrego lat y lon
datos1e<-datos1a %>% filter(l3=="Boedo",property_type=="Casa")  %>% mutate(Precio=price,Sup=surface_covered,Fondo=surface_total-surface_covered) %>% dplyr::select(Sup,Fondo,Precio,lat,lon) %>%  filter(Fondo>=0) %>% na.omit()
datos1e
summary(datos1e)
      Sup            Fondo            Precio            lat              lon        
 Min.   : 35.0   Min.   :  0.00   Min.   : 18000   Min.   :-34.65   Min.   :-58.43  
 1st Qu.:132.0   1st Qu.:  7.00   1st Qu.:246500   1st Qu.:-34.64   1st Qu.:-58.42  
 Median :180.0   Median : 33.00   Median :297000   Median :-34.63   Median :-58.42  
 Mean   :185.7   Mean   : 82.56   Mean   :335166   Mean   :-34.63   Mean   :-58.41  
 3rd Qu.:251.0   3rd Qu.:156.50   3rd Qu.:450000   3rd Qu.:-34.62   3rd Qu.:-58.41  
 Max.   :332.0   Max.   :368.00   Max.   :590000   Max.   :-34.60   Max.   :-58.38  
ggpairs(datos1e)

# Creo las nuevas variables
Sup<-datos1e$Sup
Fondo<-datos1e$Fondo
Lon<-datos1e$lon
Lat<-datos1e$lat
Precio<-datos1e$Precio
ajusM4<-lm(Precio~Sup+Fondo+Lon+Lat)
coe<-coef(ajusM4)
coe
 (Intercept)          Sup        Fondo          Lon          Lat 
1.922485e+08 9.948234e+02 1.561275e+02 1.693947e+06 2.690522e+06 
summary(ajusM4)

Call:
lm(formula = Precio ~ Sup + Fondo + Lon + Lat)

Residuals:
    Min      1Q  Median      3Q     Max 
-202730  -37972      93   31036  217949 

Coefficients:
             Estimate Std. Error t value Pr(>|t|)    
(Intercept) 1.922e+08  5.647e+07   3.404  0.00113 ** 
Sup         9.948e+02  1.472e+02   6.758 4.35e-09 ***
Fondo       1.561e+02  1.606e+02   0.972  0.33453    
Lon         1.694e+06  1.372e+06   1.235  0.22122    
Lat         2.691e+06  1.712e+06   1.571  0.12087    
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

Residual standard error: 78160 on 66 degrees of freedom
Multiple R-squared:  0.7103,    Adjusted R-squared:  0.6928 
F-statistic: 40.46 on 4 and 66 DF,  p-value: < 2.2e-16
plot(Lon,Lat)

predichos<-predict(ajusM4)
mean(abs(Precio-predichos))
[1] 53247.78
pmaeM4<-mean(abs(Precio-predichos))/mean(Precio)
pmaeM4
[1] 0.1588698
plot(Precio,predichos,xlab="Precios Observados",yla="Predichos por M4",main="Precios Predichos por M4 Vs. Observados")
abline(0,1,col="green")

Error por CV del modelo M4

n<-length(Precio)
predichos.oos<-rep(NA,n) # predichos out of sample
for (i in 1:n)
{
  ajus.cv<-lm(Precio~Sup+Fondo+lon+lat,data=datos1e[-i,])
  predichos.oos[i]<-predict(ajus.cv,newdata=datos1e[i,])
}
mean(abs(Precio-predichos.oos))
[1] 57397.51
pmaeM4.cv<-mean(abs(Precio-predichos.oos))/mean(Precio)
pmaeM4.cv
[1] 0.1712509

Vamos por mas …. Modelo mas mas complejo

agrego efectos cuadraticos a lat y lon

# agrego efectos no lineales
ajusM8<-lm(Precio~Sup+Fondo+poly(Lon,3)+poly(Lat,3))
coe<-coef(ajusM8)
coe
  (Intercept)           Sup         Fondo poly(Lon, 3)1 poly(Lon, 3)2 poly(Lon, 3)3 
  136293.1124      986.0497      190.8774   557146.4452   110893.3951   -42545.1995 
poly(Lat, 3)1 poly(Lat, 3)2 poly(Lat, 3)3 
  -76485.5627  -154553.0046   -78618.7351 
summary(ajusM8)

Call:
lm(formula = Precio ~ Sup + Fondo + poly(Lon, 3) + poly(Lat, 
    3))

Residuals:
    Min      1Q  Median      3Q     Max 
-216390  -34175     698   31947  219714 

Coefficients:
               Estimate Std. Error t value Pr(>|t|)    
(Intercept)    136293.1    30714.0   4.437 3.80e-05 ***
Sup               986.0      154.2   6.394 2.37e-08 ***
Fondo             190.9      193.9   0.985    0.329    
poly(Lon, 3)1  557146.4  1591045.5   0.350    0.727    
poly(Lon, 3)2  110893.4   443020.8   0.250    0.803    
poly(Lon, 3)3  -42545.2   106206.2  -0.401    0.690    
poly(Lat, 3)1  -76485.6  1507667.2  -0.051    0.960    
poly(Lat, 3)2 -154553.0   761154.1  -0.203    0.840    
poly(Lat, 3)3  -78618.7   274829.6  -0.286    0.776    
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

Residual standard error: 80210 on 62 degrees of freedom
Multiple R-squared:  0.7134,    Adjusted R-squared:  0.6764 
F-statistic: 19.29 on 8 and 62 DF,  p-value: 3.387e-14
plot(Lon,Lat)

predichos<-predict(ajusM8)
mean(abs(Precio-predichos))
[1] 52459.34
pmaeM8<-mean(abs(Precio-predichos))/mean(Precio)
pmaeM8
[1] 0.1565174
plot(Precio,predichos,xlab="Precios Observados",yla="Predichos por M8",main="Precios Predichos por M8 Vs. Observados")
abline(0,1,col="green")

Medida del error por Validacion Cruzada

n<-length(Precio)
predichos.oos<-rep(NA,n) # predichos out of sample
for (i in 1:n)
{
  ajus.cv<-lm(Precio~Sup+Fondo+poly(lon,3)+poly(lat,3),data=datos1e[-i,])
  predichos.oos[i]<-predict(ajus.cv,newdata=datos1e[i,])
}
mean(abs(Precio-predichos.oos))
[1] 61888.82
pmaeM8.cv<-mean(abs(Precio-predichos.oos))/mean(Precio)
pmaeM8.cv
[1] 0.1846511

Comparacion de Modelos

PMAES<-matrix(c(pmaeM1,pmaeM1.cv,pmaeM2,pmaeM2.cv,pmaeM4,pmaeM4.cv,pmaeM8,pmaeM8.cv),4,2,byrow = T)
PMAES
          [,1]      [,2]
[1,] 0.2205245 0.2275501
[2,] 0.1745913 0.1841587
[3,] 0.1588698 0.1712509
[4,] 0.1565174 0.1846511
matplot(PMAES,type="b",pch=16,col=2:3,lty=1,lwd=3,, xaxt='n',main="PMAEs Ingenuos y PMAEs CV para M!, M2, M4 y M8",ylim=c(0.13,0.25),xlab="Modelo",ylab="PMAE")
text(1,pmaeM1.cv+0.01,"M1")
text(2,pmaeM2.cv+0.01,"M2")
text(3,pmaeM4.cv+0.01,"M4")
text(4,pmaeM8.cv+0.01,"M8")

Trade-off Sesgo-Varianza

N<-68
Sup0<-250
Relacion<-function(x){(log((x-70)/520)-log(10/520))*100000+100000}
set.seed(1)
Sup<-runif(N)*520+80
Error<-rnorm(N)*50000
Precio<-Relacion(Sup)+Error
plot(Sup,Precio,col="blue",main="Precio Vs. Superficie")
curve(Relacion,from=80,to=600,add=TRUE,col="green",lwd=2)
Precio0<-Relacion(Sup0)
segments(Sup0,0,Sup0,Precio0,lty=3,col="green",lwd=2)
segments(0,Precio0,Sup0,Precio0,lty=3,col="green",lwd=2)

Estimaciones simples

set.seed(1)
Sup<-runif(N)*520+80
Error<-rnorm(N)*50000
Precio<-Relacion(Sup)+Error
cant<-50 # cantidad de estimaciones
estimaciones<-rep(NA,cant)
grilla<-data.frame(Sup=seq(80,600,length.out = 100))
# grafico fijo
plot(Sup,Precio,col="blue",main="Precio Vs. Superficie con Ajustes de Modelos Simples")

# bucle
for (i in 1:cant)
{
Sup<-runif(N)*520+80
Error<-rnorm(N)*50000
Precio<-Relacion(Sup)+Error
ajus.1<-lm(Precio~poly(Sup,1))
pred.1<-predict(ajus.1,newdata=data.frame(Sup=Sup0))
estimaciones[i]<-pred.1
curva.1<-predict(ajus.1,newdata = grilla)
lines(as.numeric(grilla$Sup),curva.1,lwd=0.5,col="red")
}
segments(0,mean(estimaciones),Sup0,mean(estimaciones),lty=3,lwd=2,col="black")
segments(0,mean(estimaciones)-2*sd(estimaciones),Sup0,mean(estimaciones)-2*sd(estimaciones),lty=3,lwd=2,col="black")
segments(0,mean(estimaciones)+2*sd(estimaciones),Sup0,mean(estimaciones)+2*sd(estimaciones),lty=3,lwd=2,col="black")
#
curve(Relacion,from=80,to=600,add=TRUE,col="green",lwd=3)
segments(Sup0,0,Sup0,Precio0,lty=3,lwd=2,col="green")
segments(0,Precio0,Sup0,Precio0,lty=3,lwd=2,col="green")

estimaciones.simples<-estimaciones

Estimaciones complejas

set.seed(1)
Sup<-runif(N)*520+80
Error<-rnorm(N)*50000
Precio<-Relacion(Sup)+Error
cant<-50 # cantidad de estimaciones
estimaciones<-rep(NA,cant)
grilla<-data.frame(Sup=seq(80,600,length.out = 100))
# grafico fijo
plot(Sup,Precio,col="blue",main="Precio Vs. Superficie con Ajustes de Modelos Complejos")

# bucle
for (i in 1:cant)
{
Sup<-runif(N)*520+80
Error<-rnorm(N)*50000
Precio<-Relacion(Sup)+Error
ajus.1<-lm(Precio~poly(Sup,12))
pred.1<-predict(ajus.1,newdata=data.frame(Sup=Sup0))
estimaciones[i]<-pred.1
curva.1<-predict(ajus.1,newdata = grilla)
lines(as.numeric(grilla$Sup),curva.1,lwd=0.5,col="red")
}
segments(0,mean(estimaciones),Sup0,mean(estimaciones),lty=3,lwd=2,col="black")
segments(0,mean(estimaciones)-2*sd(estimaciones),Sup0,mean(estimaciones)-2*sd(estimaciones),lty=3,lwd=2,col="black")
segments(0,mean(estimaciones)+2*sd(estimaciones),Sup0,mean(estimaciones)+2*sd(estimaciones),lty=3,lwd=2,col="black")#
curve(Relacion,from=80,to=600,add=TRUE,col="green",lwd=3)
segments(Sup0,0,Sup0,Precio0,lty=3,lwd=2,col="green")
segments(0,Precio0,Sup0,Precio0,lty=3,lwd=2,col="green")

estimaciones.complejas<-estimaciones

Comparacion

  boxplot(list(Simple=estimaciones.simples,Complejo=estimaciones.complejas),ylab="Precio",main="Distribucion de las Predicciones",col=c("cyan","magenta"))
abline(Precio0,0,col="green",lty=3,lwd=2)

Comparacion modelo M1 con M2

ajus.Fondo<-lm(Fondo~Sup,data=datos1e)
coe.Fondo<-coef(ajus.Fondo)
coe.M1<-coef(ajusM1)
coe.M2<-coef(ajusM2)
# pendiente
coe.M2[2]+coe.M2[3]*coe.Fondo[2]
     Sup 
1254.545 
# intercept
coe.M2[1]+coe.M2[3]*coe.Fondo[1]
(Intercept) 
   109533.2 
# el ajuste M1
coe.M1
(Intercept)         Sup 
 109601.840    1254.226 
LS0tCnRpdGxlOiAiTW9kZWxhZG8gZGUgUHJlY2lvcyBjb24gbGEgYmFzZSBkZSBQcm9wZXJhdGkiCmF1dGhvcjogIkFuZHJlcyBGYXJhbGwiCmRhdGU6ICIyOSBkZSBTZXB0aWVtYnJlIGRlIDIwMjEiCm91dHB1dDoKICBodG1sX2RvY3VtZW50OgogICAgZGZfcHJpbnQ6IHBhZ2VkCiAgICB0b2M6IHllcwogIGh0bWxfbm90ZWJvb2s6CiAgICB0aGVtZTogbHVtZW4KICAgIHRvYzogeWVzCiAgICB0b2NfZmxvYXQ6IHllcwpzdWJ0aXRsZTogTGFib3JhdG9yaW8gZGUgRGF0b3MKLS0tCgojIyMgQ2FyZ2EgZGUgTGlicmVyw61hcywgTGVjdHVyYSBkZWwgZGF0YXNldCB5IHN1IGVzdHJ1Y3R1cmEKCmBgYHtyfQojIGxlbyBlbCBhcmNoaXZvIGFyX3Byb3BlcnRpZXMgCmxpYnJhcnkodGlkeXZlcnNlKSAjIGVudG9ybm8gdGlkeQpsaWJyYXJ5KGRwbHlyKSAjIG1hbmVqbyBkZSBkYXRvcwpsaWJyYXJ5KEdHYWxseSkgIyBzY2F0dGVycGxvdHMgbXVsdGlwbGVzCmxpYnJhcnkocmdsKSAjIHBhcmEgZ3JhZmljb3MgM0QKZGF0b3MxYSA8LSByZWFkX2NzdigiL2hvbWUvYW5kcmVzZmFyYWwvRHJvcGJveC9MYWJvIGRlIERhdG9zL2FyX3Byb3BlcnRpZXMuY3N2IikgIyBBY8OhIGNvbXBsZXRlbiBjb24gc3UgcHJvcGlvIFBBVEggYWwgYXJjaGl2bwpkYXRvczFhCmBgYAoKIyMjIEFwbGljYW5kbyBmaWx0cm9zCgpgYGB7cn0KZGF0b3MxZCA8LSBkYXRvczFhICU+JSAKICAgICAgICAgICAgICAgICAgICMgTWUgcXVlZG8gY29uIGxvcyBxdWUgcGVydGVuZWNlbiBhIEFyZ2VudGluYSwgQ2FwaXRhbCBGZWRlcmFsIHkgQm9lZG8KICAgICAgICAgICAgZmlsdGVyKGwxID09ICJBcmdlbnRpbmEiLCAKICAgICAgICAgICAgICAgICAgIGwyID09ICJDYXBpdGFsIEZlZGVyYWwiLAogICAgICAgICAgICAgICAgICAgbDM9PSJCb2VkbyIsCiAgICAgICAgICAgICAgICAgICAjIGN1eW8gcHJlY2lvIGVzdGUgZW4gZG9sYXJlcyAKICAgICAgICAgICAgICAgICAgIGN1cnJlbmN5ID09ICJVU0QiLCAKICAgICAgICAgICAgICAgICAgICMgcHJvcGllZGFkIHRpcG8gQ2FzYQogICAgICAgICAgICAgICAgICAgcHJvcGVydHlfdHlwZSAlaW4lIGMoIkNhc2EiKSwKICAgICAgICAgICAgICAgICAgICMgb3BlcmFjaW9uZXMgZGUgdmVudGEKICAgICAgICAgICAgICAgICAgIG9wZXJhdGlvbl90eXBlID09ICJWZW50YSIpICU+JSAKICAgICAgICAgICAgZHBseXI6OnNlbGVjdChpZCwgbDMsIHN1cmZhY2VfdG90YWwsIHN1cmZhY2VfY292ZXJlZCwgcHJpY2UpICU+JSBtdXRhdGUoUHJlY2lvPXByaWNlLFN1cD1zdXJmYWNlX2NvdmVyZWQsRm9uZG89c3VyZmFjZV90b3RhbC1zdXJmYWNlX2NvdmVyZWQpICU+JSBkcGx5cjo6c2VsZWN0KFN1cCxGb25kbyxQcmVjaW8pICU+JSAgZmlsdGVyKEZvbmRvPj0wKSAlPiUgbmEub21pdCgpCmRhdG9zMWQKCmBgYAoKCiMjIyAgTW9kZWxhZG8gZGUgRGF0b3MKCmBgYHtyfQojIEJvZWRvCnN1bW1hcnkoZGF0b3MxZCkKZ2dwYWlycyhkYXRvczFkKQojIGFqdXN0ZQphanVzTTI8LWxtKFByZWNpb35TdXArRm9uZG8sZGF0YT1kYXRvczFkKSAjIG1vZGVsbyBsaW5lYWwgbXVsdGlwbGUKY29lPC1jb2VmKGFqdXNNMikgIyBjb2VmaWNpZW50ZXMKY29lCnN1bW1hcnkoYWp1c00yKQpwbG90M2QoYWp1c00yLHNpemU9MTUsY29sPSJibHVlIikKIyBEZWZpbm8gbGFzIHZhcmlhYmxlcwpTdXA8LWRhdG9zMWQkU3VwCkZvbmRvPC1kYXRvczFkJEZvbmRvClByZWNpbzwtZGF0b3MxZCRQcmVjaW8KYGBgCgpncmFmaWNvIGJ1ZW5vIAoKYGBge3J9CnByZWRpY2hvczI8LWZpdHRlZC52YWx1ZXMoYWp1c00yKQpjb2VmcyA8LSBjb2VmKGFqdXNNMikKYSA8LSBjb2Vmc1siU3VwIl0KYiA8LSBjb2Vmc1siRm9uZG8iXQpjYyA8LSAtMQpkPC0gY29lZnNbIihJbnRlcmNlcHQpIl0KCnBhcjNkKHdpbmRvd1JlY3QgPSBjKDAsIDAsIDgwMCwgODAwKSkgIyBtYWtlIHRoZSB3aW5kb3cgbGFyZ2UKcGFyM2Qoem9vbSA9IDEuMSkgIyBsYXJnZXIgdmFsdWVzIG1ha2UgdGhlIGltYWdlIHNtYWxsZXIKI3Bsb3QzZChkYXRvcyxjb2w9Y29sb3Jlc1tjbGFzZXNdLHNpemU9MikKcGxvdDNkKFN1cCxGb25kbyxQcmVjaW8sIAogICAgICAgdHlwZT0icyIsIHNpemU9MSxjb2w9InJlZCIscGNoPSIxNiIsIHhsYWI9IlN1cCIsIAogICAgICAgeWxhYj0iRm9uZG8iLCB6bGFiPSJQcmVjaW8iKQpwbGFuZXMzZChhLCBiLCBjYywgZCwgIGNvbCA9ICdyZWQnLCBhbHBoYSA9IDAuMikKcmdsLnNuYXBzaG90KCcvaG9tZS9hbmRyZXNmYXJhbC9Ecm9wYm94L0xhYm8gZGUgRGF0b3MvZm90bzEucG5nJykKcGxvdDNkKFN1cCxGb25kbyxwcmVkaWNob3MyLCB0eXBlPSJzIiwgc2l6ZT0xLAogICAgICAgY29sPSJwaW5rIixwY2g9IjE2IiwgIHhsYWI9IlN1cCIsIAogICAgICAgeWxhYj0iRm9uZG8iLCB6bGFiPSJQcmVjaW8iLGFkZD1UKQpyZ2wuc25hcHNob3QoJy9ob21lL2FuZHJlc2ZhcmFsL0Ryb3Bib3gvTGFibyBkZSBEYXRvcy9mb3RvMi5wbmcnKQpzZWdtZW50czNkKHg9YXMudmVjdG9yKHJiaW5kKFN1cCxTdXApKSx5PWFzLnZlY3RvcihyYmluZChGb25kbyxGb25kbykpLHo9YXMudmVjdG9yKHJiaW5kKFByZWNpbyxwcmVkaWNob3MyKSksY29sPSJkYXJrcmVkIikKcmdsLnNuYXBzaG90KCcvaG9tZS9hbmRyZXNmYXJhbC9Ecm9wYm94L0xhYm8gZGUgRGF0b3MvZm90bzMucG5nJykKYGBgCgojIyMgIEZ1bmNpb24gZGUgRXZhbHVhY2lvbgoKYGBge3J9CiMgUGVyZGlkYSBjdWFkcmF0aWNhCkV2YWwgPC0gZnVuY3Rpb24obXUsIGFsZmEsIGJldGEpIHsKICBzYWxpZGE8LW1lYW4oKFByZWNpby1tdS1hbGZhKlN1cC1iZXRhKkZvbmRvKV4yKQogIHJldHVybih0KHNhbGlkYSkpCn0KRXZhbCgxMDAwMDAsMjAwMCwxMDAwKQpgYGAKCgojIyMgT3B0aW1pemFjaW9uIEFsZWF0b3JpYQoKYGBge3J9CmZhY3JlZDwtMC45OTk5ICMgZmFjdG9yIGRlIHJlZHVjY2lvbiBkZSBsYSB2ZW50YW5hCmZhY3JlZC5hY3U8LTEgIyBmYWN0b3IgZGUgcmVkdWNjaW9uIGFjdW11bGFkbwp0b2xlcjwtMS8xZTUgIyB1bWJyYWwgZGUgdG9sZXJhbmNpYQojIHJhbmdvcwpyYW5nby5tdTwtIDUwMDAwICMgcmFuZ28gaW5pY2lhbCBkZSBtdQpyYW5nby5hbGZhPC0gNTAwICMgcmFuZ28gaW5pY2lhbCBkZSBhbGZhCnJhbmdvLmJldGE8LSA1MDAgIyByYW5nbyBpbmljaWFsIGRlIGJldGEKIyBwYXJhbWV0cm9zIGluaWNpYWxlcwptdTwtIDEwMDAwMCAjIHZhbG9yIGluaWNpYWwgZGUgbXUKYWxmYTwtIDEwMDAgIyB2YWxvciBpbmljaWFsIGRlIGFsZmEKYmV0YTwtIDEwMDAgIyB2YWxvciBpbmljaWFsIGRlIGJldGEKIyBwYXJhbWV0cm9zIG1lam9yZXMKbWVqb3IubXU8LW11Cm1lam9yLmFsZmE8LWFsZmEKbWVqb3IuYmV0YTwtYmV0YQptZWpvci5ldmFsPC1FdmFsKG11LGFsZmEsYmV0YSkgIyBlbCBtZWpvciB2YWxvcgptZWpvcmVzPC1tYXRyaXgoYyhtZWpvci5ldmFsLG11LGFsZmEsYmV0YSwxKSwxLDUpCms8LTAgIyBpbmRpY2UgZGUgaXRlcmFjaW9uCmFjdHU8LTAgIyBpbmRpY2UgZGUgYWN0dWFsaXphY2lvbgpzZXQuc2VlZCgxKSAjIEZpamFtb3Mgc2VtaWxsYSBwYXJhIHF1ZSBzaWVtcHJlIHJldG9ybmUgZWwgbWlzbW8gcmVzdWx0YWRvCnBsb3QoYWxmYSxiZXRhLHhsaW09YygwLDIwMDApLHlsaW09YygwLDIwMDApLHR5cGU9Im4iLHhsYWI9ImFsZmEiLHlsYWI9ImJldGEiLG1haW4gPSBwYXN0ZSgiQWN0OiIsYWN0dSwiTWVqb3IgYWxmYT0iLHJvdW5kKGFsZmEsMiksIk1lam9yIGJldGE9Iixyb3VuZChiZXRhLDIpKSkKcG9pbnRzKGFsZmEsYmV0YSxjZXg9MTAsY29sPSJyZWQiLHBjaD0zKQp3aGlsZSAoZmFjcmVkLmFjdT50b2xlcikKewogIGs8LWsrMQogICMgR2VuZXJvIG51ZXZvcyB2YWxvcmVzIGFsZWF0b3Jpb3MKICBtdTwtcnVuaWYoMSxtZWpvci5tdS1yYW5nby5tdSpmYWNyZWQuYWN1LG1lam9yLm11K3JhbmdvLm11KmZhY3JlZC5hY3UpCiAgYWxmYTwtcnVuaWYoMSxtZWpvci5hbGZhLXJhbmdvLmFsZmEqZmFjcmVkLmFjdSxtZWpvci5hbGZhK3JhbmdvLmFsZmEqZmFjcmVkLmFjdSkKICBiZXRhPC1ydW5pZigxLG1lam9yLmJldGEtcmFuZ28uYmV0YSpmYWNyZWQuYWN1LG1lam9yLmJldGErcmFuZ28uYmV0YSpmYWNyZWQuYWN1KQogICMgRXZhbHVhY2lvbiBkZSBsb3MgbnVldm9zIHZhbG9yZXMKICB2YWxvcjwtRXZhbChtdSxhbGZhLGJldGEpCiAgaWYgKHZhbG9yPG1lam9yLmV2YWwpICMgU0kgZW5jdWVudHJvIGFsZ28gbWVqb3IgLT4gQWN0dWFsaXphY2lvbgogIHsKICAgIGludmlzaWJsZShyZWFkbGluZShwcm9tcHQ9IlByZXNpb25lIFtlbnRlcl0gcGFyYSBzZWd1aXI6IikpCiAgICAgICAgYWN0dTwtYWN0dSsxCiAgICAjIGdyYWZpY28KICAgIHBsb3QoYWxmYSxiZXRhLHhsaW09YygwLDIwMDApLHlsaW09YygwLDIwMDApLHR5cGU9Im4iLHhsYWI9ImFsZmEiLHlsYWI9ImJldGEiLG1haW4gPXBhc3RlKCJBY3Q6IixhY3R1LCJNZWpvciBhbGZhPSIscm91bmQoYWxmYSwyKSwiTWVqb3IgYmV0YT0iLHJvdW5kKGJldGEsMikpKQogICAgcG9pbnRzKGFsZmEsYmV0YSxjZXg9MTAsY29sPSJyZWQiLHBjaD0zKQogICAgbWVqb3IuZXZhbDwtdmFsb3IKICAgIG1lam9yLm11PC1tdQogICAgbWVqb3IuYWxmYTwtYWxmYQogICAgbWVqb3IuYmV0YTwtYmV0YQogICAgbWVqb3JlczwtcmJpbmQobWVqb3JlcyxjKG1lam9yLmV2YWwsbXUsYWxmYSxiZXRhLGspKQogIH0KICBlbHNlICMgU0kgTk8gZW5jdWVudHJvIGFsZ28gbWVqb3IgLT4gUmVkdXpjbyByYW5nbyBkZSBidXNxdWVkYQogIHsKICAgIGZhY3JlZC5hY3U8LWZhY3JlZC5hY3UqZmFjcmVkCiAgfQogIHBvaW50cyhhbGZhLGJldGEsY2V4PTAuMSxjb2w9ImJsdWUiKSAjIHB1bnRvcyBldmFseWFkb3MKfQpjKG11LGFsZmEsYmV0YSkKZGltKG1lam9yZXMpCmBgYAoKIyBncmFmaWNhY2lvbgoKYGBge3J9CnBsb3QoKG1lam9yZXNbLDFdKSx0eXBlPSJsIixjb2w9ImJsdWUiLHhsYWI9IkFjdHVhbGl6YWNpb24iLHlsYWI9IlZhbG9yIGRlIFBlcmRpZGEiKQojbGluZXMoZXZvbDJbc3ViY29uaiwyXSxjb2w9ImdyZWVuIikKYWJsaW5lKGNvZVsxXSwwLGx0eT0zKQp0aXRsZSgiQ29udmVyZ2VuY2lhIGRlIGxhIFBlcmRpZGEiKQojCnBsb3QobWVqb3Jlc1ssMl0sdHlwZT0ibCIsY29sPSJibHVlIix4bGFiPSJBY3R1YWxpemFjaW9uIix5bGFiPSJWYWxvciBkZSBtdSIpCiNsaW5lcyhldm9sMltzdWJjb25qLDJdLGNvbD0iZ3JlZW4iKQphYmxpbmUoY29lWzFdLDAsbHR5PTMpCnRpdGxlKCJDb252ZXJnZW5jaWEgZGVsIFBhcmFtZXRybyBtdSIpCiMKIwpwbG90KG1lam9yZXNbLDNdLHR5cGU9ImwiLGNvbD0iYmx1ZSIseGxhYj0iQWN0dWFsaXphY2lvbiIseWxhYj0iVmFsb3IgZGUgYWxmYSIpCiNsaW5lcyhldm9sMltzdWJjb25qLDNdLGNvbD0iZ3JlZW4iKQphYmxpbmUoY29lWzJdLDAsbHR5PTMpCnRpdGxlKCJDb252ZXJnZW5jaWEgZGVsIFBhcmFtZXRybyBhbGZhIikKIwojCnBsb3QobWVqb3Jlc1ssNF0sdHlwZT0ibCIsY29sPSJibHVlIix4bGFiPSJBY3R1YWxpemFjaW9uIix5bGFiPSJWYWxvciBkZSBiZXRhIikKI2xpbmVzKGV2b2wyW3N1YmNvbmosNF0sY29sPSJncmVlbiIpCmFibGluZShjb2VbM10sMCxsdHk9MykKdGl0bGUoIkNvbnZlcmdlbmNpYSBkZWwgUGFyYW1ldHJvIGJldGEiKQojCiMKcGxvdChtZWpvcmVzWyw1XSx0eXBlPSJsIixjb2w9ImJsdWUiLHhsYWI9IkFjdHVhbGl6YWNpb24iLHlsYWI9Ikl0ZXJhY2lvbmVzIikKI2xpbmVzKGV2b2wyW3N1YmNvbmosNF0sY29sPSJncmVlbiIpCnRpdGxlKCJFdm9sdWNpb24gZGUgbG9zIEl0ZXJhY2lvbmVzIikKIwoKYGBgCgojIyMgwr8gQ3VhbmJ1ZW5vIGVzIGVsIGFqdXN0ZSA/CgpgYGB7cn0KcHJlZGljaG9zPC1wcmVkaWN0KGFqdXNNMikKbWVhbihhYnMoUHJlY2lvLXByZWRpY2hvcykpCnBtYWVNMjwtbWVhbihhYnMoUHJlY2lvLXByZWRpY2hvcykpL21lYW4oUHJlY2lvKQpwbWFlTTIKYGBgCgojIyMgTWVkaWRhIGRlbCBlcnJvciBwb3IgVmFsaWRhY2lvbiBDcnV6YWRhCgpgYGB7cn0KbjwtbGVuZ3RoKFByZWNpbykKcHJlZGljaG9zLm9vczwtcmVwKE5BLG4pICMgcHJlZGljaG9zIG91dCBvZiBzYW1wbGUKcGxvdDNkKGFqdXNNMixzaXplPTE1LGNvbD0iYmx1ZSIpCmludmlzaWJsZShyZWFkbGluZShwcm9tcHQ9IlByZXNpb25lIFtlbnRlcl0gcGFyYSBzZWd1aXI6IikpCmZvciAoaSBpbiAxOm4pCnsKICBhanVzLmN2PC1sbShQcmVjaW9+U3VwK0ZvbmRvLGRhdGE9ZGF0b3MxZFstaSxdKQogIHByZWRpY2hvcy5vb3NbaV08LXByZWRpY3QoYWp1cy5jdixuZXdkYXRhPWRhdG9zMWRbaSxdKQogIHBsb3QzZChhanVzLmN2LHNpemU9MTUsY29sPSJncmVlbiIsYWRkPVQsYWxwaGE9MC4xKQp9CiMgTUFFCm1lYW4oYWJzKFByZWNpby1wcmVkaWNob3Mub29zKSkKIyBQTUFFCnBtYWVNMi5jdjwtbWVhbihhYnMoUHJlY2lvLXByZWRpY2hvcy5vb3MpKS9tZWFuKFByZWNpbykKcG1hZU0yLmN2CmBgYAoKIyMjIMK/IEN1w6FuIGNlcnRlcmFzIChjcmVpYmxlcy9lc3RhYmxlcy9yZXBldGlibGVzKSBzb24gbGFzIHJlbGFjaW9uZXMgaGFsbGFkYXMgPyBFbCBCb290c3RyYXAKCmBgYHtyfQpCPC0xMDAwICMgY2FudGlkYWQgZGUgbXVlc3RyYXMgYm9vdHN0cmFwCm11ZXM8LXJlcChOQSxCKSAjIHZlY3RvciBwYXJhIGd1YXJkYXIgbG9zIG11IGVzdGltYWRvcwphbGZhczwtcmVwKE5BLEIpICMgdmVjdG9yIHBhcmEgZ3VhcmRhciBsb3MgYWxmYSBlc3RpbWFkb3MKYmV0YXM8LXJlcChOQSxCKSAjIHZlY3RvciBwYXJhIGd1YXJkYXIgbG9zIGJldGEgZXN0aW1hZG9zCnNldC5zZWVkKDEpCmZvciAoYiBpbiAxOkIpCnsKICBpbmRpY2VzPC1zYW1wbGUoMTo2OCw2OCxyZXBsYWNlID0gVFJVRSkKICBhanVzLmJvb3Q8LWxtKFByZWNpb35TdXArRm9uZG8sZGF0YT1kYXRvczFkW2luZGljZXMsXSkKICBjb2U8LWNvZWYoYWp1cy5ib290KQogIG11ZXNbYl08LWNvZVsxXQogIGFsZmFzW2JdPC1jb2VbMl0KICBiZXRhc1tiXTwtY29lWzNdCn0KcmVzdWw8LWNiaW5kKG11ZXMsYWxmYXMsYmV0YXMpCmhlYWQocmVzdWwpCmBgYAoKR3JhZmljbyBkZSByZXN1bHRhZG9zCgpgYGB7cn0KcGxvdChhbGZhcyxiZXRhcykKIyBwYXJhbWV0cm9zIGVzdGltYWRvcyBlbiBlbCBtb2RlbG8gaW5pY2lhbApzZWdtZW50cyg4NjMsMCw4NjMsMjAwMCxjb2w9ImdyZWVuIixsdHkgPSAxLGx3ZD0zKQpzZWdtZW50cygwLDU5MSwyMDAwLDU5MSxjb2w9ImdyZWVuIixsdHkgPSAxLGx3ZD0zKQojIGN1YW50aWxlcyBib290c3RyYXAKc2VnbWVudHMocXVhbnRpbGUoYWxmYXMsMC4wNSksMCxxdWFudGlsZShhbGZhcywwLjA1KSwyMDAwLGNvbD0icmVkIixsdHkgPSAzLGx3ZD0zKQpzZWdtZW50cyhxdWFudGlsZShhbGZhcywwLjUpLDAscXVhbnRpbGUoYWxmYXMsMC41KSwyMDAwLGNvbD0icmVkIixsdHkgPSAzLGx3ZD0zKQpzZWdtZW50cyhxdWFudGlsZShhbGZhcywwLjk1KSwwLHF1YW50aWxlKGFsZmFzLDAuOTUpLDIwMDAsY29sPSJyZWQiLGx0eSA9IDMsbHdkPTMpCnNlZ21lbnRzKDAscXVhbnRpbGUoYmV0YXMsMC4wNSksMjAwMCxxdWFudGlsZShiZXRhcywwLjA1KSwyMDAwLGNvbD0icmVkIixsdHkgPSAzLGx3ZD0zKQpzZWdtZW50cygwLHF1YW50aWxlKGJldGFzLDAuNSksMjAwMCxxdWFudGlsZShiZXRhcywwLjUpLDIwMDAsY29sPSJyZWQiLGx0eSA9IDMsbHdkPTMpCnNlZ21lbnRzKDAscXVhbnRpbGUoYmV0YXMsMC45NSksMjAwMCxxdWFudGlsZShiZXRhcywwLjk1KSwyMDAwLGNvbD0icmVkIixsdHkgPSAzLGx3ZD0zKQphYmxpbmUoMCwxLGNvbD0iYmx1ZSIpCnRpdGxlKCJFc3RpbWFjaW9uZXMgQm9vdHN0cmFwIGRlIGxvcyBQYXJhbWV0cm9zIikKbWVhbihiZXRhcz5hbGZhcykKYGBgCgojIyMgTW9kZWxvIHNpbXBsZSBjb24gU3VwCgpgYGB7cn0KYWp1c00xPC1sbShQcmVjaW9+U3VwLGRhdGE9ZGF0b3MxZCkKY29lPC1jb2VmKGFqdXNNMSkKY29lCnN1bW1hcnkoYWp1c00xKQpwbG90KGFqdXNNMSkKcGxvdChTdXAsUHJlY2lvKQphYmxpbmUoYWp1c00xKQp0aXRsZSgiUmVncmVzaW9uIExpbmVhbCBTaW1wbGUgUHJlY2lvIFZzLiBTdXAiKQpgYGAKCiMjIyDCvyBDdWFuIGJ1ZW5vIGVzIGVsIGFqdXN0ZSA/CgpgYGB7cn0KcHJlZGljaG9zPC1wcmVkaWN0KGFqdXNNMSkKbWVhbihhYnMoUHJlY2lvLXByZWRpY2hvcykpCnBtYWVNMTwtbWVhbihhYnMoUHJlY2lvLXByZWRpY2hvcykpL21lYW4oUHJlY2lvKQpwbWFlTTEKIyBjdgpuPC1sZW5ndGgoUHJlY2lvKQpwcmVkaWNob3Mub29zPC1yZXAoTkEsbikgIyBwcmVkaWNob3Mgb3V0IG9mIHNhbXBsZQpmb3IgKGkgaW4gMTpuKQp7CiAgYWp1cy5jdjwtbG0oUHJlY2lvflN1cCxkYXRhPWRhdG9zMWRbLWksXSkKICBwcmVkaWNob3Mub29zW2ldPC1wcmVkaWN0KGFqdXMuY3YsbmV3ZGF0YT1kYXRvczFkW2ksXSkKfQptZWFuKGFicyhQcmVjaW8tcHJlZGljaG9zLm9vcykpCnBtYWVNMS5jdjwtbWVhbihhYnMoUHJlY2lvLXByZWRpY2hvcy5vb3MpKS9tZWFuKFByZWNpbykKcG1hZU0xLmN2CmBgYAojIyMgIE1vZGVsbyBtYXMgY29tcGxlam8KCmBgYHtyfQojIGFncmVnbyBsYXQgeSBsb24KZGF0b3MxZTwtZGF0b3MxYSAlPiUgZmlsdGVyKGwzPT0iQm9lZG8iLHByb3BlcnR5X3R5cGU9PSJDYXNhIikgICU+JSBtdXRhdGUoUHJlY2lvPXByaWNlLFN1cD1zdXJmYWNlX2NvdmVyZWQsRm9uZG89c3VyZmFjZV90b3RhbC1zdXJmYWNlX2NvdmVyZWQpICU+JSBkcGx5cjo6c2VsZWN0KFN1cCxGb25kbyxQcmVjaW8sbGF0LGxvbikgJT4lICBmaWx0ZXIoRm9uZG8+PTApICU+JSBuYS5vbWl0KCkKZGF0b3MxZQpzdW1tYXJ5KGRhdG9zMWUpCmdncGFpcnMoZGF0b3MxZSkKIyBDcmVvIGxhcyBudWV2YXMgdmFyaWFibGVzClN1cDwtZGF0b3MxZSRTdXAKRm9uZG88LWRhdG9zMWUkRm9uZG8KTG9uPC1kYXRvczFlJGxvbgpMYXQ8LWRhdG9zMWUkbGF0ClByZWNpbzwtZGF0b3MxZSRQcmVjaW8KYWp1c000PC1sbShQcmVjaW9+U3VwK0ZvbmRvK0xvbitMYXQpCmNvZTwtY29lZihhanVzTTQpCmNvZQpzdW1tYXJ5KGFqdXNNNCkKcGxvdChMb24sTGF0KQpwcmVkaWNob3M8LXByZWRpY3QoYWp1c000KQptZWFuKGFicyhQcmVjaW8tcHJlZGljaG9zKSkKcG1hZU00PC1tZWFuKGFicyhQcmVjaW8tcHJlZGljaG9zKSkvbWVhbihQcmVjaW8pCnBtYWVNNApwbG90KFByZWNpbyxwcmVkaWNob3MseGxhYj0iUHJlY2lvcyBPYnNlcnZhZG9zIix5bGE9IlByZWRpY2hvcyBwb3IgTTQiLG1haW49IlByZWNpb3MgUHJlZGljaG9zIHBvciBNNCBWcy4gT2JzZXJ2YWRvcyIpCmFibGluZSgwLDEsY29sPSJncmVlbiIpCmBgYAoKIyMjIEVycm9yIHBvciBDViBkZWwgbW9kZWxvIE00CgpgYGB7cn0KbjwtbGVuZ3RoKFByZWNpbykKcHJlZGljaG9zLm9vczwtcmVwKE5BLG4pICMgcHJlZGljaG9zIG91dCBvZiBzYW1wbGUKZm9yIChpIGluIDE6bikKewogIGFqdXMuY3Y8LWxtKFByZWNpb35TdXArRm9uZG8rbG9uK2xhdCxkYXRhPWRhdG9zMWVbLWksXSkKICBwcmVkaWNob3Mub29zW2ldPC1wcmVkaWN0KGFqdXMuY3YsbmV3ZGF0YT1kYXRvczFlW2ksXSkKfQptZWFuKGFicyhQcmVjaW8tcHJlZGljaG9zLm9vcykpCnBtYWVNNC5jdjwtbWVhbihhYnMoUHJlY2lvLXByZWRpY2hvcy5vb3MpKS9tZWFuKFByZWNpbykKcG1hZU00LmN2CmBgYAojIyMgIFZhbW9zIHBvciBtYXMgLi4uLiBNb2RlbG8gbWFzIG1hcyBjb21wbGVqbwoKYWdyZWdvIGVmZWN0b3MgY3VhZHJhdGljb3MgYSBsYXQgeSBsb24KYGBge3J9CiMgYWdyZWdvIGVmZWN0b3Mgbm8gbGluZWFsZXMKYWp1c004PC1sbShQcmVjaW9+U3VwK0ZvbmRvK3BvbHkoTG9uLDMpK3BvbHkoTGF0LDMpKQpjb2U8LWNvZWYoYWp1c004KQpjb2UKc3VtbWFyeShhanVzTTgpCnBsb3QoTG9uLExhdCkKcHJlZGljaG9zPC1wcmVkaWN0KGFqdXNNOCkKbWVhbihhYnMoUHJlY2lvLXByZWRpY2hvcykpCnBtYWVNODwtbWVhbihhYnMoUHJlY2lvLXByZWRpY2hvcykpL21lYW4oUHJlY2lvKQpwbWFlTTgKcGxvdChQcmVjaW8scHJlZGljaG9zLHhsYWI9IlByZWNpb3MgT2JzZXJ2YWRvcyIseWxhPSJQcmVkaWNob3MgcG9yIE04IixtYWluPSJQcmVjaW9zIFByZWRpY2hvcyBwb3IgTTggVnMuIE9ic2VydmFkb3MiKQphYmxpbmUoMCwxLGNvbD0iZ3JlZW4iKQpgYGAKCiMjIyBNZWRpZGEgZGVsIGVycm9yIHBvciBWYWxpZGFjaW9uIENydXphZGEKCmBgYHtyfQpuPC1sZW5ndGgoUHJlY2lvKQpwcmVkaWNob3Mub29zPC1yZXAoTkEsbikgIyBwcmVkaWNob3Mgb3V0IG9mIHNhbXBsZQpmb3IgKGkgaW4gMTpuKQp7CiAgYWp1cy5jdjwtbG0oUHJlY2lvflN1cCtGb25kbytwb2x5KGxvbiwzKStwb2x5KGxhdCwzKSxkYXRhPWRhdG9zMWVbLWksXSkKICBwcmVkaWNob3Mub29zW2ldPC1wcmVkaWN0KGFqdXMuY3YsbmV3ZGF0YT1kYXRvczFlW2ksXSkKfQptZWFuKGFicyhQcmVjaW8tcHJlZGljaG9zLm9vcykpCnBtYWVNOC5jdjwtbWVhbihhYnMoUHJlY2lvLXByZWRpY2hvcy5vb3MpKS9tZWFuKFByZWNpbykKcG1hZU04LmN2CmBgYAoKIyMjIENvbXBhcmFjaW9uIGRlIE1vZGVsb3MKCmBgYHtyfQpQTUFFUzwtbWF0cml4KGMocG1hZU0xLHBtYWVNMS5jdixwbWFlTTIscG1hZU0yLmN2LHBtYWVNNCxwbWFlTTQuY3YscG1hZU04LHBtYWVNOC5jdiksNCwyLGJ5cm93ID0gVCkKUE1BRVMKbWF0cGxvdChQTUFFUyx0eXBlPSJiIixwY2g9MTYsY29sPTI6MyxsdHk9MSxsd2Q9MywsIHhheHQ9J24nLG1haW49IlBNQUVzIEluZ2VudW9zIHkgUE1BRXMgQ1YgcGFyYSBNISwgTTIsIE00IHkgTTgiLHlsaW09YygwLjEzLDAuMjUpLHhsYWI9Ik1vZGVsbyIseWxhYj0iUE1BRSIpCnRleHQoMSxwbWFlTTEuY3YrMC4wMSwiTTEiKQp0ZXh0KDIscG1hZU0yLmN2KzAuMDEsIk0yIikKdGV4dCgzLHBtYWVNNC5jdiswLjAxLCJNNCIpCnRleHQoNCxwbWFlTTguY3YrMC4wMSwiTTgiKQpgYGAKCgoKIyMjIFRyYWRlLW9mZiBTZXNnby1WYXJpYW56YQoKYGBge3J9Ck48LTY4ClN1cDA8LTI1MApSZWxhY2lvbjwtZnVuY3Rpb24oeCl7KGxvZygoeC03MCkvNTIwKS1sb2coMTAvNTIwKSkqMTAwMDAwKzEwMDAwMH0Kc2V0LnNlZWQoMSkKU3VwPC1ydW5pZihOKSo1MjArODAKRXJyb3I8LXJub3JtKE4pKjUwMDAwClByZWNpbzwtUmVsYWNpb24oU3VwKStFcnJvcgpwbG90KFN1cCxQcmVjaW8sY29sPSJibHVlIixtYWluPSJQcmVjaW8gVnMuIFN1cGVyZmljaWUiKQpjdXJ2ZShSZWxhY2lvbixmcm9tPTgwLHRvPTYwMCxhZGQ9VFJVRSxjb2w9ImdyZWVuIixsd2Q9MikKUHJlY2lvMDwtUmVsYWNpb24oU3VwMCkKc2VnbWVudHMoU3VwMCwwLFN1cDAsUHJlY2lvMCxsdHk9Myxjb2w9ImdyZWVuIixsd2Q9MikKc2VnbWVudHMoMCxQcmVjaW8wLFN1cDAsUHJlY2lvMCxsdHk9Myxjb2w9ImdyZWVuIixsd2Q9MikKYGBgCgojIyMgRXN0aW1hY2lvbmVzIHNpbXBsZXMKCmBgYHtyfQpzZXQuc2VlZCgxKQpTdXA8LXJ1bmlmKE4pKjUyMCs4MApFcnJvcjwtcm5vcm0oTikqNTAwMDAKUHJlY2lvPC1SZWxhY2lvbihTdXApK0Vycm9yCmNhbnQ8LTUwICMgY2FudGlkYWQgZGUgZXN0aW1hY2lvbmVzCmVzdGltYWNpb25lczwtcmVwKE5BLGNhbnQpCmdyaWxsYTwtZGF0YS5mcmFtZShTdXA9c2VxKDgwLDYwMCxsZW5ndGgub3V0ID0gMTAwKSkKIyBncmFmaWNvIGZpam8KcGxvdChTdXAsUHJlY2lvLGNvbD0iYmx1ZSIsbWFpbj0iUHJlY2lvIFZzLiBTdXBlcmZpY2llIGNvbiBBanVzdGVzIGRlIE1vZGVsb3MgU2ltcGxlcyIpCgojIGJ1Y2xlCmZvciAoaSBpbiAxOmNhbnQpCnsKU3VwPC1ydW5pZihOKSo1MjArODAKRXJyb3I8LXJub3JtKE4pKjUwMDAwClByZWNpbzwtUmVsYWNpb24oU3VwKStFcnJvcgphanVzLjE8LWxtKFByZWNpb35wb2x5KFN1cCwxKSkKcHJlZC4xPC1wcmVkaWN0KGFqdXMuMSxuZXdkYXRhPWRhdGEuZnJhbWUoU3VwPVN1cDApKQplc3RpbWFjaW9uZXNbaV08LXByZWQuMQpjdXJ2YS4xPC1wcmVkaWN0KGFqdXMuMSxuZXdkYXRhID0gZ3JpbGxhKQpsaW5lcyhhcy5udW1lcmljKGdyaWxsYSRTdXApLGN1cnZhLjEsbHdkPTAuNSxjb2w9InJlZCIpCn0Kc2VnbWVudHMoMCxtZWFuKGVzdGltYWNpb25lcyksU3VwMCxtZWFuKGVzdGltYWNpb25lcyksbHR5PTMsbHdkPTIsY29sPSJibGFjayIpCnNlZ21lbnRzKDAsbWVhbihlc3RpbWFjaW9uZXMpLTIqc2QoZXN0aW1hY2lvbmVzKSxTdXAwLG1lYW4oZXN0aW1hY2lvbmVzKS0yKnNkKGVzdGltYWNpb25lcyksbHR5PTMsbHdkPTIsY29sPSJibGFjayIpCnNlZ21lbnRzKDAsbWVhbihlc3RpbWFjaW9uZXMpKzIqc2QoZXN0aW1hY2lvbmVzKSxTdXAwLG1lYW4oZXN0aW1hY2lvbmVzKSsyKnNkKGVzdGltYWNpb25lcyksbHR5PTMsbHdkPTIsY29sPSJibGFjayIpCiMKY3VydmUoUmVsYWNpb24sZnJvbT04MCx0bz02MDAsYWRkPVRSVUUsY29sPSJncmVlbiIsbHdkPTMpCnNlZ21lbnRzKFN1cDAsMCxTdXAwLFByZWNpbzAsbHR5PTMsbHdkPTIsY29sPSJncmVlbiIpCnNlZ21lbnRzKDAsUHJlY2lvMCxTdXAwLFByZWNpbzAsbHR5PTMsbHdkPTIsY29sPSJncmVlbiIpCmVzdGltYWNpb25lcy5zaW1wbGVzPC1lc3RpbWFjaW9uZXMKYGBgCgojIyMgRXN0aW1hY2lvbmVzIGNvbXBsZWphcwoKYGBge3J9CnNldC5zZWVkKDEpClN1cDwtcnVuaWYoTikqNTIwKzgwCkVycm9yPC1ybm9ybShOKSo1MDAwMApQcmVjaW88LVJlbGFjaW9uKFN1cCkrRXJyb3IKY2FudDwtNTAgIyBjYW50aWRhZCBkZSBlc3RpbWFjaW9uZXMKZXN0aW1hY2lvbmVzPC1yZXAoTkEsY2FudCkKZ3JpbGxhPC1kYXRhLmZyYW1lKFN1cD1zZXEoODAsNjAwLGxlbmd0aC5vdXQgPSAxMDApKQojIGdyYWZpY28gZmlqbwpwbG90KFN1cCxQcmVjaW8sY29sPSJibHVlIixtYWluPSJQcmVjaW8gVnMuIFN1cGVyZmljaWUgY29uIEFqdXN0ZXMgZGUgTW9kZWxvcyBDb21wbGVqb3MiKQoKIyBidWNsZQpmb3IgKGkgaW4gMTpjYW50KQp7ClN1cDwtcnVuaWYoTikqNTIwKzgwCkVycm9yPC1ybm9ybShOKSo1MDAwMApQcmVjaW88LVJlbGFjaW9uKFN1cCkrRXJyb3IKYWp1cy4xPC1sbShQcmVjaW9+cG9seShTdXAsMTIpKQpwcmVkLjE8LXByZWRpY3QoYWp1cy4xLG5ld2RhdGE9ZGF0YS5mcmFtZShTdXA9U3VwMCkpCmVzdGltYWNpb25lc1tpXTwtcHJlZC4xCmN1cnZhLjE8LXByZWRpY3QoYWp1cy4xLG5ld2RhdGEgPSBncmlsbGEpCmxpbmVzKGFzLm51bWVyaWMoZ3JpbGxhJFN1cCksY3VydmEuMSxsd2Q9MC41LGNvbD0icmVkIikKfQpzZWdtZW50cygwLG1lYW4oZXN0aW1hY2lvbmVzKSxTdXAwLG1lYW4oZXN0aW1hY2lvbmVzKSxsdHk9Myxsd2Q9Mixjb2w9ImJsYWNrIikKc2VnbWVudHMoMCxtZWFuKGVzdGltYWNpb25lcyktMipzZChlc3RpbWFjaW9uZXMpLFN1cDAsbWVhbihlc3RpbWFjaW9uZXMpLTIqc2QoZXN0aW1hY2lvbmVzKSxsdHk9Myxsd2Q9Mixjb2w9ImJsYWNrIikKc2VnbWVudHMoMCxtZWFuKGVzdGltYWNpb25lcykrMipzZChlc3RpbWFjaW9uZXMpLFN1cDAsbWVhbihlc3RpbWFjaW9uZXMpKzIqc2QoZXN0aW1hY2lvbmVzKSxsdHk9Myxsd2Q9Mixjb2w9ImJsYWNrIikjCmN1cnZlKFJlbGFjaW9uLGZyb209ODAsdG89NjAwLGFkZD1UUlVFLGNvbD0iZ3JlZW4iLGx3ZD0zKQpzZWdtZW50cyhTdXAwLDAsU3VwMCxQcmVjaW8wLGx0eT0zLGx3ZD0yLGNvbD0iZ3JlZW4iKQpzZWdtZW50cygwLFByZWNpbzAsU3VwMCxQcmVjaW8wLGx0eT0zLGx3ZD0yLGNvbD0iZ3JlZW4iKQplc3RpbWFjaW9uZXMuY29tcGxlamFzPC1lc3RpbWFjaW9uZXMKYGBgCgpDb21wYXJhY2lvbgoKYGBge3J9CiAgYm94cGxvdChsaXN0KFNpbXBsZT1lc3RpbWFjaW9uZXMuc2ltcGxlcyxDb21wbGVqbz1lc3RpbWFjaW9uZXMuY29tcGxlamFzKSx5bGFiPSJQcmVjaW8iLG1haW49IkRpc3RyaWJ1Y2lvbiBkZSBsYXMgUHJlZGljY2lvbmVzIixjb2w9YygiY3lhbiIsIm1hZ2VudGEiKSkKYWJsaW5lKFByZWNpbzAsMCxjb2w9ImdyZWVuIixsdHk9Myxsd2Q9MikKYGBgCgpDb21wYXJhY2lvbiBtb2RlbG8gTTEgY29uIE0yCgpgYGB7cn0KYWp1cy5Gb25kbzwtbG0oRm9uZG9+U3VwLGRhdGE9ZGF0b3MxZSkKY29lLkZvbmRvPC1jb2VmKGFqdXMuRm9uZG8pCmNvZS5NMTwtY29lZihhanVzTTEpCmNvZS5NMjwtY29lZihhanVzTTIpCiMgcGVuZGllbnRlCmNvZS5NMlsyXStjb2UuTTJbM10qY29lLkZvbmRvWzJdCiMgaW50ZXJjZXB0CmNvZS5NMlsxXStjb2UuTTJbM10qY29lLkZvbmRvWzFdCiMgZWwgYWp1c3RlIE0xCmNvZS5NMQpgYGAKCg==