Microsegment.ru
  • Главная страница
  • О проекте
  • Портфолио
  • Блог

Регрессионный анализ и бутстреп для выбора района нефтедобычи

Описание проекта

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

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

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

Инструкция по выполнению проекта

  1. Загрузите и подготовьте данные. Поясните порядок действий.
  2. Обучите и проверьте модель для каждого региона:
    1. Разбейте данные на обучающую и валидационную выборки в соотношении 75:25.
    2. Обучите модель и сделайте предсказания на валидационной выборке.
    3. Сохраните предсказания и правильные ответы на валидационной выборке.
    4. Напечатайте на экране средний запас предсказанного сырья и RMSE модели.
    5. Проанализируйте результаты.
  3. Подготовьтесь к расчёту прибыли:
    1. Все ключевые значения для расчётов сохраните в отдельных переменных.
    2. Рассчитайте достаточный объём сырья для безубыточной разработки новой скважины. Сравните полученный объём сырья со средним запасом в каждом регионе.
    3. Напишите выводы по этапу подготовки расчёта прибыли.
  4. Напишите функцию для расчёта прибыли по выбранным скважинам и предсказаниям модели:
    1. Выберите скважины с максимальными значениями предсказаний.
    2. Просуммируйте целевое значение объёма сырья, соответствующее этим предсказаниям.
    3. Рассчитайте прибыль для полученного объёма сырья.
  5. Посчитайте риски и прибыль для каждого региона:
    1. Примените технику Bootstrap с 1000 выборок, чтобы найти распределение прибыли.
    2. Найдите среднюю прибыль, 95%-й доверительный интервал и риск убытков. Убыток — это отрицательная прибыль.
    3. Напишите выводы: предложите регион для разработки скважин и обоснуйте выбор.

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

Данные геологоразведки трёх регионов находятся в файлах:

  • /datasets/geo_data_0.csv.
  • /datasets/geo_data_1.csv.
  • /datasets/geo_data_2.csv.

Атрибуты:

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

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

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

Данные синтетические: детали контрактов и характеристики месторождений не разглашаются.

Оглавление

  • 1  Загрузка и подготовка данных
    • 1.1  Подготовка тетради и загрузка данных
    • 1.2  Анализ данных датафрейма первого региона
    • 1.3  Анализ данных датафрейма второго региона
    • 1.4  Анализ данных датафрейма третьего региона
    • 1.5  Выводы из анализа данных датафреймов всех регионов
  • 2  Обучение и проверка модели
    • 2.1  Полезные функции подготовки данных и подбора моделей и их параметров
    • 2.2  Модель машинного обучения для первого региона
      • 2.2.1  Подготовка выборок из датафрейма с данными первого региона
      • 2.2.2  Модель LinearRegression с использованием технологий Pipline и GridSearchSV для первого региона
      • 2.2.3  Предсказания для первого региона
    • 2.3  Модель машинного обучения для второго региона
      • 2.3.1  Подготовка выборок из датафрейма с данными второго региона
      • 2.3.2  Модель LinearRegression с использованием технологий Pipline и GridSearchSV для второго региона с аттрибутом f2, сильно коррелирующим с целевым признаком
      • 2.3.3  Предсказания для второго региона
    • 2.4  Модель машинного обучения для третьего региона
      • 2.4.1  Подготовка выборок из датафрейма с данными третьего региона
      • 2.4.2  Модель LinearRegression с использованием технологий Pipline и GridSearchSV для третьего региона
      • 2.4.3  Предсказания для третьего региона
    • 2.5  Анализ результатов обучения и проверки моделей
  • 3  Подготовка к расчёту прибыли
    • 3.1  Константы проекта
    • 3.2  Точка безубыточности
    • 3.3  Итоги подготовки к расчету прибыли
    • 3.4  Функция расчета прибыли
  • 4  Расчёт прибыли и рисков
    • 4.1  Функция расчета доходов и убытков
    • 4.2  Расчет ожидаемой средней прибыли и вероятности убытков
    • 4.3  Выводы расчета прибыли и рисков
  • 5  Выводы проекта
  • 6  Чек-лист готовности проекта

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

Подготовка тетради и загрузка данных¶

In [1]:
# Базовые библиотеки
import pandas as pd # Датафреймы
import numpy as np # Математика для массивов
from math import factorial # Факториалы
from scipy import stats as st # Статистика

# Pipeline (пайплайн)
from sklearn.pipeline import(
    Pipeline, # Pipeline с ручным вводом названий шагов.
    make_pipeline # Pipeline с автоматическим названием шагов.
)

# Функция для поддержки экспериментальной функции HavingGridSearchSV
from sklearn.experimental import enable_halving_search_cv
# Ускоренная автоматизация поиска лучших моделей и их параметров
from sklearn.model_selection import HalvingGridSearchCV
# Ускоренная автоматизация рандомного поиска лучших моделей и их параметров
from sklearn.model_selection import HalvingRandomSearchCV

# Автоматизация раздельного декодирования признаков
from sklearn.compose import(
    make_column_selector, 
    make_column_transformer, 
    ColumnTransformer
)

# Обработка данных для машинного обучения
# Стандартизация данных
import re
from sklearn.preprocessing import(
    OneHotEncoder, # Создание отдельных столбцов для каждого категориального значения, drop='first' (удаление первого столбца против dummy-ловушки), sparse=False (?)
    OrdinalEncoder, # Кодирование порядковых категориальных признаков
    LabelEncoder, 
    StandardScaler, 
    MinMaxScaler
)
from sklearn.utils import shuffle # Перемешивание данных для уравновешивания их в разных выборках
from statsmodels.stats.outliers_influence import variance_inflation_factor # Коэффициент инфляции дисперсии (5 и более - признак коррелирует со всеми остальными, его можно удалить и выразить через другие признаки)

from sklearn.model_selection import(
    GridSearchCV, # Поиск гиперпараметров по сетке (GridSearch)
    train_test_split, # Разделение выборок с целевыми и нецелевыми признаками на обучающую и тестовую
    validation_curve, 
    StratifiedKFold, # Кроссвалидация с указанием количества фолдов (частей, на которые будет разбита обучающая выборка, одна из которых будет участвовать в валидации)
    KFold, # Кроссвалидация 
    cross_val_score # Оценка качества модели на кроссвалидации
)

