Прогнозирование приемлемости кредита: обработка данных-2
В последней части этой серии я показал основные операции обработки данных, которые включают в себя: удаление постоянных функций, удаление повторяющихся функций, удаление повторяющихся строк, удаление функций, связанных ›85% отсутствующих значений. Это предварительные шаги, которые нам нужно выполнить почти для каждого набора данных. После завершения описанной выше обработки мы сократили количество функций со 153 до 93. В этой части я рассмотрю каждую функцию вручную, обработаю их и удаляю ненужные функции.
В последней части мы сохранили все точки данных в одном фрейме данных «df». Начнем изучать форму данных.
df.shape (457728, 93)
Мы видим, что теперь у нас есть 93 функции. Прежде чем мы исследуем каждую функцию, нам нужно создать функцию графика для визуализации. По этой ссылке я позаимствовал следующую функцию.
Вышеупомянутая функция принимает два параметра; первая - это имя функции, а вторая - логическая переменная: независимо от того, является ли функция непрерывной или категориальной. Если функция является непрерывной, то функция строит две подзаголовки: (1) распределение признака и (2) две коробчатые диаграммы на основе класса credit_status. С другой стороны, если признак является категориальным, то первый подзаголовок является графиком подсчета, а второй подзаголовок основан на классах group_by ссуды_статус.
Следующие коды в основном не требуют пояснений. Я иногда опускаю подробные пояснения.
Функции 0–10:
df.iloc[0:5, 0: 10]
Функция: сумма кредита
### Feature: loan_amnt ------------------------------- len(df.loan_amnt.value_counts()) 1415 plot_feature('loan_amnt', True)
Похоже, все кредиты не уникальны. Определенная сумма выпадает несколько раз. Это может быть причиной; у компании есть некоторый диапазон или определенная сумма для ссуды.
Функция: термин
### Feature: term ------------------------------- df.term = df.term.str.replace('months', '').astype(np.int) df.term.value_counts() 36 341042 60 116686 Name: term, dtype: int64 plot_feature('term', False)
Функция: процентная ставка
### Feature: int_rate ------------------------------- df.int_rate = df.int_rate.str.replace('%', '').astype(np.float32) len(df.int_rate.value_counts()) 200 plot_feature('int_rate', True)
Похоже, что заявители, которые не могли позволить себе выплатить долг и в конечном итоге были списаны со счетов, должны были заплатить более высокую процентную ставку.
Характеристики: уклон и земляное полотно
Кажется, что grade и sub_grade имеют одинаковую форму и взаимосвязь со статусом ссуды. В этом случае я бы оставил sub_grade, потому что он несет больше информации, чем оценка.
Функция: должность
### Feature: emp_title ------------------------------- len(df.emp_title.value_counts()) 128310 It looks like emp_title has lots of unique value, which may not strongly be associated with predicted loan_status. Therefore, I delete the feature. features_to_be_removed.extend(['emp_title', 'id'])
11–20 функций
df.iloc[0:5, 6: 20]
На правом графике похоже, что emp_lenght не является сильным предсказателем и имеет небольшую связь со статусом ссуды. Я сохраняю эту функцию прямо сейчас, в зависимости от производительности модели, мы можем удалить ее.
Feature: Home_ownership
Функция: статус подтверждения
Функция verify_status несколько различается в том смысле, что среди заявителей, чей источник был проверен, больше шансов быть списанным с того, что немного связано.
Функция: Issue_d
### Feature: issue_d ### ------------------ df.issue_d.value_counts() Oct-2014 33699 Jul-2014 25974 Jul-2015 23990 Jan-2015 22750 Oct-2015 22431 Nov-2014 21186 Apr-2015 20097 Dec-2015 19106 May-2015 17964 Aug-2015 17492 Apr-2014 17140 May-2014 17133 Aug-2014 16780 Nov-2015 16540 Jun-2015 15304 Jun-2014 15207 Mar-2015 14997 Mar-2014 14988 Feb-2015 14464 Jan-2014 14464 Feb-2014 13945 Sep-2015 13838 Sep-2014 9344 Dec-2014 8283 Jan-2017 5912 Mar-2017 5008 Feb-2017 4241 May-2017 3644 Apr-2017 3431 Jun-2017 2849 Jul-2017 2366 Aug-2017 1863 Sep-2017 1298 Name: issue_d, dtype: int64
Функция «Issue_d» - это строка. Поскольку мы имеем дело с данными за три года и сохраняем независимость нашей модели от года, я извлекаю только месяц, а затем конвертирую их в категории.
df['issue_month'] = pd.Series(df.issue_d).str.replace(r'-\d+', '') plot_feature('issue_month', False)
Похоже, что у людей, взявших в долг в декабре, больше шансов списать деньги, чем у тех, кто занимал в другие месяцы. Действительно интересно.
df.issue_month = df.issue_month.astype("category", categories=np.unique(df.issue_month)).cat.codes df.issue_month.value_counts() 10 56130 5 52330 4 43126 0 40668 8 38741 9 37726 1 36135 7 34993 6 33360 3 32650 2 27389 11 24480 Name: issue_month, dtype: int64 df['issue_year'] = pd.Series(df.issue_d).str.replace(r'\w+-', '').astype(np.int) df.issue_year.value_counts() 2015 218973 2014 208143 2017 30612 Name: issue_year, dtype: int64
Поскольку URL-адрес не имеет ничего общего с кредитным_статусом, я просто удаляю его.
Функция: цель
Похоже, цель может быть хорошей дискриминацией. Например, люди, которые взяли ссуду на возобновляемую энергию, с большей вероятностью будут списаны, чем соискатели, которые взяли ссуду на автомобили или образовательные цели.
Поскольку заголовок и почтовый индекс имеют много уникальных значений, я просто удаляю их из пространства функций.
Функция: состояние адреса
Функция addr_state имеет пятьдесят уникальных значений, поскольку существует пятьдесят состояний. Если мы посмотрим на график ниже, то увидим, что кандидаты из одних штатов заплатили больше, чем другие. Следовательно, эта особенность может быть дискриминационной.
21–30 функций
31–40 функций
df.iloc[0:5, 25: 40]
41–50 функций
df.iloc[0:5, 35: 50]
51–60 функций
61–70 функций
71–80 функций
81–90 функций
91 остальные функции
df.iloc[0:5, 85:]
Удаленные функции
Проверив каждую функцию вручную, я обнаружил, что 61 неуместная. Давайте посмотрим, какие функции выбраны для удаления.
len(set(features_to_be_removed)) 61 print(features_to_be_removed) ['emp_title', 'id', 'url', 'title', 'zip_code', 'issue_d', 'mths_since_last_delinq', 'mths_since_last_record', 'inq_last_6mths', 'mths_since_last_delinq', 'mths_since_last_record', 'total_pymnt', 'total_pymnt_inv', 'total_rec_prncp', 'total_rec_int', 'total_rec_late_fee', 'recoveries', 'collection_recovery_fee', 'last_pymnt_d', 'last_pymnt_amnt', 'last_credit_pull_d', 'last_fico_range_high', 'last_fico_range_low', 'collections_12_mths_ex_med', 'mths_since_last_major_derog', 'acc_now_delinq', 'tot_coll_amt', 'tot_cur_bal', 'total_rev_hi_lim', 'avg_cur_bal', 'bc_open_to_buy', 'bc_util', 'chargeoff_within_12_mths', 'delinq_amnt', 'mo_sin_old_il_acct', 'mo_sin_old_rev_tl_op', 'mo_sin_rcnt_rev_tl_op', 'mo_sin_rcnt_tl', 'mths_since_recent_bc', 'mths_since_recent_bc_dlq', 'mths_since_recent_inq', 'mths_since_recent_revol_delinq', 'num_accts_ever_120_pd', 'num_actv_bc_tl', 'num_actv_rev_tl', 'num_bc_sats', 'num_bc_tl', 'num_il_tl', 'num_op_rev_tl', 'num_rev_accts', 'num_rev_tl_bal_gt_0', 'num_sats', 'num_tl_120dpd_2m', 'num_tl_30dpd', 'num_tl_90g_dpd_24m', 'num_tl_op_past_12m', 'pct_tl_nvr_dlq', 'percent_bc_gt_75', 'tot_hi_cred_lim', 'total_bal_ex_mort', 'total_bc_limit', 'debt_settlement_flag', 'total_il_high_credit_limit']
И, наконец, я отказался от всех вышеперечисленных функций:
df_selected = df.drop(list(set(features_to_be_removed)), axis = 1) df_selected.shape (457728, 36)
В приведенном выше коде мы видим, что есть 36 финальных функций, готовых для создания модели прогнозирования кредита. Давайте также проверим, есть ли какие-либо пропущенные значения в любой из выбранных 36 функций.
Если вы запустите приведенный выше код, вы увидите, что «dti» и «revol_util» имеют 21 и 223 пропущенных значения. Я использую метод panda dropna (), чтобы удалить примеры, связанные с отсутствующими значениями.
Кодирование функции
Пришло время закодировать некоторые категориальные особенности. В следующем коде я закодировал «цель», «домовладение», «степень», «под_граду», «addr_state»:
Хорошо, давайте сохраним окончательный набор данных с выбранными функциями.
df_selected.to_csv('./data/df_selected.csv', index = False)
В следующей части серии я проведу предварительный анализ. Если возможно, сделайте некоторую разработку функций. А пока, если у вас есть какие-либо вопросы по этой части, пожалуйста, напишите комментарий ниже или вы можете связаться со мной:
Email: [email protected] LinkedIn: https://www.linkedin.com/in/sabber-ahamed/ Github: https://github.com/msahamed Medium: https://medium.com/@sabber/