1. CARGAR LIBRERÍAS

library(readr)
library(dplyr)
library(caret)
library(randomForest)
library(ggplot2)
library(showtext)
library(sysfonts)

font_add_google("Lora", "Lora")
showtext_auto()

2. CARGAR DATA SET

datos_originales <- readr::read_csv2(
  "C:/Users/cordo/OneDrive/Desktop/ESTADISITCA/Oil__Gas____Other_Regulated_Wells__Beginning_1860.csv",
  locale = readr::locale(encoding = "Latin1")
)

head(datos_originales)
## # A tibble: 6 × 55
##   `API Well Number` `County Code` `API Hole Number` Sidetrack Completion
##               <dbl>         <dbl>             <dbl>     <dbl>      <dbl>
## 1           3.10e15             3              2670         0          0
## 2           3.10e15             3              4599         0          0
## 3           3.10e15             3              4842         0          0
## 4           3.10e15             3              5419         0          0
## 5           3.11e15           101             26525         0          0
## 6           3.11e15           121             23269         0          0
## # ℹ 50 more variables: `Well Name` <chr>, `Company Name` <chr>,
## #   `Operator Number` <dbl>, `Well Type` <chr>, `Map Symbol` <chr>,
## #   `Well Status` <chr>, `Status Date` <chr>, `Permit Application Date` <chr>,
## #   `Permit Issued Date` <chr>, `Date Spudded` <chr>,
## #   `Date of Total Depth` <chr>, `Completion Decade` <chr>,
## #   `Completion Year` <chr>, `Completion Month` <chr>, `Completion Day` <chr>,
## #   `Date Well Plugged` <chr>, `Date Well Confidentiality Ends` <chr>, …

3. PROCESAMIENTO DE DATOS

datos <- datos_originales %>%
  select(
    `True Vertical Depth, ft`,
    `Proposed Depth, ft`,
    `Elevation, ft`,
    `Surface Longitude`,
    `Surface Latitude`,
    County,
    Region,
    `Well Type`,
    `Original Well Type`,
    `Objective Formation`,
    `Producing Formation`,
    Slant,
    `Spacing Acres`
  ) %>%
  na.omit()

# Renombrar variables
colnames(datos) <- c(
  "TrueVerticalDepth",
  "ProposedDepth",
  "Elevation",
  "SurfaceLongitude",
  "SurfaceLatitude",
  "County",
  "Region",
  "WellType",
  "OriginalWellType",
  "ObjectiveFormation",
  "ProducingFormation",
  "Slant",
  "SpacingAcres"
)

# Convertir variables categóricas
datos$County <- as.factor(datos$County)
datos$Region <- as.factor(datos$Region)
datos$WellType <- as.factor(datos$WellType)
datos$OriginalWellType <- as.factor(datos$OriginalWellType)
datos$ObjectiveFormation <- as.factor(datos$ObjectiveFormation)
datos$ProducingFormation <- as.factor(datos$ProducingFormation)
datos$Slant <- as.factor(datos$Slant)

4. DIVISIÓN DE DATOS

Para evaluar el desempeño del modelo, el conjunto de datos se divide en dos grupos:

  • 70 % para entrenamiento.
  • 30 % para prueba.

Esta metodología permite comprobar la capacidad del modelo para realizar predicciones sobre datos que no fueron utilizados durante el entrenamiento.

set.seed(123)

indice <- createDataPartition(
  datos$TrueVerticalDepth,
  p = 0.70,
  list = FALSE
)

train <- datos[indice, ]
test <- datos[-indice, ]

5. EVALUACIÓN DEL CONJUNTO DE DATOS

summary(train)
##  TrueVerticalDepth ProposedDepth     Elevation    SurfaceLongitude    
##  Min.   : 1152     Min.   : 1200   Min.   : 395   Min.   :-7.954e+16  
##  1st Qu.: 2812     1st Qu.: 2842   1st Qu.:1203   1st Qu.:-7.798e+16  
##  Median : 3669     Median : 3828   Median :1417   Median :-7.681e+16  
##  Mean   : 5114     Mean   : 5134   Mean   :1396   Mean   :-7.218e+16  
##  3rd Qu.: 6948     3rd Qu.: 6679   3rd Qu.:1592   3rd Qu.:-7.563e+16  
##  Max.   :11673     Max.   :12749   Max.   :2257   Max.   :-7.558e+06  
##                                                                       
##  SurfaceLatitude          County   Region    WellType   OriginalWellType
##  Min.   :4.222e+05   Erie    :53   4: 1   GW     :123   GD: 23          
##  1st Qu.:4.214e+16   Chenango:38   7:88   GE     : 63   GE: 63          
##  Median :4.251e+16   Chemung :33   8:84   GD     : 28   GW:146          
##  Mean   :3.702e+16   Madison :27   9:67   DW     : 11   NL:  1          
##  3rd Qu.:4.272e+16   Steuben :26          NL     :  4   OW:  4          
##  Max.   :4.313e+16   Schuyler:17          DH     :  2   ST:  3          
##                      (Other) :46          (Other):  9                   
##    ObjectiveFormation   ProducingFormation         Slant      SpacingAcres    
##  Black River:62       Black River:57       Directional: 24   Min.   :   40.0  
##  Medina     :46       Medina     :48       Horizontal : 75   1st Qu.:  433.5  
##  Herkimer   :43       Herkimer   :43       Vertical   :141   Median : 5042.0  
##  Queenston  :22       Queenston  :26                         Mean   :16071.6  
##  Theresa    :15       Theresa    :15                         3rd Qu.:11219.0  
##  Marcellus  :10       Oneida     :12                         Max.   :66499.0  
##  (Other)    :42       (Other)    :39
summary(test)
##  TrueVerticalDepth ProposedDepth     Elevation    SurfaceLongitude    
##  Min.   : 1060     Min.   : 1052   Min.   : 435   Min.   :-7.929e+16  
##  1st Qu.: 2820     1st Qu.: 2732   1st Qu.:1264   1st Qu.:-7.842e+16  
##  Median : 3699     Median : 3846   Median :1431   Median :-7.694e+16  
##  Mean   : 5056     Mean   : 5104   Mean   :1425   Mean   :-6.861e+16  
##  3rd Qu.: 6951     3rd Qu.: 6983   3rd Qu.:1692   3rd Qu.:-7.562e+16  
##  Max.   :11953     Max.   :11900   Max.   :2140   Max.   :-7.713e+04  
##                                                                       
##  SurfaceLatitude             County   Region    WellType  OriginalWellType
##  Min.   :4.211e+07   Erie       :22   4: 2   GW     :52   GD:14           
##  1st Qu.:4.217e+16   Chenango   :20   7:28   GE     :23   GE:25           
##  Median :4.248e+16   Steuben    :15   8:38   GD     :17   GW:57           
##  Mean   :3.781e+16   Chemung    :11   9:32   DH     : 2   NL: 0           
##  3rd Qu.:4.269e+16   Schuyler   : 6          DW     : 2   OW: 2           
##  Max.   :4.310e+16   Cattaraugus: 5          OW     : 2   ST: 2           
##                      (Other)    :21          (Other): 2                   
##    ObjectiveFormation   ProducingFormation         Slant     SpacingAcres  
##  Black River:25       Black River:25       Directional: 9   Min.   :   40  
##  Medina     :19       Medina     :20       Horizontal :25   1st Qu.: 1174  
##  Herkimer   :12       Herkimer   :12       Vertical   :66   Median : 4392  
##  Marcellus  :11       Marcellus  :11                        Mean   :18454  
##  Oneida     : 9       Oneida     : 9                        3rd Qu.:30553  
##  Queenston  : 5       Queenston  : 6                        Max.   :65457  
##  (Other)    :19       (Other)    :17

