Серия инструментов с открытым исходным кодом для решения реальных задач
Я открываю новую серию под названием Инструменты с открытым исходным кодом для решения реальных проблем.
В этой серии я сначала рассмотрю инструмент с открытым исходным кодом, а затем покажу, как применять его для решения реальных задач. В ходе этого процесса я покажу весь код и перечислю все термины, теоремы и алгоритмы, которые вам необходимо знать.
Потенциальная аудитория:
- Студенты, которые хотят подробно описать проект в резюме и получить больше интервью.
- специалисты по данным/инженеры машинного обучения, которые хотят создать систему показателей и запустить ее в производство.
В этом блоге вы узнаете:
- Создайте систему показателей, используя машинное обучение с помощью Python.
- Набор навыков: Логистическая регрессия, Градиентный бустинг, Вес доказательства (WOE), Информационная ценность (IV), Биннинг, Биннинг хи-квадрат
Создание кредитной скоринговой карты — очень типичная проблема отраслевого уровня.
- оценка транзакцииили надежности клиента для выполнения дальнейших действий, таких каквыпуск кредитной карты или предложение перевода баланса для клиентов с высоким уровнем кредитоспособности в компании-эмитенте кредитных карт,
- предоставление рекламных акций или премиальных прав ценным клиентам на платформе электронной коммерции,
- предоставление хорошей сегментации клиентов для привлечения нужных людей в маркетинговой фирме.
Вам нужно создать систему для оценки клиентов, и она должна быть понятна для неспециалистов, потому что, когда что-то пойдет не так (ложная тревога), вы будете знать, как это сделать. объяснить это менеджеру/заказчику/деловой стороне.
Введение:
Код и данные для этого блога доступны здесь:
Инструмент с открытым исходным кодом: Жаба
Toad — готовая библиотека для создания оценочных карт; он предлагает EDA, разработку функций и создание оценочных карт. Его ключевые функции оптимизируют наиболее важные и трудоемкие процессы, такие как выбор функций и точное группирование.
Набор данных: набор данных клиентов кредитных карт по умолчанию
Описание можно найти на Kaggle. Исходный набор данных можно найти на UCI.
Есть 25 переменных:
- ID: идентификатор клиента.
- 23 функции включают: ограничение баланса, пол, образование, брак, возраст, погашение, сумма выписки по счету, сумма предыдущего платежа.
- Ярлык: платеж по умолчанию (1=да, 0=нет)
Предполагая, что вы специалист по данным в компании, выпускающей кредитные карты, ваш менеджер посоветовал вам создать систему показателей для существующих клиентов, чтобы стимулировать использование кредитных карт. , чтобы отправить им несколько предложений о переносе баланса. Допустим, 6 месяцев с 0 % годовых + 3 % комиссии.
У вас есть исторические данные об этих клиентах. Вы не хотите отправлять тем, кто постоянно дефолт, потому что они, вероятно, возьмут деньги и убегут. Ваша компания не сможет вернуть эти переводы через 6 месяцев, и это станет убытком для вашей компании. Вам также может понадобиться нанять коллекторское агентство для возврата этих долгов. Это плохо.
Так что все зависит от вашей системы показателей!
Давай начнем.
1. Предварительная обработка данных
В реальной жизни вам может понадобиться извлечь необработанные данные из базы данных вашей компании, используя SQL-подобный запрос; это может занять у вас много времени.
В этом блоге мы будем использовать только CSV-файл.
Установка и импорт пакетов
import pkg_resources import pip installedPackages = {pkg.key for pkg in pkg_resources.working_set} required = { 'pandas','numpy', 'matplotlib', 'seaborn','toad','pickle','sklearn'} missing = required - installedPackages if missing: !pip install pandas !pip install numpy !pip install matplotlib !pip install seaborn !pip install toad !pip install pickle !pip install sklearn import pandas as pd from sklearn.metrics import roc_auc_score,roc_curve,auc,precision_recall_curve from sklearn.model_selection import train_test_split from sklearn.linear_model import LogisticRegression from sklearn.ensemble import GradientBoostingClassifier import numpy as np import glob import math import seaborn as sns import matplotlib.pyplot as plt import toad import pickle
Загрузите данные и проверьте скорость метки по умолчанию
# use pandas to load the csv file data = pd.read_csv('UCI_Credit_Card.csv') # check the size of the data data.shape # check few lines data.head() #use the world 'label' data['label']=data['default.payment.next.month'] data=data.drop(columns=['default.payment.next.month']) #check the fraud proportion of the data target_info(data['label']) # set an exclude list for the scorecard package Toad exclude_list = ['ID','label']
Коэффициент мошенничества 22% (люди по умолчанию), это довольно высокий уровень по умолчанию в исторических данных.
Тренировочный и тестовый сплит
В реальном проекте вы можете захотеть разбить поезд и протестировать по дате/времени, делать случайное разбиение нехорошо, потому что это нарушит временной ряд и может привести к переоснащению.
Мы будем использовать идентификатор пользователя в качестве времени для разделения.
# use the ID column to split the train-test data data.ID.describe() train = data_split(data,start = 0, end=22500,date_col='ID') test = data_split(data,start = 22500, end=172792,date_col='ID')
2. Фильтрация функций
Во-первых, нам нужно выполнить фильтрацию функций, чтобы отбросить функции с низкой информационной ценностью и высокой корреляцией.
###feature filtering by missing value, IV & corrrelation: ##If the missing value rate is greater than the threshold, delete the feature ##If the correlation coefficient is greater than the threshold, delete the feature ##If the IV is smaller than the threshold, delete the features train_selected, drop_lst= toad.selection.select(frame = train, target=train['label'], empty = 0.7, iv = 0.02, corr = 1, return_drop=True, exclude=exclude_list) print("keep:",train_selected.shape[1], "drop empty:",len(drop_lst['empty']), "drop iv:",len(drop_lst['iv']), "drop corr:",len(drop_lst['corr']))
Таким образом, мы оставим в общей сложности 23 функции и исключим 2 функции ['SEX', 'MARIAGE'], потому что у них низкий IV.
- Весность доказательств (WOE) — описывает взаимосвязь между прогностической переменной и бинарной целевой переменной.
- Информационная ценность (IV) — измеряет силу этих отношений на основе WOE. На отраслевом уровне исключаются функции с IV ниже 0,02.
# output the iv table to a dataframe def output_iv_importance(train_selected,label_col): feat_import_iv = toad.quality(train_selected,label_col,iv_only=True) feat_import_iv=feat_import_iv['iv'] feat_import_iv = feat_import_iv.reset_index() feat_import_iv.columns = ['name','iv'] return feat_import_iv df_iv=output_iv_importance(train_selected,'label') df_iv.head(30)
Это IV рейтинг по всем характеристикам. Мы видим, что PAY_0 имеет самый высокий IV, что логично, поскольку эта функция указывает самый последний статус погашения. ОБРАЗОВАНИЕ и ВОЗРАСТ имеют низкий IV по сравнению со статусом и суммой платежа.
3. Биннинг функций
Биннинг признаков — это преобразование непрерывной или числовой переменной в категориальный признак.
Преимущества объединения функций:
- Он упрощаетмодель логистической регрессии и снижает риск переобучения модели.
- Логистическая регрессия — это обобщенная линейная модель, и ее выразительные возможности ограничены; Объединение признаков может привнести нелинейность в модель, что может улучшить выразительность модели и помочь лучше подобрать модель.
- Дискретизированные функции очень устойчивы к аномальным данным: например, значение функции равно 1, если возраст › 30 лет, и 0 иначе. Если функции не дискретизированы, аномальная точка данных «300 лет» повлияет на подгонку модели.
- Он может обрабатывать нулевые данные как отдельный класс.
Этапы объединения функций:
Шаг 1. Инициализация: c = toad.transform.Combiner()
Шаг 2. Учебный биннинг:
c.fit(dataframe, y = 'target', method = 'chi', min_samples = 0.05, n_bins = None, empty_separate = False)
- y: целевой столбец
- method: метод биннинга, поддерживает chi (бинирование хи-квадрат), dt (бинирование дерева решений), kmean , квантиль, шаг (бинирование с одинаковым размером шага)
- min_samples: каждое поле содержитнаименьшее количество образцов, которое может быть числом или пропорцией.
- n_bins: количество бинов; Если невозможно разделить такое количество ящиков, будет разделено максимальное количество ящиков.
- empty_separate: разделять ли пустые поля отдельно.
Шаг 3. проверить узлы бинирования: c.export()
Шаг 4. Настроить биннинг вручную: c.load(dict)
Шаг 5. Применить результаты объединения: c.transform(dataframe, labels=False)
- labels: следует ли преобразовывать результаты биннинга в метки блоков. Если False, выведите 0, 1, 2… (дискретные переменные сортируются в соответствии с пропорцией), а если True, выведите( -inf, 0], (0,10], (10, inf).
import time start = time.time() combiner = toad.transform.Combiner() # use the filtered features for training # Use the stable chi-square binning, # specifying that each bin has at least 5% data to ensure stability # empty values will be automatically assigned to the best bin combiner.fit(X=train_selected, y=train_selected['label'], method='chi', min_samples = 0.05, exclude=exclude_list) end = time.time() print((end-start)/60) #output binning bins = combiner.export()
Результат биндинга:
#apply binning train_selected_bin = combiner.transform(train_selected) test_bin = combiner.transform(test[train_selected_bin.columns]) #Fine tune bins from toad.plot import bin_plot,badrate_plot bin_plot(train_selected_bin,x='PAY_AMT1',target='label') bin_plot(test_bin,x='PAY_AMT1',target='label')
На этом графике гистограмма представляет долю данных в соответствующей ячейке; красная линия представляет собой долю постоянных клиентов.
Нам нужно убедиться, что биннинг имеет монотонность, что означает, что линия движется в одном направлении без резких скачков или падений.
Этот график выглядит нормально, если есть внезапный скачок или падение, нам нужно использовать c.set_rules(dict) для объединения биннинга.
Например.
#setting rules rule = {'PAY_AMT1':[['0', 'nan'],['1'], ['2'], ['3']]} #Adjust binning c.set_rules(rule)
4. Преобразование в WOE и расчет PSI
Преобразование WOE выполняется после завершения биннинга.
Шаги следующие:
- Используйте настроенный выше Combiner c для преобразования данных
- Инициализировать преобразование woe t:t= toad.transform.WOETransformer()
- Обучениеt: t.fit_transform обучает и выводит преобразованные данные для набора поездов.
- target: данные целевого столбца (не имя столбца)
- исключить: столбцы, которые не нужно преобразовывать WOE. Примечание. Все столбцы будут преобразованы, включая столбцы, которые не были объединены в группы, а столбцы, которые не нужно преобразовывать с помощью WOE, будут удалены с помощью исключения, особенно целевой столбец.
- Преобразование данных теста/OOT: transer.transform
##transform to WOE t=toad.transform.WOETransformer() #transform training set train_woe = t.fit_transform(X=train_selected_bin, y=train_selected_bin['label'], exclude=exclude_list) #transform testing set test_woe = t.transform(test_bin) final_data_woe = pd.concat([train_woe,test_woe])
Рассчитать фунт на квадратный дюйм
PSI (индекс стабильности населения) отражает стабильность распределения. Мы часто используем его для просмотра функций и оценки стабильности модели. На отраслевом уровне следует отказаться от функций с PSI выше 0,2.
#get the feature name features_list = [feat for feat in train_woe.columns if feat not in exclude_list] #calculate PSI using toad psi_df = toad.metrics.PSI(train_woe[features_list], test_woe[features_list]).sort_values(0) #put into a dataframe psi_df = psi_df.reset_index() psi_df = psi_df.rename(columns = {'index' : 'feature',0:'psi'}) # features less than 0.25 psi005 = list(psi_df[psi_df.psi<0.25].feature) # features geater than 0.25 psi_remove = list(psi_df[psi_df.psi>=0.25].feature) # keep exclude list for i in exclude_list: if i in psi005: pass else: psi005.append(i) # remove features that are geater than 0.25 train_selected_woe_psi = train_woe[psi005] off_woe_psi = test_woe[psi005] # output our final data table final_data_woe = pd.concat([train_selected_woe_psi,off_woe_psi])
5. Выходной финал IV
Этот шаг заключается в выводе IV после преобразования WOE, он немного отличается от IV необработанных признаков.
# output the IV features_use = [feat for feat in final_data_woe.columns if feat not in exclude_list] len(features_use) df_iv=output_iv_importance(final_data_woe[features_use+['label']],'label')
Идея состоит в том, чтобы получить функции с самым высоким IV и самым низким PSI.
6. Настройка модели
Логистическая регрессия
Наиболее часто используемый алгоритм в процессе моделирования системы кредитных показателей — это логистическая регрессия. Причины следующие:
- Простая линейная связь: связь между переменными представляет собой линейную связь.
- Хорошая интерпретируемость: влияние входных переменных на целевые переменные легко доступно
- Дайте вероятности вместо дискриминационных классов: характеристическую информацию о покупателе (например, брак, возраст, историческую кредитную историю и т. д.) можно интегрировать и преобразовать в вероятность. значение, которое обеспечивает интуитивную основу для прогнозирования, хороший клиент или плохой. То есть, чем больше значение, тем меньше вероятность того, что клиент не выполнит обязательства в будущем.
- Простота развертывания: тестирование, развертывание, мониторинг, настройка и т. д. относительно просты.
def check_train_test_auc(x_train,y_train,x_test,y_test): from sklearn.linear_model import LogisticRegression lr = LogisticRegression(random_state=42,C= 0.1, penalty='l2', solver='newton-cg') lr = LogisticRegression(class_weight='balanced') lr.fit(x_train, y_train) pred_train = lr.predict_proba(x_train)[:,1] from toad.metrics import KS, AUC print('train KS',KS(pred_train, y_train)) print('train AUC',AUC(pred_train, y_train)) pred_OOT =lr.predict_proba(x_test)[:,1] print('Test KS',KS(pred_OOT, y_test)) print('Test AUC',AUC(pred_OOT, y_test)) from sklearn.metrics import confusion_matrix, accuracy_score, roc_auc_score, plot_roc_curve, classification_report fig, ax = plt.subplots(figsize=(12, 8)) plot_roc_curve(lr, x_test, y_test, color='blue', ax=ax) #train & test check_train_test_auc(x_train = train_woe[features_use],y_train=train_woe['label'], x_test =test_woe[features_use] ,y_test = test_woe['label'])
Мы видим, что небольшой разницы между поездом AUC и тестовым AUC или поездом KS и тестом KS нет. Это означает, что наша модель не подходит.
Обучите GradientBoostingClassifier и проверьте таблицу важности функций
Чтобы увидеть, будет ли модель GBDT работать лучше, чем LR, и сравнить таблицу важности функций с IV.
def get_evaluation_scores(label, predictions): from sklearn.metrics import classification_report, confusion_matrix, accuracy_score from sklearn.metrics import balanced_accuracy_score tp, fn, fp, tn = confusion_matrix(label,predictions,labels=[1,0]).reshape(-1) print('True Positive:',tp) print('True Negative:',tn) print('False Positive:',fp) print('False Negative:',fn) accuracy = (tp+tn)/(tp+fn+fp+tn) print('accuracy: ',accuracy) recall = tp/(tp+fn) print('(recall): ',recall) precision = tp/(tp+fp) print('(precision): ',precision) #f1 score = 2*(P*R)/(P+R) f1 = 2*precision*recall/(precision+recall) print('F1 score: ',f1) print(classification_report(label, predictions)) print('balanced_accuracy_score: ',balanced_accuracy_score(label,predictions)) return precision, recall def evaluate_result(df_train,df_test,features_name): from sklearn.ensemble import AdaBoostClassifier, GradientBoostingClassifier, RandomForestClassifier, ExtraTreesClassifier import seaborn as sns import matplotlib.pyplot as plt start = time.time() x_train = df_train[features_name] y_train = df_train['label'] x_test = df_test[features_name] y_test = df_test['label'] model = GradientBoostingClassifier(n_estimators=250,random_state=0) model.fit(x_train,y_train) predictions = model.predict(x_test) get_evaluation_scores(label = y_test, predictions=predictions) feat_importances = pd.Series(model.feature_importances_, index=features_name) feat_importances=pd.DataFrame(feat_importances).reset_index() feat_importances.columns=['feature_name','feature_importance'] feat_importances=feat_importances.sort_values(['feature_importance'],ascending=False) import matplotlib.pyplot as plt plt.figure(figsize=(15,15)) sns_plot1=sns.barplot(feat_importances.feature_importance,feat_importances.feature_name,estimator=sum) plt.title("Features Importance",size=18) plt.ylabel('', size = 15) plt.tick_params(labelsize=18) return feat_importances,model,x_train,y_train,x_test,y_test fet_importance_GBDT_reason,model,x_train,y_train,x_test,y_test = evaluate_result(df_train=train_woe, df_test=test_woe, features_name=features_use)
Как видно из таблицы важности функций, GBDT придает большое значение (64%) функции PAY_0.
def plot_roc_pre_recall_curve(labels, probs): from sklearn.metrics import precision_recall_curve # Get ROC curve FPR and TPR from true labels vs score values fpr, tpr, _ = roc_curve(labels, probs) # Calculate ROC Area Under the Curve (AUC) from FPR and TPR data points roc_auc = auc(fpr, tpr) # Calculate precision and recall from true labels vs score values precision, recall, _ = precision_recall_curve(labels, probs) plt.figure(figsize=(8, 3)) plt.subplot(1,2,1) lw = 2 plt.plot(fpr, tpr, color='darkorange', lw=lw, label='ROC curve (area = %0.4f)' % roc_auc) plt.plot([0, 1], [0, 1], color='navy', lw=lw, linestyle='--') plt.xlim([0.0, 1.0]) plt.ylim([0.0, 1.05]) plt.xlabel('False Positive Rate') plt.ylabel('True Positive Rate') plt.title('ROC Curve') plt.legend(loc="lower right") plt.grid(True) plt.subplot(1,2,2) plt.step(recall, precision, color='orange', where='post') # plt.fill_between(recall, precision, step='post', alpha=0.5, color='orange') plt.xlabel('Recall') plt.ylabel('Precision') plt.ylim([0.0, 1.05]) plt.xlim([0.0, 1.0]) plt.title('Precision Recall Curve') plt.grid(True) left = 0.125 # the left side of the subplots of the figure right = 0.9 # the right side of the subplots of the figure bottom = 0.1 # the bottom of the subplots of the figure top = 0.9 # the top of the subplots of the figure wspace = 0.5 # the amount of width reserved for blank space between subplots hspace = 0.2 # the amount of height reserved for white space between subplots plt.subplots_adjust(left, bottom, right, top, wspace, hspace) plt.show() probs = model.predict_proba(x_test)[:,1] sns.set(font_scale = 1) plot_roc_pre_recall_curve(y_test, probs)
Кривая ROC и Precision-Recall выглядит нормально.
7. Изготовление моделей
Давайте обучим нашу производственную модель для логистической регрессии.
#prepare train & test data x_train = train_woe[features_use] y_train=train_woe['label'] x_test =test_woe[features_use] y_test = test_woe['label'] #Train LR #lr = LogisticRegression(random_state=42,C= 0.1, penalty='l2', solver='newton-cg') lr = LogisticRegression(class_weight = 'balanced') lr.fit(x_train, y_train) #check AUC probs = lr.predict_proba(x_test)[:,1] sns.set(font_scale = 1) plot_roc_pre_recall_curve(y_test, probs)
AUC LR: 0,7835
AUC GBDT: 0,7892
Не большая разница между этими моделями. Так что можно использовать LR для создания системы показателей.
8. Настройка системы показателей
Следующие параметры являются наиболее важными для настройки системы показателей.
- base_score = 1000, base_odds = 35 , pdo = 80, рейтинг = 2
На самом деле это означает, что когда базовый коэффициент равен 35, контрольный показатель равен 1000, а когда коэффициент в два раза превышает контрольный показатель, контрольный оценка снижается на 80 баллов.
# scorecard tuning card = toad.ScoreCard( combiner = combiner, transer = t, class_weight = 'balanced', C=0.1, base_score = 1000, base_odds = 35 , pdo = 80, rate = 2 ) card.fit(train_woe[features_use], train_woe['label']) #inference on test data test['CreditScore'] = card.predict(test) test['CreditScore'].describe() #output the scorecard final_card_score=card.export() len(final_card_score) #transform the scorecard into dataframe and save to csv keys = list(card.export().keys()) score_card_df = pd.DataFrame() for n in keys: temp = pd.DataFrame.from_dict(final_card_score[n], orient='index') temp = temp.reset_index() temp.columns= ['binning','score'] temp['variable'] = n temp = temp[['variable','binning','score']] score_card_df=score_card_df.append(temp) score_card_df.head(30)
Здесь у нас есть наша система показателей; как только мы получим эту таблицу, мы можем передать этот CSV-файл разработчику и позволить ему разработать сервис для оценки каждого клиента.
Но есть еще кое-что, что нам нужно сделать; для типичной системы показателей нам нужен диапазон оценок, и каждый диапазон представляет собой уровень доверия.
Таким образом, деловым людям будет легче совершать действия против клиентов разного уровня.
Например, мы можем установить уровень кредита следующим образом:
9. Анализ распределения
Нам нужно построить график распределения баллов для клиентов по умолчанию и обычных клиентов. хороших клиентов, чтобы разделить уровни кредита (от 0 до 8).
plt.figure(figsize=(12,10)) import random import numpy from matplotlib import pyplot as plt w = 40 n = math.ceil((data['CreditScore'].max() - data['CreditScore'].min())/w) #bins = numpy.linspace(-10, 10, 100) plt.hist(data[data.label==1].CreditScore, alpha=0.5, label='Black',bins = n) plt.hist(data[data.label==0].CreditScore, alpha=0.5, label='White',bins = n) plt.legend(loc='upper left') plt.title('Credit Score Distribution: Test Set',size=15) plt.show()
Черный означает постоянных клиентов, а белый означает хороших клиентов.
Хорошая модель четко разделяет распределение черного и белого.
Идеальным распределением является форма улыбки.
- Хорошие клиенты с высоким кредитным рейтингом — справа
- Клиенты по умолчанию с низким кредитным рейтингом-› слева.
Наша текущая модель не очень хорошо разделяет эти распределения. Что касается меня, я бы вернулся, чтобы изучить дополнительные функции, чтобы увеличить мощность прогнозирования. Но мы всегда можем сначала создать базовую модель и улучшать ее на ее основе.
10. Настройка порога
Нам нужно выполнить настройку порога для разных кредитных уровней, и это компромисс между убытком и покрытием.
Допустим, ваш начальник согласен с некоторыми потерями, но вы должны покрыть 70 % хороших клиентов в следующем месяце.
Другими словами, ваша цель – найти порог с потерями ≤10% и охватом ≥70%.
def get_credit_level( test, target_score ='order_score', out_col = 'order_level', left_bound = -100, level_0 = 100, level_1 = 200, level_2 = 250, level_3 = 300, level_4 = 350, level_5 = 400, level_6 = 450, level_7 = 500, level_8 = 800): level = [] for i in range(len(test)): if (test[target_score][i]>left_bound) & (test[target_score][i]<=level_0): level.append(0) elif (test[target_score][i]>level_0) & (test[target_score][i]<=level_1): level.append(1) elif (test[target_score][i]>level_1) & (test[target_score][i]<=level_2): level.append(2) elif (test[target_score][i]>level_2) & (test[target_score][i]<=level_3): level.append(3) elif (test[target_score][i]>level_3) & (test[target_score][i]<=level_4): level.append(4) elif (test[target_score][i]>level_4) & (test[target_score][i]<=level_5): level.append(5) elif (test[target_score][i]>level_5) & (test[target_score][i]<=level_6): level.append(6) elif (test[target_score][i]>level_6) & (test[target_score][i]<=level_7): level.append(7) elif (test[target_score][i]>level_7 )& (test[target_score][i]<=level_8): level.append(8) test[out_col] = level return test def plot_bts_level_loss(test, target_col): bts_level_df = test[target_col].value_counts() bts_level_df=pd.DataFrame(bts_level_df) df_label_level= test[test.label==1].groupby(target_col)['label'].count()/ test.groupby(target_col)['label'].count() df_label_level = pd.DataFrame(df_label_level) bts_level_df.sort_index().plot.bar(title='') df_label_level.plot() test = get_credit_level(test, target_score ='CreditScore', out_col = 'CreditScore_level', left_bound = -1000, level_0 = 250, level_1 = 300, level_2 = 400, level_3 = 500, level_4 = 580, level_5 = 630, level_6 = 690, level_7 = 730, level_8 = 1000 ) plot_bts_level_loss(test,target_col='CreditScore_level') def get_loss_coverage(test,target_level): #level 5-Leve 8 Loss (percentage of default people) L5_loss = test[test[target_level]>=5 ].label.value_counts()/len(test[test[target_level]>=5 ]) #level 5- level 8 Coverage (percentage of good people) L5_coverage=test[test[target_level]>=5 ].label.value_counts()[0]/test[test.label==0].shape[0] print("Level 5-Level 8: Loss is ",L5_loss[1], "; Coverage is ",L5_coverage) #level 6-level 8 Loss L6_loss=test[test[target_level]>=6 ].label.value_counts()/len(test[test[target_level]>=6 ]) #level 6-level 8 Coverage L6_coverage=test[test[target_level]>=6].label.value_counts()[0]/test[test.label==0].shape[0] print("Level 6-Level 8: Loss is ",L6_loss[1], "; Coverage is ",L6_coverage)
На этом графике показано распределение каждого уровня кредита и коэффициента дефолта по кредиту на этом уровне.
Изучив каждый уровень, вы получите таблицу потерь и покрытия. Например, если вы отправите предложения о переводе остатка всем людям 7501 (L0-L8), вы понесете 21% потерь (1548/7501) .
Чтобы достичь цели (потери ≤10% и покрытие ≥70%), вам нужно выбрать L6-L8 с потерями 10,1% (347+120+34)/(2573+1570+796) и 75% покрытие (2226+1450+762)/5953.
По сути, в следующем месяце (при условии, что тестовый набор представляет собой данные за следующий месяц) сотрудники компании отправят предложения о переводе остатка клиентам с рейтингом уровня 6 или выше, всего 4939 клиентов.
11. Протестируйте нашу систему показателей вручную
Можем ли мы отправить клиенту предложение о переносе баланса со следующей информацией в следующем месяце?
Давайте вручную проверим систему показателей.
Вывод по жабе:
Проверив нашу таблицу уровней кредитоспособности:
Мы видим, что этот клиент является клиентом уровня 8 с Perfect Credit. Таким образом, мы можем выдать ему / ей предложение о переводе баланса.
Заключение:
В этом блоге рассматривается сквозной процесс создания кредитной скоринговой карты на основе инструмента машинного обучения с открытым исходным кодом Toad.
В этом блоге обсуждаются следующие модные словечки ML:
Информационная ценность (IV), вес доказательств (WOE), индекс стабильности населения (PSI), AUC (площадь под ROC-кривой), KS (Колмогорова-Смирнова), логистическая регрессия (LR), GBDT (решение о повышении градиента). дерево)
Для будущей работы, как специалист по данным, вы можете попробовать использовать другие модели ML для построения системы показателей, такие как Deep Neural Networks, чтобы еще больше повысить точность и снизить уровень ложных срабатываний, чтобы повысить удовлетворенность клиентов.
Спасибо.
Примечание от редакторов Towards Data Science. Хотя мы разрешаем независимым авторам публиковать статьи в соответствии с нашими правилами и рекомендациями, мы не одобряем вклад каждого автора. Не стоит полагаться на авторские работы, не обратившись за профессиональной консультацией. Подробнее см. в наших Условиях чтения.