Введение

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

Хотя вы уверены, что у вас есть средства, чтобы покрыть все, карта все равно не примет платеж. После этого вы отходите в сторону и позволяете кассиру обслуживать другого покупателя, а вам приходит уведомление или сообщение от банка, что «Нажмите 1, если вы действительно пытались потратить 500 на сыр чеддер».

Этот момент очень смущает всех, кто встречает эту судьбу. Было бы здорово, если бы мы могли предоставить хорошую систему предотвращения мошенничества, которая фактически экономит потребителю или клиенту миллионы долларов в год. Исследователи из IEEE Computational Intelligence Society, также известного как IEEE-CIS, хотят улучшить этот сценарий, а также повысить качество обслуживания потребителей. Чем лучше производительность системы, тем больше денег мы можем предотвратить.

IEEE-CIS работает в различных областях ИИ и машинного обучения, включая глубокие нейронные сети, нечеткие системы, эволюционные вычисления и групповой интеллект. Сегодня они сотрудничают с ведущей в мире платежной компанией Корпорация Веста в поисках лучших решений для индустрии предотвращения мошенничества, и теперь вы можете присоединиться к этому вызову.

Пожалуйста, перейдите по этой ссылке на веб-сайт Конкурса: Обнаружение мошенничества IEEE-CIS.



Основная цель этой статьи — предоставить базовую модель и методологию обнаружения мошенничества с использованием предоставленного набора данных конкурентов. Я надеюсь, что эта статья поможет всем, кто изо всех сил пытается начать соревнование по машинному обучению или хочет понять, что ИИ или машинное обучение можно применить в реальном проекте. Мы начали это соревнование командой из 3 человек и хотим поделиться методикой, которая помогает нам войти в 3% лучших из 6381 команд.

Без лишних слов, давайте начнем!

Цель этого конкурса

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

Если мы успешно изобретем действительно хороший метод, мы повысим эффективность предупреждений о мошеннических транзакциях для миллионов людей по всему миру, помогая тысячам предприятий сократить свои потери от мошенничества и увеличить свою прибыль. Кроме того, мы будем спасать людей, которых ждет та же участь, что и мы, и вызывать улыбку на их лицах.

Настройка среды

Язык: Python 3.5.5

Основная библиотека:

  1. Нампи
  2. Панды
  3. Scikit-Learn
  4. Сиборн
  5. Матплотлиб
  6. CatBoost

Исследование данных

Набор данных можно найти и загрузить с веб-сайта Kaggle здесь.

Данные разделены на два файла identity и transaction, которые объединены файлом TransactionID. Обратите внимание, что не все транзакции имеют одинаковые идентификационные данные.

Категориальные признаки — транзакция

  • ProductCD
  • card1 - card6
  • addr1, addr2
  • P_emaildomain
  • R_emaildomain
  • M1 - M9

Категориальные признаки — идентичность

  • DeviceType
  • DeviceInfo
  • id_12 - id_38

Функция TransactionDT представляет собой дельту времени от заданной ссылки DateTime (а не фактическую отметку времени).

Столбец Описание

Таблица транзакций

  • TransactionDT: дельта времени от указанной эталонной даты и времени (не фактическая отметка времени)
  • TransactionAMT: сумма платежа по транзакции в долларах США.
  • ProductCD: код продукта, продукт для каждой транзакции
  • card1 — card6: информация о платежной карте, такая как тип карты, категория карты, банк-эмитент, страна и т. д.
  • адрес: адрес
  • расстояние: расстояние
  • Домен электронной почты P_ и (R__): домен электронной почты покупателя и получателя.
  • C1-C14: подсчет, например, сколько адресов связано с платежной картой и т. д. Фактическое значение скрыто.
  • D1–D15: разница во времени, например количество дней между предыдущей транзакцией и т. д.
  • M1-M9: совпадение, например, имена на карточке, адрес и т. д.
  • Vxxx: Веста разработала богатые функции, включая ранжирование, подсчет и другие отношения сущностей.

Категорические характеристики
ProductCD
card1 — card6
addr1, addr2
Pдомен электронной почты Rдомен электронной почты
M1 — M9

Таблица идентификаторов

