Este documento presenta un modelo de regresión múltiple en tres dimensiones para el análisis de pozos petroleros en Ontario. El objetivo es predecir la Profundidad Total basándose en la elevación del terreno y la profundidad vertical verdadera.
library(scatterplot3d)
library(plotly)
# Carga de datos
# Asegúrate de que el archivo .csv esté en la misma carpeta que este archivo .Rmd
datos <- read.csv("Petroleo_Ontaro.csv",
header = TRUE, sep = ";", dec = ".", fill = TRUE)
# Conversión y limpieza de formatos numéricos
datos$TOTAL_DEPTH <- as.numeric(gsub(",", ".", as.character(datos$TOTAL_DEPTH)))
datos$GROUND_ELEVATION <- as.numeric(gsub(",", ".", as.character(datos$GROUND_ELEVATION)))
datos$TRUE_VERTICAL_DEPTH <- as.numeric(gsub(",", ".", as.character(datos$TRUE_VERTICAL_DEPTH)))
# Filtrado de valores nulos (NA)
datos_filtrados <- subset(datos,
!is.na(TOTAL_DEPTH) &
!is.na(GROUND_ELEVATION) &
!is.na(TRUE_VERTICAL_DEPTH))Se aplica el criterio del Rango Intercuartílico (IQR) para asegurar la robustez del modelo eliminando valores atípicos.
eliminar_outliers <- function(x) {
Q1 <- quantile(x, 0.25, na.rm = TRUE)
Q3 <- quantile(x, 0.75, na.rm = TRUE)
IQR <- Q3 - Q1
(x >= (Q1 - 1.5 * IQR)) & (x <= (Q3 + 1.5 * IQR))
}
sin_outliers <- eliminar_outliers(datos_filtrados$TOTAL_DEPTH) &
eliminar_outliers(datos_filtrados$GROUND_ELEVATION) &
eliminar_outliers(datos_filtrados$TRUE_VERTICAL_DEPTH)
datos_limpios <- datos_filtrados[sin_outliers, ]
df_reg <- data.frame(
y = datos_limpios$TOTAL_DEPTH,
x1 = datos_limpios$GROUND_ELEVATION,
x2 = datos_limpios$TRUE_VERTICAL_DEPTH
)Se genera el modelo lineal múltiple.
##
## Call:
## lm(formula = y ~ x1 + x2, data = df_reg)
##
## Residuals:
## Min 1Q Median 3Q Max
## -64.42 -0.50 -0.30 -0.10 534.81
##
## Coefficients:
## Estimate Std. Error t value Pr(>|t|)
## (Intercept) 1.8841424 0.7580924 2.485 0.01295 *
## x1 -0.0097176 0.0037178 -2.614 0.00896 **
## x2 1.0010477 0.0003471 2883.831 < 2e-16 ***
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
##
## Residual standard error: 9.636 on 21225 degrees of freedom
## Multiple R-squared: 0.9975, Adjusted R-squared: 0.9975
## F-statistic: 4.228e+06 on 2 and 21225 DF, p-value: < 2.2e-16
par(mar = c(4,4,2,1))
scatter3d <- scatterplot3d(
df_reg$x1, df_reg$x2, df_reg$y,
pch = 16, color = alpha("steelblue", 0.6),
xlab = "Elevación del terreno (m)",
ylab = "Profundidad Vertical (TVD) (m)",
zlab = "Profundidad Total (m)",
main = "Plano de Regresión Ajustado",
angle = 55
)
# Plano de regresión
x1_seq <- seq(min(df_reg$x1), max(df_reg$x1), length.out = 20)
x2_seq <- seq(min(df_reg$x2), max(df_reg$x2), length.out = 20)
grid <- expand.grid(x1 = x1_seq, x2 = x2_seq)
grid$y_pred <- predict(modelo_multi, newdata = grid)
coords <- scatter3d$xyz.convert(grid$x1, grid$x2, grid$y_pred)
# Líneas del plano
for (i in seq(1, nrow(grid), by = 20)) lines(coords$x[i:(i+19)], coords$y[i:(i+19)], col = "red")
for (j in 1:20) lines(coords$x[seq(j, nrow(grid), by = 20)], coords$y[seq(j, nrow(grid), by = 20)], col = "red")plot_ly() %>%
add_markers(data = df_reg, x = ~x1, y = ~x2, z = ~y,
marker = list(size = 3, color = 'steelblue'), name = "Datos Reales") %>%
add_surface(x = matrix(grid$x1, 20, 20), y = matrix(grid$x2, 20, 20),
z = matrix(grid$y_pred, 20, 20), opacity = 0.5, name = "Modelo", showscale = FALSE) %>%
layout(scene = list(xaxis = list(title = "Elevación"),
yaxis = list(title = "TVD"),
zaxis = list(title = "Prof. Total")))Realizamos el cálculo de la predicción para los valores solicitados (Elevación: 200m, TVD: 250m).
# Definir nuevos valores
nueva_obs <- data.frame(x1 = 200, x2 = 250)
# Calcular predicción
prediccion_fit <- predict(modelo_multi, newdata = nueva_obs)
valor_estimado <- round(prediccion_fit, 2)Resultado del cálculo: 250.2 metros.
La regresión múltiple muestra que tanto la elevación del terreno como la profundidad vertical influyen significativamente en la profundidad total. El modelo presenta un excelente ajuste (\(R^2 =\) 0.9975) y permite estimar con alta precisión la profundidad total a partir de estas variables.
Por ejemplo, al aplicar el modelo a un escenario con una elevación de 200 m y una profundidad vertical de 250 m, obtenemos una estimación de 250.2 metros para la profundidad total. Esto confirma la capacidad predictiva del modelo para la planificación de perforaciones.