Modelo de Probabilidad Geométrico para la Clasificación Operativa de los Pozos Petrolíferos en Brasil
El presente estudio aplica un modelo de probabilidad geométrico para caracterizar la clasificación operativa de los pozos petrolíferos en Brasil, con base en datos oficiales de la ANP. A partir de las frecuencias observadas, se estima el parámetro del modelo, se evalúa su bondad de ajuste mediante los tests de Pearson y Chi-Cuadrado, y se calculan probabilidades de ocurrencia para cada tipo de pozo registrado.
Se importa el conjunto de datos de pozos petroleros de Brasil y se verifica su estructura, tipos de variables y codificación.
Se extrae la variable de clasificación operativa y se contabiliza la frecuencia absoluta de cada categoría registrada.
library(dplyr)
TDFTipoPozo$Grupo <- case_when(
TDFTipoPozo$TipoPozo %in% c(
"PRODUTOR COMERCIAL DE GÁS NATURAL", "PRODUTOR COMERCIAL DE GÁS NATURAL E CONDENSADO",
"PRODUTOR COMERCIAL DE PETRÓLEO", "PRODUTOR COMERCIAL DE PETRÓLEO E GÁS NATURAL",
"PRODUTOR COMERCIAL DE PETRÓLEO, GÁS NATURAL E CONDENSADO",
"PRODUTOR SUBCOMERCIAL DE GÁS NATURAL", "PRODUTOR SUBCOMERCIAL DE GÁS NATURAL E CONDENSADO",
"PRODUTOR SUBCOMERCIAL DE PETRÓLEO", "PRODUTOR SUBCOMERCIAL DE PETRÓLEO E GÁS NATURAL",
"PRODUTOR SUBCOMERCIAL DE PETRÓLEO, GÁS NATURAL E CONDENSADO",
"DESCOBRIDOR DE CAMPO COM GÁS NATURAL", "DESCOBRIDOR DE CAMPO COM GÁS NATURAL E CONDENSADO",
"DESCOBRIDOR DE CAMPO COM PETRÓLEO", "DESCOBRIDOR DE CAMPO COM PETRÓLEO E GÁS NATURAL",
"DESCOBRIDOR DE CAMPO COM PETRÓLEO, GÁS NATURAL E CONDENSADO",
"DESCOBRIDOR DE NOVA JAZIDA GÁS NATURAL", "DESCOBRIDOR DE NOVA JAZIDA GÁS NATURAL E CONDENSADO",
"DESCOBRIDOR DE NOVA JAZIDA PETRÓLEO", "DESCOBRIDOR DE NOVA JAZIDA PETRÓLEO E GÁS NATURAL",
"DESCOBRIDOR DE NOVA JAZIDA PETRÓLEO, GÁS NATURAL E CONDENSADO",
"EXTENSÃO PARA GÁS NATURAL", "EXTENSÃO PARA GÁS NATURAL E CONDENSADO",
"EXTENSÃO PARA PETRÓLEO", "EXTENSÃO PARA PETRÓLEO E GÁS NATURAL",
"EXTENSÃO PARA PETRÓLEO, GÁS NATURAL E CONDENSADO",
"PORTADOR DE GÁS NATURAL", "PORTADOR DE GÁS NATURAL E CONDENSADO",
"PORTADOR DE PETRÓLEO", "PORTADOR DE PETRÓLEO E GÁS NATURAL",
"PORTADOR DE PETRÓLEO, GÁS NATURAL E CONDENSADO"
) ~ "Pozos productivos",
TDFTipoPozo$TipoPozo %in% c(
"INJEÇÃO DE ÁGUA", "INJEÇÃO DE ÁGUA ADITIVADA", "INJEÇÃO DE CO2",
"INJEÇÃO DE GÁS NATURAL", "INJEÇÃO DE QUALQUER OUTRO FLUIDO", "INJEÇÃO DE VAPOR"
) ~ "Inyección/Soporte",
TDFTipoPozo$TipoPozo %in% c(
"SECO COM INDÍCIOS DE GÁS NATURAL E CONDENSADO", "SECO COM INDÍCIOS DE PETRÓLEO",
"SECO COM INDÍCIOS DE PETRÓLEO E GÁS NATURAL", "SECO COM INDÍCIOS GÁS NATURAL",
"SECO SEM INDÍCIOS"
) ~ "Pozos secos",
.default = "Pozos abandonados"
)
# Factor ordenado (del más favorable al menos)
niveles_ordinales <- c("Pozos productivos", "Inyección/Soporte",
"Pozos secos", "Pozos abandonados")
TDFTipoPozo$Grupo <- factor(TDFTipoPozo$Grupo,
levels = niveles_ordinales, ordered = TRUE)
TDFTipoPozo <- TDFTipoPozo[order(TDFTipoPozo$Grupo), ]Se calculan las frecuencias absolutas (ni) y relativas porcentuales (hi) por grupo operacional.
TDFTipoPozo$Freq <- as.numeric(as.character(TDFTipoPozo$Freq))
library(dplyr)
TDFReclasificación1 <- Datos$TDFTipoPozo
TDFReclasificación1 <- TDFTipoPozo %>%
group_by(Grupo) %>%
summarise(
ni = sum(Freq),
hi = round(sum(Freq) / sum(TDFTipoPozo$Freq)*100, 5))
TDFReclasificación1 <- data.frame(TDFReclasificación1)Se integran las frecuencias en una tabla con totales para verificar la coherencia del conjunto de datos.
TDFReclasificación1$fi <- TDFReclasificación1$ni / sum(TDFReclasificación1$ni)
TDFReclasificación1 <- TDFReclasificación1 [, c("Grupo", "ni", "hi", "fi")]
total_ni <- sum(TDFReclasificación1$ni)
total_hi <- sum(TDFReclasificación1$hi)
total_fi <- sum(TDFReclasificación1$fi)
TDFReclasificación1.1 <- rbind(TDFReclasificación1, data.frame( Grupo = "Total",
ni = total_ni,
hi = total_hi,
fi = total_fi))
print(TDFReclasificación1.1)## Grupo ni hi fi
## 1 Pozos productivos 18803 63.57735 0.63577346
## 2 Inyección/Soporte 1447 4.89265 0.04892646
## 3 Pozos secos 4816 16.28402 0.16284024
## 4 Pozos abandonados 4509 15.24598 0.15245985
## 5 Total 29575 100.00000 1.00000000
La tabla se formatea con gt para su presentación en el informe final.
library(gt)
gt(TDFReclasificación1.1) %>%
tab_header(
title = md("**Tabla N°1: DISTRIBUCIÓN DE FRECUENCIAS DE POZOS PETROLEROS DE BRASIL**"),
subtitle = "Frecuencias observadas para la estimación del modelo geométrico") %>%
tab_spanner(
label = md("**Frecuencia Relativa**"),
columns = c(hi, fi)
) %>%
cols_label(
ni = md("**ni**"),
hi = md("Porcentual (%)"),
fi = md("Fracción")
) %>%
fmt_number(columns = hi, decimals = 2) %>%
fmt_number(columns = fi, decimals = 4) %>%
cols_align(align = "center", columns = everything()) %>%
tab_style(
style = list(cell_fill(color = "#2E4053"),
cell_text(color = "white", weight = "bold")),
locations = cells_title()
) %>%
tab_style(
style = list(cell_fill(color = "#F2F3F4"),
cell_text(weight = "bold", color = "#2E4053")),
locations = cells_column_labels()
) %>%
tab_style(
style = list(cell_fill(color = "#2E4053"),
cell_text(color = "white", weight = "bold")),
locations = cells_column_spanners()
) %>%
tab_style(
style = list(cell_fill(color = "#D5D8DC"),
cell_text(weight = "bold", color = "#2E4053")),
locations = cells_body(rows = nrow(TDFReclasificación1.1))
) %>%
tab_options(
table.border.top.color = "#2E4053",
table.border.bottom.color = "#2E4053",
column_labels.border.bottom.color = "#2E4053",
data_row.padding = px(6),
table.font.size = px(13)
)| Tabla N°1: DISTRIBUCIÓN DE FRECUENCIAS DE POZOS PETROLEROS DE BRASIL | |||
| Frecuencias observadas para la estimación del modelo geométrico | |||
| Grupo | ni |
Frecuencia Relativa
|
|
|---|---|---|---|
| Porcentual (%) | Fracción | ||
| Pozos productivos | 18803 | 63.58 | 0.6358 |
| Inyección/Soporte | 1447 | 4.89 | 0.0489 |
| Pozos secos | 4816 | 16.28 | 0.1628 |
| Pozos abandonados | 4509 | 15.25 | 0.1525 |
| Total | 29575 | 100.00 | 1.0000 |
Muestran la cantidad de pozos por grupo con escala ajustada.
TDFReclasificación2 <- TDFReclasificación1.1[TDFReclasificación1.1$Grupo != "Total", ]
par(mar = c(9, 4, 4, 2))
bp <- barplot(TDFReclasificación2$ni,
main = "Gráfica N°1: Frecuencia Observada por Tipo de Pozo",
ylab = "Cantidad",
col = "#2E4053",
xaxt = "n",
cex.axis = 0.8, cex.main = 0.9)
text(x = bp, y = -3,
labels = TDFReclasificación2$Grupo,
srt = 45, adj = 1.2, xpd = TRUE, cex = 0.8)
mtext("Reclasificación", side = 1, line = 6, adj = 0.8)Se estima un modelo geométrico para representar el comportamiento probabilístico de la clasificación operativa de los pozos.
TDFTipoPozo2 <- TDFReclasificación1
TDFTipoPozo2$ni <- as.numeric(TDFTipoPozo2$ni)
TDFTipoPozo2$hi <- as.numeric(TDFTipoPozo2$hi)
TDFTipoPozo2 <- TDFTipoPozo2 %>%
arrange(desc(ni))
TDFTipoPozo2$ID <- 1:nrow(TDFTipoPozo2)
# Estimación del parámetro p por método de momentos
media_observada <- sum(TDFTipoPozo2$ID * TDFTipoPozo2$ni) / sum(TDFTipoPozo2$ni)
p_estimado <- 1 / media_observada
# Probabilidades del modelo geométrico
prob_geom <- p_estimado * (1 - p_estimado)^(TDFTipoPozo2$ID - 1)
prob_geom <- prob_geom / sum(prob_geom)
TDFTipoPozo2$hi_modelo <- prob_geom * 100
# Gráfico comparativo
library(tidyr)
library(ggplot2)
df_comp <- pivot_longer(TDFTipoPozo2, cols = c("hi", "hi_modelo"),
names_to = "Origen", values_to = "Valor")
df_comp$Origen <- ifelse(df_comp$Origen == "hi", "Realidad", "Modelo")
ggplot(df_comp, aes(x = Grupo, y = Valor, fill = Origen)) +
geom_bar(stat = "identity", position = "dodge", color = "black") +
scale_fill_manual(values = c("Modelo" = "skyblue", "Realidad" = "#2E4053")) +
theme_minimal() +
theme(axis.text.x = element_text(angle = 45, hjust = 1)) +
labs(
title = "Gráfica N°2: Modelo de Probabilidad Geométrico - Tipo de Pozo",
subtitle = paste("p estimado =", round(p_estimado, 4)),
x = "Tipo de Pozo", y = "Probabilidad (%)", fill = "Origen"
)Se evalúa la correlación entre las frecuencias observadas y las estimadas por el modelo geométrico.
Fo <- TDFTipoPozo2$hi
Fe <- TDFTipoPozo2$hi_modelo
plot(Fo, Fe,
main = "Gráfica N°3: Correlación Observado vs Esperado\nTipo de Pozo Petrolífero",
cex.main = 0.78,
xlab = "Frecuencia Observada (hi)",
ylab = "Frecuencia Esperada (hi modelo)",
pch = 19, col = "#2E4053")
abline(lm(Fe ~ 0 + Fo), col = "red", lwd = 2)Correlacion_Geo <- cor(Fo, Fe) * 100
cat("Correlación de Pearson:", round(Correlacion_Geo, 2), "%\n")## Correlación de Pearson: 97.68 %
Se verifica la bondad de ajuste del modelo mediante la comparación entre valores observados y esperados.
## Chi-Cuadrado: 7.1242
## Valor Crítico: 9.2103
## ¿Modelo aceptado?: TRUE
Se presentan los indicadores estadísticos utilizados para validar el ajuste del modelo geométrico.
tabla_resumen_S <- data.frame(
Variable = "Tipo de Pozo (Reclasificación)",
Pearson = round(Correlacion_Geo, 2),
Chi2 = round(x2, 2),
Umbral = round(vc, 2),
Resultado = x2 < vc
)
tabla_resumen_S %>%
gt() %>%
cols_label(
Variable = "Variable",
Pearson = "Test Pearson (%)",
Chi2 = "Chi Cuadrado",
Umbral = "Umbral de Aceptación",
Resultado = "Resultado"
) %>%
tab_header(
title = md("**Tabla N°2: Bondad de Ajuste del Modelo Geométrico**")
) %>%
tab_source_note(source_note = "Autor: Anahi Macias") %>%
cols_align(align = "center", columns = everything()) %>%
tab_style(
style = list(cell_fill(color = "#2E4053"), cell_text(color = "white", weight = "bold")),
locations = cells_title()
) %>%
tab_style(
style = list(cell_fill(color = "#F2F3F4"), cell_text(weight = "bold", color = "#2E4053")),
locations = cells_column_labels()
) %>%
tab_options(
table.border.top.color = "#2E4053",
table.border.bottom.color = "#2E4053",
column_labels.border.bottom.color = "#2E4053",
data_row.padding = px(6)
)| Tabla N°2: Bondad de Ajuste del Modelo Geométrico | ||||
| Variable | Test Pearson (%) | Chi Cuadrado | Umbral de Aceptación | Resultado |
|---|---|---|---|---|
| Tipo de Pozo (Reclasificación) | 97.68 | 7.12 | 9.21 | TRUE |
| Autor: Anahi Macias | ||||
Se determinan probabilidades asociadas a la ocurrencia de cada tipo de pozo petrolero.
¿Cuál es la probabilidad de que un pozo seleccionado al azar sea productivo? ¿Y de que sea abandonado?
prob_tabla <- TDFReclasificación1
prob_tabla$P <- prob_tabla$ni / sum(prob_tabla$ni)
print(prob_tabla[, c("Grupo", "ni", "P")])## Grupo ni P
## 1 Pozos productivos 18803 0.63577346
## 2 Inyección/Soporte 1447 0.04892646
## 3 Pozos secos 4816 0.16284024
## 4 Pozos abandonados 4509 0.15245985
P_productivo <- prob_tabla$P[prob_tabla$Grupo == "Pozos productivos"]
cat("P(pozo productivo) =", round(P_productivo, 4), "\n")## P(pozo productivo) = 0.6358
P_abandonado <- prob_tabla$P[prob_tabla$Grupo == "Pozos abandonados"]
cat("P(pozo abandonado) =", round(P_abandonado, 4), "\n")## P(pozo abandonado) = 0.1525
## P(no productivo) = 0.3642
Los resultados muestran que la mayor probabilidad corresponde a los pozos productivos, lo que evidencia un predominio de operaciones económicamente activas dentro del conjunto analizado. En contraste, la probabilidad de encontrar pozos abandonados es considerablemente menor, indicando una menor presencia de instalaciones fuera de operación permanente.
¿Cuántos pozos productivos se esperan en una muestra de 200 pozos?
n <- 200
p <- prob_tabla$P[prob_tabla$Grupo == "Pozos productivos"]
E_x <- n * p
SD_x <- sqrt(n * p * (1 - p))
cat("Esperanza E(X) =", round(E_x, 2), "pozos productivos\n")## Esperanza E(X) = 127.15 pozos productivos
## Desv. estándar = 6.81
Con base en la probabilidad estimada, se espera que aproximadamente 127 pozos de una muestra de 200 sean productivos. Este resultado refleja una alta proporción de pozos operativos y confirma la tendencia observada en la distribución original de los datos.