В этой статье я поделюсь несколькими вещами, которые помогли мне, и я узнал, когда писал свое первое ядро, что сделает его немного проще для всех, кто только начинает работать с kaggle и наукой о данных. Прежде чем мы начнем, я хочу заявить об одном: я новичок в науке о данных и Python, поэтому я не эксперт и могу сделать что-то не так или ошибиться, если я это сделаю, пожалуйста, исправьте меня.

Начнем,

Когда я решил написать (закодировать) свое первое ядро, я немного волновался, это была моя первая попытка написать что-то, что будет доступно всем, чтобы прочитать и просмотреть на такой большой платформе, как kaggle. Пройдя через несколько конкурсов и наборов данных, я решил написать ядро ​​для обнаружения мошеннических транзакций IEEE-CIS из-за его набора данных, который содержал более 400 столбцов и 5000000 записей. Я понятия не имел, с чего начать, поэтому я сделал первое.

1. Читать другие ядра.

Публичные ядра - лучшая часть kaggle. Они отлично подходят для таких новичков, как я. вы узнаете что-то новое с каждым ядром. Вот несколько хороших примеров:











Первое ядро ​​познакомило меня с LightGBM, одним из любимых алгоритмов многих в соревнованиях по kaggle. Второе ядро ​​познакомило меня с функцией кросс-таблицы, функцией pandas, которая вычисляет кросс-таблицу по двум или более факторам. Простой пример:

a=np.array(['cat1','cat2','cat3','cat1','cat2','cat3','cat1'], dtype=object)
b=np.array(['subcat1','subcat2','subcat1','subcat2','subcat1','subcat2','subcat2'], dtype=object)
c = np.array([2,4,6,8,10,12,14], dtype=int)
pd.crosstab(a, b, rownames='a', colnames='b')

pd.crosstab(a, b, normalize='index', rownames='a', colnames='b')*100

pd.crosstab(a, b, c, aggfunc='sum', rownames='a', colnames='b')

По умолчанию он просто дает количество каждого значения в b для каждого значения в a. для более подробной информации документация pandas будет более полезной.

Вначале я понятия не имел о LightGBM и кросс-таблице, поэтому сделал следующее.

2. Погугли это. Поймите, что вы делаете

Как только вы узнаете то, чего не знаете, просто погуглите. Я знаю, что это не божественное и уникальное предложение, но оно очень полезно. Для науки о данных у нас есть такие сайты, как Towards Data Science, Medium, на которых есть много полезных статей, и другие, такие как StackOverflow, quora, geeks for geeks, Chris Albon даст вам больше фрагментов кода, простых примеров для лучшего понимания. Официальная документация библиотек также является отличным источником, их объяснения сложны (по крайней мере, для меня), но они отлично подходят для получения знаний о различных параметрах и методах. После прочтения используйте простые коды, подобные приведенному выше примеру, чтобы узнать основы.

Теперь, когда вы прочитали несколько статей и освоили несколько новых приемов, давайте приступим к написанию вашего первого ядра.

Первый шаг для любого ядра или ноутбука - это знать ваши данные. Удивительно, но вы не можете просто передать свои данные модели и ожидать результатов.

3. Знайте свои данные

Я использую три метода, чтобы получить общее представление о данных. Первый - создать функцию метаданных.

def metadata(df):
    metadata = pd.DataFrame()
    metadata['Name'] = df.columns.values
    metadata['Dtype'] = df.dtypes.values
    t =df.shape[0]
    missing =[]
    permissing = []
    Unique =[]
    for col in df.columns:
        s = df[col].isnull().sum()
        missing.append(s)
        permissing.append(round((s/t)*100, 3))
        Unique.append(df[col].nunique())
    metadata['Missing'] = missing
    metadata['Percentage_Missing'] = permissing
    metadata['Unique'] = Unique
    return metadata
other_col = ['isFraud','TransactionDT','TransactionAmt','ProductCD']
metadata(train_trans[other_col])

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

Второй метод, который я использую, - это функция pandas Describe (), которая предоставляет информацию, показанную ниже.

train_trans[['TransactionAmt']].describe()

Здесь значение 25% означает, что 25% значений меньше этих значений, поэтому здесь 25% значений в столбце «TransactionAmt» меньше 43,321. Аналогично в случае 50%, 75%.

Третий метод - использовать функцию pandas Quantile (). Он показывает вам значения в разных квантилях для значений в столбцах.