# Различные модели машинного обучения (в данном проекте требуется регрессия)
# (есть разбор на https://russianblogs.com/article/83691573909/)
# Линейная модель
from sklearn.linear_model import(
    #LogisticRegression, # Линейная классификация
    LinearRegression, # Линейная регрессия
    Ridge , # Линейная регрессия. "Хребтовая" регрессия (метод наименьших квадратов)
    BayesianRidge , # Линейная регрессия. Байесовская "хребтовая" регрессия (максимизации предельного логарифмического правдоподобия)
    SGDRegressor # Линейная регрессия. SGD - Стохастический градиентный спуск (минимизирует регуляризованные эмпирические потери за счет стохастического градиентного спуска)
)
# Решающее дерево
from sklearn.tree import(
    #DecisionTreeClassifier, # Решающее дерево. Классификация
    DecisionTreeRegressor # Решающее дерево. Регрессия
)
# Случайный лес
from sklearn.ensemble import(
    #RandomForestClassifier, # Случайный лес. Классификация
    RandomForestRegressor # Случайный лес. Регрессия
)
# Машина опорных векторов
from sklearn.svm import(
    SVR # # Линейная модель. Регрессия с использованием опорных векторов
)
# Нейронная сеть
from sklearn.neural_network import(
    MLPRegressor # Нейронная сеть. Регрессия
)

# Метрики (Показатели качества моделей)
from sklearn.metrics import(
    # Метрики для моделей регрессии
    mean_absolute_error, # MAE, Средняя абсолютная ошибка (не чувствительная к выбросам)
    mean_absolute_percentage_error, # MAPE, Средняя абсолютная ошибка в % (универсальная в %)
    mean_squared_error, # MSE, Средняя квадратичная ошибка (дисперсия, чувствительная к выбросам), RMSE (сигма) = mean_squared_error(test_y, preds, squared=False)
    r2_score, # R^2, Коэффициент детерминации (универсальная в %, чувствительная к выбросам, может быть отрицательной и возвращать NaN)
    
    # Другое
    ConfusionMatrixDisplay
)

# Визуализация графиков
import seaborn as sns
import matplotlib
%matplotlib inline
from matplotlib import pyplot as plt
from matplotlib import rcParams, rcParamsDefault
from pandas.plotting import scatter_matrix
In [2]:
# Отображение всех столбцов таблицы
pd.set_option('display.max_columns', None)
# Обязательно для нормального отображения графиков plt
rcParams['figure.figsize'] = 10, 6
%config InlineBackend.figure_format = 'svg'
# Дополнительно и не обязательно для декорирования графиков
factor = .8
default_dpi = rcParamsDefault['figure.dpi']
rcParams['figure.dpi'] = default_dpi * factor
In [3]:
# Чтение файла с датафреймами
try:
    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')
except:
    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')
    

Анализ данных датафрейма первого региона¶

In [4]:
# Проверка датафрейма первого региона
print(geo_data_0.info())
geo_data_0.head() 
<class 'pandas.core.frame.DataFrame'>
RangeIndex: 100000 entries, 0 to 99999
Data columns (total 5 columns):
 #   Column   Non-Null Count   Dtype  
---  ------   --------------   -----  
 0   id       100000 non-null  object 
 1   f0       100000 non-null  float64
 2   f1       100000 non-null  float64
 3   f2       100000 non-null  float64
 4   product  100000 non-null  float64
dtypes: float64(4), object(1)
memory usage: 3.8+ MB
None
Out[4]:
id f0 f1 f2 product
0 txEyH 0.705745 -0.497823 1.221170 105.280062
1 2acmU 1.334711 -0.340164 4.365080 73.037750
2 409Wp 1.022732 0.151990 1.419926 85.265647
3 iJLyR -0.032172 0.139033 2.978566 168.620776
4 Xdl7t 1.988431 0.155413 4.751769 154.036647
In [5]:
# Распределение значений датафрейма первого региона
geo_data_0.describe() 
Out[5]:
f0 f1 f2 product
count 100000.000000 100000.000000 100000.000000 100000.000000
mean 0.500419 0.250143 2.502647 92.500000
std 0.871832 0.504433 3.248248 44.288691
min -1.408605 -0.848218 -12.088328 0.000000
25% -0.072580 -0.200881 0.287748 56.497507
50% 0.502360 0.250252 2.515969 91.849972
75% 1.073581 0.700646 4.715088 128.564089
max 2.362331 1.343769 16.003790 185.364347
In [6]:
# Соответствие количества уникальных идентификаторов 
# и количества объектов в датафрейме первого региона
# (сколько месторождений в регионе)
geo_data_id = len(geo_data_0.id.unique())
if geo_data_id == len(geo_data_0):
    print(f'Количество уникальных идентификаторов: {geo_data_id} == Количество объектов {len(geo_data_0)}')
else:
    print(f'Количество уникальных идентификаторов: {geo_data_id} < Количество объектов {len(geo_data_0)}')
Количество уникальных идентификаторов: 99990 < Количество объектов 100000
In [7]:
# Анализ объектов с дубликатами в аттрибуте "id"
id = geo_data_0.loc[geo_data_0['id'].duplicated(), 'id'].values

for i in id:
    print(geo_data_0.loc[geo_data_0['id'] == i])
    print()
         id        f0        f1         f2     product
931   HZww2  0.755284  0.368511   1.863211   30.681774
7530  HZww2  1.061194 -0.373969  10.430210  158.828695

          id        f0        f1        f2    product
1364   bxg6G  0.411645  0.856830 -3.653440  73.604260
41724  bxg6G -0.823752  0.546319  3.630479  93.007798

          id        f0        f1        f2    product
3389   A5aEY -0.039949  0.156872  0.209861  89.249364
51970  A5aEY -0.180335  0.935548 -2.094773  33.020205

          id        f0        f1        f2    product
1949   QcMuo  0.506563 -0.323775 -2.215583  75.496502
63593  QcMuo  0.635635 -0.473422  0.862670  64.578675

          id        f0        f1        f2     product
64022  74z30  0.741456  0.459229  5.153109  140.771492
66136  74z30  1.084962 -0.312358  6.990771  127.643327

          id        f0        f1        f2     product
42529  AGS9W  1.454747 -0.479651  0.683380  126.370504
69163  AGS9W -0.933795  0.116194 -3.655896   19.230453

          id        f0        f1        f2    product
