Skip to content

Выбор локации для скважины

Допустим, вы работаете в добывающей компании «ГлавРосГосНефть». Нужно решить, где бурить новую скважину.

Вам предоставлены пробы нефти в трёх регионах: в каждом 10 000 месторождений, где измерили качество нефти и объём её запасов. Постройте модель машинного обучения, которая поможет определить регион, где добыча принесёт наибольшую прибыль. Проанализируйте возможную прибыль и риски техникой Bootstrap.

Шаги для выбора локации:

  • В избранном регионе ищут месторождения, для каждого определяют значения признаков;
  • Строят модель и оценивают объём запасов;
  • Выбирают месторождения с самым высокими оценками значений. Количество месторождений зависит от бюджета компании и стоимости разработки одной скважины;
  • Прибыль равна суммарной прибыли отобранных месторождений.

Условия задачи:

  • Для обучения модели подходит только линейная регрессия (остальные — недостаточно предсказуемые).
  • При разведке региона исследуют 500 точек, из которых с помощью машинного обучения выбирают 200 лучших для разработки.
  • Бюджет на разработку скважин в регионе — 10 млрд рублей.
  • При нынешних ценах один баррель сырья приносит 450 рублей дохода. Доход с каждой единицы продукта составляет 450 тыс. рублей, поскольку объём указан в тысячах баррелей.
  • После оценки рисков нужно оставить лишь те регионы, в которых вероятность убытков меньше 2.5%. Среди них выбирают регион с наибольшей средней прибылью.

Описание данных:

  • id — уникальный идентификатор скважины;
  • f0, f1, f2 — три признака точек;
  • product — объём запасов в скважине (тыс. баррелей).

Загрузка и подготовка данных

pip install sweetviz
# импортируем библиотеки
import pandas as pd
import numpy as np
from matplotlib import pyplot as plt
from sklearn.model_selection import train_test_split
from sklearn.metrics import mean_squared_error
from sklearn.linear_model import LinearRegression, Ridge, Lasso
from sklearn.preprocessing import StandardScaler
from sklearn.utils import shuffle
from joblib import dump, load
import sweetviz as sv
# загрузим данные
geo_data_0 = pd.read_csv('datasets/geo_data_0.csv')
geo_data_1 = pd.read_csv('datasets/geo_data_1.csv')
geo_data_2 = pd.read_csv('datasets/geo_data_2.csv')

for data, name in zip([geo_data_0, geo_data_1, geo_data_2], 
                ["geo_data_0", "geo_data_1", "geo_data_2"]):
    print("Регион {}".format(name))
    display(data.head(3))
    print("Количество дубликатов {}, пропущенных значений {}"
         .format(data.duplicated().sum(), data.isna().sum().sum()))
  • Проведем исследовательский анализ данных с помощью пакета sweetviz.
report_0 = sv.analyze([geo_data_0[["f0", "f1", "f2", "product"]], "geo_data_0"], target_feat="product")
report_0.show_html("sweetviz/geo_data_0.html")
# report_0.show_notebook()
report_1 = sv.analyze([geo_data_1[["f0", "f1", "f2", "product"]], "geo_data_1"], target_feat="product")
report_1.show_html("sweetviz/geo_data_1.html")
# report_1.show_notebook()
report_2 = sv.analyze([geo_data_2[["f0", "f1", "f2", "product"]], "geo_data_2"], target_feat="product")
report_2.show_html("sweetviz/geo_data_2.html")
# report_2.show_notebook()

Исследуемые данные обладают следующими особенностями:

  • не наблюдается пропущенных значений, дубликатов и выбросов;
  • распределение целевого признака (запас сырья) в регионах 0 и 2 близко к нормальному, а в регионе 1 больше соответствует равномерному, но с увеличенным содержанием скважин с минимальным и максимальным запасом сырья;
  • в регионе 0 целевой признак коррелирует со всеми 3 признаками (f0, f1, f2) и имеет наибольшую корреляцию с f2;
  • в регионах 1 и 2 целевой признак коррелируе главным образов с признаком f2 и намного слабее с остальными, причем в регионе 1 данная корреляция является очень сильной, в в регионе 2 находится на среднем уровне.

Обучение и проверка модели

  • Разобъем данные для каждого региона на обущающую и валидационную выборку в соотношении 75/25.

Создадим функцию, которая разбивает данные на необходимые для анализа признаки, и целевой признак, после чего делит их на обучающую и валидационную выборку.

def data_split(geo_data, features_drop=["id", "product"], target="product",
                  test_size=.25, random_state=12345):
    """
    Функция принимает на вход датафрейм с геоданными.
    Делит его на признаки (f0, f1, f2) и целевой признак (product), 
    после этого разделяет на обучающую и валидационную выборки в соотношении 75/25.
    На выходе выдает словарь с признаками и целевым признаком получившихся выборок.
    """
    features = geo_data.drop(features_drop, axis=1)
    target = geo_data[target]
    
    features_train, features_valid, target_train, target_valid = \
                    train_test_split(features, target, test_size=test_size, random_state=random_state)
    
    return {"features_train": features_train, "target_train": target_train, 
            "features_valid": features_valid, "target_valid": target_valid}