quantiles = train_trans.quantile([.01, .20, .25, .50, .70, .75, .90, .95, .96,.99]) 
quantiles

Как я уже говорил ранее о 25% в функции Describe (), здесь также мы можем видеть значения в разных квантилях. С помощью Describe () вы можете получить любое значение квантиля, добавив квантиль в список. Если мы видим столбец «addr1», мы можем сказать, что он хорошо распределен, но если мы видим столбец «add2», каждый квантиль от 10% до 99% находится на 87, что означает, что он не очень хорошо распределен. Вы можете получить более подробную информацию с помощью графика.

4. Разработка функций

Теперь давайте перейдем к разработке функций, допустим, у вас есть столбец с несколькими значениями, как показано ниже.

train_id['id_31'].unique()#Output shown below is a small snippet of actual array

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

train_id['id_31'].unique() #After mapping

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

browsermapping = {'google':'Google', 'google search application 48.0':'Google' ,  'google search application 49.0':'Google' , 'android webview 4.0': 'Android' , 'Generic/Android 7.0': 'Android', 'Generic/Android': 'Android', 'android browser 4.0': 'Android', 'android': 'Android', 'samsung browser 6.2' : 'Samsung' , 'mobile safari 11.0':'Safari Mobile' , 'chrome 62.0':'Chrome PC' , 'chrome 62.0 for android':'Chrome Android' , 'edge 15.0':'Edge' , 'mobile safari generic':'Safari Mobile' , 'chrome 49.0':'Chrome PC' , 'chrome 61.0':'Chrome PC' , 'edge 16.0':'Edge' , 'safari generic':'Safari' , 'edge 14.0':'Edge' , 'chrome 56.0 for android':'Chrome Android' , 'firefox 57.0':'Firefox' , 'chrome 54.0 for android':'Chrome Android' , 'mobile safari uiwebview':'Safari Mobile' , 'chrome':'Chrome PC' , 'chrome 62.0 for ios':'Chrome IOS' , 'firefox':'Firefox' , 'chrome 60.0 for android':'Chrome Android' , 'mobile safari 10.0':'Safari Mobile' , 'chrome 61.0 for android':'Chrome Android' , 'ie 11.0 for desktop':'IE PC', 'Microsoft/Windows':'IE PC' , 'ie 11.0 for tablet':'IE TABLET' , 'mobile safari 9.0':'Safari Mobile', 'chrome generic':'Chrome PC' , 'chrome 59.0 for android':'Chrome Android' , 'firefox 56.0':'Firefox' , 'chrome 55.0':'Chrome PC' , 'opera 49.0':'Opera' , 'ie':'IE PC' , 'chrome 55.0 for android':'Chrome Android' , 'firefox 52.0':'Firefox' , 'chrome 57.0 for android':'Chrome Android' , 'chrome 56.0':'Chrome PC' , 'chrome 46.0 for android':'Chrome Android' , 'chrome 58.0':'Chrome PC' , 'firefox 48.0':'Firefox' , 'chrome 59.0':'Chrome PC' , 'samsung browser 4.0':'Samsung', 'edge 13.0':'Edge' , 'chrome 53.0 for android':'Chrome Android' , 'chrome 58.0 for android':'Chrome Android' , 'chrome 60.0':'Chrome PC' , 'mobile safari 8.0':'Safari Mobile', 'firefox generic':'Firefox' , 'Samsung/SM-G532M':'Samsung', 'chrome 50.0 for android':'Chrome Android' , 'chrome 51.0 for android':'Chrome Android' , 'chrome 63.0':'Chrome PC' , 'chrome 52.0 for android':'Chrome Android' , 'chrome 51.0':'Chrome PC' , 'firefox 55.0':'Firefox' , 'edge':'Edge' , 'opera':'Opera' , 'chrome generic for android':'Chrome Android' , 'samsung browser 5.4':'Samsung', 'Samsung/SCH':'Samsung', 'chrome 57.0':'Chrome PC' , 'firefox 47.0':'Firefox' , 'chrome 63.0 for android':'Chrome Android' , 'Samsung/SM-G531H':'Samsung', 'chrome 43.0 for android':'Chrome Android' , 'chrome 63.0 for ios':'Chrome IOS' , 'chrome 49.0 for android':'Chrome Android' , 'safari':'Safari', 'samsung browser 5.2':'Samsung', 'firefox 58.0':'Firefox' , 'chrome 64.0 for android':'Chrome Android' , 'chrome 64.0':'Chrome PC' , 'firefox 59.0':'Firefox' , 'chrome 64.0 for ios':'Chrome IOS' , 'samsung browser generic':'Samsung', 'opera 51.0':'Opera' , 'samsung browser 7.0':'Samsung', 'Mozilla/Firefox':'Firefox' ,'samsung':'Samsung', 'opera generic':'Opera' , 'samsung browser 4.2':'Samsung', 'samsung browser 6.4':'Samsung', 'chrome 65.0':'Chrome PC' , 'chrome 65.0 for android':'Chrome Android' , 'chrome 65.0 for ios':'Chrome IOS' ,'edge 17.0':'Edge' , 'chrome 66.0':'Chrome PC' , 'chrome 66.0 for android':'Chrome Android' , 'safari 11.0':'Safari', 'safari 9.0':'Safari', 'safari 10.0':'Safari', 'chrome 66.0 for ios':'Chrome IOS', 'opera 52.0':'Opera' , 'firefox 60.0':'Firefox' , 'opera 53.0':'Opera' , 'samsung browser 3.3':'Samsung', 'chrome 67.0 for ios':'Chrome IOS' , 'firefox mobile 61.0':'Firefox Mobile' , 'chrome 67.0':'Chrome PC' , 'chrome 69.0':'Chrome PC' , 'chrome 67.0 for android':'Chrome Android', 'chromium':'Chrome PC', 'chrome 39.0 for android':'Chrome Android' , 'chrome 68.0':'Chrome PC' , 'chrome 68.0 for android':'Chrome Android' , 'chrome 68.0 for ios':'Chrome IOS' , 'chrome 69.0 for android':'Chrome Android' , 'chrome 69.0 for ios':'Chrome IOS' , 'chrome 70.0':'Chrome PC' , 'chrome 70.0 for android':'Chrome Android' , 'chrome 70.0 for ios':'Chrome IOS' , 'chrome 71.0':'Chrome PC','chrome 71.0 for android':'Chrome Android' , 'chrome 71.0 for ios':'Chrome IOS' , 'edge 18.0':'Edge', 'firefox 61.0':'Firefox', 'firefox 62.0':'Firefox', 'firefox 63.0':'Firefox', 'firefox 64.0':'Firefox', 'firefox mobile 62.0':'Firefox Mobile', 'firefox mobile 63.0':'Firefox Mobile','google search application 52.0':'Google' , 'google search application 54.0':'Google' , 'google search application 56.0':'Google' , 'google search application 58.0':'Google' , 'google search application 59.0':'Google' , 'google search application 60.0':'Google' , 'google search application 61.0':'Google' , 'google search application 62.0':'Google' , 'google search application 63.0':'Google' , 'google search application 64.0':'Google' , 'google search application 65.0':'Google' , 'mobile safari 12.0':'Safari Mobile', 'opera 54.0':'Opera' , 'opera 55.0':'Opera' , 'opera 56.0':'Opera' , 'safari 12.0':'Safari' , 'samsung browser 7.2':'Samsung', 'samsung browser 7.4':'Samsung', 'samsung browser 8.2':'Samsung'}
# THIS FUNCTION WILL MAP OS(ID_30) AND BROWSER(ID_31) IN GROUPS
def mappingOSandBrowser(val, mappingList):
    if val in mappingList.keys():
        return mappingList[val]
    else:
        return val