21426  Tdehs  0.829407  0.298807 -0.049563  96.035308
75715  Tdehs  0.112079  0.430296  3.218993  60.964018

          id        f0        f1        f2     product
16633  fiKDv  0.157341  1.028359  5.585586   95.817889
90815  fiKDv  0.049883  0.841313  6.394613  137.346586

          id        f0        f1        f2     product
60140  TtcGQ  0.569276 -0.104876  6.440215   85.350186
92341  TtcGQ  0.110711  1.022689  0.911381  101.318008

          id        f0        f1         f2     product
89582  bsk9y  0.398908 -0.400253  10.122376  163.433078
97785  bsk9y  0.378429  0.005837   0.160827  160.637302

In [8]:
# Гистограммы числовых данных 
# первого региона
geo_data_0.hist();
2023-09-22T08:08:31.729806 image/svg+xml Matplotlib v3.3.4, https://matplotlib.org/
In [9]:
# Анализ выбросов данных 
# первого региона
for i in geo_data_0:
    if i != 'id':
        geo_data_0.boxplot(column=i);
        plt.show() 
2023-09-22T08:08:32.052510 image/svg+xml Matplotlib v3.3.4, https://matplotlib.org/
2023-09-22T08:08:32.255176 image/svg+xml Matplotlib v3.3.4, https://matplotlib.org/
2023-09-22T08:08:32.476106 image/svg+xml Matplotlib v3.3.4, https://matplotlib.org/
2023-09-22T08:08:32.684175 image/svg+xml Matplotlib v3.3.4, https://matplotlib.org/
In [10]:
# Анализ корреляции аттрибутов
# датафрейма первого региона
geo_data_0.corr()
Out[10]:
f0 f1 f2 product
f0 1.000000 -0.440723 -0.003153 0.143536
f1 -0.440723 1.000000 0.001724 -0.192356
f2 -0.003153 0.001724 1.000000 0.483663
product 0.143536 -0.192356 0.483663 1.000000
In [11]:
# Коэффициент инфляции дисперсии аттрибутов третьего региона
# (5 и более - признак коррелирует со всеми остальными признаками 
# и его можно удалить и выразить через другие признаки)
geo_data = geo_data_0.select_dtypes('number')#.columns
vif = [variance_inflation_factor(geo_data, i) for i in range(len(geo_data.columns))]
_ = sns.barplot(x=geo_data.columns.tolist(), y=vif)

vif
Out[11]:
[1.5342414107959919, 1.275466160458148, 2.0723577504192945, 2.828465688943373]
2023-09-22T08:08:33.829796 image/svg+xml Matplotlib v3.3.4, https://matplotlib.org/

Анализ данных датафрейма второго региона¶

In [12]:
# Проверка датафрейма второго региона
print(geo_data_1.info())
geo_data_1.head() 
<class 'pandas.core.frame.DataFrame'>
RangeIndex: 100000 entries, 0 to 99999
Data columns (total 5 columns):
 #   Column   Non-Null Count   Dtype  
---  ------   --------------   -----  
 0   id       100000 non-null  object 
 1   f0       100000 non-null  float64
 2   f1       100000 non-null  float64
 3   f2       100000 non-null  float64
 4   product  100000 non-null  float64
dtypes: float64(4), object(1)
memory usage: 3.8+ MB
None
Out[12]:
id f0 f1 f2 product
0 kBEdx -15.001348 -8.276000 -0.005876 3.179103
1 62mP7 14.272088 -3.475083 0.999183 26.953261
2 vyE1P 6.263187 -5.948386 5.001160 134.766305
3 KcrkZ -13.081196 -11.506057 4.999415 137.945408
4 AHL4O 12.702195 -8.147433 5.004363 134.766305
In [13]:
# Распределение значений датафрейма второго региона
geo_data_1.describe() 
Out[13]:
f0 f1 f2 product
count 100000.000000 100000.000000 100000.000000 100000.000000
mean 1.141296 -4.796579 2.494541 68.825000
std 8.965932 5.119872 1.703572 45.944423
min -31.609576 -26.358598 -0.018144 0.000000
25% -6.298551 -8.267985 1.000021 26.953261
50% 1.153055 -4.813172 2.011479 57.085625
75% 8.621015 -1.332816 3.999904 107.813044
max 29.421755 18.734063 5.019721 137.945408
In [14]:
# Соответствие количества уникальных идентификаторов 
# и количества объектов в датафрейме второго региона
# (сколько месторождений в регионе)
geo_data_id = len(geo_data_1.id.unique())
if geo_data_id == len(geo_data_1):
    print(f'Количество уникальных идентификаторов: {geo_data_id} == Количество объектов {len(geo_data_1)}')
else:
    print(f'Количество уникальных идентификаторов: {geo_data_id} < Количество объектов {len(geo_data_1)}')
Количество уникальных идентификаторов: 99996 < Количество объектов 100000
In [15]:
# Анализ объектов с дубликатами в аттрибуте "id"
id = geo_data_1.loc[geo_data_1['id'].duplicated(), 'id'].values

for i in id:
    print(geo_data_1.loc[geo_data_1['id'] == i])
    print()
          id         f0        f1        f2    product
1305   LHZR0  11.170835 -1.945066  3.002872  80.859783
41906  LHZR0  -8.989672 -4.286607  2.009139  57.085625

          id        f0        f1        f2     product
2721   bfPNe -9.494442 -5.463692  4.006042  110.992147
82178  bfPNe -6.202799 -4.820045  2.995107   84.038886

          id         f0        f1        f2     product
47591  wt4Uk  -9.091098 -8.109279 -0.002314    3.179103
82873  wt4Uk  10.259972 -9.376355  4.994297  134.766305

          id         f0         f1        f2     product
5849   5ltQ6  -3.435401 -12.296043  1.999796   57.085625
84461  5ltQ6  18.213839   2.191999  3.993869  107.813044

In [16]:
# Гистограммы числовых данных 
# второго региона
geo_data_1.hist();
2023-09-22T08:08:34.534730 image/svg+xml Matplotlib v3.3.4, https://matplotlib.org/
In [17]:
# Анализ выбросов данных 
# второго региона
for i in geo_data_1:
    if i != 'id':
        geo_data_0.boxplot(column=i);
        plt.show() 