Переменные в этой таблице — это идентификационная информация — информация о сетевом подключении (IP, интернет-провайдер, прокси-сервер и т. д.) и цифровая подпись (UA/браузер/ОС/версия и т. д.), связанные с транзакциями.
Они собираются системой защиты от мошенничества Vesta. система и партнеры по цифровой безопасности.
(имена полей маскируются, и попарный словарь не будет предоставлен для защиты конфиденциальности и соглашения о контракте)

Категориальные признаки:
DeviceType
DeviceInfo
id12 — id38

Подтверждение: вся информация была предоставлена ​​веб-сайтом конкурса Kaggle.

Методология

  1. Во-первых, мы начинаем с объединения обучающих данных из файла транзакций и файла идентификации на основе их уникального идентификатора.
  2. Как только мы получим обучающую выборку, мы разделим эти данные на 5 поровну выборок данных. Я также хотел бы упомянуть, что стратифицированный K-Fold немного отличается от обычного разделения K-Fold таким образом, что его можно использовать только для задачи двоичной классификации, как в нашем случае (значение 0 и 1). Стратифицированные K-кратные данные разделены на несколько кратных, которые содержат примерно одинаковое количество образцов в обоих классах в каждом фрагменте.
  3. После того, как все данные подготовлены, пришло время создать модель/классификатор, чтобы обобщить эти данные и сделать прогноз.
  4. Наконец, соберите прогнозы, усредняя их, чтобы получить окончательный прогноз.

Параметр XGBoost

clf = xgb.XGBClassifier(
        n_estimators=500,
        max_depth=9,
        learning_rate=0.05,
        subsample=0.9,
        colsample_bytree=0.9,
        missing=-999,
        random_state=2019,
        tree_method='auto',
        n_jobs = -1,
        
    )
  • Стратифицированный K-Fold = 5 фрагментов данных

КОД

Импорт библиотеки

import os
import numpy as np
import pandas as pd
from sklearn import preprocessing
import xgboost as xgb
from catboost import CatBoostClassifier

Загрузка данных

%%time
train_transaction = pd.read_csv('train_transaction.csv', index_col='TransactionID')
test_transaction = pd.read_csv('test_transaction.csv', index_col='TransactionID')
train_identity = pd.read_csv('train_identity.csv', index_col='TransactionID')
test_identity = pd.read_csv('test_identity.csv', index_col='TransactionID')
sample_submission = pd.read_csv('sample_submission.csv', index_col='TransactionID')
train = train_transaction.merge(train_identity, how='left', left_index=True, right_index=True)
test = test_transaction.merge(test_identity, how='left', left_index=True, right_index=True)
print(train.shape)
print(test.shape)
y_train = train['isFraud'].copy()
del train_transaction, train_identity, test_transaction, test_identity
# Drop target, fill in NaNs
X_train = train.drop('isFraud', axis=1)
X_test = test.copy()
del train, test
# Label Encoding
for f in X_train.columns:
    if X_train[f].dtype=='object' or X_test[f].dtype=='object': 
        lbl = preprocessing.LabelEncoder()
        lbl.fit(list(X_train[f].values) + list(X_test[f].values))
        X_train[f] = lbl.transform(list(X_train[f].values))
        X_test[f] = lbl.transform(list(X_test[f].values))

Сокращение использования памяти

%%time
# From kernel https://www.kaggle.com/gemartin/load-data-reduce-memory-usage
# WARNING! THIS CAN DAMAGE THE DATA 
def reduce_mem_usage(df):
    """ iterate through all the columns of a dataframe and modify the data type
        to reduce memory usage.        
    """
    start_mem = df.memory_usage().sum() / 1024**2
    print('Memory usage of dataframe is {:.2f} MB'.format(start_mem))
    
    for col in df.columns:
        col_type = df[col].dtype
        
        if col_type != object:
            c_min = df[col].min()
            c_max = df[col].max()
            if str(col_type)[:3] == 'int':
                if c_min > np.iinfo(np.int8).min and c_max < np.iinfo(np.int8).max:
                    df[col] = df[col].astype(np.int8)
                elif c_min > np.iinfo(np.int16).min and c_max < np.iinfo(np.int16).max:
                    df[col] = df[col].astype(np.int16)
                elif c_min > np.iinfo(np.int32).min and c_max < np.iinfo(np.int32).max:
                    df[col] = df[col].astype(np.int32)
                elif c_min > np.iinfo(np.int64).min and c_max < np.iinfo(np.int64).max:
                    df[col] = df[col].astype(np.int64)  
            else:
                if c_min > np.finfo(np.float16).min and c_max < np.finfo(np.float16).max:
                    df[col] = df[col].astype(np.float16)
                elif c_min > np.finfo(np.float32).min and c_max < np.finfo(np.float32).max:
                    df[col] = df[col].astype(np.float32)
                else:
                    df[col] = df[col].astype(np.float64)
        else:
            df[col] = df[col].astype('category')