Затем используйте функцию apply () для сопоставления каждого значения в соответствии со списком. После того, как вы получите значения в столбце, как показано ранее.

train_data['id_31'] = train_data['id_31'].apply(mappingOSandBrowser, mappingList = browsermapping)
test_data['id_31'] = test_data['id_31'].apply(mappingOSandBrowser, mappingList = browsermapping)

Чтобы упростить создание списка для сопоставления, используйте функцию unique () и преобразуйте список в набор, он вернет отсортированный список, показанный ниже.

set(train_id['id_31'].unique())

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

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

5. Моделирование

Помните, что я сказал в первом и втором пунктах, чтобы прочитать затем google, именно так я узнал о randomSearchCV и LightGBM. LightGBM имеет более 100 параметров, каждый из которых влияет на прогнозы. Вам не обязательно изучать их все, но есть некоторые важные параметры, такие как скорость обучения, максимальная глубина, n_ оценок и т. Д. Вы можете узнать о них из официальной документации LightGBM и этих статей, которые действительно мне помогли.





Итак, с чего начать, вы знаете, как работает LightGBM и его важные параметры, но все же какие значения следует установить для каждого параметра. Это когда на картинке появляется randomSearchCV (RSCV), я использую RSCV, чтобы получить базовый уровень для параметров моего алгоритма. Также доступен gridSearchCV, но он требует много вычислительных ресурсов и времени.