2023-09-22T08:08:34.885077 image/svg+xml Matplotlib v3.3.4, https://matplotlib.org/
2023-09-22T08:08:35.072386 image/svg+xml Matplotlib v3.3.4, https://matplotlib.org/
2023-09-22T08:08:35.250039 image/svg+xml Matplotlib v3.3.4, https://matplotlib.org/
2023-09-22T08:08:35.612293 image/svg+xml Matplotlib v3.3.4, https://matplotlib.org/
In [18]:
# Анализ корреляции аттрибутов 
# датафрейма второго региона
geo_data_1.corr()
Out[18]:
f0 f1 f2 product
f0 1.000000 0.182287 -0.001777 -0.030491
f1 0.182287 1.000000 -0.002595 -0.010155
f2 -0.001777 -0.002595 1.000000 0.999397
product -0.030491 -0.010155 0.999397 1.000000
In [19]:
# Коэффициент инфляции дисперсии аттрибутов второго региона
# (5 и более - признак коррелирует со всеми остальными признаками 
# и его можно удалить и выразить через другие признаки)
geo_data = geo_data_1.select_dtypes('number')#.columns
vif = [variance_inflation_factor(geo_data, i) for i in range(len(geo_data.columns))]
_ = sns.barplot(x=geo_data.columns.tolist(), y=vif)

vif
Out[19]:
[1.9873199714997407, 1.8282400357569757, 4660.924528638744, 4692.5535256238845]
2023-09-22T08:08:36.522371 image/svg+xml Matplotlib v3.3.4, https://matplotlib.org/

Анализ данных датафрейма третьего региона¶

In [20]:
# Проверка датафрейма третьего региона
print(geo_data_2.info())
geo_data_2.head() 
<class 'pandas.core.frame.DataFrame'>
RangeIndex: 100000 entries, 0 to 99999
Data columns (total 5 columns):
 #   Column   Non-Null Count   Dtype  
---  ------   --------------   -----  
 0   id       100000 non-null  object 
 1   f0       100000 non-null  float64
 2   f1       100000 non-null  float64
 3   f2       100000 non-null  float64
 4   product  100000 non-null  float64
dtypes: float64(4), object(1)
memory usage: 3.8+ MB
None
Out[20]:
id f0 f1 f2 product
0 fwXo0 -1.146987 0.963328 -0.828965 27.758673
1 WJtFt 0.262778 0.269839 -2.530187 56.069697
2 ovLUW 0.194587 0.289035 -5.586433 62.871910
3 q6cA6 2.236060 -0.553760 0.930038 114.572842
4 WPMUX -0.515993 1.716266 5.899011 149.600746
In [21]:
# Распределение значений датафрейма третьего региона
geo_data_2.describe() 
Out[21]:
f0 f1 f2 product
count 100000.000000 100000.000000 100000.000000 100000.000000
mean 0.002023 -0.002081 2.495128 95.000000
std 1.732045 1.730417 3.473445 44.749921
min -8.760004 -7.084020 -11.970335 0.000000
25% -1.162288 -1.174820 0.130359 59.450441
50% 0.009424 -0.009482 2.484236 94.925613
75% 1.158535 1.163678 4.858794 130.595027
max 7.238262 7.844801 16.739402 190.029838
In [22]:
# Соответствие количества уникальных идентификаторов 
# и количества объектов в датафрейме третьего региона
# (сколько месторождений в регионе)
geo_data_id = len(geo_data_2.id.unique())
if geo_data_id == len(geo_data_2):
    print(f'Количество уникальных идентификаторов: {geo_data_id} == Количество объектов {len(geo_data_2)}')
else:
    print(f'Количество уникальных идентификаторов: {geo_data_id} < Количество объектов {len(geo_data_2)}')
Количество уникальных идентификаторов: 99996 < Количество объектов 100000
In [23]:
# Анализ объектов с дубликатами в аттрибуте "id"
id = geo_data_2.loc[geo_data_2['id'].duplicated(), 'id'].values

for i in id:
    print(geo_data_2.loc[geo_data_2['id'] == i])
    print()
          id        f0        f1        f2     product
28039  xCHr8  1.633027  0.368135 -2.378367    6.120525
43233  xCHr8 -0.847066  2.101796  5.597130  184.388641

          id        f0        f1        f2     product
11449  VF7Jo  2.122656 -0.858275  5.746001  181.716817
49564  VF7Jo -0.883115  0.560537  0.723601  136.233420

          id        f0        f1        f2     product
45404  KUPhW  0.231846 -1.698941  4.990775   11.716299
55967  KUPhW  1.211150  3.176408  5.543540  132.831802

          id        f0        f1        f2     product
44378  Vcm5J -1.229484 -2.439204  1.222909  137.968290
95090  Vcm5J  2.587702  1.986875  2.482245   92.327572

In [24]:
# Гистограммы числовых данных 
# третьего региона
geo_data_2.hist();
2023-09-22T08:08:37.315322 image/svg+xml Matplotlib v3.3.4, https://matplotlib.org/
In [25]:
# Анализ выбросов данных 
# третьего региона
for i in geo_data_2:
    if i != 'id':
        geo_data_0.boxplot(column=i);
        plt.show() 
2023-09-22T08:08:37.641489 image/svg+xml Matplotlib v3.3.4, https://matplotlib.org/
2023-09-22T08:08:37.837762 image/svg+xml Matplotlib v3.3.4, https://matplotlib.org/
2023-09-22T08:08:38.028253 image/svg+xml Matplotlib v3.3.4, https://matplotlib.org/
2023-09-22T08:08:38.269586 image/svg+xml Matplotlib v3.3.4, https://matplotlib.org/
In [26]:
# Анализ корреляции аттрибутов
# датафрейма третьего региона
geo_data_2.corr()
Out[26]:
f0 f1 f2 product
f0 1.000000 0.000528 -0.000448 -0.001987
f1 0.000528 1.000000 0.000779 -0.001012
f2 -0.000448 0.000779 1.000000 0.445871
product -0.001987 -0.001012 0.445871 1.000000
In [27]:
# Коэффициент инфляции дисперсии аттрибутов третьего региона
# (5 и более - признак коррелирует со всеми остальными признаками 
# и его можно удалить и выразить через другие признаки)
geo_data = geo_data_2.select_dtypes('number')#.columns
vif = [variance_inflation_factor(geo_data, i) for i in range(len(geo_data.columns))]
_ = sns.barplot(x=geo_data.columns.tolist(), y=vif)

