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(dplyr)
library(ggplot2)
library(scatterplot3d)
library(plotly)
datos <- read.csv(
"Petroleo_Ontaro.csv",
header = TRUE,
sep = ";",
stringsAsFactors = FALSE
)
# Conversión a numéricas
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 datos válidos
datos_filtrados <- subset(datos,
!is.na(TOTAL_DEPTH) &
!is.na(GROUND_ELEVATION) &
!is.na(TRUE_VERTICAL_DEPTH))
# Eliminar outliers usando IQR
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
)
cat("Variable dependiente (y): TOTAL_DEPTH\n")
## Variable dependiente (y): TOTAL_DEPTH
cat("Variables independientes (x1, x2): GROUND_ELEVATION, TRUE_VERTICAL_DEPTH\n")
## Variables independientes (x1, x2): GROUND_ELEVATION, TRUE_VERTICAL_DEPTH
Se plantea que la profundidad total del pozo depende linealmente de la elevación del terreno y de la profundidad vertical verdadera. Matemáticamente, la relación se expresa como:
\[ \text{TOTAL_DEPTH} = \beta_0 + \beta_1 \cdot \text{GROUND_ELEVATION} + \beta_2 \cdot \text{TRUE_VERTICAL_DEPTH} + \epsilon \]
donde:
modelo_multi <- lm(y ~ x1 + x2, data = df_reg)
coeficientes <- coef(modelo_multi)
cat("Parámetros estimados:\n")
## Parámetros estimados:
cat("β0 (Intercepto) =", round(coeficientes[1],2), "\n")
## β0 (Intercepto) = 1.88
cat("β1 (x1) =", round(coeficientes[2],2), "\n")
## β1 (x1) = -0.01
cat("β2 (x2) =", round(coeficientes[3],2), "\n")
## β2 (x2) = 1
r2 <- summary(modelo_multi)$r.squared
r2_ajustado <- summary(modelo_multi)$adj.r.squared
cat("R²:", round(r2,4), "\n")
## R²: 0.9975
cat("R² ajustado:", round(r2_ajustado,4), "\n")
## R² ajustado: 0.9975
# Punto a proyectar
scatter3d <- scatterplot3d(df_reg$x1, df_reg$x2, df_reg$y,
pch = 16, color = "steelblue",
xlab = "Elevación del terreno (m)",
ylab = "Profundidad Vertical Verdadera (m)",
zlab = "Profundidad Total (m)",
main = "Modelo de Regresión Múltiple 3D",
angle = 135)
# 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_seq, x2_seq)
colnames(grid) <- c("x1", "x2")
grid$y_pred <- predict(modelo_multi, newdata = grid)
coords <- scatter3d$xyz.convert(grid$x1, grid$x2, grid$y_pred)
# Dibujar 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", lwd = 2)
}
for (j in 1:20) {
lines(coords$x[seq(j, nrow(grid), by = 20)], coords$y[seq(j, nrow(grid), by = 20)], col = "red", lwd = 2)
}
plot_ly() %>%
add_markers(
data = df_reg,
x = ~x1,
y = ~x2,
z = ~y,
marker = list(color = "steelblue", size = 3),
name = "Datos reales"
) %>%
add_surface(
x = matrix(grid$x1, nrow = 20, ncol = 20),
y = matrix(grid$x2, nrow = 20, ncol = 20),
z = matrix(grid$y_pred, nrow = 20, ncol = 20),
opacity = 0.6,
colorscale = "Reds",
name = "Plano de regresión"
) %>%
layout(
title = "Modelo de Regresión Múltiple 3D - Plotly",
scene = list(
xaxis = list(title = "Elevación del terreno (m)"),
yaxis = list(title = "Profundidad Vertical Verdadera (m)"),
zaxis = list(title = "Profundidad Total (m)")
)
)
nueva_obs <- data.frame(x1 = 200, x2 = 250)
y_predicha <- predict(modelo_multi, newdata = nueva_obs)
cat("Profundidad estimada (TOTAL_DEPTH) para Elevación=200 y Vertical=250:", round(y_predicha,2), "m\n")
## Profundidad estimada (TOTAL_DEPTH) para Elevación=200 y Vertical=250: 250.2 m
En el análisis de pozos petroleros se aplicó un modelo de regresión lineal múltiple, utilizando como variables explicativas la Elevación del Terreno y la Profundidad Vertical Verdadera (TVD), y como variable respuesta la Profundidad Total. El modelo se describe mediante la ecuación TOTAL_DEPTH=β0+β1⋅GROUND_ELEVATION+β2⋅TRUE_VERTICAL_DETH⋅e y nos presenta un coeficiente de determinación R2= 0.9975, lo que indica que el 99.75 % de la variabilidad de la Profundidad Total es explicada por las variables incluidas, evidenciando un ajuste extremadamente alto y una fuerte relación entre las variables. Para una Elevación de 200 m y una TVD de 250 m, el modelo estima una Profundidad Total aproximada de 250.2 m.