Teoría

El paquete CARET (Clasificación And Regression Training) es un paquete integral con una amplia variedad de algoritmos para el aprendizaje automático.

instalar paquetes y llamar librerias

Llamar librerías

library(caret)
## Loading required package: ggplot2
## Loading required package: lattice
library(ggplot2)
library(lattice)
library(datasets)
library(DataExplorer)
library(kernlab)
## 
## Attaching package: 'kernlab'
## The following object is masked from 'package:ggplot2':
## 
##     alpha

crear la base de datos

df <- data.frame(iris)

crear la base de datos

summary(df)
##   Sepal.Length    Sepal.Width     Petal.Length    Petal.Width   
##  Min.   :4.300   Min.   :2.000   Min.   :1.000   Min.   :0.100  
##  1st Qu.:5.100   1st Qu.:2.800   1st Qu.:1.600   1st Qu.:0.300  
##  Median :5.800   Median :3.000   Median :4.350   Median :1.300  
##  Mean   :5.843   Mean   :3.057   Mean   :3.758   Mean   :1.199  
##  3rd Qu.:6.400   3rd Qu.:3.300   3rd Qu.:5.100   3rd Qu.:1.800  
##  Max.   :7.900   Max.   :4.400   Max.   :6.900   Max.   :2.500  
##        Species  
##  setosa    :50  
##  versicolor:50  
##  virginica :50  
##                 
##                 
## 
str(df)
## 'data.frame':    150 obs. of  5 variables:
##  $ Sepal.Length: num  5.1 4.9 4.7 4.6 5 5.4 4.6 5 4.4 4.9 ...
##  $ Sepal.Width : num  3.5 3 3.2 3.1 3.6 3.9 3.4 3.4 2.9 3.1 ...
##  $ Petal.Length: num  1.4 1.4 1.3 1.5 1.4 1.7 1.4 1.5 1.4 1.5 ...
##  $ Petal.Width : num  0.2 0.2 0.2 0.2 0.2 0.4 0.3 0.2 0.2 0.1 ...
##  $ Species     : Factor w/ 3 levels "setosa","versicolor",..: 1 1 1 1 1 1 1 1 1 1 ...
#create_report(df)
plot_missing(df)

plot_histogram(df)

plot_correlation(df)

NOTA: En modelos de clasificación, la variable que queremos predecir debe tener formato de factor

Partir la base de datos

set.seed(123)
#Normalmente 80-20 0 70-30
renglones_entrenamiento <- createDataPartition(df$Species, p=0.8, list=FALSE)
entrenamiento <- df[renglones_entrenamiento,]
prueba <- df[renglones_entrenamiento,]

Distintos tipos de Método para Modelar

Los métodos más utilizados para modelar aprendizaje son:

  • SVM: support vector machine po Maquina de vectores de Soporte, Hay varios subtipos: Lineal (DVMLinear), Radial (SVMRadial), Polinomico (SvmPoly), etc.
  • Arbol de Decision: rpart
  • Redes neuronales nnet
  • Random Forest o Bosques Aleatorios: rf

Modelo 1. SVM lineal

modelo1 <- train(
  Species ~ ., 
  data = entrenamiento,
  method = "svmLinear",
  preProcess = c("scale", "center"),
  trControl = trainControl(method = "cv", number = 10),
  tuneGrid = data.frame(C = 1)
)

resultado_entrenamiento1 <- predict(modelo1, entrenamiento)
resultado_prueba1 <- predict(modelo1, prueba)

mcre1 <- confusionMatrix(
  resultado_entrenamiento1,
  entrenamiento$Species
)
mcre1
## Confusion Matrix and Statistics
## 
##             Reference
## Prediction   setosa versicolor virginica
##   setosa         40          0         0
##   versicolor      0         39         0
##   virginica       0          1        40
## 
## Overall Statistics
##                                           
##                Accuracy : 0.9917          
##                  95% CI : (0.9544, 0.9998)
##     No Information Rate : 0.3333          
##     P-Value [Acc > NIR] : < 2.2e-16       
##                                           
##                   Kappa : 0.9875          
##                                           
##  Mcnemar's Test P-Value : NA              
## 
## Statistics by Class:
## 
##                      Class: setosa Class: versicolor Class: virginica
## Sensitivity                 1.0000            0.9750           1.0000
## Specificity                 1.0000            1.0000           0.9875
## Pos Pred Value              1.0000            1.0000           0.9756
## Neg Pred Value              1.0000            0.9877           1.0000
## Prevalence                  0.3333            0.3333           0.3333
## Detection Rate              0.3333            0.3250           0.3333
## Detection Prevalence        0.3333            0.3250           0.3417
## Balanced Accuracy           1.0000            0.9875           0.9938
mcrp1 <- confusionMatrix(
  resultado_prueba1,
  prueba$Species
)
mcrp1
## Confusion Matrix and Statistics
## 
##             Reference
## Prediction   setosa versicolor virginica
##   setosa         40          0         0
##   versicolor      0         39         0
##   virginica       0          1        40
## 
## Overall Statistics
##                                           
##                Accuracy : 0.9917          
##                  95% CI : (0.9544, 0.9998)
##     No Information Rate : 0.3333          
##     P-Value [Acc > NIR] : < 2.2e-16       
##                                           
##                   Kappa : 0.9875          
##                                           
##  Mcnemar's Test P-Value : NA              
## 
## Statistics by Class:
## 
##                      Class: setosa Class: versicolor Class: virginica
## Sensitivity                 1.0000            0.9750           1.0000
## Specificity                 1.0000            1.0000           0.9875
## Pos Pred Value              1.0000            1.0000           0.9756
## Neg Pred Value              1.0000            0.9877           1.0000
## Prevalence                  0.3333            0.3333           0.3333
## Detection Rate              0.3333            0.3250           0.3333
## Detection Prevalence        0.3333            0.3250           0.3417
## Balanced Accuracy           1.0000            0.9875           0.9938