vif
Out[27]:
[1.0000003784119968, 1.0000043346184886, 1.8701231139033965, 1.870127315208737]
2023-09-22T08:08:39.328231 image/svg+xml Matplotlib v3.3.4, https://matplotlib.org/

Выводы из анализа данных датафреймов всех регионов¶

Предварительный анализ данных выявил следующее:

  1. Все три датафрейма содержат один текстовый оттрибут с идентификаторами скважин, а также три количественных числовых нецелевых аттрибута и один количественный числовой целевой аттрибут.
  2. В данных отсутствуют пропуски.
  3. Выявлены неявные дубликаты. Во всех датафреймах обнаружены от 6 до 10 объектов (скважин) с неуникальными идентификаторами в аттрибуте id. Все значения аттрибутов этих дубликатов значительно отличаются друг от друга. Учитывая отсутствие возможности выяснить причину наличия схожих идентификаторов и разницы значений их аттрибутов, предлагается оставить данные объекты.
  4. Аттрибут id с идентификаторами скважин имеет тип Object и около ста тысяч уникальных значений, за исключением 6-10 объектов, почти равных по количеству количеству всех объектов датафреймов. Для использования данного аттрибута в моделях, требуется его декодирование в числовые значения. Для линейной модели регрессии не подходит декодирование с помощью LabelEncoder, а с помощью OHE его декодировать накладно. Поэтому в модели линейной регрессии его использовать не желательно.
  5. Аттрибуты f0 и f1 датафрейма с объектами первого региона, а также f0, f2 и product датафрейма с объектами второго региона не имеют нормального распределения. При этом, данные аттрибуты имеют значительные всплески вдали от основного центра распределения. Это нужно учесть при работе с моделями.
  6. Аттрибут f2 датафреймов всех регионов имеет множество выбросов. Т.к. смысл данного атрибута не известен, предлагается не удалять объекты с выбросами данных в нем.
  7. Числовые нецелевые аттрибуты имеют близкие, но не достаточно схожие диапазоны значений. Требуется их стандартизировать.
  8. В датасетах разных регионов разные аттрибуты по разному коррелируют между собой. Так, в первом регионе обладают ниже средней прямой корреляцией признаки f0 с f1 и f2 с product, а в третьем регионе только f2 с product. Близкой к максимальной прямой корреляции в размере 0.999397 обладают аттрибуты f2 с product во втором регионе. Коэффициент инфляции дисперсии этих двух аттрибутов близкий к 5, но не превышает это значение. Не смотря на практику удаления признаков из датафреймов в подобных случаях, аттрибут f2 не следует удалять из датафрейма, т.к. сильная корреляция с целевым признаком позволяет более точно предсказывать этот самый целевой признак.

Данные готовы для использования в машинном обучении перед которым требуется стандартизировать нецелевые числовые аттрибуты.

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

Для достижения целей проекта требуется использовать регрессионную модель с кроссвалидацией, имеющей наилучшие показатели качества. В качестве средств автоматизации будет использованы технологии Pipline и GridSearchSV. Перед подбором параметров датафреймы будут разделены на целевые и нецелевые, а также на обучающие и треннировочные выборки в соотношении 75% и 25%. Обучающие выборки в рамках GridSearchSV будут разделены для кроссвалидации на обучающие и валидационные выборки в соотношении 75% и 25%. Аттрибут с идентификаторами будет исключен из всех выборок, а нецелевые числовые аттрибуты будут стандартизированы.

Полезные функции подготовки данных и подбора моделей и их параметров¶

In [28]:
# Значение "random_state"
STATE = 42

# Массив лучших параметров моделей 
# всех регионов
total_best_params = [] 

# Массив лучших результатов
# всех регионов
total_results= [] 
In [29]:
# Функция подготовки данных перед подбором моделей и их параметров
def data_preprocessing(geo_data):
    
    # Разделение датафреймов на целевую и нецелевую выборку
    features = geo_data.drop(['id', 'product'], axis=1)
    target = geo_data['product']

    # Значение "random_state"
    state = 42

    # Разделение целевой и нецелевой выборки 
    # на обучающие и тестовые выборки
    features_train,  features_test, target_train, target_test = train_test_split(
        features, 
        target, 
        test_size=.25, 
        random_state=state
    )
    
    return features_train,  features_test, target_train, target_test
In [30]:
# Функция создания структуры пайплайна
def params_and_model_selection(
    features_train, 
    features_test, 
    target_train, 
    target_test, 
    model_params
):

    # Значение "random_state"
    state = 42
    
    # Удаление аттрибута "id"
    #features_train = features_train.drop('id', axis=1)
    
    # Стандартизация числовых значений
    numeric_transformer = make_pipeline(
        StandardScaler()
    )
    
    # Шаг препроцессинга в Пайплайне
    preprocessor = make_column_transformer(
        (numeric_transformer, features_train.columns)
    )
    
    # Pipeline
    pipe = Pipeline([
        ('preprocessor', preprocessor), 
        ('regressor', model_params[0]['regressor'][0])
    ])
    pipe.fit(features_train, target_train)
    
    # HalvingGridSearchCV
    # (о подборе оптимальных параметров:
    # https://scikit-learn.ru/3-2-tuning-the-hyper-parameters-of-an-estimator/)
    grid = HalvingGridSearchCV(
        pipe, 
        model_params, 
        cv=4, # параметр KFold для кроссвалидации (обучющая и валидационная выборки 75:25)
        n_jobs=-1, # количество параллельно выполняемых заданий (-1 - задействованы все процессоры)
        # если scoring=mean_squared_error, то в результате "nan"
        scoring='neg_root_mean_squared_error', # корень из средней квадратичной ошибки (чувствительна к выбросам, в результате реальные, а не квадратные значения)
        random_state=state
    )
    grid.fit(features_train, target_train)
    
    return grid

Модель машинного обучения для первого региона¶

Подготовка выборок из датафрейма с данными первого региона¶

In [31]:
# Подготовка выборок из датафрейма 
# с данными первого региона
features_0_train,  features_0_test, target_0_train, target_0_test = data_preprocessing(geo_data_0)

features_0_test.head()
Out[31]:
f0 f1 f2
75721 0.599283 -0.557623 2.121187
80184 0.739017 -0.463156 -1.347584
19864 1.422743 -0.534917 3.718798
76699 1.580244 -0.238458 2.805149
92991 0.918974 0.023961 2.598575

Модель LinearRegression с использованием технологий Pipline и GridSearchSV для первого региона¶

