Workflow Objective

Create a prioritized list of High-Performer wells that may require re-frack or re-stimulation jobs.


I am using a Neural Network known as kohonen maps or self-organizing maps that project a multidimensional space into a 2-d space.

The Self-Organizing Maps (SOM) model is a special class of Artificial Neural Networks, which are based on competitive learning.

A self-organizing map is therefore characterized by the formation of a topographic map of the input patterns, in which the spatial locations (i.e., coordinates) of the neurons in the lattice are indicative of intrinsic statistical features contained in the input patterns—hence, the name “self-organizing map.”


The self-organizing map is inherently nonlinear.

**Note: This is a work in progress.

Working directory and Libraries to load

#setwd("C:/Users/drome/Dropbox/Machine Learning - Azure/EF_ORCL")
library(readxl)
library(tidyverse)
library(stringr)
library(forecast) # Moving Average
library(imputeTS) # Time Series Missing Value Imputation
library(kohonen)
library(RcppRoll)

Reading Data FIle

# Read Well Header info
dheader <- read_excel("DATA_FINAL_SHORT_.xlsx", na = c("0"))
names(dheader) <- sub(" ", "", names(dheader))
head(dheader)
## # A tibble: 6 × 7
##               uwi tdepth_000 tvd_000 latrllen_000 prop_conc_000 xcoord
##             <chr>      <dbl>   <dbl>        <dbl>         <dbl>  <dbl>
## 1 M42311346980000     17.970  12.698        5.137         44.17 -98.59
## 2 M42311345500000     17.622  12.394        2.576         42.62 -98.57
## 3 M42311342460000     18.446  12.790        5.553         54.15 -98.55
## 4 M42311348950000     18.497  12.823        5.662         43.22 -98.53
## 5 M42311341370000     15.975  11.972        3.809         47.55 -98.62
## 6 M42311350270000     18.278  11.988        5.807         44.19 -98.61
## # ... with 1 more variables: ycoord <dbl>
# Read Production data
dprod <- read_excel("DPROD.xlsx", col_types = c("text", "text", "numeric", "numeric"), na = c("0"))
dprod$d_date <- as.Date(dprod$d_date, format = "%Y%m%d")
names(dprod) <- c("uwi", "d_date", "oil", "gas")

Data Transformation - Input to SOM Model

# Well (rows) with oil & gas null production
head(dprod[is.na(dprod$oil) & is.na(dprod$gas),], 20)

# Eliminate Well (rows) with oil & gas null production
dprod <- dprod[!(is.na(dprod$oil) & is.na(dprod$gas)),]

# Merge Header and Dprod
dt <- left_join(dheader, dprod, by = "uwi")

dt <- dt %>% group_by(uwi) %>% mutate(cumoil = cumsum(ifelse(is.na(oil), 0, oil)), 
                                      cumgas = cumsum(ifelse(is.na(gas), 0, gas)))

dt <- dt %>% group_by(uwi) %>% mutate(nobs = n())

dt <- dt %>% filter(nobs > 120)

dt$b30 <- ma(dt$oil, order = 30, centre = TRUE)

Exploratory Plots

Setup SOM (Kohonen) Model


For a detailed discussion of results please contact me at dromero@cpq-energy.com