LEFT JOIN MA_NAPA_DPI_STAT_201704 c ON a.ID_CLIENT = c.CLIENT_ID AND a.BILLING_ID = c.CITY_ID \
LEFT JOIN PREDICT_BIL_201704 d ON a.ID_CLIENT = d.ID_CLIENT AND a.BILLING_ID = d.BILLING_ID \
LEFT JOIN PREDICT_CAT_201704 e ON a.ID_CLIENT = e.ID_CLIENT AND a.BILLING_ID = e.BILLING_ID \
LEFT JOIN PREDICT_CAMP_201704 f ON a.ID_CLIENT = f.ID_CLIENT AND a.BILLING_ID = f.BILLING_ID \
INNER JOIN \
(SELECT ID_CLIENT, BILLING_ID, VIASAT_ON FROM CA_201704 WHERE VIASAT_ON IS NOT NULL) g \
ON a.ID_CLIENT = g.ID_CLIENT AND a.BILLING_ID = g.BILLING_ID'
# Определение запроса SQL для получения данных за 201705
sql_query_201705 = 'SELECT DISTINCT g.VIASAT_ON, \
a.ID_CLIENT, a.BILLING_ID, a.CALC_PERIOD, CL_PRIV, ADP_AMEDIAPREMIUMHD, ADP_BAZOVYYHD, ADP_MATCHFUTBOL, ADP_NASTROYKINO, AG_BEFORE_PAID_SVOD, AG_COUNT_ACT_IKTV, \
AG_COUNT_CHANNEL_HD_TOTAL, AG_COUNT_CHANNEL_TOTAL, AG_IKTV_ARPU, AG_IKTV_TARIFF_ARCH, AG_INTER_ARPU, AG_MULTIROOM_COST, AG_MULTISCR, AG_PAY_CUR_MONTH, APP_NASTROYKINO, \
PAY_ARPU_SUMM, PAY_COUNT_ADD_PACK_DISC, \
HOME2_VISITS_DAYS_WKND_M, LEISURE2_VISITS_DAYS_WKND_M, MAX_SHOPS2_VISITS_DAY_CNT, MAX_SPORT2_VISITS_DAY_CNT, NEWS_VISITS_DAYS_WKND_M, SHOPS2_VISITS_DAYS_WKND_M, \
SHOPS2_VISITS_SHARE_M, SOC_VISITS_DAYS_WKND_M, SOCCER_VISITS_DAYS_WKND_M, SPORT2_VISITS_CNT_WKND_M, SPORT2_VISITS_DAYS_M, SPORT2_VISITS_SHARE_WORKD_M, \
CNT_AD_SERV_IKTV_CM, HAS_PC_MFUT_CM, HAS_PC_NASTKIN_CM, HAS_AD_PC_CM, CNT_TELE_AD_PC_CM, MAX_DAYS_FILM_AD_PC_CM, AG_IKTV_ARPU_CM, PAY_ARPU_SUMM_CM, HAS_ANY_AD_SERV_CM, \
CNT_FILM_AD_PC_PPM, AG_INTER_ARPU_PPM, AG_IKTV_ARPU_MORE_AVG_AAB, AG_INTER_ARPU_TO_MEDIAN_AAB, AG_INTER_ARPU_MORE_MOD_AAB, PAY_ARPU_SUMM_TO_MOD_AAB, \
PAY_ARPU_SUMM_MORE_AVG_AAB, MONTHPART_PC_MFUT_CM, MONTHPART_PC_NASTKIN_CM, \
MINUTES_COMMUN_CM, MINUTES_COMMUN_SPECPREDLK_CM, CNT_UNIQ_CHANNEL_CM, CNT_LOYAL_CM, MINUTES_LOYAL_CM, CNT_ESPONSE_2_CM, CNT_RESPONSE_3_CM, GP_2_OBJ_SOHR_CM, \
GP_3_OBJ_DZ_CM, MIN_ONE_COMM_SPECPREDLK_PM, CNT_COMMUN_PPM, MINUTES_COMMUN_SPECPREDLK_PPM, MINUTES_LOYAL_PPM, CNT_ESPONSE_2_PPM, CNT_LOYAL_CM_TO_PM, GP_2_OBJ_RAZVUSL_PPM, \
MAX_SPORT_HTTP_VISITS_CM, CNT_SPORT_HTTP_WKND_CM, CNT_DAYS_SPORT_HTTP_CM, SPORT_HTTP_TO_ALL_CM, CNT_DAYS_HOMELIFE_HTTP_CM, CNT_SPORT_HTTP_PM, SPORT_HTTP_CNT_TO_DAYS_PM, \
CNT_DAYS_INTBUY_HTTP_PM, FILM_HTTP_TO_ALL_PPM, CNT_DAYS_SPORT_HTTP_PPM, SPORT_HTTP_SHARE_CM_MORE_PM, INTBUY_HTTP_SHARE_CM_MORE_PM, HOMELIFE_HTTP_SHARE_CM_MORE_PM, \
NEWS_VISITS_CM_TO_PM, \
ANT_KASPERSKY_DAYS_MNTH, APP_BOOKING_DAYS_M, APP_DROPBOX_DAYS_M, APP_VIBER_DAYS_MNTH, APP_WHATSAPP_DAYS_MNTH, APP_YA_MAPS_DAYS_M, APP_YA_TAXI_DAYS_M, \
DEV_CONSOLE_PS_DAYS_MNTH, DEV_CONSOLE_XBOX_DAYS_MNTH, HTTP_VIS_ANDD_WKND_SHARE_MNTH, HTTP_VIS_S_TV_WORKD_SHARE_MNTH, OBP_SBERBANK_DAYS_M, PROTO_HTTP_DAYS_M, \
PROTO_HTTP_SHARE_MNTH, PROTO_OTHER_DAYS_M, PROTO_TORRENT_DAYS_M, PROTO_TOTAL_DAYS_M, WTHT_HTTP_VIS_S_TV_DAYS_ALL, WTHT_HTTP_VIS_WIN_M_DAYS_ALL, WTHT_HTTP_VISITS_DAYS \
FROM MA_CLIENT_DATA_MART_201705 a \
INNER JOIN MA_NAPA_DPI_CAT_201705 b ON a.ID_CLIENT = b.CLIENT_ID AND a.BILLING_ID = b.CITY_ID \
LEFT JOIN MA_NAPA_DPI_STAT_201705 c ON a.ID_CLIENT = c.CLIENT_ID AND a.BILLING_ID = c.CITY_ID \
LEFT JOIN PREDICT_BIL_201705 d ON a.ID_CLIENT = d.ID_CLIENT AND a.BILLING_ID = d.BILLING_ID \
LEFT JOIN PREDICT_CAT_201705 e ON a.ID_CLIENT = e.ID_CLIENT AND a.BILLING_ID = e.BILLING_ID \
LEFT JOIN PREDICT_CAMP_201705 f ON a.ID_CLIENT = f.ID_CLIENT AND a.BILLING_ID = f.BILLING_ID \
INNER JOIN \
(SELECT ID_CLIENT, BILLING_ID, VIASAT_ON FROM CA_201705 WHERE VIASAT_ON IS NOT NULL) g \
ON a.ID_CLIENT = g.ID_CLIENT AND a.BILLING_ID = g.BILLING_ID'
%%time
# Magic %%time для фиксации времени выполнения запроса
conn = None # Объявление переменной для соединения с БД
# Отлавливаем ошибку отсутствия подключения к заданной БД
try:
conn = cx_Oracle.connect("ext_consult/GfhjkmGjlhzlxbrf@DM") # Объявляем соединение с БД
df201703 = pd.read_sql(sql_query_201703, conn) # Получение DataFrame по запросу SQL
finally:
if conn is not None:
conn.close() # Закрываем соединение с БД
# Проверяем количество записей с целевой меткой
# 1 для определения объема обучающей выборки
df201703[df201703.VIASAT_ON == 1].shape
df201703tr = df201703[df201703.VIASAT_ON == 1]
# Получение всех записей со значением целевой метки, равным 1
df201703fls = df201703[df201703.VIASAT_ON == 0].sample(60000, axis = 0)
# Получение всех записей с негативными исходами,
# выделение случайным образом выборки объемом 60000 записей
del df201703 # Удаление DataFrame со свеми данными за период 201703 (с целью освобождения памяти)
%%time
# Magic %%time для фиксации времени выполнения запроса
conn = None # Объявление переменной для соединения с БД
# Отлавливаем ошибку отсутствия подключения к заданной БД
try:
conn = cx_Oracle.connect("ext_consult/GfhjkmGjlhzlxbrf@DM") # Объявляем соединение с БД
df201704 = pd.read_sql(sql_query_201704, conn) # Получение DataFrame по запросу SQL
finally:
if conn is not None:
conn.close() # Закрываем соединение с БД
df201704tr = df201704[df201704.VIASAT_ON == 1] # Получение всех записей со значением целевой метки, равным 1
df201704fls = df201704[df201704.VIASAT_ON == 0].sample(60000, axis = 0) # Получение всех записей с негативными исходами,
# выделение случайным образом выборки объемом 60000 записей
del df201704 # Удаление DataFrame со свеми данными за период 201704 (с целью освобождения памяти)
%%time
# Magic %%time для фиксации времени выполнения запроса
conn = None # Объявление переменной для соединения с БД
# Отлавливаем ошибку отсутствия подключения к заданной БД
try:
conn = cx_Oracle.connect("ext_consult/GfhjkmGjlhzlxbrf@DM") # Объявляем соединение с БД
df201705 = pd.read_sql(sql_query_201705, conn) # Получение DataFrame по запросу SQL
finally:
if conn is not None:
conn.close() # Закрываем соединение с БД
df201705tr = df201705[df201705.VIASAT_ON == 1] # Получение всех записей со значением целевой метки, равным 1
df201705fls = df201705[df201705.VIASAT_ON == 0].sample(60000, axis = 0) # Получение всех записей с негативными исходами,
# выделение случайным образом выборки объемом 60000 записей
del df201705 # Удаление DataFrame со свеми данными за период 201705 (с целью освобождения памяти)
# Создание обучающей выборки за 201703 - 201705
df = pd.concat([df201703tr, df201703fls, df201704tr, df201704fls, df201705tr, df201705fls], axis = 0, ignore_index = True) # Вертикальная конкатенация датасетов
# с целевой меткой 0 и 1 за 201703, 201704, 201705
# Определение DataFrame с исключительно вещественными значениями (без бинарных, категориальных и дат)
df1 = df[['ADP_AMEDIAPREMIUMHD', 'ADP_BAZOVYYHD', 'ADP_MATCHFUTBOL', 'ADP_NASTROYKINO', 'AG_BEFORE_PAID_SVOD', 'AG_COUNT_ACT_IKTV',
'AG_COUNT_CHANNEL_HD_TOTAL', 'AG_COUNT_CHANNEL_TOTAL', 'AG_IKTV_ARPU', 'AG_INTER_ARPU', 'AG_MULTIROOM_COST', 'AG_MULTISCR', 'AG_PAY_CUR_MONTH', 'APP_NASTROYKINO',
'PAY_ARPU_SUMM', 'PAY_COUNT_ADD_PACK_DISC',
'HOME2_VISITS_DAYS_WKND_M', 'LEISURE2_VISITS_DAYS_WKND_M', 'MAX_SHOPS2_VISITS_DAY_CNT', 'MAX_SPORT2_VISITS_DAY_CNT', 'NEWS_VISITS_DAYS_WKND_M', 'SHOPS2_VISITS_DAYS_WKND_M',
'SHOPS2_VISITS_SHARE_M', 'SOC_VISITS_DAYS_WKND_M', 'SOCCER_VISITS_DAYS_WKND_M', 'SPORT2_VISITS_CNT_WKND_M', 'SPORT2_VISITS_DAYS_M', 'SPORT2_VISITS_SHARE_WORKD_M',
'CNT_AD_SERV_IKTV_CM', 'CNT_TELE_AD_PC_CM', 'MAX_DAYS_FILM_AD_PC_CM', 'AG_IKTV_ARPU_CM', 'PAY_ARPU_SUMM_CM',
'CNT_FILM_AD_PC_PPM', 'AG_INTER_ARPU_PPM', 'AG_INTER_ARPU_TO_MEDIAN_AAB', 'PAY_ARPU_SUMM_TO_MOD_AAB',
'MONTHPART_PC_MFUT_CM', 'MONTHPART_PC_NASTKIN_CM',
'MINUTES_COMMUN_CM', 'MINUTES_COMMUN_SPECPREDLK_CM', 'CNT_UNIQ_CHANNEL_CM', 'CNT_LOYAL_CM', 'MINUTES_LOYAL_CM', 'CNT_ESPONSE_2_CM', 'CNT_RESPONSE_3_CM',
'MIN_ONE_COMM_SPECPREDLK_PM', 'CNT_COMMUN_PPM', 'MINUTES_COMMUN_SPECPREDLK_PPM', 'MINUTES_LOYAL_PPM', 'CNT_ESPONSE_2_PPM', 'CNT_LOYAL_CM_TO_PM',
'MAX_SPORT_HTTP_VISITS_CM', 'CNT_SPORT_HTTP_WKND_CM', 'CNT_DAYS_SPORT_HTTP_CM', 'SPORT_HTTP_TO_ALL_CM', 'CNT_DAYS_HOMELIFE_HTTP_CM', 'CNT_SPORT_HTTP_PM', 'SPORT_HTTP_CNT_TO_DAYS_PM',
'CNT_DAYS_INTBUY_HTTP_PM', 'FILM_HTTP_TO_ALL_PPM', 'CNT_DAYS_SPORT_HTTP_PPM', 'SPORT_HTTP_SHARE_CM_MORE_PM', 'INTBUY_HTTP_SHARE_CM_MORE_PM', 'HOMELIFE_HTTP_SHARE_CM_MORE_PM',
'NEWS_VISITS_CM_TO_PM',
'ANT_KASPERSKY_DAYS_MNTH', 'APP_BOOKING_DAYS_M', 'APP_DROPBOX_DAYS_M', 'APP_VIBER_DAYS_MNTH', 'APP_WHATSAPP_DAYS_MNTH', 'APP_YA_MAPS_DAYS_M', 'APP_YA_TAXI_DAYS_M',
'DEV_CONSOLE_PS_DAYS_MNTH', 'DEV_CONSOLE_XBOX_DAYS_MNTH', 'HTTP_VIS_ANDD_WKND_SHARE_MNTH', 'HTTP_VIS_S_TV_WORKD_SHARE_MNTH', 'OBP_SBERBANK_DAYS_M', 'PROTO_HTTP_DAYS_M',
'PROTO_HTTP_SHARE_MNTH', 'PROTO_OTHER_DAYS_M', 'PROTO_TORRENT_DAYS_M', 'PROTO_TOTAL_DAYS_M', 'WTHT_HTTP_VIS_S_TV_DAYS_ALL', 'WTHT_HTTP_VIS_WIN_M_DAYS_ALL', 'WTHT_HTTP_VISITS_DAYS']]
# Определение пользовательской функции борьбы с выбросами
def mist(dtfrm):
for col in dtfrm.columns: # Для каждого поля из DataFrame
df2 = dtfrm[col].dropna().sort_values(ascending = True) # Создаем DataFrame, удаляя пустые значения для данного поля и сортируя по возрастанию значения
df2 = df2.reset_index(drop = True) # Реиндексируем DataFrame
qty_25 = math.ceil(df2.shape[0] * 0.25) # Определяем номер строки, содержащей 25-квантиль
qty_75 = math.ceil(df2.shape[0] * 0.75) # Определяем номер строки, содержащей 75-квантиль
q_25 = df2[df2.index == qty_25].item() # Находим 25-квантиль
q_75 = df2[df2.index == qty_75].item() # Находим 75-квантиль
iqr = math.ceil((q_75 - q_25) * 1.5) # Находим полтора квантильных размаха
min_q = q_25 - iqr # Находим минимально допустимое значение, которое не будет считаться выбросом
max_q = q_75 + iqr # Находим максимально допустимое значение, которое не будет считаться выбросом
med = df2.median() # Находим медиану
i = 0
while i < dtfrm[col].shape[0]: # Перебираем все строки из DataFrame
if ((dtfrm[col][i] < min_q) | (dtfrm[col][i] > max_q)): # Если значение в строке меньше наименее допустимого или больше наиболее допустимого,
dtfrm[col][i] = med # То меняем данное значение на медиану
i += 1 # Переходим к следующей строке
return dtfrm # Возвращаем полученный DataFrame
mist(df1) # Применение определенной выше функции
for col in df.coumns:
df[col] = df1[col] # Заменяем атрибуты исходного DataFrame полями, полученными после применения функции
# Проверка на наличие Null-значений, заполнение пропусков либо значением 30
if df.isnull().values.any() == True:
df['WTHT_HTTP_VIS_S_TV_DAYS_ALL'] = df['WTHT_HTTP_VIS_S_TV_DAYS_ALL'].fillna(30)
df['WTHT_HTTP_VIS_WIN_M_DAYS_ALL'] = df['WTHT_HTTP_VIS_WIN_M_DAYS_ALL'].fillna(30)
df['WTHT_HTTP_VISITS_DAYS'] = df['WTHT_HTTP_VISITS_DAYS'].fillna(30)
# Создание dummy-переменных на основании категориальных признаков для обучающей выборки
df = pd.get_dummies(df, columns = ['MONTHPART_PC_MFUT_CM','MONTHPART_PC_NASTKIN_CM'], drop_first = True)
# Выведение полученного DataFrame (Видим, что количество атрибутов увеличено за счет создания dummy)
df.head()
# В блоке производится очистка большинства производных от dummy атрибутов
df1 = [] # Сохдание дополнительных массивов для удаления производных от dummy-переменных атрибутов
df2 = []
for col in df.columns: # Поиск необходимых для сохранения атрибутов
if ((('MONTHPART_PC_MFUT_CM_' not in col) | (col == 'MONTHPART_PC_MFUT_CM_1')) &
(('MONTHPART_PC_NASTKIN_CM_' not in col) | (col == 'MONTHPART_PC_NASTKIN_CM_1'))):
df1.append(col) # Добавление названий атрибутов в list
for i in df1:
df2.append(df[i]) # Добавление полей из df с названиями атрибутов из df1 в list
df = pd.DataFrame(df2).transpose() # Преобразование полученного выше list в DataFrame
del df1, df2 # Удаление вспомогательных массивов
# Выведениие итогового DataFrame на экран
df.head()
train_labels = df['VIASAT_ON'] # Определение целевых меток для обучающей выборки
train_data = df.drop(['VIASAT_ON', 'ID_CLIENT', 'BILLING_ID', 'CALC_PERIOD'], axis = 1) # Определение предикторов для обучающей выборки
# Определение запроса для получения данных за 201706 (для проведения тестов)
sql_query_201706 = 'SELECT DISTINCT g.VIASAT_ON, \
a.ID_CLIENT, a.BILLING_ID, a.CALC_PERIOD, CL_PRIV, ADP_AMEDIAPREMIUMHD, ADP_BAZOVYYHD, ADP_MATCHFUTBOL, ADP_NASTROYKINO, AG_BEFORE_PAID_SVOD, AG_COUNT_ACT_IKTV, \
AG_COUNT_CHANNEL_HD_TOTAL, AG_COUNT_CHANNEL_TOTAL, AG_IKTV_ARPU, AG_IKTV_TARIFF_ARCH, AG_INTER_ARPU, AG_MULTIROOM_COST, AG_MULTISCR, AG_PAY_CUR_MONTH, APP_NASTROYKINO, \
PAY_ARPU_SUMM, PAY_COUNT_ADD_PACK_DISC, \
HOME2_VISITS_DAYS_WKND_M, LEISURE2_VISITS_DAYS_WKND_M, MAX_SHOPS2_VISITS_DAY_CNT, MAX_SPORT2_VISITS_DAY_CNT, NEWS_VISITS_DAYS_WKND_M, SHOPS2_VISITS_DAYS_WKND_M, \
SHOPS2_VISITS_SHARE_M, SOC_VISITS_DAYS_WKND_M, SOCCER_VISITS_DAYS_WKND_M, SPORT2_VISITS_CNT_WKND_M, SPORT2_VISITS_DAYS_M, SPORT2_VISITS_SHARE_WORKD_M, \
CNT_AD_SERV_IKTV_CM, HAS_PC_MFUT_CM, HAS_PC_NASTKIN_CM, HAS_AD_PC_CM, CNT_TELE_AD_PC_CM, MAX_DAYS_FILM_AD_PC_CM, AG_IKTV_ARPU_CM, PAY_ARPU_SUMM_CM, HAS_ANY_AD_SERV_CM, \
CNT_FILM_AD_PC_PPM, AG_INTER_ARPU_PPM, AG_IKTV_ARPU_MORE_AVG_AAB, AG_INTER_ARPU_TO_MEDIAN_AAB, AG_INTER_ARPU_MORE_MOD_AAB, PAY_ARPU_SUMM_TO_MOD_AAB, \
PAY_ARPU_SUMM_MORE_AVG_AAB, MONTHPART_PC_MFUT_CM, MONTHPART_PC_NASTKIN_CM, \
MINUTES_COMMUN_CM, MINUTES_COMMUN_SPECPREDLK_CM, CNT_UNIQ_CHANNEL_CM, CNT_LOYAL_CM, MINUTES_LOYAL_CM, CNT_ESPONSE_2_CM, CNT_RESPONSE_3_CM, GP_2_OBJ_SOHR_CM, \
GP_3_OBJ_DZ_CM, MIN_ONE_COMM_SPECPREDLK_PM, CNT_COMMUN_PPM, MINUTES_COMMUN_SPECPREDLK_PPM, MINUTES_LOYAL_PPM, CNT_ESPONSE_2_PPM, CNT_LOYAL_CM_TO_PM, GP_2_OBJ_RAZVUSL_PPM, \
MAX_SPORT_HTTP_VISITS_CM, CNT_SPORT_HTTP_WKND_CM, CNT_DAYS_SPORT_HTTP_CM, SPORT_HTTP_TO_ALL_CM, CNT_DAYS_HOMELIFE_HTTP_CM, CNT_SPORT_HTTP_PM, SPORT_HTTP_CNT_TO_DAYS_PM, \
CNT_DAYS_INTBUY_HTTP_PM, FILM_HTTP_TO_ALL_PPM, CNT_DAYS_SPORT_HTTP_PPM, SPORT_HTTP_SHARE_CM_MORE_PM, INTBUY_HTTP_SHARE_CM_MORE_PM, HOMELIFE_HTTP_SHARE_CM_MORE_PM, \
NEWS_VISITS_CM_TO_PM, \
ANT_KASPERSKY_DAYS_MNTH, APP_BOOKING_DAYS_M, APP_DROPBOX_DAYS_M, APP_VIBER_DAYS_MNTH, APP_WHATSAPP_DAYS_MNTH, APP_YA_MAPS_DAYS_M, APP_YA_TAXI_DAYS_M, \
DEV_CONSOLE_PS_DAYS_MNTH, DEV_CONSOLE_XBOX_DAYS_MNTH, HTTP_VIS_ANDD_WKND_SHARE_MNTH, HTTP_VIS_S_TV_WORKD_SHARE_MNTH, OBP_SBERBANK_DAYS_M, PROTO_HTTP_DAYS_M, \
PROTO_HTTP_SHARE_MNTH, PROTO_OTHER_DAYS_M, PROTO_TORRENT_DAYS_M, PROTO_TOTAL_DAYS_M, WTHT_HTTP_VIS_S_TV_DAYS_ALL, WTHT_HTTP_VIS_WIN_M_DAYS_ALL, WTHT_HTTP_VISITS_DAYS \
FROM MA_CLIENT_DATA_MART_201706 a \
LEFT JOIN MA_NAPA_DPI_CAT_201706 b ON a.ID_CLIENT = b.CLIENT_ID AND a.BILLING_ID = b.CITY_ID \
LEFT JOIN MA_NAPA_DPI_STAT_201706 c ON a.ID_CLIENT = c.CLIENT_ID AND a.BILLING_ID = c.CITY_ID \
LEFT JOIN PREDICT_BIL_201706 d ON a.ID_CLIENT = d.ID_CLIENT AND a.BILLING_ID = d.BILLING_ID \
LEFT JOIN PREDICT_CAT_201706 e ON a.ID_CLIENT = e.ID_CLIENT AND a.BILLING_ID = e.BILLING_ID \
LEFT JOIN PREDICT_CAMP_201706 f ON a.ID_CLIENT = f.ID_CLIENT AND a.BILLING_ID = f.BILLING_ID \
INNER JOIN \
(SELECT ID_CLIENT, BILLING_ID, VIASAT_ON FROM CA_201706 WHERE VIASAT_ON IS NOT NULL) g \
ON a.ID_CLIENT = g.ID_CLIENT AND a.BILLING_ID = g.BILLING_ID'
%%time
# Magic %%time для фиксации времени выполнения запроса
conn = None # Объявление переменной для соединения с БД
# Отлавливаем ошибку отсутствия подключения к заданной БД
try:
conn = cx_Oracle.connect("ext_consult/GfhjkmGjlhzlxbrf@DM") # Объявляем соединение с БД
df201706 = pd.read_sql(sql_query_201706, conn) # Получение DataFrame по запросу SQL
finally:
if conn is not None:
conn.close() # Закрываем соединение с БД
# Проверка на наличие Null-значений, заполнение пропусков либо значением 30
if df201706.isnull().values.any() == True:
df201706['WTHT_HTTP_VIS_S_TV_DAYS_ALL'] = df201706['WTHT_HTTP_VIS_S_TV_DAYS_ALL'].fillna(30)
df201706['WTHT_HTTP_VIS_WIN_M_DAYS_ALL'] = df201706['WTHT_HTTP_VIS_WIN_M_DAYS_ALL'].fillna(30)
df201706['WTHT_HTTP_VISITS_DAYS'] = df201706['WTHT_HTTP_VISITS_DAYS'].fillna(30)
# Создание dummy-переменных на основании категориальных признаков для тестовой выборки
df201706 = pd.get_dummies(df201706, columns = ['MONTHPART_PC_MFUT_CM','MONTHPART_PC_NASTKIN_CM'], drop_first = True)
# В блоке производится очистка большинства производных от dummy атрибутов
df1 = [] # Сохдание дополнительных массивов для удаления производных от dummy-переменных атрибутов
df2 = []
for col in df201706.columns: # Поиск необходдимых для сохранения атрибутов
if ((('MONTHPART_PC_MFUT_CM_' not in col) | (col == 'MONTHPART_PC_MFUT_CM_1')) &
(('MONTHPART_PC_NASTKIN_CM_' not in col) | (col == 'MONTHPART_PC_NASTKIN_CM_1'))):
df1.append(col) # Добавление названий атрибутов в list
for i in df1:
df2.append(df201706[i]) # Добавление полей из df201706 с названиями атрибутов из df1 в list
df201706 = pd.DataFrame(df2).transpose() # Преобразование полученного выше list в DataFrame
del df1, df2 # Удаление вспомогательных массивов
test_labels = df201706['VIASAT_ON'] # Определение целевых меток для тестовой выборки
test_data = df201706.drop(['VIASAT_ON', 'ID_CLIENT', 'BILLING_ID', 'CALC_PERIOD'], axis = 1) # Определение предикторов для тестовой выборки
# Создание пользовательской функции для расчета cummulative lift
def cumm_lift(DataFrame, booster, test_set):
pred = pd.DataFrame(booster.predict(test_set), columns = ['pred']) # Создание переменной, хранящей прогнозные значения вероятностей принадлежности к классу 1
result = pd.concat([DataFrame['VIASAT_ON'],DataFrame['ID_CLIENT'],DataFrame['BILLING_ID'],DataFrame['CALC_PERIOD'], pred], axis = 1) # Создание DataFrame, хранящего фактические значения целевой переменной, идентификаторы Клиента, биллинга и периода, а также