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

Внимание! Если размещение файла нарушает Ваши авторские права, то обязательно сообщите нам

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, хранящего фактические значения целевой переменной, идентификаторы Клиента, биллинга и периода, а также

Источник: https://otherreferats.allbest.ru/download/1003541/