In [32]:
# LinearRegression
grids_0 = params_and_model_selection(
    features_0_train, 
    features_0_test, 
    target_0_train, 
    target_0_test, 
    [{
        'regressor': [LinearRegression()], # score: R^2
        'regressor__fit_intercept': [True, False]
    }]
)

print('Модель   :', 'LinearRegression')
print('RMSE     :', grids_0.best_score_)
print('Параметры:\n', grids_0.best_estimator_)
Модель   : LinearRegression
RMSE     : -37.67176560084854
Параметры:
 Pipeline(steps=[('preprocessor',
                 ColumnTransformer(transformers=[('pipeline',
                                                  Pipeline(steps=[('standardscaler',
                                                                   StandardScaler())]),
                                                  Index(['f0', 'f1', 'f2'], dtype='object'))])),
                ('regressor', LinearRegression())])

Предсказания для первого региона¶

In [33]:
# Предсказания для первого региона
#predict_0 = grids_0.predict(features_0_test.drop('id', axis=1))
predict_0 = grids_0.predict(features_0_test)
total_results.append([
    1, 
    predict_0.mean(), 
    mean_squared_error(target_0_test, predict_0, squared=False)
])
print('Регион                           :', total_results[0][0])
print('Средний предсказанный запас сырья:', total_results[0][1])
print('RMSE                             :', total_results[0][2])
Регион                           : 1
Средний предсказанный запас сырья: 92.39879990657768
RMSE                             : 37.75660035026169

Модель машинного обучения для второго региона¶

Подготовка выборок из датафрейма с данными второго региона¶

In [34]:
# Подготовка выборок из датафрейма 
# с данными второго региона
features_1_train,  features_1_test, target_1_train, target_1_test = data_preprocessing(geo_data_1)
#features_1_train = features_1_train.drop('f2', axis=1)
#features_1_test = features_1_test.drop('f2', axis=1)

features_1_train.head()
Out[34]:
f0 f1 f2
98980 9.296378 -4.480220 1.999544
69824 15.836796 1.952969 4.989288
9928 -1.594937 -0.407367 3.003358
75599 12.335752 -6.508978 2.001396
95621 -4.954638 -8.026328 1.001472

Модель LinearRegression с использованием технологий Pipline и GridSearchSV для второго региона с аттрибутом f2, сильно коррелирующим с целевым признаком¶

In [35]:
# LinearRegression
grids_1 = params_and_model_selection(
    features_1_train, 
    features_1_test, 
    target_1_train, 
    target_1_test, 
    [{
        'regressor': [LinearRegression()], # score: R^2
        'regressor__fit_intercept': [True, False]
    }]
)

print('Модель   :', 'LinearRegression')
print('RMSE     :', grids_1.best_score_)
print('Параметры:\n', grids_1.best_estimator_)
Модель   : LinearRegression
RMSE     : -0.8904633868175174
Параметры:
 Pipeline(steps=[('preprocessor',
                 ColumnTransformer(transformers=[('pipeline',
                                                  Pipeline(steps=[('standardscaler',
                                                                   StandardScaler())]),
                                                  Index(['f0', 'f1', 'f2'], dtype='object'))])),
                ('regressor', LinearRegression())])

Предсказания для второго региона¶

In [36]:
# Предсказания для второго региона
#predict_1 = grids_1.predict(features_1_test.drop('id', axis=1))
predict_1 = grids_1.predict(features_1_test)
total_results.append([
    2, 
    predict_1.mean(), 
    mean_squared_error(target_1_test, predict_1, squared=False)
])
print('Регион                           :', total_results[0][0])
print('Средний предсказанный запас сырья:', total_results[0][1])
print('RMSE                             :', total_results[0][2])
Регион                           : 1
Средний предсказанный запас сырья: 92.39879990657768
RMSE                             : 37.75660035026169

Модель машинного обучения для третьего региона¶

Подготовка выборок из датафрейма с данными третьего региона¶

In [37]:
# Подготовка выборок из датафрейма 
# с данными третьего региона
features_2_train,  features_2_test, target_2_train, target_2_test = data_preprocessing(geo_data_2)

features_2_test.head()
Out[37]:
f0 f1 f2
75721 2.111118 -1.679773 3.112240
80184 0.734759 0.747788 3.670879
19864 -2.513109 0.844631 -4.922889
76699 -2.035301 -1.522988 5.072839
92991 2.744145 1.429952 -1.372661

Модель LinearRegression с использованием технологий Pipline и GridSearchSV для третьего региона¶

In [38]:
# Модель LinearRegression с использованием 
# технологий Pipline и GridSearchSV для третьего региона
grids_2 = params_and_model_selection(
    features_2_train, 
    features_2_test, 
    target_2_train, 
    target_2_test, 
    [{
        'regressor': [LinearRegression()], # score: R^2
        'regressor__fit_intercept': [True, False]
    }]
)

print('Модель   :', 'LinearRegression')
print('RMSE     :', grids_2.best_score_)
print('Параметры:\n', grids_2.best_estimator_)
Модель   : LinearRegression
RMSE     : -40.028747787073236
Параметры:
 Pipeline(steps=[('preprocessor',
                 ColumnTransformer(transformers=[('pipeline',
                                                  Pipeline(steps=[('standardscaler',
                                                                   StandardScaler())]),
                                                  Index(['f0', 'f1', 'f2'], dtype='object'))])),
                ('regressor', LinearRegression())])

Предсказания для третьего региона¶

In [39]:
# Предсказания для третьего региона
#predict_2 = grids_2.predict(features_2_test.drop('id', axis=1))
predict_2 = grids_2.predict(features_2_test)
total_results.append([
    3, 
    predict_2.mean(), 
    mean_squared_error(target_2_test, predict_2, squared=False)
])
print('Регион                           :', total_results[0][0])
print('Средний предсказанный запас сырья:', total_results[0][1])
print('RMSE                             :', total_results[0][2])
Регион                           : 1
Средний предсказанный запас сырья: 92.39879990657768
RMSE                             : 37.75660035026169

Анализ результатов обучения и проверки моделей¶

In [40]:
# Сводная таблица результатов моделей всех регионов
total_results = pd.DataFrame(data=total_results, columns=['region', 'average', 'rmse'])
total_results['minus_3_sigma'] = total_results['average'] - total_results['rmse']*3
total_results['minus_1_sigma'] = total_results['average'] - total_results['rmse']
total_results['plus_1_sigma'] = total_results['average'] + total_results['rmse']
total_results['plus_3_sigma'] = total_results['average'] + total_results['rmse']*3