param = {
   'objective': ['binary'], 
   'boosting_type': ['gbdt'],  #boosting 
   'n_estimators':[200,250,300,350,400,450,500,550],
   'max_depth':[10,12,14,16,18,20], 
   'min_split_gain':uniform(loc=0, scale=4),#min_gain_to_split
   'num_leaves':[200,205,210,215,220,225,230,235,240,245,250,255,260,265,270,275, 280],
   'min_child_samples':[50,60,70,80,100,115,130,150,170],
   'subsample': uniform(loc=0.6, scale=0.3),  #bagging_fraction
   'colsample_bytree': uniform(loc=0.6, scale=0.3),#feature_fraction
   'subsample_freq':[1,2,3,4,5],
   'learning_rate':uniform(loc=0, scale=0.5),
   'metric':['auc'],
   'reg_alpha': uniform(loc=0, scale=1),#lambda_l1
   'reg_lambda': uniform(loc=0, scale=1) #lambda_l2
}
clf = lgbm.LGBMClassifier()
randSearchCV = RandomizedSearchCV(clf, param_distributions= param, cv=5, n_iter=10)
randSearchCV.fit(x_train,y_train)
randSearchCV.best_params_

Я использовал указанные выше параметры, чтобы ввести RSCV с 10 итерациями. Как видите, я использую функцию uniform () из scipy.stats. Если у вас есть параметры, которые принимают значения с плавающей запятой, uniform () выдаст случайное значение с плавающей запятой от loc до loc + scale, например, в значении reg_alpha будет от 0 до 0 + 1.

Как только это будет выполнено, используйте best_params_, чтобы получить лучшую комбинацию параметров для лучшей итерации. Это были мои лучшие параметры от RSCV.

param = {
  'boosting_type': 'gbdt',
  'colsample_bytree': 0.660201224714178,
  'learning_rate': 0.18558795195977706,
  'max_depth': 20,
  'metric': 'auc',
  'min_child_samples': 150,
  'min_split_gain': 0.7447489311593505,
  'n_estimators': 450,
  'num_leaves': 230,
  'objective': 'binary',
  'reg_alpha': 0.3866729149893172,
  'reg_lambda': 0.6716281805093148,
  'subsample': 0.870092664400306,
  'subsample_freq': 4
}

К сожалению, с этими параметрами моя модель переоснащалась, поэтому я следовал советам, упомянутым в документах LightGBM. Для борьбы с переобучением в LightGBM используйте более низкое значение для num_leaves, а для повышения точности используйте малую learning_rate с большими n_estimator. После множества различных комбинаций я получил лучший результат со следующими параметрами.

param = {
         'boosting_type': 'gbdt',
         'colsample_bytree': 0.660201224714178,
         'learning_rate': 0.03,
         'max_depth': 20,
         'metric': 'auc',
         'min_child_samples': 150,
         'min_split_gain': 0.7447489311593505,
         'n_estimators': 1200,
         'num_leaves': 35,
         'objective': 'binary',
         'reg_alpha': 0.3866729149893172,
         'reg_lambda': 0.6716281805093148,
         'subsample': 0.870092664400306,
         'subsample_freq': 4
        }
train_set = lgbm.Dataset(x_train, label=y_train)
lgb = lgbm.train(param, train_set)
y_predict = lgb.predict(x_test)

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

submission =pd.DataFrame()
submission['TransactionID'] = test_data.index
submission['isFraud']= y_predict
submission.to_csv('submission.csv', index=False)

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

6. Разное (фиксация против выполнения, версии и т. Д.)

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

При фиксации выполняется все ваше ядро, файл отправки и любой другой файл, созданный вами в ядре, будет сохранен в разделе вывода, а ядро ​​будет сохранено как новая версия.

Вот несколько изображений с информацией об интерфейсе, о различиях, версиях и т. Д.

На изображении выше показаны разные линии в 2 выбранных версиях.

Надеюсь, эта статья кому-то поможет. Если вы сочтете это полезным, поделитесь им с тем, кому он может понадобиться. если вы хотите прочитать мое ядро, это ссылка



Спасибо, что прочитали