Teoría

El paquete CARET (Classification and regression training) es un paquete integral con una amplia variedad de algoritmos para el aprendizaje automático.

Instalar paquetes y llamar librerías

#install.packages("ggplot2") # Gráfica
library(ggplot2)
#install.packages("lattice") # Gráfica
library(lattice)
#install.packages("caret") # Algoritmos de aprendizaje automatico
library(caret)
#install.packages("datasets") # Usar bases de datos, en este caso iris
library(datasets)
#install.packages("DataExplorer") # Análisis Exploratorio
library(DataExplorer)
#install.packages("kernlab")

Crear la base de datos

df <- data.frame(iris)

Entender 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: la variable que queremos predecir debe tener formtao de factor**

Entender la base de datos

# Normalmente 80-20
set.seed(123)
renglones_entrenamiento <- createDataPartition(df$Species, p=0.8, list = FALSE)

entrenamiento <- iris[renglones_entrenamiento, ]
prueba <- iris[-renglones_entrenamiento, ]

Distintos tipos de Métodos para Molderar

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

  • SVM: Support Vector Mchine o Máquina de Vectores de Soporte. Hay varios subtipos: Lineal (svmlinear), Radial (svmRadial), Polinómico (svmPoly), etc.

  • Árbol de Decisión: rpart

  • Redes Neuronales: nnet

  • Random Forest o Bosques Aleatorios: Rf

Modelo 1. SVM Lineal

modelo1 <- train(Species ~ ., data=entrenamiento,
                 method = "svmLinear", #Cambiar
                 preProcess=c("scale", "center"),
                 trControl = trainControl(method="cv", number=10),
                 tuneGride = data.frame(C=1) # Cambiar
                 )
                
resultado_entrenamiento1 <- predict(modelo1, entrenamiento)
resultado_prueba1 <- predict(modelo1, prueba)

#Matriz de Confusión
# Es una tabla de evaluación que desglosa el rendimiento del modelo de clasificación

# Matriz de clasificación del resultado de entrenamiento
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
# Matriz de clasificación del resultado de la prueba
mcrp1 <- confusionMatrix(resultado_prueba1, prueba$Specie)
mcrp1
## Confusion Matrix and Statistics
## 
##             Reference
## Prediction   setosa versicolor virginica
##   setosa         10          0         0
##   versicolor      0         10         1
##   virginica       0          0         9
## 
## Overall Statistics
##                                           
##                Accuracy : 0.9667          
##                  95% CI : (0.8278, 0.9992)
##     No Information Rate : 0.3333          
##     P-Value [Acc > NIR] : 2.963e-13       
##                                           
##                   Kappa : 0.95            
##                                           
##  Mcnemar's Test P-Value : NA              
## 
## Statistics by Class:
## 
##                      Class: setosa Class: versicolor Class: virginica
## Sensitivity                 1.0000            1.0000           0.9000
## Specificity                 1.0000            0.9500           1.0000
## Pos Pred Value              1.0000            0.9091           1.0000
## Neg Pred Value              1.0000            1.0000           0.9524
## Prevalence                  0.3333            0.3333           0.3333
## Detection Rate              0.3333            0.3333           0.3000
## Detection Prevalence        0.3333            0.3667           0.3000
## Balanced Accuracy           1.0000            0.9750           0.9500

span style=“color:blue;”> Modelo 2. SVM Radial

modelo2 <- train(Species ~ ., data=entrenamiento,
                 method = "svmRadial", #Cambiar
                 preProcess=c("scale", "center"),
                 trControl = trainControl(method="cv", number=10),
                 tuneGride = data.frame(C=1) # Cambiar
                 )
                
resultado_entrenamiento2 <- predict(modelo2, entrenamiento)
resultado_prueba2 <- predict(modelo2, prueba)

#Matriz de Confusión
# Es una tabla de evaluación que desglosa el rendimiento del modelo de clasificación