end_mem = df.memory_usage().sum() / 1024**2
    print('Memory usage after optimization is: {:.2f} MB'.format(end_mem))
    print('Decreased by {:.1f}%'.format(100 * (start_mem - end_mem) / start_mem))
    
    return df
X_train = reduce_mem_usage(X_train)
X_test = reduce_mem_usage(X_test)

Очистите любое значение Null, представленное в данных

#data cleaning
def clean_inf_nan(df):
    return df.replace([np.inf, -np.inf], np.nan)
# Cleaning infinite values to NaN
X_train = clean_inf_nan(X_train)
X_test = clean_inf_nan(X_test) # replace all nan,inf,-inf to nan so it will be easy to replace
for i in X_train.columns:
    X_train[i].fillna(X_train[i].median(),inplace=True) # fill with median because mean may be affect by outliers.
#X.isna().sum().sum()
for i in X_test.columns:
    X_test[i].fillna(X_test[i].median(),inplace=True)

Основная модель

#%%time
from sklearn.model_selection import StratifiedKFold
from sklearn.metrics import roc_auc_score
EPOCHS = 5
kf = StratifiedKFold(n_splits = EPOCHS, shuffle = True)
y_preds = np.zeros(sample_submission.shape[0])
y_oof = np.zeros(X_train.shape[0])
for tr_idx, val_idx in kf.split(X_train, y_train):
    
    clf = xgb.XGBClassifier(
        n_estimators=500,
        max_depth=9,
        learning_rate=0.05,
        subsample=0.9,
        colsample_bytree=0.9,
        missing=-999,
        random_state=2019,
        tree_method='auto',
        n_jobs = -1,
        
    )
    
    X_tr, X_vl = X_train.iloc[tr_idx, :], X_train.iloc[val_idx, :]
    y_tr, y_vl = y_train.iloc[tr_idx], y_train.iloc[val_idx]
    
    clf.fit(X_tr, y_tr)
    
    y_pred_train = clf.predict_proba(X_vl)[:,1]
    y_oof[val_idx] = y_pred_train
    
    print('ROC AUC {}'.format(roc_auc_score(y_vl, y_pred_train)))
    
    y_preds+= clf.predict_proba(X_test)[:,1] / EPOCHS

Показатель оценки

Чтобы определить, насколько хороша наша модель, нам нужно использовать наиболее подходящую метрику оценки. К счастью, Scikit-Learn предоставляет нам множество полезных показателей. Однако мы будем использовать ту же метрику, что и на веб-сайте соревнований Kaggle, которая называется ROC AUC SCORE.

ROC AUC SCORE: Вычисление площади под кривой рабочих характеристик приемника (ROC AUC) на основе оценок прогнозирования. Чем выше, тем лучше.

Результат каждой складки/фрагмента для обучения

ROC AUC: 0,9645106433450377
ROC AUC: 0,9623382759183995
ROC AUC: 0,9628282124302243
ROC AUC: 0,9620205684446603
ROC AUC: 0,96228855

Оценка и место в частной таблице лидеров

ROC-AUC: 0,929200

РЕЙТИНГ: 153 из 6381 команд

Достижение: Серебряная медаль

Всего членов команды: 3

Заключение

В заключение, машинное обучение и глубокое обучение показали многообещающие результаты в решении реальной проблемы. Система обнаружения мошенничества — один из хороших примеров применения машинного обучения. Хотя это не может решить все, с чем мы сталкиваемся прямо сейчас, я считаю, что каждое изобретение — это ступенька к продвижению технологий для нового поколения. Надеюсь, в ближайшем будущем мы сможем внедрить более мощную систему, которая предотвратит любые плохие вещи.

Ваше здоровье!!!

Пожалуйста, следуйте за мной на Medium, если вы хотите быть в курсе моей статьи и проекта: D

Связаться

Линкедин