total_results.rename(columns = {
    'region':'Регион', 
    'average':'Среднее значение', 
    'rmse':'RMSE', 
    'minus_3_sigma':'-3 sigma', 
    'minus_1_sigma':'-1 sigma', 
    'plus_1_sigma':'+1 sigma', 
    'plus_3_sigma':'+3 sigma'
})
Out[40]:
Регион Среднее значение RMSE -3 sigma -1 sigma +1 sigma +3 sigma
0 1 92.398800 37.756600 -20.871001 54.642200 130.155400 205.668601
1 2 68.712878 0.890280 66.042038 67.822598 69.603158 71.383718
2 3 94.771024 40.145872 -25.666593 54.625152 134.916896 215.208641

Выводы:

  1. Третий регион имеет наиболее высокое предсказанное среднее значение целевого аттрибута product (предполагаемый объем запасов нефти), равное 95. В этом же регионе самый большое значение корня из средней квадратичной ошибки (RMSE, далее $\sigma$) предсказаний аттрибута product, равное 40.
  2. Во втором регионе самое низкое значение целевого аттрибута product, равное 69. Это почти на четверть меньше, чем в других регионах. При этом, во втором регионе самое низкое значение разброса $\sigma$ предсказаний аттрибута product. Оно равно 0.89, что почти в 40 раз меньше, чем в других регионах. Благодаря минимальному отклонению предсказанных значений от реальных, второй регион наиболее предсказуемый. В нем самые большие значения на нижней границе одной $\sigma$ и нет отрицательных значений на нижней границе трех $\sigma$.
  3. В первом и втором регионах нижняя граница трех $\sigma$ находится существенно ниже 0. Возможно, это следует трактовать как наличие некоторого количества скважин без нефти.

Предварительно можно утверждать, что, по результатам предсказаний моделей линейной регрессии, второй регион является самым предсказуемым, но низкодоходным, а третий самым доходным и рискованным.

Подготовка к расчёту прибыли¶

Константы проекта¶

In [41]:
# Константы проекта
OBJECTS_UNDER_STUDY_NUM = 500 # количество исследуемых объектов, участвующих в обучении модели
BEST_OBJECTS_NUM = 200 # количество лучших объектов в регионе, которые будут разработаны (из 500 оцененных)
TOTAL_BUDGET = 10000000000 # бюджет проекта для одного региона
REVENUE_PER_UNIT = 450000 # доходность одной единицы продукта (= 450 за баррель * 1000 баррелей в одной единице объекта "total")
MAX_PROBABILITY_OF_LOSS = .025 # максимально допустимая веросятность убытков
Успех: Хорошо, что в названиях константных переменных использовались только большие буквы!

Точка безубыточности¶

In [42]:
# Точка безубыточности равна частному 
# от деления всего бюджета проекта для одного региона 
# и стоисомти 1000 баррелей нефти, 
# деленные на количество разрабатываемых скважин 
# в рамках одного региона
break_event_point = (TOTAL_BUDGET / REVENUE_PER_UNIT) / BEST_OBJECTS_NUM
print(f'Точка безубыточности проекта равна добыче {break_event_point} баррелей в одной из 200 скважин одного региона.')
Точка безубыточности проекта равна добыче 111.11111111111111 баррелей в одной из 200 скважин одного региона.
In [43]:
# Разница между объемами добычи, 
# требуемыми для безубыточности проекта 
# и средними значениями предсказанных 
# объемов добычи нефти во всех скважинах 
# разных регионов
total_results['average'] - break_event_point
Out[43]:
0   -18.712311
1   -42.398233
2   -16.340087
Name: average, dtype: float64

Во всех регионах средние предсказанные значения объемов добычи нефти в одной сважине меньше минимум на 16 тыс. баррелей, чем требуется для безубыточности проекта.

In [44]:
# Разница между объемами добычи, 
# требуемыми для безубыточности проекта 
# и средними значениями объемов добычи нефти 
# в 200 скважинах с предсказанным 
# максимальным объемом в разных регионов
print('Разница между объемами добычи, \
требуемыми для безубыточности проекта и средними значениями \
объемов добычи нефти в 200 скважинах с предсказанным \
максимальным объемом в разных регионов.\n')
print('Первый регион:', pd.Series(predict_0).sort_values(ascending=False).head(200).mean() - break_event_point)
print('Второй регион:', pd.Series(predict_1).sort_values(ascending=False).head(200).mean() - break_event_point)
print('Третий регион:', pd.Series(predict_2).sort_values(ascending=False).head(200).mean() - break_event_point)
Разница между объемами добычи, требуемыми для безубыточности проекта и средними значениями объемов добычи нефти в 200 скважинах с предсказанным максимальным объемом в разных регионов.

Первый регион: 43.29620532962386
Второй регион: 27.632645722212004
Третий регион: 37.53312793016613

Средние значения 200 скважин с максимальным предсказанным объемом нефти во всех регионах превышают точку безубыточности. Лидирует первый регион с превышением в 43 тыс. баррелей.

Итоги подготовки к расчету прибыли¶

Для безубыточности проекта минимальный объем добычи в одной скважине должен быть не менее 111 тыс. баррелей. Средние же значения предсказанных объемов добычи в одной скважине всех регионов меньше этого значения минимум на 16 тыс. баррелей. Однако, средние значения 200 скважин с максимальным предсказанным объемом нефти во всех регионах превышают точку безубыточности. Лидирует первый регион.

Функция расчета прибыли¶

In [45]:
# Функция расчета прибыли
def profit_calc(df):
    # df = columns 'id', 'product', 'predict'
    
    # Выбор 200 скважин в первом регионе
    # с максимальным предсказанным значением 
    # запасов нефти
    df_200 = df.sort_values(
        by='predict', 
        ascending=False
    ).head(BEST_OBJECTS_NUM)
    
    # Расчет прибыли целевых значений, 
    # соответствующих 200 предсказаниям 
    # с максимальными значениями запасов нефти
    return (df_200['product'].sum() * REVENUE_PER_UNIT) - TOTAL_BUDGET

Расчёт прибыли и рисков¶

Функция расчета доходов и убытков¶