# Matriz de clasificación del resultado 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 clasificación del resultado de la prueba
mcrp2 <- confusionMatrix(resultado_prueba2, prueba$Specie)
mcrp2
## Confusion Matrix and Statistics
## 
##             Reference
## Prediction   setosa versicolor virginica
##   setosa         10          0         0
##   versicolor      0         10         2
##   virginica       0          0         8
## 
## Overall Statistics
##                                           
##                Accuracy : 0.9333          
##                  95% CI : (0.7793, 0.9918)
##     No Information Rate : 0.3333          
##     P-Value [Acc > NIR] : 8.747e-12       
##                                           
##                   Kappa : 0.9             
##                                           
##  Mcnemar's Test P-Value : NA              
## 
## Statistics by Class:
## 
##                      Class: setosa Class: versicolor Class: virginica
## Sensitivity                 1.0000            1.0000           0.8000
## Specificity                 1.0000            0.9000           1.0000
## Pos Pred Value              1.0000            0.8333           1.0000
## Neg Pred Value              1.0000            1.0000           0.9091
## Prevalence                  0.3333            0.3333           0.3333
## Detection Rate              0.3333            0.3333           0.2667
## Detection Prevalence        0.3333            0.4000           0.2667
## Balanced Accuracy           1.0000            0.9500           0.9000

span style=“color:blue;”> Modelo 3. SVM Radial

modelo3 <- train(Species ~ ., data=entrenamiento,
                 method = "svmPoly", #Cambiar
                 preProcess=c("scale", "center"),
                 trControl = trainControl(method="cv", number=10),
                 tuneGride = data.frame(C=1) # Cambiar
                 )
                
resultado_entrenamiento3 <- predict(modelo3, entrenamiento)
resultado_prueba3 <- predict(modelo3, prueba)

#Matriz de Confusión
# Es una tabla de evaluación que desglosa el rendimiento del modelo de clasificación

# Matriz de clasificación del resultado de entrenamiento
mcre3 <- confusionMatrix(resultado_entrenamiento3, entrenamiento$Species)
mcre3
## Confusion Matrix and Statistics
## 
##             Reference
## Prediction   setosa versicolor virginica
##   setosa         40          0         0
##   versicolor      0         40         4
##   virginica       0          0        36
## 
## 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            1.0000           0.9000
## Specificity                 1.0000            0.9500           1.0000
## Pos Pred Value              1.0000            0.9091           1.0000
## Neg Pred Value              1.0000            1.0000           0.9524
## Prevalence                  0.3333            0.3333           0.3333
## Detection Rate              0.3333            0.3333           0.3000
## Detection Prevalence        0.3333            0.3667           0.3000
## Balanced Accuracy           1.0000            0.9750           0.9500
# Matriz de clasificación del resultado de la prueba
mcrp3 <- confusionMatrix(resultado_prueba3, prueba$Specie)
mcrp3
## Confusion Matrix and Statistics
## 
##             Reference
## Prediction   setosa versicolor virginica
##   setosa         10          0         0
##   versicolor      0         10         2
##   virginica       0          0         8
## 
## Overall Statistics
##                                           
##                Accuracy : 0.9333          
##                  95% CI : (0.7793, 0.9918)
##     No Information Rate : 0.3333          
##     P-Value [Acc > NIR] : 8.747e-12       
##                                           
##                   Kappa : 0.9             
##                                           
##  Mcnemar's Test P-Value : NA              
## 
## Statistics by Class:
## 
##                      Class: setosa Class: versicolor Class: virginica
## Sensitivity                 1.0000            1.0000           0.8000
## Specificity                 1.0000            0.9000           1.0000
## Pos Pred Value              1.0000            0.8333           1.0000
## Neg Pred Value              1.0000            1.0000           0.9091
## Prevalence                  0.3333            0.3333           0.3333
## Detection Rate              0.3333            0.3333           0.2667
## Detection Prevalence        0.3333            0.4000           0.2667
## Balanced Accuracy           1.0000            0.9500           0.9000

span style=“color:blue;”> Modelo 4. Árbol de Decisión

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

#Matriz de Confusión
# Es una tabla de evaluación que desglosa el rendimiento del modelo de clasificación

