ADCA tutorial
This tutorial assumes that you have installed ADCA and that your Python virtual environment is activated. See Installation for more information about how to install ADCA. Read The ADCA package before starting this tutorial, or alongside it.
Creating a demo dataset
If you want to run on a demo dataset instead of on real-world data, you can use the adca init command.
Assuming you have followed the installation instructions, open a terminal, activate the virtual environment, change directories to a suitable folder using the cd command, then run:
adca --help
To list all available sub-commands.
You’ll see that one of the sub-commands is init, so run the following in your terminal:
adca init
Two files will be created in your current working directory. If you open a file explorer you will see:
demo.csv: demo data with columnswell_id,time,productionandtime_on.demo.yaml: a file with a basic configuration setup for ADCA.
Have a look at both files if you like. They are text files and can be opened in Notepad on Windows. You might have to close them before running ADCA on them if you’re on Windows.
Note
If you want to run on real-world wells from PDM, change demo.yaml to:
source:
name: "PDM"
table: "PDMVW.WB_PROD_DAY"
phases: ["oil"]
frequency: "monthly"
period_range: [null, null]
wells:
"NO 16/X-X-XX":
"NO 16/X-X-YY":
Another option is to run on the public Volve data set:
source:
name: "volve"
phases: ["oil"]
frequency: "monthly"
wells:
"NO 15/9-F-11 H":
"NO 15/9-F-12 H":
"NO 15/9-F-14 H":
"NO 15/9-F-15 D":
If you run on real-world wells, your numbers might differ from mine for the rest of the tutorial. I recommend first running on the demo dataset before running on real-world wells.
A first run
To run ADCA on the recently created files above, execute the following command in the terminal:
adca run demo.yaml
Congratulations! You have just forecasted your first group of wells!
Note
Running on the demo dataset should take approximately one minute. Forecasting 200 real-world wells on monthly resolution will take around 12 minutes.
The result of the run are stored in the folder ./output/YYYY-MM-DD-HH-MM-demo-demo_wells/.
The folder is timestamped with the current time.
In the output folder you will find many files and figures:
forecast.csv: the actual forecasted values for every well - daily/monthly rates and cumulatives.curve_parameters.csv: the curve parameters that ADCA found.log.log: the terminal output, stored as a log file.Many
.pngfigures to help you assess the fit and forecasts.
Have a look at the outputs and familiarize yourself with them.
Especially the .png figures, since they are the most important part of assessing the models.
Customizing the configuration file
Because ADCA fits decline curves automatically, it removes a lot of subjective assessments.
Once you have a good setup you can re-run without much effort in the future.
Simply execute adca run demo.yaml a few months or years later.
That said, you will have to spend some time on the initial configuration.
There is no configuration that is universally the best for all forecasting scenarios, so the initial setup requires some work.
Note
Need help setting up a good configuration? If you still have questions after reading the documentation, do not hesitate to contact us!
The first step to building a good configuration is to decide on a few things in the configuration file
demo.yaml.The second step is to do a few trial runs and potentially change some hyper parameters.
Let us first look at the basic configuration that you should set up:
Pick a good descriptive name. The name in the demo file is
demo_wells.Choose the correct phase, e.g.
gasoroil. When reading local CSV files likedemo.csv, this choice does not matter because the columnproductionis read regardless of the phase specified in the config file.Choose the desired frequency. In general we recommend
monthly, butdailyis possible too.Choose the appropriate preprocessing option, either
producing_timeorcalendar_time.Set
forecast_periodsto an appropriate number, e.g.360for a 30-year forecast on monthly resolution.
For more information about the options available in the config file, see The ADCA package.
Note
You can reduce the number of output plots to speed up ADCA and avoid cluttering your folders.
You can also output more plots than the default if you want.
To control the number of plots generated, use the --plot-verbosity argument or its shorthand -pv.
The higher the number, the more plots will be produced.
For instance, to output all possible plots, run adca run demo.yaml --plot-verbosity 9.
To output no plots at all, run adca run demo.yaml --plot-verbosity 0.
For more information about optional arguments, run adca run --help.
Segmenting a well
Let us start by looking at the terminal outputs. You can skip most of the data processing output in the beginning. Go down to the section
{
"half_life": 6.261375778652348,
"prior_strength": 0.0011364636663857253
}
-------------------EVALUATE ON TEST SET WITH BEST HYPERPARAMETERS-------------------
Negative log-likelihood: -0.4391
RMSE in logspace: 0.2509
Relative error (expected): 5.63%
Relative error (P50): -15.90%
Here we observe that the expected case forecast, which corresponds to the column cumulative_production in forecast.csv, leads to a total error of 5.63 %.
In other words, ADCA over-forecasted slightly compared to what actually happened on the test set.
Have a look at the plot forecast_ramp_up_well_1.png in the output folder.
You’ll see that the decline curve does not achieve a great fit because the ramp-up period confuses the model.
You can also see this if you study table with individual errors in the ADCA terminal output.
The well ramp_up_well has a high RMSE, high relative error, etc:
| well_id | RMSE in logspace | Rel. error (expected) | Rel. error (P50) |
|:--------------------|-------------------:|:------------------------|:-------------------|
| constant_well | 0.2191 | -1.53% | -13.98% |
| little_data_well | 0.1787 | 9.80% | -14.62% |
| plateu_well | 0.2606 | 9.69% | -2.80% |
| long_declining_well | 0.1079 | -7.68% | -18.26% |
| noisy_well | 0.264 | 18.93% | -17.04% |
| ramp_up_well | 0.463 | 36.91% | -37.35% |
| arps_well | 0.1607 | -8.89% | -18.68% |
Let us segment the problematic well by changing the demo.yaml file to:
"ramp_up_well":
- ["2010-09", null]
After making this change, you can re-run adca run demo.yaml.
If you re-run without any other changes, you’ll see that the output changes to:
Best hyperparams:
{
"half_life": 6.261375778652348,
"prior_strength": 0.0011364636663857253
}
-------------------EVALUATE ON TEST SET WITH BEST HYPERPARAMETERS-------------------
Negative log-likelihood: -0.4576
RMSE in logspace: 0.1888
Relative error (expected): 2.88%
Relative error (P50): -14.15%
The overall test-set error went down from 5.63% to 2.88% when we segmented the well.
If you examine the plot forecast_ramp_up_well_1.png in the output folder for this new run, you’ll see that the problematic ramp-up phase has been filtered out.
Hyperparameters
ADCA has a few hyperparameters. These can either be set as fixed values, or as brackets, in which case ADCA will search for the optimal parameters within the range. The optimal hyperparameters are those that lead to the best out-of-sample predictions on the test set.
In our runs so far, the hyperparameter ranges in demo.yaml were given as:
# Hyperparameters given as numbers are fixed, and those given as
# a range [low, high] are tuned out-of-sample on test data using the split
hyperparameters:
half_life : [6, 60]
prior_strength : [0.001, 1]
The chosen hyperparameters were:
Best hyperparams:
{
"half_life": 6.261375778652348,
"prior_strength": 0.0011364636663857253
}
Both parameters are in the lower end of their ranges: 6.2613 is near the bottom of [6, 60] and 0.0011 is near the bottom of [0.001, 1].
This suggests that we should broaden the search range in the lower end.
Let us try with:
hyperparameters:
half_life : [1, 60]
prior_strength : [0.0000001, 0.1]
Making this change, saving demo.yaml and re-running adca produces:
Best hyperparams:
{
"half_life": 4.223240466094437,
"prior_strength": 1.2915496650148853e-07
}
-------------------EVALUATE ON TEST SET WITH BEST HYPERPARAMETERS-------------------
Negative log-likelihood: -0.4874
RMSE in logspace: 0.1756
Relative error (expected): 1.79%
Relative error (P50): -14.30%
We got the error down to 1.79%.
The optimal half-life was found to be half_life=4.22324..., which means that the most recent month of production data has a relative weighting of 1, the month before it 2^(-1 / 4.22) = 0.84, the month before that 2^(-2 / 4.22) = 0.72, and so on.
Some subjective assessment of hyperparameters can be appropriate, especially when there are few wells in the well group. With little data, like in this demo example, there is good reason to use some engineering judgement and override the hyperparameters. A half life of 4 months is quite short after all.
Manually setting hyperparameters to:
hyperparameters:
half_life : 8
prior_strength : 0.000001 # 1e-06
Will make ADCA run much faster since it does not have to search for hyperparameters. The test-set error does go up a little bit, but a half-life of 8 instead of 4 might be more appropriate.
Note
You can increase or decrease the number of hyperparameter combinations used in search.
Use the --hyperparam-maxfun argument or its shorthand -hm.
For instance, adca run demo.yaml --hyperparam-maxfun 10.
Exercises
Here are some exercises that are highly recommended to get some hands-on experience.
Train/test split. Set
splitto0.5instead of0.8indemo.yamland examine the output figures. You should see that the split is made at 50%, so the first half of the data is in the training data set and the remaining half is in the test data set. Then try settingsplitto-1. You should see that only the last data point is in the test data set. The train/test split should mimic your forecasting scenario - if your goal is to forecast short term, then the test set should be relatively small, and vice versa.Hyperparameter experimentation. Manually set
half_life=1and run ADCA. Look at the output figures. You should see that the curve model becomes very dependent on the last few data points. You can also setprior_strength=1000and see that every well has the same prediction, which is close to the grand mean of every well.Preprocessing options. Read the description of
preprocessingin The ADCA package. Then updatedemo.csvwith a dataset that hastime_on=0.5:
well_id,time,production,time_on arps_well,2010-01,100,0.5 arps_well,2010-02,100,0.5 arps_well,2010-03,100,0.5 arps_well,2010-04,100,0.5 arps_well,2010-05,100,0.5 arps_well,2010-06,100,0.5 arps_well,2010-07,100,0.5 arps_well,2010-08,100,0.5and run it with the preprocessing option
producing_time. Remember to remove all wells exceptarps_wellfromdemo.yaml. You should see that predictions inforecast.csvare close to200for every future period. Then run it with preprocessing optioncalendar_time. Now you should see that predictions are close to100for every future period.