6. ENTRENAMIENTO DEL MODELO

Una vez preparados los datos, se construye el modelo Random Forest Regressor, utilizando la profundidad vertical verdadera como variable objetivo.

Se emplean 500 árboles de decisión, ya que este número proporciona un equilibrio adecuado entre precisión y tiempo de entrenamiento.

modelo_rf <- randomForest(
  TrueVerticalDepth ~ .,
  data = train,
  ntree = 500,
  importance = TRUE
)

print(modelo_rf)
## 
## Call:
##  randomForest(formula = TrueVerticalDepth ~ ., data = train, ntree = 500,      importance = TRUE) 
##                Type of random forest: regression
##                      Number of trees: 500
## No. of variables tried at each split: 4
## 
##           Mean of squared residuals: 291382.6
##                     % Var explained: 96.65

7. MODELO

print(modelo_rf)
## 
## Call:
##  randomForest(formula = TrueVerticalDepth ~ ., data = train, ntree = 500,      importance = TRUE) 
##                Type of random forest: regression
##                      Number of trees: 500
## No. of variables tried at each split: 4
## 
##           Mean of squared residuals: 291382.6
##                     % Var explained: 96.65
importance(modelo_rf)
##                      %IncMSE IncNodePurity
## ProposedDepth      28.225662     801471911
## Elevation           8.449556      17835619
## SurfaceLongitude    8.737593      10893843
## SurfaceLatitude    11.301940      61903021
## County             11.843601     154121372
## Region              5.921244      43393867
## WellType            4.535864       6698470
## OriginalWellType    3.606344       3829328
## ObjectiveFormation 15.118945     395223282
## ProducingFormation 15.759310     429653726
## Slant               4.753870      12617413
## SpacingAcres        8.731309     135778912

8. GRÁFICAS DEL MODELO

8.1. Importancia de Variables

varImpPlot(
  modelo_rf,
  sort = TRUE,
  main = "Importancia de las Variables Predictoras"
)

8.2. Error del Modelo

plot(modelo_rf)

9. PREDICCIONES

Finalmente se realizaron las predicciones utilizando el conjunto de prueba con el fin de comparar los valores estimados por el modelo con los valores reales.

predicciones <- predict(
  modelo_rf,
  newdata = test
)

head(predicciones)
##        1        2        3        4        5        6 
## 3501.066 9380.539 9310.540 9808.960 3680.861 9722.810

10. EVALUACIÓN DEL MODELO

10.1. RMSE

RMSE(
  predicciones,
  test$TrueVerticalDepth
)
## [1] 552.6097
MAE(
  predicciones,
  test$TrueVerticalDepth
)
## [1] 332.5479
R2(
  predicciones,
  test$TrueVerticalDepth
)
## [1] 0.9689511

10.2. Comparación de Valores Reales y Predichos

comparacion <- data.frame(
  Real = test$TrueVerticalDepth,
  Predicho = predicciones
)

head(comparacion)
##    Real Predicho
## 1  1529 3501.066
## 2  9152 9380.539
## 3  9627 9310.540
## 4 10045 9808.960
## 5  2467 3680.861
## 6  9474 9722.810

10.3. Gráfico Final

ggplot(comparacion,
       aes(x = Real, y = Predicho)) +

  geom_point(
    color = "steelblue",
    size = 2,
    alpha = 0.7
  ) +

  geom_abline(
    intercept = 0,
    slope = 1,
    color = "red",
    linewidth = 1
  ) +

  labs(
    title = "Valores Reales vs Valores Predichos",
    x = "Profundidad Vertical Real (ft)",
    y = "Profundidad Vertical Predicha (ft)"
  ) +

  theme_minimal()