# Matriz de clasificación del resultado 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 clasificación del resultado de la prueba
mcrp4 <- confusionMatrix(resultado_prueba4, prueba$Specie)
LS0tCnRpdGxlOiAiQ0FSRVQiCmF1dGhvcjogIkh1bWJlcnRvIENvcnTDqXMgU2FsZGHDsWEiCmRhdGU6ICIyMDI1LTA4LTIyIgpvdXRwdXQ6IAogIGh0bWxfZG9jdW1lbnQ6CiAgICB0b2M6IFRSVUUKICAgIHRvY19mbG9hdDogVFJVRQogICAgY29kZV9kb3dubG9hZDogVFJVRQogICAgdGhlbWU6IHlldGkKLS0tCgoKPGNlbnRlcj4KIVtdKGh0dHBzOi8vbWlyby5tZWRpdW0uY29tL3YyL3Jlc2l6ZTpmaXQ6MTQwMC8xKlpLOV9IcnBQX2xoU3pUcTl4VkpVUXcucG5nKQo8Y2VudGVyPgoKIyA8c3BhbiBzdHlsZT0iY29sb3I6Ymx1ZTsiPiBUZW9yw61hIDwvc3Bhbj4KRWwgcGFxdWV0ZSAqKkNBUkVUIChDbGFzc2lmaWNhdGlvbiBhbmQgcmVncmVzc2lvbiB0cmFpbmluZykqKiBlcyB1biBwYXF1ZXRlIGludGVncmFsIGNvbiB1bmEgYW1wbGlhIHZhcmllZGFkIGRlIGFsZ29yaXRtb3MgcGFyYSBlbCBhcHJlbmRpemFqZSBhdXRvbcOhdGljby4KCiMgPHNwYW4gc3R5bGU9ImNvbG9yOmJsdWU7Ij4gSW5zdGFsYXIgcGFxdWV0ZXMgeSBsbGFtYXIgbGlicmVyw61hcyA8L3NwYW4+CmBgYHtyfQojaW5zdGFsbC5wYWNrYWdlcygiZ2dwbG90MiIpICMgR3LDoWZpY2EKbGlicmFyeShnZ3Bsb3QyKQojaW5zdGFsbC5wYWNrYWdlcygibGF0dGljZSIpICMgR3LDoWZpY2EKbGlicmFyeShsYXR0aWNlKQojaW5zdGFsbC5wYWNrYWdlcygiY2FyZXQiKSAjIEFsZ29yaXRtb3MgZGUgYXByZW5kaXphamUgYXV0b21hdGljbwpsaWJyYXJ5KGNhcmV0KQojaW5zdGFsbC5wYWNrYWdlcygiZGF0YXNldHMiKSAjIFVzYXIgYmFzZXMgZGUgZGF0b3MsIGVuIGVzdGUgY2FzbyBpcmlzCmxpYnJhcnkoZGF0YXNldHMpCiNpbnN0YWxsLnBhY2thZ2VzKCJEYXRhRXhwbG9yZXIiKSAjIEFuw6FsaXNpcyBFeHBsb3JhdG9yaW8KbGlicmFyeShEYXRhRXhwbG9yZXIpCiNpbnN0YWxsLnBhY2thZ2VzKCJrZXJubGFiIikKCgpgYGAKCiMgPHNwYW4gc3R5bGU9ImNvbG9yOmJsdWU7Ij4gQ3JlYXIgbGEgYmFzZSBkZSBkYXRvcyA8L3NwYW4+CmBgYHtyfQpkZiA8LSBkYXRhLmZyYW1lKGlyaXMpCmBgYAoKIyA8c3BhbiBzdHlsZT0iY29sb3I6Ymx1ZTsiPiBFbnRlbmRlciBsYSBiYXNlIGRlIGRhdG9zIDwvc3Bhbj4KYGBge3J9CnN1bW1hcnkoZGYpCnN0cihkZikKIyBjcmVhdGVfcmVwb3J0KGRmKQoKcGxvdF9taXNzaW5nKGRmKQpwbG90X2hpc3RvZ3JhbShkZikKcGxvdF9jb3JyZWxhdGlvbihkZikKCmBgYAoqKiBOT1RBOiBsYSB2YXJpYWJsZSBxdWUgcXVlcmVtb3MgcHJlZGVjaXIgZGViZSB0ZW5lciBmb3JtdGFvIGRlIGZhY3RvcioqCgojIDxzcGFuIHN0eWxlPSJjb2xvcjpibHVlOyI+IEVudGVuZGVyIGxhIGJhc2UgZGUgZGF0b3MgPC9zcGFuPgpgYGB7ciBtZXNzYWdlPUZBTFNFLCB3YXJuaW5nPUZBTFNFLCBwYWdlZC5wcmludD1GQUxTRX0KIyBOb3JtYWxtZW50ZSA4MC0yMApzZXQuc2VlZCgxMjMpCnJlbmdsb25lc19lbnRyZW5hbWllbnRvIDwtIGNyZWF0ZURhdGFQYXJ0aXRpb24oZGYkU3BlY2llcywgcD0wLjgsIGxpc3QgPSBGQUxTRSkKCmVudHJlbmFtaWVudG8gPC0gaXJpc1tyZW5nbG9uZXNfZW50cmVuYW1pZW50bywgXQpwcnVlYmEgPC0gaXJpc1stcmVuZ2xvbmVzX2VudHJlbmFtaWVudG8sIF0KYGBgCiMgPHNwYW4gc3R5bGU9ImNvbG9yOmJsdWU7Ij4gRGlzdGludG9zIHRpcG9zIGRlIE3DqXRvZG9zIHBhcmEgTW9sZGVyYXIgPC9zcGFuPgpMb3MgbcOpdG9kb3MgbcOhcyB1dGlsaXphZG9zIHBhcmEgbW9kZWxhciBhcHJlbmRpemFqZSBhdXRvbcOhdGljbyBzb246CgoqICoqU1ZNKio6ICpTdXBwb3J0IFZlY3RvciBNY2hpbmUqIG8gTcOhcXVpbmEgZGUgVmVjdG9yZXMgZGUgU29wb3J0ZS4gSGF5IHZhcmlvcyBzdWJ0aXBvczogTGluZWFsIChzdm1saW5lYXIpLCBSYWRpYWwgKHN2bVJhZGlhbCksIFBvbGluw7NtaWNvIChzdm1Qb2x5KSwgZXRjLgoKKiAqKsOBcmJvbCBkZSBEZWNpc2nDs24qKjogcnBhcnQKCiogKipSZWRlcyBOZXVyb25hbGVzKio6IG5uZXQKCiogKipSYW5kb20gRm9yZXN0KiogbyBCb3NxdWVzIEFsZWF0b3Jpb3M6IFJmCgojIDxzcGFuIHN0eWxlPSJjb2xvcjpibHVlOyI+IE1vZGVsbyAxLiBTVk0gTGluZWFsIDwvc3Bhbj4KCmBgYHtyIG1lc3NhZ2U9RkFMU0UsIHdhcm5pbmc9RkFMU0UsIHBhZ2VkLnByaW50PUZBTFNFfQptb2RlbG8xIDwtIHRyYWluKFNwZWNpZXMgfiAuLCBkYXRhPWVudHJlbmFtaWVudG8sCiAgICAgICAgICAgICAgICAgbWV0aG9kID0gInN2bUxpbmVhciIsICNDYW1iaWFyCiAgICAgICAgICAgICAgICAgcHJlUHJvY2Vzcz1jKCJzY2FsZSIsICJjZW50ZXIiKSwKICAgICAgICAgICAgICAgICB0ckNvbnRyb2wgPSB0cmFpbkNvbnRyb2wobWV0aG9kPSJjdiIsIG51bWJlcj0xMCksCiAgICAgICAgICAgICAgICAgdHVuZUdyaWRlID0gZGF0YS5mcmFtZShDPTEpICMgQ2FtYmlhcgogICAgICAgICAgICAgICAgICkKICAgICAgICAgICAgICAgIApyZXN1bHRhZG9fZW50cmVuYW1pZW50bzEgPC0gcHJlZGljdChtb2RlbG8xLCBlbnRyZW5hbWllbnRvKQpyZXN1bHRhZG9fcHJ1ZWJhMSA8LSBwcmVkaWN0KG1vZGVsbzEsIHBydWViYSkKCiNNYXRyaXogZGUgQ29uZnVzacOzbgojIEVzIHVuYSB0YWJsYSBkZSBldmFsdWFjacOzbiBxdWUgZGVzZ2xvc2EgZWwgcmVuZGltaWVudG8gZGVsIG1vZGVsbyBkZSBjbGFzaWZpY2FjacOzbgoKIyBNYXRyaXogZGUgY2xhc2lmaWNhY2nDs24gZGVsIHJlc3VsdGFkbyBkZSBlbnRyZW5hbWllbnRvCm1jcmUxIDwtIGNvbmZ1c2lvbk1hdHJpeChyZXN1bHRhZG9fZW50cmVuYW1pZW50bzEsIGVudHJlbmFtaWVudG8kU3BlY2llcykKbWNyZTEKCiMgTWF0cml6IGRlIGNsYXNpZmljYWNpw7NuIGRlbCByZXN1bHRhZG8gZGUgbGEgcHJ1ZWJhCm1jcnAxIDwtIGNvbmZ1c2lvbk1hdHJpeChyZXN1bHRhZG9fcHJ1ZWJhMSwgcHJ1ZWJhJFNwZWNpZSkKbWNycDEKYGBgCgojIHNwYW4gc3R5bGU9ImNvbG9yOmJsdWU7Ij4gTW9kZWxvIDIuIFNWTSBSYWRpYWwgPC9zcGFuPgoKYGBge3IgbWVzc2FnZT1GQUxTRSwgd2FybmluZz1GQUxTRSwgcGFnZWQucHJpbnQ9RkFMU0V9Cm1vZGVsbzIgPC0gdHJhaW4oU3BlY2llcyB+IC4sIGRhdGE9ZW50cmVuYW1pZW50bywKICAgICAgICAgICAgICAgICBtZXRob2QgPSAic3ZtUmFkaWFsIiwgI0NhbWJpYXIKICAgICAgICAgICAgICAgICBwcmVQcm9jZXNzPWMoInNjYWxlIiwgImNlbnRlciIpLAogICAgICAgICAgICAgICAgIHRyQ29udHJvbCA9IHRyYWluQ29udHJvbChtZXRob2Q9ImN2IiwgbnVtYmVyPTEwKSwKICAgICAgICAgICAgICAgICB0dW5lR3JpZGUgPSBkYXRhLmZyYW1lKEM9MSkgIyBDYW1iaWFyCiAgICAgICAgICAgICAgICAgKQogICAgICAgICAgICAgICAgCnJlc3VsdGFkb19lbnRyZW5hbWllbnRvMiA8LSBwcmVkaWN0KG1vZGVsbzIsIGVudHJlbmFtaWVudG8pCnJlc3VsdGFkb19wcnVlYmEyIDwtIHByZWRpY3QobW9kZWxvMiwgcHJ1ZWJhKQoKI01hdHJpeiBkZSBDb25mdXNpw7NuCiMgRXMgdW5hIHRhYmxhIGRlIGV2YWx1YWNpw7NuIHF1ZSBkZXNnbG9zYSBlbCByZW5kaW1pZW50byBkZWwgbW9kZWxvIGRlIGNsYXNpZmljYWNpw7NuCgojIE1hdHJpeiBkZSBjbGFzaWZpY2FjacOzbiBkZWwgcmVzdWx0YWRvIGRlIGVudHJlbmFtaWVudG8KbWNyZTIgPC0gY29uZnVzaW9uTWF0cml4KHJlc3VsdGFkb19lbnRyZW5hbWllbnRvMiwgZW50cmVuYW1pZW50byRTcGVjaWVzKQptY3JlMgoKIyBNYXRyaXogZGUgY2xhc2lmaWNhY2nDs24gZGVsIHJlc3VsdGFkbyBkZSBsYSBwcnVlYmEKbWNycDIgPC0gY29uZnVzaW9uTWF0cml4KHJlc3VsdGFkb19wcnVlYmEyLCBwcnVlYmEkU3BlY2llKQptY3JwMgpgYGAKCiMgc3BhbiBzdHlsZT0iY29sb3I6Ymx1ZTsiPiBNb2RlbG8gMy4gU1ZNIFJhZGlhbCA8L3NwYW4+CgpgYGB7ciBtZXNzYWdlPUZBTFNFLCB3YXJuaW5nPUZBTFNFLCBwYWdlZC5wcmludD1GQUxTRX0KbW9kZWxvMyA8LSB0cmFpbihTcGVjaWVzIH4gLiwgZGF0YT1lbnRyZW5hbWllbnRvLAogICAgICAgICAgICAgICAgIG1ldGhvZCA9ICJzdm1Qb2x5IiwgI0NhbWJpYXIKICAgICAgICAgICAgICAgICBwcmVQcm9jZXNzPWMoInNjYWxlIiwgImNlbnRlciIpLAogICAgICAgICAgICAgICAgIHRyQ29udHJvbCA9IHRyYWluQ29udHJvbChtZXRob2Q9ImN2IiwgbnVtYmVyPTEwKSwKICAgICAgICAgICAgICAgICB0dW5lR3JpZGUgPSBkYXRhLmZyYW1lKEM9MSkgIyBDYW1iaWFyCiAgICAgICAgICAgICAgICAgKQogICAgICAgICAgICAgICAgCnJlc3VsdGFkb19lbnRyZW5hbWllbnRvMyA8LSBwcmVkaWN0KG1vZGVsbzMsIGVudHJlbmFtaWVudG8pCnJlc3VsdGFkb19wcnVlYmEzIDwtIHByZWRpY3QobW9kZWxvMywgcHJ1ZWJhKQoKI01hdHJpeiBkZSBDb25mdXNpw7NuCiMgRXMgdW5hIHRhYmxhIGRlIGV2YWx1YWNpw7NuIHF1ZSBkZXNnbG9zYSBlbCByZW5kaW1pZW50byBkZWwgbW9kZWxvIGRlIGNsYXNpZmljYWNpw7NuCgojIE1hdHJpeiBkZSBjbGFzaWZpY2FjacOzbiBkZWwgcmVzdWx0YWRvIGRlIGVudHJlbmFtaWVudG8KbWNyZTMgPC0gY29uZnVzaW9uTWF0cml4KHJlc3VsdGFkb19lbnRyZW5hbWllbnRvMywgZW50cmVuYW1pZW50byRTcGVjaWVzKQptY3JlMwoKIyBNYXRyaXogZGUgY2xhc2lmaWNhY2nDs24gZGVsIHJlc3VsdGFkbyBkZSBsYSBwcnVlYmEKbWNycDMgPC0gY29uZnVzaW9uTWF0cml4KHJlc3VsdGFkb19wcnVlYmEzLCBwcnVlYmEkU3BlY2llKQptY3JwMwpgYGAKCgoKIyBzcGFuIHN0eWxlPSJjb2xvcjpibHVlOyI+IE1vZGVsbyA0LiDDgXJib2wgZGUgRGVjaXNpw7NuIDwvc3Bhbj4KCmBgYHtyIG1lc3NhZ2U9RkFMU0UsIHdhcm5pbmc9RkFMU0UsIHBhZ2VkLnByaW50PUZBTFNFfQptb2RlbG80IDwtIHRyYWluKFNwZWNpZXMgfiAuLCBkYXRhPWVudHJlbmFtaWVudG8sCiAgICAgICAgICAgICAgICAgbWV0aG9kID0gInJwYXJ0IiwgI0NhbWJpYXIKICAgICAgICAgICAgICAgICBwcmVQcm9jZXNzPWMoInNjYWxlIiwgImNlbnRlciIpLAogICAgICAgICAgICAgICAgIHRyQ29udHJvbCA9IHRyYWluQ29udHJvbChtZXRob2Q9ImN2IiwgbnVtYmVyPTEwKSwKICAgICAgICAgICAgICAgICB0dW5lTGVuZ3RoID0gMTAgIyBDYW1iaWFyCiAgICAgICAgICAgICAgICAgKQogICAgICAgICAgICAgICAgCnJlc3VsdGFkb19lbnRyZW5hbWllbnRvNCA8LSBwcmVkaWN0KG1vZGVsbzQsIGVudHJlbmFtaWVudG8pCnJlc3VsdGFkb19wcnVlYmE0IDwtIHByZWRpY3QobW9kZWxvNCwgcHJ1ZWJhKQoKI01hdHJpeiBkZSBDb25mdXNpw7NuCiMgRXMgdW5hIHRhYmxhIGRlIGV2YWx1YWNpw7NuIHF1ZSBkZXNnbG9zYSBlbCByZW5kaW1pZW50byBkZWwgbW9kZWxvIGRlIGNsYXNpZmljYWNpw7NuCgojIE1hdHJpeiBkZSBjbGFzaWZpY2FjacOzbiBkZWwgcmVzdWx0YWRvIGRlIGVudHJlbmFtaWVudG8KbWNyZTQgPC0gY29uZnVzaW9uTWF0cml4KHJlc3VsdGFkb19lbnRyZW5hbWllbnRvNCwgZW50cmVuYW1pZW50byRTcGVjaWVzKQptY3JlNAoKIyBNYXRyaXogZGUgY2xhc2lmaWNhY2nDs24gZGVsIHJlc3VsdGFkbyBkZSBsYSBwcnVlYmEKbWNycDQgPC0gY29uZnVzaW9uTWF0cml4KHJlc3VsdGFkb19wcnVlYmE0LCBwcnVlYmEkU3BlY2llKQpgYGA=