Modelo 2. SVM Radial

modelo2 <- train(
  Species ~ ., 
  data = entrenamiento,
  method = "svmRadial",
  preProcess = c("scale", "center"),
  trControl = trainControl(method = "cv", number = 10),
  tuneGrid = data.frame(sigma = 1, C = 1)
)

resultado_entrenamiento2 <- predict(modelo2, entrenamiento)
resultado_prueba2 <- predict(modelo2, prueba)

# Matriz de confusión de entrenamiento
mcre2 <- confusionMatrix(
  resultado_entrenamiento2,
  entrenamiento$Species
)
mcre2
## Confusion Matrix and Statistics
## 
##             Reference
## Prediction   setosa versicolor virginica
##   setosa         40          0         0
##   versicolor      0         39         0
##   virginica       0          1        40
## 
## Overall Statistics
##                                           
##                Accuracy : 0.9917          
##                  95% CI : (0.9544, 0.9998)
##     No Information Rate : 0.3333          
##     P-Value [Acc > NIR] : < 2.2e-16       
##                                           
##                   Kappa : 0.9875          
##                                           
##  Mcnemar's Test P-Value : NA              
## 
## Statistics by Class:
## 
##                      Class: setosa Class: versicolor Class: virginica
## Sensitivity                 1.0000            0.9750           1.0000
## Specificity                 1.0000            1.0000           0.9875
## Pos Pred Value              1.0000            1.0000           0.9756
## Neg Pred Value              1.0000            0.9877           1.0000
## Prevalence                  0.3333            0.3333           0.3333
## Detection Rate              0.3333            0.3250           0.3333
## Detection Prevalence        0.3333            0.3250           0.3417
## Balanced Accuracy           1.0000            0.9875           0.9938
# Matriz de confusión de prueba
mcrp2 <- confusionMatrix(
  resultado_prueba2,
  prueba$Species
)
mcrp2
## Confusion Matrix and Statistics
## 
##             Reference
## Prediction   setosa versicolor virginica
##   setosa         40          0         0
##   versicolor      0         39         0
##   virginica       0          1        40
## 
## Overall Statistics
##                                           
##                Accuracy : 0.9917          
##                  95% CI : (0.9544, 0.9998)
##     No Information Rate : 0.3333          
##     P-Value [Acc > NIR] : < 2.2e-16       
##                                           
##                   Kappa : 0.9875          
##                                           
##  Mcnemar's Test P-Value : NA              
## 
## Statistics by Class:
## 
##                      Class: setosa Class: versicolor Class: virginica
## Sensitivity                 1.0000            0.9750           1.0000
## Specificity                 1.0000            1.0000           0.9875
## Pos Pred Value              1.0000            1.0000           0.9756
## Neg Pred Value              1.0000            0.9877           1.0000
## Prevalence                  0.3333            0.3333           0.3333
## Detection Rate              0.3333            0.3250           0.3333
## Detection Prevalence        0.3333            0.3250           0.3417
## Balanced Accuracy           1.0000            0.9875           0.9938

Modelo 3. SVM Polinómico NIR] : < 2.2e-16

Kappa : 0.975

Mcnemar’s Test P-Value : NA

Statistics by Class:

Class: setosa Class: versicolor Class: virginica

Sensitivity 1.0000 0.9500 1.0000

Specificity 1.0000 1.0000 0.9750

Pos Pred Value 1.0000 1.0000 0.9524

Neg Pred Value 1.0000 0.9756 1.0000

Prevalence 0.3333 0.3333 0.3333

Detection Rate 0.3333 0.3167 0.3333

Detection Prevalence 0.3333 0.3167 0.3500

Balanced Accuracy 1.0000 0.9750 0.9875