In [46]:
# Функция расчета доходов и убытков
def profit_and_loss(target_test, predict):
    
    # Создание единого датафрейма
    df = pd.DataFrame({
        'product':target_test.values, 
        'predict':predict
    })
    
    # Значение для random_state
    state = np.random.RandomState(42)
    # Массив доходности после применения техники bootstrep
    profit_bootstrep = []
    
    for i in range(0, 1000, 1):
        df_sample = df.sample(
            n=500, 
            replace=True, 
            random_state=state
        )
        
        profit_bootstrep.append(profit_calc(df_sample))
    
    profit_bootstrep = pd.Series(profit_bootstrep)
    # Средний доход
    mean_profit = int(profit_bootstrep.mean())
    # Нижний квантиль 2.5% от 95% доверительного интервала
    lower_profit = int(profit_bootstrep.quantile(.025))
    # Верхний квантиль 97.5% от 95% доверительного интервала
    upper_profit = int(profit_bootstrep.quantile(.975))
    # Средний убыток
    #mean_loss = int(profit_bootstrep[profit_bootstrep < 0].mean())
    # Вероятность убытка
    #probability_of_loss = len(profit_bootstrep[profit_bootstrep < 0]) / len(profit_bootstrep)
    probability_of_loss = (profit_bootstrep.values < 0).mean()
    
    print(f'95% доверительный интервал доходности находится в пределах от {lower_profit} до {upper_profit}')
    print('Средний доход     :', mean_profit)
    #print('Средний убыток    :', mean_loss)
    print(f'Вероятность убытка: {probability_of_loss*100}%')
    
    return mean_profit, probability_of_loss
In [47]:
# Массив средней доходности и вероянтости убытков
# mppl - mean profit and probability of loss
mean_profits = []
probabilities_of_losses = []

Расчет ожидаемой средней прибыли и вероятности убытков¶

In [48]:
# Первый регион
mean_profit, probabilitу_of_loss = profit_and_loss(target_0_test, predict_0)
mean_profits.append(mean_profit)
probabilities_of_losses.append(probabilitу_of_loss)
95% доверительный интервал доходности находится в пределах от -110467895 до 897460327
Средний доход     : 399575478
Вероятность убытка: 6.0%
In [49]:
# Второй регион
mean_profit, probabilitу_of_loss = profit_and_loss(target_1_test, predict_1)
mean_profits.append(mean_profit)
probabilities_of_losses.append(probabilitу_of_loss)
95% доверительный интервал доходности находится в пределах от 61684479 до 845340177
Средний доход     : 452048890
Вероятность убытка: 1.5%
In [50]:
# Третий регион
mean_profit, probabilitу_of_loss = profit_and_loss(target_2_test, predict_2)
mean_profits.append(mean_profit)
probabilities_of_losses.append(probabilitу_of_loss)
95% доверительный интервал доходности находится в пределах от -144766727 до 888390403
Средний доход     : 375009902
Вероятность убытка: 8.0%

Выводы расчета прибыли и рисков¶

In [51]:
# Выводы расчета прибыли и рисков 
mppl_df = pd.DataFrame(
    {
        'profit':mean_profits, 
        'probability_of_loss':probabilities_of_losses
    }
)
mppl_df = mppl_df.loc[mppl_df['probability_of_loss'] < MAX_PROBABILITY_OF_LOSS]
mppl_df = mppl_df.loc[mppl_df['profit'] == mppl_df['profit'].max()]

num = {1:'первый', 2:'второй', 3:'третий'}

print(f"Для инвестирования предлагается выбрать {num[mppl_df.index[0]]} регион. \
В этом регионе ожидаемая доходность {mppl_df.loc[mppl_df.index[0], 'profit']}, \
а верояность убытка {mppl_df.loc[mppl_df.index[0], 'probability_of_loss']*100}%. \
Среди регионов с вероятностью убытка, находящегося \
в пределах допустимого значения {MAX_PROBABILITY_OF_LOSS*100}%, \
в данном регионе самая высокая ожидаемая прибыль.")
Для инвестирования предлагается выбрать первый регион. В этом регионе ожидаемая доходность 452048890, а верояность убытка 1.5%. Среди регионов с вероятностью убытка, находящегося в пределах допустимого значения 2.5%, в данном регионе самая высокая ожидаемая прибыль.

Выводы проекта¶

Цели проекта достигнуты. Предложен регион для инвестирования. Выбор региона обоснован. Для достижения целей проекта были решены следующие задачи:

  1. Загружены и подготовлены данные. Поясните порядок действий.
  2. Обучены и проверены модели для каждого региона
  3. Проведена подготовка к расчёту прибыли:
  4. Рассчитаны риски и прибыль для каждого региона.

Чек-лист готовности проекта¶

Поставьте ‘x’ в выполненных пунктах. Далее нажмите Shift+Enter.

  • [x] Jupyter Notebook открыт
  • [x] Весь код выполняется без ошибок
  • [x] Ячейки с кодом расположены в порядке исполнения
  • [x] Выполнен шаг 1: данные подготовлены
  • [x] Выполнен шаг 2: модели обучены и проверены
    • [x] Данные корректно разбиты на обучающую и валидационную выборки
    • [x] Модели обучены, предсказания сделаны
    • [x] Предсказания и правильные ответы на валидационной выборке сохранены
    • [x] На экране напечатаны результаты
    • [x] Сделаны выводы
  • [x] Выполнен шаг 3: проведена подготовка к расчёту прибыли
    • [x] Для всех ключевых значений созданы константы Python
    • [x] Посчитано минимальное среднее количество продукта в месторождениях региона, достаточное для разработки
    • [x] По предыдущему пункту сделаны выводы
    • [x] Написана функция расчёта прибыли
  • [x] Выполнен шаг 4: посчитаны риски и прибыль
    • [x] Проведена процедура Bootstrap
    • [x] Все параметры бутстрепа соответствуют условию
    • [x] Найдены все нужные величины
    • [x] Предложен регион для разработки месторождения
    • [x] Выбор региона обоснован

Политика конфиденциальности

Продолжая использовать данный сайт вы подтверждаете свое согласие с условиями его политики конфиденциальности. Подробнее…




Администрация и владельцы данного информационного ресурса не несут ответственности за возможные последствия, связанные с использованием информации, размещенной на нем.


Все права защищены. При копировании материалов сайта обязательно указывать ссылку на © Microsegment.ru (2020-2025)