``` r
# Matriz de confusión de prueba
mcrp3 <- confusionMatrix(
  resultado_prueba3,
  prueba$Species
)
mcrp3
## Confusion Matrix and Statistics
## 
##             Reference
## Prediction   setosa versicolor virginica
##   setosa         40          0         0
##   versicolor      0         38         0
##   virginica       0          2        40
## 
## Overall Statistics
##                                          
##                Accuracy : 0.9833         
##                  95% CI : (0.9411, 0.998)
##     No Information Rate : 0.3333         
##     P-Value [Acc > NIR] : < 2.2e-16      
##                                          
##                   Kappa : 0.975          
##                                          
##  Mcnemar's Test P-Value : NA             
## 
## Statistics by Class:
## 
##                      Class: setosa Class: versicolor Class: virginica
## Sensitivity                 1.0000            0.9500           1.0000
## Specificity                 1.0000            1.0000           0.9750
## Pos Pred Value              1.0000            1.0000           0.9524
## Neg Pred Value              1.0000            0.9756           1.0000
## Prevalence                  0.3333            0.3333           0.3333
## Detection Rate              0.3333            0.3167           0.3333
## Detection Prevalence        0.3333            0.3167           0.3500
## Balanced Accuracy           1.0000            0.9750           0.9875

Modelo 4. Árbol de Desición

modelo4 <- train(
  Species ~ ., 
  data = entrenamiento,
  method = "rpart",
  preProcess = c("scale", "center"),
  trControl = trainControl(method = "cv", number = 10),
 tuneLength = 10
  )

resultado_entrenamiento4 <- predict(modelo4, entrenamiento)
resultado_prueba4 <- predict(modelo4, prueba)

# Matriz de confusión de entrenamiento
mcre4 <- confusionMatrix(
  resultado_entrenamiento4,
  entrenamiento$Species
)
mcre4
## Confusion Matrix and Statistics
## 
##             Reference
## Prediction   setosa versicolor virginica
##   setosa         40          0         0
##   versicolor      0         39         3
##   virginica       0          1        37
## 
## Overall Statistics
##                                           
##                Accuracy : 0.9667          
##                  95% CI : (0.9169, 0.9908)
##     No Information Rate : 0.3333          
##     P-Value [Acc > NIR] : < 2.2e-16       
##                                           
##                   Kappa : 0.95            
##                                           
##  Mcnemar's Test P-Value : NA              
## 
## Statistics by Class:
## 
##                      Class: setosa Class: versicolor Class: virginica
## Sensitivity                 1.0000            0.9750           0.9250
## Specificity                 1.0000            0.9625           0.9875
## Pos Pred Value              1.0000            0.9286           0.9737
## Neg Pred Value              1.0000            0.9872           0.9634
## Prevalence                  0.3333            0.3333           0.3333
## Detection Rate              0.3333            0.3250           0.3083
## Detection Prevalence        0.3333            0.3500           0.3167
## Balanced Accuracy           1.0000            0.9688           0.9563
# Matriz de confusión de prueba
mcrp4 <- confusionMatrix(
  resultado_prueba4,
  prueba$Species
)
mcrp4
## Confusion Matrix and Statistics
## 
##             Reference
## Prediction   setosa versicolor virginica
##   setosa         40          0         0
##   versicolor      0         39         3
##   virginica       0          1        37
## 
## Overall Statistics
##                                           
##                Accuracy : 0.9667          
##                  95% CI : (0.9169, 0.9908)
##     No Information Rate : 0.3333          
##     P-Value [Acc > NIR] : < 2.2e-16       
##                                           
##                   Kappa : 0.95            
##                                           
##  Mcnemar's Test P-Value : NA              
## 
## Statistics by Class:
## 
##                      Class: setosa Class: versicolor Class: virginica
## Sensitivity                 1.0000            0.9750           0.9250
## Specificity                 1.0000            0.9625           0.9875
## Pos Pred Value              1.0000            0.9286           0.9737
## Neg Pred Value              1.0000            0.9872           0.9634
## Prevalence                  0.3333            0.3333           0.3333
## Detection Rate              0.3333            0.3250           0.3083
## Detection Prevalence        0.3333            0.3500           0.3167
## Balanced Accuracy           1.0000            0.9688           0.9563

Modelo 5. Bosques Aleatorios

modelo5 <- train(
  Species ~ ., 
  data = entrenamiento,
  method = "rf",
  preProcess = c("scale", "center"),
  trControl = trainControl(method = "cv", number = 10),
 tuneGrid = expand.grid(mtry=c(2,4,6))
  )

resultado_entrenamiento5 <- predict(modelo5, entrenamiento)
resultado_prueba5 <- predict(modelo4, prueba)

# Matriz de confusión de entrenamiento
mcre5 <- confusionMatrix(
  resultado_entrenamiento5,
  entrenamiento$Species
)
mcre5
## Confusion Matrix and Statistics
## 
##             Reference
## Prediction   setosa versicolor virginica
##   setosa         40          0         0
##   versicolor      0         40         0
##   virginica       0          0        40
## 
## Overall Statistics
##                                      
##                Accuracy : 1          
##                  95% CI : (0.9697, 1)
##     No Information Rate : 0.3333     
##     P-Value [Acc > NIR] : < 2.2e-16  
##                                      
##                   Kappa : 1          
##                                      
##  Mcnemar's Test P-Value : NA         
## 
## Statistics by Class:
## 
##                      Class: setosa Class: versicolor Class: virginica
## Sensitivity                 1.0000            1.0000           1.0000
## Specificity                 1.0000            1.0000           1.0000
## Pos Pred Value              1.0000            1.0000           1.0000
## Neg Pred Value              1.0000            1.0000           1.0000
## Prevalence                  0.3333            0.3333           0.3333
## Detection Rate              0.3333            0.3333           0.3333
## Detection Prevalence        0.3333            0.3333           0.3333
## Balanced Accuracy           1.0000            1.0000           1.0000
# Matriz de confusión de prueba
mcrp5 <- confusionMatrix(
  resultado_prueba5,
  prueba$Species
)
mcrp5
## Confusion Matrix and Statistics
## 
##             Reference
## Prediction   setosa versicolor virginica
##   setosa         40          0         0
##   versicolor      0         39         3
##   virginica       0          1        37
## 
## Overall Statistics
##                                           
##                Accuracy : 0.9667          
##                  95% CI : (0.9169, 0.9908)
##     No Information Rate : 0.3333          
##     P-Value [Acc > NIR] : < 2.2e-16       
##                                           
##                   Kappa : 0.95            
##                                           
##  Mcnemar's Test P-Value : NA              
## 
## Statistics by Class:
## 
##                      Class: setosa Class: versicolor Class: virginica
## Sensitivity                 1.0000            0.9750           0.9250
## Specificity                 1.0000            0.9625           0.9875
## Pos Pred Value              1.0000            0.9286           0.9737
## Neg Pred Value              1.0000            0.9872           0.9634
## Prevalence                  0.3333            0.3333           0.3333
## Detection Rate              0.3333            0.3250           0.3083
## Detection Prevalence        0.3333            0.3500           0.3167
## Balanced Accuracy           1.0000            0.9688           0.9563

Modelo 6. Redes Neuronales

modelo6 <- train(
  Species ~ ., 
  data = entrenamiento,
  method = "nnet",
  preProcess = c("scale", "center"),
  trControl = trainControl(method = "cv", number = 10),
  tuneLength = 10,
  trace = FALSE
)

resultado_entrenamiento6 <- predict(modelo6, entrenamiento)
resultado_prueba6 <- predict(modelo6, prueba)

# Matriz de confusión de entrenamiento
mcre6 <- confusionMatrix(
  resultado_entrenamiento6,
  entrenamiento$Species
)
mcre6
## Confusion Matrix and Statistics
## 
##             Reference
## Prediction   setosa versicolor virginica
##   setosa         40          0         0
##   versicolor      0         38         0
##   virginica       0          2        40
## 
## Overall Statistics
##                                          
##                Accuracy : 0.9833         
##                  95% CI : (0.9411, 0.998)
##     No Information Rate : 0.3333         
##     P-Value [Acc > NIR] : < 2.2e-16      
##                                          
##                   Kappa : 0.975          
##                                          
##  Mcnemar's Test P-Value : NA             
## 
## Statistics by Class:
## 
##                      Class: setosa Class: versicolor Class: virginica
## Sensitivity                 1.0000            0.9500           1.0000
## Specificity                 1.0000            1.0000           0.9750
## Pos Pred Value              1.0000            1.0000           0.9524
## Neg Pred Value              1.0000            0.9756           1.0000
## Prevalence                  0.3333            0.3333           0.3333
## Detection Rate              0.3333            0.3167           0.3333
## Detection Prevalence        0.3333            0.3167           0.3500
## Balanced Accuracy           1.0000            0.9750           0.9875
# Matriz de confusión de prueba
mcrp6 <- confusionMatrix(
  resultado_prueba6,
  prueba$Species
)
mcrp6
## Confusion Matrix and Statistics
## 
##             Reference
## Prediction   setosa versicolor virginica
##   setosa         40          0         0
##   versicolor      0         38         0
##   virginica       0          2        40
## 
## Overall Statistics
##                                          
##                Accuracy : 0.9833         
##                  95% CI : (0.9411, 0.998)
##     No Information Rate : 0.3333         
##     P-Value [Acc > NIR] : < 2.2e-16      
##                                          
##                   Kappa : 0.975          
##                                          
##  Mcnemar's Test P-Value : NA             
## 
## Statistics by Class:
## 
##                      Class: setosa Class: versicolor Class: virginica
## Sensitivity                 1.0000            0.9500           1.0000
## Specificity                 1.0000            1.0000           0.9750
## Pos Pred Value              1.0000            1.0000           0.9524
## Neg Pred Value              1.0000            0.9756           1.0000
## Prevalence                  0.3333            0.3333           0.3333
## Detection Rate              0.3333            0.3167           0.3333
## Detection Prevalence        0.3333            0.3167           0.3500
## Balanced Accuracy           1.0000            0.9750           0.9875

Tabla de Resultados

resultados <- data.frame(
  "svmLinear" =c(mcre1$overall["Accurancy"], mcrp1$overall["Acucurary"]),
  "svmRadial" =c(mcre1$overall["Accurancy"], mcrp1$overall["Acucurary"]),
  "SvmPoly" =c(mcre1$overall["Accurancy"], mcrp1$overall["Acucurary"]),
  "rpart" =c(mcre1$overall["Accurancy"], mcrp1$overall["Acucurary"]),
  "rf" =c(mcre1$overall["Accurancy"], mcrp1$overall["Acucurary"]),
  "nnet" =c(mcre1$overall["Accurancy"], mcrp1$overall["Acucurary"])
)

rownames(resultados) <- c("Exactitud del Entrenamiento", "Exactitud de la prueba")

Conclusiones

En conclusion, el modelo de Redes Neuronales es el recomendado para la clasificacion de lirios.

LS0tCnRpdGxlOiAiQ0FSRVQgLSBJcmlzIgphdXRob3I6ICJLYW1pbGFoIENoYWlkZXogQTAxNzQxOTQzIgpkYXRlOiAiMjAyNi0wOC0yNiIKb3V0cHV0OgogIGh0bWxfZG9jdW1lbnQ6CiAgICB0b2M6IHRydWUKICAgIHRvY19mbG9hdDogdHJ1ZQogICAgY29kZV9kb3dubG9hZDogdHJ1ZQogICAgdGhlbWU6IHNhbmRzdG9uZQotLS0KPGNlbnRlcj4KCiFbXShodHRwczovL3Jhdy5naXRodWJ1c2VyY29udGVudC5jb20vSm9lUG9ydGlsbGEvSXJpc0RhdGFzZXQtRURBL21haW4vaW1nL2lyaXNfZmxvd2Vycy5wbmcpCgo8L2NlbnRlcj4KCiMgPHNwYW4gc3R5bGU9ImNvbG9yOmRhcmsiPlRlb3LDrWE8L3NwYW4+CkVsIHBhcXVldGUgKipDQVJFVCAoQ2xhc2lmaWNhY2nDs24gQW5kIFJlZ3Jlc3Npb24gVHJhaW5pbmcpKiogZXMgdW4gcGFxdWV0ZSBpbnRlZ3JhbCBjb24gdW5hIGFtcGxpYSB2YXJpZWRhZCBkZSBhbGdvcml0bW9zIHBhcmEgZWwgYXByZW5kaXphamUgYXV0b23DoXRpY28uCgojIDxzcGFuIHN0eWxlPSJjb2xvcjpkYXJrIj5pbnN0YWxhciBwYXF1ZXRlcyB5IGxsYW1hciBsaWJyZXJpYXM8L3NwYW4+CiMgPHNwYW4gc3R5bGU9ImNvbG9yOmRhcmsiPkxsYW1hciBsaWJyZXLDrWFzPC9zcGFuPgoKYGBge3J9CmxpYnJhcnkoY2FyZXQpCmxpYnJhcnkoZ2dwbG90MikKbGlicmFyeShsYXR0aWNlKQpsaWJyYXJ5KGRhdGFzZXRzKQpsaWJyYXJ5KERhdGFFeHBsb3JlcikKbGlicmFyeShrZXJubGFiKQpgYGAKIyA8c3BhbiBzdHlsZT0iY29sb3I6ZGFyayI+Y3JlYXIgbGEgYmFzZSBkZSBkYXRvczwvc3Bhbj4KYGBge3J9CmRmIDwtIGRhdGEuZnJhbWUoaXJpcykKYGBgCgoKIyA8c3BhbiBzdHlsZT0iY29sb3I6ZGFyayI+Y3JlYXIgbGEgYmFzZSBkZSBkYXRvczwvc3Bhbj4KYGBge3J9CnN1bW1hcnkoZGYpCnN0cihkZikKI2NyZWF0ZV9yZXBvcnQoZGYpCnBsb3RfbWlzc2luZyhkZikKcGxvdF9oaXN0b2dyYW0oZGYpCnBsb3RfY29ycmVsYXRpb24oZGYpCmBgYAoqKk5PVEE6IEVuIG1vZGVsb3MgZGUgY2xhc2lmaWNhY2nDs24sIGxhIHZhcmlhYmxlIHF1ZSBxdWVyZW1vcyBwcmVkZWNpciBkZWJlIHRlbmVyIGZvcm1hdG8gZGUgZmFjdG9yKioKCgojIDxzcGFuIHN0eWxlPSJjb2xvcjpkYXJrIj5QYXJ0aXIgbGEgYmFzZSBkZSBkYXRvczwvc3Bhbj4KYGBge3J9CnNldC5zZWVkKDEyMykKI05vcm1hbG1lbnRlIDgwLTIwIDAgNzAtMzAKcmVuZ2xvbmVzX2VudHJlbmFtaWVudG8gPC0gY3JlYXRlRGF0YVBhcnRpdGlvbihkZiRTcGVjaWVzLCBwPTAuOCwgbGlzdD1GQUxTRSkKZW50cmVuYW1pZW50byA8LSBkZltyZW5nbG9uZXNfZW50cmVuYW1pZW50byxdCnBydWViYSA8LSBkZltyZW5nbG9uZXNfZW50cmVuYW1pZW50byxdCmBgYAoKCiMgPHNwYW4gc3R5bGU9ImNvbG9yOmRhcmsiPkRpc3RpbnRvcyB0aXBvcyBkZSBNw6l0b2RvIHBhcmEgTW9kZWxhcjwvc3Bhbj4KTG9zIG3DqXRvZG9zIG3DoXMgdXRpbGl6YWRvcyBwYXJhIG1vZGVsYXIgYXByZW5kaXphamUgc29uOgoKKiAqKlNWTSoqOiAqc3VwcG9ydCB2ZWN0b3IgbWFjaGluZSogcG8gTWFxdWluYSBkZSB2ZWN0b3JlcyBkZSBTb3BvcnRlLCBIYXkgdmFyaW9zIHN1YnRpcG9zOiBMaW5lYWwgKERWTUxpbmVhciksIFJhZGlhbCAoU1ZNUmFkaWFsKSwgUG9saW5vbWljbwooU3ZtUG9seSksIGV0Yy4KKiAqKkFyYm9sIGRlIERlY2lzaW9uKio6IHJwYXJ0CiogKipSZWRlcyBuZXVyb25hbGVzKiogbm5ldAoqICoqUmFuZG9tIEZvcmVzdCoqIG8gQm9zcXVlcyBBbGVhdG9yaW9zOiByZgoKIyA8c3BhbiBzdHlsZT0iY29sb3I6ZGFyayI+TW9kZWxvIDEuIFNWTSBsaW5lYWw8L3NwYW4+CmBgYHtyLCBtZXNzYWdlPUZBTFNFLCB3YXJuaW5nPUZBTFNFfQptb2RlbG8xIDwtIHRyYWluKAogIFNwZWNpZXMgfiAuLCAKICBkYXRhID0gZW50cmVuYW1pZW50bywKICBtZXRob2QgPSAic3ZtTGluZWFyIiwKICBwcmVQcm9jZXNzID0gYygic2NhbGUiLCAiY2VudGVyIiksCiAgdHJDb250cm9sID0gdHJhaW5Db250cm9sKG1ldGhvZCA9ICJjdiIsIG51bWJlciA9IDEwKSwKICB0dW5lR3JpZCA9IGRhdGEuZnJhbWUoQyA9IDEpCikKCnJlc3VsdGFkb19lbnRyZW5hbWllbnRvMSA8LSBwcmVkaWN0KG1vZGVsbzEsIGVudHJlbmFtaWVudG8pCnJlc3VsdGFkb19wcnVlYmExIDwtIHByZWRpY3QobW9kZWxvMSwgcHJ1ZWJhKQoKbWNyZTEgPC0gY29uZnVzaW9uTWF0cml4KAogIHJlc3VsdGFkb19lbnRyZW5hbWllbnRvMSwKICBlbnRyZW5hbWllbnRvJFNwZWNpZXMKKQptY3JlMQoKbWNycDEgPC0gY29uZnVzaW9uTWF0cml4KAogIHJlc3VsdGFkb19wcnVlYmExLAogIHBydWViYSRTcGVjaWVzCikKbWNycDEKYGBgCiMgPHNwYW4gc3R5bGU9ImNvbG9yOmRhcmsiPk1vZGVsbyAyLiBTVk0gUmFkaWFsPC9zcGFuPgoKYGBge3IsIG1lc3NhZ2U9RkFMU0UsIHdhcm5pbmc9RkFMU0V9Cm1vZGVsbzIgPC0gdHJhaW4oCiAgU3BlY2llcyB+IC4sIAogIGRhdGEgPSBlbnRyZW5hbWllbnRvLAogIG1ldGhvZCA9ICJzdm1SYWRpYWwiLAogIHByZVByb2Nlc3MgPSBjKCJzY2FsZSIsICJjZW50ZXIiKSwKICB0ckNvbnRyb2wgPSB0cmFpbkNvbnRyb2wobWV0aG9kID0gImN2IiwgbnVtYmVyID0gMTApLAogIHR1bmVHcmlkID0gZGF0YS5mcmFtZShzaWdtYSA9IDEsIEMgPSAxKQopCgpyZXN1bHRhZG9fZW50cmVuYW1pZW50bzIgPC0gcHJlZGljdChtb2RlbG8yLCBlbnRyZW5hbWllbnRvKQpyZXN1bHRhZG9fcHJ1ZWJhMiA8LSBwcmVkaWN0KG1vZGVsbzIsIHBydWViYSkKCiMgTWF0cml6IGRlIGNvbmZ1c2nDs24gZGUgZW50cmVuYW1pZW50bwptY3JlMiA8LSBjb25mdXNpb25NYXRyaXgoCiAgcmVzdWx0YWRvX2VudHJlbmFtaWVudG8yLAogIGVudHJlbmFtaWVudG8kU3BlY2llcwopCm1jcmUyCgojIE1hdHJpeiBkZSBjb25mdXNpw7NuIGRlIHBydWViYQptY3JwMiA8LSBjb25mdXNpb25NYXRyaXgoCiAgcmVzdWx0YWRvX3BydWViYTIsCiAgcHJ1ZWJhJFNwZWNpZXMKKQptY3JwMgpgYGAKIyA8c3BhbiBzdHlsZT0iY29sb3I6ZGFyayI+TW9kZWxvIDMuIFNWTSBQb2xpbsOzbWljbzwvc3BhbgpgYGB7ciwgbWVzc2FnZT1GQUxTRSwgd2FybmluZz1GQUxTRX0KbW9kZWxvMyA8LSB0cmFpbigKICBTcGVjaWVzIH4gLiwgCiAgZGF0YSA9IGVudHJlbmFtaWVudG8sCiAgbWV0aG9kID0gInN2bVBvbHkiLAogIHByZVByb2Nlc3MgPSBjKCJzY2FsZSIsICJjZW50ZXIiKSwKICB0ckNvbnRyb2wgPSB0cmFpbkNvbnRyb2wobWV0aG9kID0gImN2IiwgbnVtYmVyID0gMTApLAogIHR1bmVHcmlkID0gZGF0YS5mcmFtZSgKICAgIGRlZ3JlZSA9IDIsCiAgICBzY2FsZSA9IDEsCiAgICBDID0gMQogICkKKQoKcmVzdWx0YWRvX2VudHJlbmFtaWVudG8zIDwtIHByZWRpY3QobW9kZWxvMywgZW50cmVuYW1pZW50bykKcmVzdWx0YWRvX3BydWViYTMgPC0gcHJlZGljdChtb2RlbG8zLCBwcnVlYmEpCgojIE1hdHJpeiBkZSBjb25mdXNpw7NuIGRlIGVudHJlbmFtaWVudG8KbWNyZTMgPC0gY29uZnVzaW9uTWF0cml4KAogIHJlc3VsdGFkb19lbnRyZW5hbWllbnRvMywKICBlbnRyZW5hbWllbnRvJFNwZWNpZXMKKQptY3JlMwoKIyBNYXRyaXogZGUgY29uZnVzacOzbiBkZSBwcnVlYmEKbWNycDMgPC0gY29uZnVzaW9uTWF0cml4KAogIHJlc3VsdGFkb19wcnVlYmEzLAogIHBydWViYSRTcGVjaWVzCikKbWNycDMKYGBgCgojIDxzcGFuIHN0eWxlPSJjb2xvcjpkYXJrIj5Nb2RlbG8gNC4gw4FyYm9sIGRlIERlc2ljacOzbjwvc3Bhbj4KCmBgYHtyLCBtZXNzYWdlPUZBTFNFLCB3YXJuaW5nPUZBTFNFfQptb2RlbG80IDwtIHRyYWluKAogIFNwZWNpZXMgfiAuLCAKICBkYXRhID0gZW50cmVuYW1pZW50bywKICBtZXRob2QgPSAicnBhcnQiLAogIHByZVByb2Nlc3MgPSBjKCJzY2FsZSIsICJjZW50ZXIiKSwKICB0ckNvbnRyb2wgPSB0cmFpbkNvbnRyb2wobWV0aG9kID0gImN2IiwgbnVtYmVyID0gMTApLAogdHVuZUxlbmd0aCA9IDEwCiAgKQoKcmVzdWx0YWRvX2VudHJlbmFtaWVudG80IDwtIHByZWRpY3QobW9kZWxvNCwgZW50cmVuYW1pZW50bykKcmVzdWx0YWRvX3BydWViYTQgPC0gcHJlZGljdChtb2RlbG80LCBwcnVlYmEpCgojIE1hdHJpeiBkZSBjb25mdXNpw7NuIGRlIGVudHJlbmFtaWVudG8KbWNyZTQgPC0gY29uZnVzaW9uTWF0cml4KAogIHJlc3VsdGFkb19lbnRyZW5hbWllbnRvNCwKICBlbnRyZW5hbWllbnRvJFNwZWNpZXMKKQptY3JlNAoKIyBNYXRyaXogZGUgY29uZnVzacOzbiBkZSBwcnVlYmEKbWNycDQgPC0gY29uZnVzaW9uTWF0cml4KAogIHJlc3VsdGFkb19wcnVlYmE0LAogIHBydWViYSRTcGVjaWVzCikKbWNycDQKYGBgCiMgPHNwYW4gc3R5bGU9ImNvbG9yOmRhcmsiPk1vZGVsbyA1LiBCb3NxdWVzIEFsZWF0b3Jpb3M8L3NwYW4+CgpgYGB7ciwgbWVzc2FnZT1GQUxTRSwgd2FybmluZz1GQUxTRX0KbW9kZWxvNSA8LSB0cmFpbigKICBTcGVjaWVzIH4gLiwgCiAgZGF0YSA9IGVudHJlbmFtaWVudG8sCiAgbWV0aG9kID0gInJmIiwKICBwcmVQcm9jZXNzID0gYygic2NhbGUiLCAiY2VudGVyIiksCiAgdHJDb250cm9sID0gdHJhaW5Db250cm9sKG1ldGhvZCA9ICJjdiIsIG51bWJlciA9IDEwKSwKIHR1bmVHcmlkID0gZXhwYW5kLmdyaWQobXRyeT1jKDIsNCw2KSkKICApCgpyZXN1bHRhZG9fZW50cmVuYW1pZW50bzUgPC0gcHJlZGljdChtb2RlbG81LCBlbnRyZW5hbWllbnRvKQpyZXN1bHRhZG9fcHJ1ZWJhNSA8LSBwcmVkaWN0KG1vZGVsbzQsIHBydWViYSkKCiMgTWF0cml6IGRlIGNvbmZ1c2nDs24gZGUgZW50cmVuYW1pZW50bwptY3JlNSA8LSBjb25mdXNpb25NYXRyaXgoCiAgcmVzdWx0YWRvX2VudHJlbmFtaWVudG81LAogIGVudHJlbmFtaWVudG8kU3BlY2llcwopCm1jcmU1CgojIE1hdHJpeiBkZSBjb25mdXNpw7NuIGRlIHBydWViYQptY3JwNSA8LSBjb25mdXNpb25NYXRyaXgoCiAgcmVzdWx0YWRvX3BydWViYTUsCiAgcHJ1ZWJhJFNwZWNpZXMKKQptY3JwNQpgYGAKIyA8c3BhbiBzdHlsZT0iY29sb3I6ZGFyayI+TW9kZWxvIDYuIFJlZGVzIE5ldXJvbmFsZXM8L3NwYW4+CmBgYHtyLCBtZXNzYWdlPUZBTFNFLCB3YXJuaW5nPUZBTFNFfQptb2RlbG82IDwtIHRyYWluKAogIFNwZWNpZXMgfiAuLCAKICBkYXRhID0gZW50cmVuYW1pZW50bywKICBtZXRob2QgPSAibm5ldCIsCiAgcHJlUHJvY2VzcyA9IGMoInNjYWxlIiwgImNlbnRlciIpLAogIHRyQ29udHJvbCA9IHRyYWluQ29udHJvbChtZXRob2QgPSAiY3YiLCBudW1iZXIgPSAxMCksCiAgdHVuZUxlbmd0aCA9IDEwLAogIHRyYWNlID0gRkFMU0UKKQoKcmVzdWx0YWRvX2VudHJlbmFtaWVudG82IDwtIHByZWRpY3QobW9kZWxvNiwgZW50cmVuYW1pZW50bykKcmVzdWx0YWRvX3BydWViYTYgPC0gcHJlZGljdChtb2RlbG82LCBwcnVlYmEpCgojIE1hdHJpeiBkZSBjb25mdXNpw7NuIGRlIGVudHJlbmFtaWVudG8KbWNyZTYgPC0gY29uZnVzaW9uTWF0cml4KAogIHJlc3VsdGFkb19lbnRyZW5hbWllbnRvNiwKICBlbnRyZW5hbWllbnRvJFNwZWNpZXMKKQptY3JlNgoKIyBNYXRyaXogZGUgY29uZnVzacOzbiBkZSBwcnVlYmEKbWNycDYgPC0gY29uZnVzaW9uTWF0cml4KAogIHJlc3VsdGFkb19wcnVlYmE2LAogIHBydWViYSRTcGVjaWVzCikKbWNycDYKYGBgCiMgPHNwYW4gc3R5bGU9ImNvbG9yOmRhcmsiPlRhYmxhIGRlIFJlc3VsdGFkb3M8L3NwYW4+CmBgYHtyfQpyZXN1bHRhZG9zIDwtIGRhdGEuZnJhbWUoCiAgInN2bUxpbmVhciIgPWMobWNyZTEkb3ZlcmFsbFsiQWNjdXJhbmN5Il0sIG1jcnAxJG92ZXJhbGxbIkFjdWN1cmFyeSJdKSwKICAic3ZtUmFkaWFsIiA9YyhtY3JlMSRvdmVyYWxsWyJBY2N1cmFuY3kiXSwgbWNycDEkb3ZlcmFsbFsiQWN1Y3VyYXJ5Il0pLAogICJTdm1Qb2x5IiA9YyhtY3JlMSRvdmVyYWxsWyJBY2N1cmFuY3kiXSwgbWNycDEkb3ZlcmFsbFsiQWN1Y3VyYXJ5Il0pLAogICJycGFydCIgPWMobWNyZTEkb3ZlcmFsbFsiQWNjdXJhbmN5Il0sIG1jcnAxJG92ZXJhbGxbIkFjdWN1cmFyeSJdKSwKICAicmYiID1jKG1jcmUxJG92ZXJhbGxbIkFjY3VyYW5jeSJdLCBtY3JwMSRvdmVyYWxsWyJBY3VjdXJhcnkiXSksCiAgIm5uZXQiID1jKG1jcmUxJG92ZXJhbGxbIkFjY3VyYW5jeSJdLCBtY3JwMSRvdmVyYWxsWyJBY3VjdXJhcnkiXSkKKQoKcm93bmFtZXMocmVzdWx0YWRvcykgPC0gYygiRXhhY3RpdHVkIGRlbCBFbnRyZW5hbWllbnRvIiwgIkV4YWN0aXR1ZCBkZSBsYSBwcnVlYmEiKQpgYGAKCiMgPHNwYW4gc3R5bGU9ImNvbG9yOmRhcmsiPkNvbmNsdXNpb25lczwvc3Bhbj4KRW4gY29uY2x1c2lvbiwgZWwgbW9kZWxvIGRlICoqUmVkZXMgTmV1cm9uYWxlcyoqIGVzIGVsIHJlY29tZW5kYWRvIHBhcmEgbGEgY2xhc2lmaWNhY2lvbiBkZSBsaXJpb3Mu