Data Science Private Sharing
الذهاب إلى القناة على Telegram
Советы и лайфхаки для соревновательного (в основном) дата сайнса, о которых не расскажут на курсах. Если есть идеи, которыми хотите поделиться, пишите -> @slivka_83 Tags: #EDA #Evaluation #Models #TimeSeries #Train #Preprocessing #Valid
إظهار المزيد1 340
المشتركون
-124 ساعات
+57 أيام
+2630 أيام
جاري تحميل البيانات...
القنوات المماثلة
سحابة العلامات
لا توجد بيانات
هل تواجه مشاكل؟ يرجى تحديث الصفحة أو الاتصال بمدير الدعم الخاص بنا.
الإشارات الواردة والصادرة
---
---
---
---
---
---
جذب المشتركين
سبتمبر '24
سبتمبر '24
+10
في 0 قنوات
أغسطس '24
+40
في 0 قنوات
Get PRO
يوليو '24
+56
في 0 قنوات
Get PRO
يونيو '24
+72
في 0 قنوات
Get PRO
مايو '24
+69
في 0 قنوات
Get PRO
أبريل '24
+56
في 0 قنوات
Get PRO
مارس '24
+118
في 1 قنوات
Get PRO
فبراير '24
+56
في 0 قنوات
Get PRO
يناير '24
+68
في 0 قنوات
Get PRO
ديسمبر '23
+81
في 1 قنوات
Get PRO
نوفمبر '23
+100
في 1 قنوات
Get PRO
أكتوبر '23
+51
في 1 قنوات
Get PRO
سبتمبر '23
+52
في 0 قنوات
Get PRO
أغسطس '23
+62
في 0 قنوات
Get PRO
يوليو '23
+61
في 0 قنوات
Get PRO
يونيو '23
+44
في 0 قنوات
Get PRO
مايو '23
+159
في 0 قنوات
Get PRO
أبريل '23
+24
في 0 قنوات
Get PRO
مارس '23
+16
في 0 قنوات
Get PRO
فبراير '23
+16
في 0 قنوات
Get PRO
يناير '23
+24
في 0 قنوات
Get PRO
ديسمبر '22
+33
في 0 قنوات
Get PRO
نوفمبر '22
+48
في 0 قنوات
Get PRO
أكتوبر '22
+35
في 0 قنوات
Get PRO
سبتمبر '22
+59
في 0 قنوات
Get PRO
أغسطس '22
+529
في 0 قنوات
| التاريخ | نمو المشتركين | الإشارات | القنوات | |
| 20 سبتمبر | 0 | |||
| 19 سبتمبر | 0 | |||
| 18 سبتمبر | 0 | |||
| 17 سبتمبر | +1 | |||
| 16 سبتمبر | 0 | |||
| 15 سبتمبر | 0 | |||
| 14 سبتمبر | 0 | |||
| 13 سبتمبر | +2 | |||
| 12 سبتمبر | 0 | |||
| 11 سبتمبر | 0 | |||
| 10 سبتمبر | 0 | |||
| 09 سبتمبر | 0 | |||
| 08 سبتمبر | 0 | |||
| 07 سبتمبر | 0 | |||
| 06 سبتمبر | 0 | |||
| 05 سبتمبر | +2 | |||
| 04 سبتمبر | +1 | |||
| 03 سبتمبر | +1 | |||
| 02 سبتمبر | +3 | |||
| 01 سبتمبر | 0 |
منشورات القناة
#Tip42 #EDA #Pandas
На прошлой неделе поучаствовал в хакатоне GO ALGO, организованный Московской фондовой биржей.
Для решения задачи нужно было анализировать биржевую информацию. И наконец-то мне мне удалось применить на практике очень редкий вид графиков - Спарклайны (Sparkline).
Спарклайны — это небольшие немаркированные графики. Обычно они не содержат ни осей ни подписей, поэтому в основном предназначены для передачи какой-то общей идеи.
А т.к. спарклайны очень маленькие, то они отлично помещаются в ячейках Pandas'а :)
import base64
from io import BytesIO
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
from IPython.display import HTML
def sparkline(data):
data = list(data)
fig, ax = plt.subplots(1, 1, figsize=(4, 0.25))
ax.plot(data)
# Убираем все лишнее с графика
ax.set_axis_off()
# Заливаем график
ax.fill_between(range(len(data)), data, len(data)*[min(data)], alpha=0.1)
# Выводим min/max
plt.plot(np.argmax(data), data[np.argmax(data)], 'r.')
plt.plot(np.argmin(data), data[np.argmin(data)], 'm.')
img = BytesIO()
plt.savefig(img)
img.seek(0)
plt.close()
return '<img src="data:image/png;base64,{}"/>'.format(base64.b64encode(img.read()).decode())
agg_df = df.groupby('tradedate', as_index=False)['pr_open'].agg(list)
agg_df['sparkline'] = agg_df['pr_open'].map(sparkline)
HTML(agg_df[['tradedate','sparkline']][-10:].to_html(escape=False))
Графики можно редактировать в определенных границах: менять их ширину/высоту, можно разукрасить на свое усмотрение. Также вы можете вывести другие типы графиков: барплоты, гистограммы и пр.
З.Ы. Сам хакатон проходил в интересном формате. С одной стороны это был обычный хактон - с чек-поинтами и общением с экспертами. С другой - он длился целых 10 дней (вместо обычных 2-3). А за это время можно было сделать неплохой продукт :)| 2 | #competitions
Обычно я не пишу анонсы соревнований, но тут прям интересный случай.
Соревнование по EDA :) Оно же Exploratory Data Analysis, оно же Разведочный анализ данных.
Чтобы поучаствовать даже в ML разбираться не нужно - нужно уметь искать инсайты в данных и рисовать красивые графики.
И вишенка на торте: действие происходит на карте :)
И за это еще и заплатят (три призовых места :)
Подробнее: https://xmas-hack.ru/#case1 | 1 540 |
| 3 | #Tip41 #Pandas
Есть у пандаса такая функция - автоматическое определение типа колонок при загрузке данных. Но тип данных может быть определен не верно. Казалась бы, ну и ладно - переопределим после загрузки. Но тут кроется одна неявная проблема.
Звучит она так: "Категории могут начинаться с 0, а числа - нет".
Яркий тому пример коды ОКАТО, ОКВЭД и пр. Если пандас определит колонки ОКАТО и ОКВЭД как числа он ничего не сообщит, а просто отбросит начальные нули и спокойно загрузит данные. Тем самым изменив идентификатор изначальной категории и, возможно, смешав их с другими категориями. И это можно попросту не заметить (сам с таким сталкивался).
Чтобы избежать этого нужно явно указать тип колонки при загрузке данных:
type_dict = {
'Col_A': 'category',
'Col_B': 'int16',
'Col_C': 'float16',
'Col_D': 'float32'}
df = pd.read_csv(myfile, dtype=type_dict) | 676 |
| 4 | Написал небольшое эссе (вру, больше :) на тему, какие задачи могут без дообучения выполнять современные большие языковые модели (LLM):
https://habr.com/ru/articles/775870/ | 964 |
| 5 | #competitions #зашквар
Раз уж астрологи объявили неделю соревновательных постов, то расскажу об еще одном занятном хакатоне, который прошел месяц назад :) GoodsForecast Hack - Определение наличия товаров на полке.
Задача - классификация на временных рядах. Нужно было спрогнозировать, что какой-то товар в каком-то магазине в какое-то время забудут выложить на полку (и Дикси разорится :)
Первые подходы к снаряду выдавали очень веселый ROC AUC на отложенной выборке - ~43% :) Хотя обучение проходило нормально.
Стал разбираться почему и обнаружил такую интересную картину (см. картинку). Это сумма таргета по дням по каждому магазину за каждый день. Тут не вооруженным глазом видно, что в конце тренировочной выборки резко и сильно меняется паттерн данных (и скорее всего это продолжается в тестовом периоде - что потом и подтвердилось). Обучаться на таком нельзя.
Сразу же вспомнилось золотое правило МЛ: дерьмо на входе - дерьмо на выходе.
На вопрос к организаторам: "Что это за порнография?", был получен скромный ответ: "Изменилась модель".
Причем тут модель - не понятно :) Скорее таргет изменился или методология его сбора - хз...
Ничего не оставалось, кроме как выкинуть 80% тренировочной выборки :) После этого скор стал адекватным (~70%).
Но теперь получалось, что у нас на обучение и оценку 10 дней, а предсказывать надо 12. Такой себе временной ряд :)
Не знаю, преследовали ли какую-нибудь цель организаторы, выдавая такой датасет. Но похоже, что просто кто-то недоглядел :)
З.Ы. А чтобы такого не происходило, не забываем про пункт 7: https://t.me/ds_private_sharing/77 | 788 |
| 6 | #competitions #зашквар
На прошлой неделе участвовал в еще одном соревновании, заслужившим свое место в истории ML-соревнований - DataWagon. Трек 1: Прогнозирование спроса на грузовые ЖД перевозки. Задача регрессии на временных рядах. Нужно было прогнозировать спрос на вагоны на отдельных ЖД станциях на 5 месяцев вперед.
Но организаторы хотели слишком многого от 2 дней соревнований и откровенно переборщили со сложностью. Например, модель должна была считать одно, а оценивалось другое. Были и другие сложности...
Бейзлайн, который представили организаторы, был очень примитивен: просто копировали последний исторический месяц на 5 месяцев прогноза.
Все попытки построить нормальную ML-модель на временных рядах давали скор заметно ниже бейзлайна. Участники быстро смекнули что к чему и начали мучать бейзлайн :) Например, вместо последнего месяц, брали последние два месяца. Или как-то усредняли значения последних месяцев и т.д. В результате лучшие по скору решения так или иначе были основаны на бейзлайне.
А это значит, что это первое в истории ML соревнование, в котором победили организаторы :)))
Что хочу сказать-то: участвуйте в соревнованиях - это весело :)
З.Ы. А чтобы такого не происходило, нужно всего-то выполнить 7 пункт этого списка: https://t.me/ds_private_sharing/77 | 854 |
| 7 | #competitions #зашквар
На этих выходных удалось поучаствовать в хакатоне AgroCode Hack 2023. Трек 2: Система краткосрочного прогнозирования заболеваний винограда. Выиграть ничего не удалось (призовое место было только одно), но это не главное.
Главное, что соревнование было про гео-данные. ИМХО, это самый интересный вид ML-соревнований. Во первых потому что он сам по себе очень редкий. Встретить гео-соревнование это как встретить единорога :) Во вторых на нем вы можете порисовать интересные визуализации прямо на карте (а не эти ваши гистограммы и барплоты :). А в третьих можно насчитать кучу интересных фичей в двух или трехмерном пространстве.
На выходе нужна была интерактивная карта с прогнозом заболевания винограда. Наши поделки прикрепил :)
Но самое интересно началось после объявления победителя. Оказалось, что победитель представил старое решение. А по правилам хакатона нужно было разработать решение непосредственно на хакатоне. От этого у участников знатно бомбануло и в чатике начался срач :) Участники включили режим детектива и вскоре выяснилось что победитель это фирма (с оборотом 7 млн. руб.), которая занимается IoT в агросекторе, а в интернете нашлась старая их презентация, которую они и демонстрировали на питче.
Организаторов тут же обвинили в фальсификации и попросили прокомментировать зашквар :)
Сейчас организаторы взяли таймаут для ответ. Продолжаю наблюдений...
(будут новости - добавлю здесь) | 787 |
| 8 | #competitions
За свою карьеру ДС я участвовал во многих соревнованиях/хакатонах (несколько десятков точно).
И участвуя в соревнованиях я раз за разом встречаю одни и те же ошибки, которые вызывают боль. Особенно на хакатонах, где и так мало времени, а еще нужно разбираться с креативом организаторов :)
Итак, представляю вам мои правила хорошего хакатона/соревнования:
1. Сделайте пример сабмита. Назовите файлик submit_example.csv и положите его рядом с остальными выборками. И заполните чем-нибудь предикты (1 для регрессии, 0.5 для ROC AUC и т.д.). И этот пример лидерборд должен принимать без ошибок.
2. Обязательно должен быть бейзлайн. И бейзлайн должен полностью и без ошибок отрабатывать из коробки (только пути до файлов нужно подправить). И бейзлайн должен на выходе формировать корректный файл сабмита.
3. Лучше не использовать специфические метрики. Популярные ML библиотеки имеют схожий набор типовых метрик. Их можно из коробки использовать в этих библиотеках для различных расчетов. Наверняка среди них найдется метрика, которая подойдет и под вашу задачу (или максимально похожая на вашу кастомную метрику).
А чтобы подцепить к этим библиотекам кастомную метрику нужно проводить танцы с бубнами.
4. Расчет метрики должен быть явно представлен в бейзлайне. Не надо просто писать где-то, что считайте F1. Вариаций расчета F1 - паровоз и маленький вагончик. Участники не должны гадать какую метрику использовать.
5. Не мудрите с названиями. Есть устоявшиеся практики, которые ожидают увидеть участники. Часть для обучения называйте train.csv, часть для предсказания - test.csv
З.Ы. Бывают совсем экзотические случаи. Например, когда вместо файлов вам выдают доступ к БД, из которой надо взять данные. Этого тоже лучше избегать.
6. Не мудрите с оценкой. Участникам выдается тестовая выборка для оценки. Тест делится на приватную и публичную часть (cоотношение выбирайте сами). Скор на публичной части виден участникам в течении всего соревнования. Приватная часть появляется по завершении соревнования. Этот подход проверен и перепроверен годами. Он позволяет с одной стороны проверять решение в ходе соревнования, а с другой - не переобучиться под тест.
З.Ы. На чем считать итоговый скор? Тут на выше усмотрение. Например, Кегл (ацтой) считает итоговую оценку только на приватной части, а Zindi считает на всем тесте.
Из этих правил конечно же есть исключения. Например, докерные соревнования, в которых тест вовсе не выдается, а динамически подается в докер при отправке решения.
Если есть что добавить к этому списку - пишите в комментариях :) | 1 179 |
| 9 | Pruners в Optuna — это набор методов для прерывания бесперспективных экспериментов.
Как это работает. Ряд алгоритмов машинного обучения по своей природе имеют итеративный характер. Например: линейные модели, градиентный бустинг и т.д. Допустим мы создали LGBM модель на 300 шагов. Так вот, пройдя к примеру 20 или 50 шагов мы уже можем понят по скору, что лучшее значение мы скорее всего не превзойдём. А раз так, то и не стоит тратить на это время и ресурсы. И прерываем обучение.
В Optuna реализованы несколько прунеров:
- MedianPruner — останавливает испытание, если промежуточный скор хуже медианы промежуточных скоров предыдущих испытаний на том же этапе.
- PercentilePruner — останавливает испытание, если промежуточное значение находится в нижнем процентиле среди предыдущих испытаний на том же этапе.
- SuccessiveHalvingPruner — Successive Halving это "бандитский" алгоритм, позволяющий определить лучшую среди нескольких конфигураций.
- HyperbandPruner — типа улучшенная версия предыдущего варианта.
- ThresholdPruner — останавливает испытание, если скор превысил определенный порог.
Согласно этому исследованию Benchmarks with Kurobako (https://github.com/optuna/optuna/wiki/Benchmarks-with-Kurobako) лучший вариант для не глубогкого обучения — Hyperband (для TPESampler).
Пример кода для LGBM добавил в комментарии. | 634 |
| 10 | Написал очередной эпос :) На этот раз посвященный библиотеки Diffusers и моделям класс Stable Diffusion в целом.
Читать тут: https://habr.com/ru/articles/766094/ | 686 |
| 11 | #курс
Самый лучший в мире курс (Алгоритмы Машинного обучения с нуля :) пополнился модулем кластеризации.
Доступны три самых популярных алгоритма:
- K-Means: https://stepik.org/lesson/329904/step/1?unit=313244
- Иерархическая агломеративная кластеризация: https://stepik.org/lesson/329909/step/1?unit=313249
- DBSCAN: https://stepik.org/lesson/1076196/step/1?unit=1086342
Дальше нас ждет понижение размерности. | 718 |
| 12 | Target Encoding — популярный способ кодирования категориальных переменных.
И есть у него интересный парадокс. Согласно теории мы должны избегать лика в данных. Но с помощью Target Encoding'а мы по сути помещаем информацию о таргете в категориальную переменную. И все бы ничего, но если обучающая выборка не соответствует генеральной совокупности, то Target Encoding может не корректно кодировать фичи. А если данных по категориям совсем мало, то начинаются проблемы:
1. Неизвестные категории. Например, вы применили на трейне к фичи таргет энкодинг. И там допустим было 5 категорий. И вам необходимо применить такую же кодировку и к тесту. И тут оказывается, что в тесте у этой фичи 6 категорий. Что делать?
2. Редкие категории. Например, какая-то категория представлена только один раз. И таргет у нее - 1. И она будет также закодирована как 1. И для модели это будет явный лик. И если в тесте у этой категории будет настоящее значение 0, то модель ошибется.
Решением этих проблем является Smoothing Target Encoding. Его идея состоит в том, чтобы «сгладить» среднее значение по категориям, включив в него информацию об общем среднем по таргету. Логика такова: если данных по категории не хватает, нам следует больше полагаться на общее среднее, а если данных достаточно, то можем смело использовать среднее значение по категории.
З.Ы. А если данных в тесте по категории нет вовсе, то ей будет назначено среднее значение по всему таргету (помноженное на вес).
Формула такая:
encoding = weight * mean_by_cat + (1 - weight) * mean_overall
где:
- mean_by_cat — среднее значение таргета по категориям (Target Encoding)
- mean_overall — среднее по таргету
- weight — вес который мы назначаем среднему по категории и общему среднему. Вычисляется по формуле:
weight = n / (n + m)
где:
- n — сколько раз встречается категория.
- m — коэффициент сглаживания. Задается вручную.
Большие значения m придают больший вес общему среднему таргету. Меньшие значения отдают предпочтение среднему по категориям. А если m = 0, то получим обычный Target Encoding.
Код на питоне выглядит примерно так:
m = 0.01
n = df.groupby('cat_feature').size()
weight = n / (n + m)
mean_overall = df['y'].mean()
mean_by_cat = df.groupby('cat_feature')['y'].mean()
encoding = weight * mean_by_cat + (1 - weight) * mean_overall
В результате вы получите словарь состоящий из категорий и их кодов. | 1 092 |
| 13 | #Tip38 #EDA
Делаем из унылой корреляционной таблицы няшную :) С помощью Seaborn'а.
Самый простой способ нарисовать таблицу корреляции примерно такой:
corr = df.corr()
sns.heatmap(corr)
или:
corr = df.corr()
corr.style.background_gradient(cmap='coolwarm')
Выглядит довольно грустно (про непонятно я уже молчу).
Щас исправим:
1. Таблица обязательно должна быть треугольной. Квадрат избыточен и дублирует одну и ту же информацию. А это затрудняет анализ.
2. Только один цвет (точнее его градиент до белого). Цвет на ваш вкус, но только один.
3. Выводим в ячейках ровно столько информации сколько влазит в квадрат. В моем примере я вывел целые значения от 0 до 10, что соответствует диапазонам 0%-10%, 10%-20% и т.д.
4. Обычно для целей ML-соревнований не важно направление корреляции. Важно сама сила связи (чтобы, например, отфильтровать поля). Поэтому берем значения корреляции по модулю.
И вуаля:
corr = df.corr()
corr = (corr.abs()*10).round()
mask = np.triu(np.ones_like(corr, dtype=bool))
plt.figure(figsize=(7, 6))
sns.heatmap(
corr,
mask = mask,
cmap = 'RdBu',
center = 0,
square = True,
linewidths = 0.1,
annot = True,
annot_kws = {'size': 9},
cbar_kws={'ticks': [i for i in range(10+1)]}
) | 656 |
| 14 | #курс
Co времени последнего объявления самый лучший в мире курс (Алгоритмы Машинного обучения с нуля :) обзавелся двумя новыми модулями:
Метод ближайших соседей (kNN):
- Классификация: https://stepik.org/lesson/329908/step/1?unit=313248
- Регрессия: https://stepik.org/lesson/917932/step/1?unit=923726
Бэггинг:
- Регрессия: https://stepik.org/lesson/917945/step/1?unit=923739
- Классификация: https://stepik.org/lesson/329905/step/1?unit=313245
Следующий на подходе - какая-нибудь кластеризация. | 630 |
| 15 | #LightGBM #lgbm
Тихонечко, не привлекая особого внимания, вышел новый релиз LightGBM. Впервые за ~1.5 года. И сразу мажорный: 3.3.1 -> 4.0.0
https://github.com/microsoft/LightGBM/releases/tag/v4.0.0
Из интересных особенностей:
- Полностью переписали и ускорили GPU-реализацию. Теперь еще больше операций будут выполнятся на GPU (а то раньше совсем память простаивала). И вроде как теперь на линукс можно поставить просто через pip, без всяких сборок.
- Добавили квантизацию при обучении на CPU. И без того самый быстрый фреймворк на CPU станет еще быстрее (пишут про 2х) :)
Про остальные изменения можете почитать по ссылке. | 1 049 |
| 16 | #Tip37 #Jupyter
Часто пользуетесь одними и теми же библиотеками? И надоело каждый раз писать для них импорты?
В Jupyter Notebooks есть возможность по умолчанию импортировать нужные библиотеки.
1. Перейдите в:
Для линукса: /Users/<user_name>/.ipython/profile_default/startup
Для винды: C:\Users\<user_name>\.ipython\profile_default\startup
З.Ы. Если папки startup нету - создайте ее.
2. Создайте файл start.py
З.Ы. Название может быть любым - по сути будут выполнены все .py файлы находящиеся в этой папке.
3. Добавьте в него нужные импорты.
Теперь при каждом открытии ноуnбука ваши библиотеки уже будут импортированы. | 679 |
| 17 | #Tip36 #feature_engineering
Сидите вы такой и соревку решаете. Месяц, второй... Уже дохера чего перепробовали.
А вам все мало :) Хочется еще :) А нормальные идеи уже заканчиваются. Что делать?
Тут вам на помощь приходят они - Golden Features.
Golden Features это фичи созданные из существующих путем применения к ним простых математических операций.
Алгоритм простой: для каждой пары исходных фичей создайте новую фичу с помощью следующих операторов: + - / * ** sqrt
На выходе у вас получится что-то вроде:
feature_1_2_plus = feature_1 + feature_2
...
feature_3_7_ratio = feature_3 / feature_7
...
feature_9_17_power = np.power(feature_9, feature_17)
Обычно после таких манипуляций фичей становится неприлично много. Поэтому, перед тем как обучать нормальную модель, их сокращают. Для этого используется какая-нибудь простая модель, которая может выдавать важность фичей. После нее, для дальнейшей работы, берут N-топ фичей - они и будут Golden Features.
Смысл маневра в следующем: отдельные признаки сами по себе могут быть не очень полезны, но их взаимосвязь может дать модели какой-нибудь новый полезный сигнал. | 686 |
| 18 | #Tip35 #Jupyter
Иногда смотрю мок-интервью на DS-позиции и там, в том числе, спрашивают про питоновские магические команды.
Самая популярная - %%time. И я не понимаю, почему они до сих пор не вымерли (как динозавры :)
В своей работе я пользуюсь рядом аддонов для ноутбуков. Среди них - ExecuteTime.
Данные аддон добавляет под каждой ячейкой ноутбука узкую полоску. В ней при каждом выполнении ячейке отображается время завершения и сколько выполнялась.
Не нужно об этом задумываться. Не нужно писать никакого дополнительного кода. У вас всегда будет время выполнения :)
Вообще аддонов для ноутбука довольно много:
https://jupyter-contrib-nbextensions.readthedocs.io/en/latest/nbextensions.html
Устанавливаются они так:
https://jupyter-contrib-nbextensions.readthedocs.io/en/latest/install.html#install-the-python-package
Я обычно использую следующие:
1. ExecuteTime - отображает сколько выполнялась ячейка и когда она завершилась.
2. Codefolding - позволяет сворачивать код (в ячейке) по отступам. Удобно когда кода много.
3. Table of Contents - создает на боковой панели меню из заголовков ноутбука. Кликая по ним можно быстро перемещаться по большому ноутбуку.
4. Highlight selected word - когда вы выделяете какой-то фрагмент кода это расширение автоматически выделит точно такой же фрагмент во всех ячейках ноутбука. Помогает, например, быстро найти где используется выделенная переменная.
5. Code Completion (Hinterland) - вместо огромной простыни трассировки ошибки выводит ее краткую суть. При этом всегда можно развернуть полной описание.
Помимо "стандартных" аддонов в интернете можно найти и другие (в частности на GitHub).
Например Qgrid (https://github.com/quantopian/qgrid) - позволяет фильтровать датафрейм пандаса посредством визуального интерфейса.
Если знаете еще какие полезные аддоны пишите в комментариях :) | 612 |
| 19 | #Tip34 #feature_engineering
Weight of evidence (WoE) — это метод кодирования категориальных признаков в задачах бинарной классификации. Также как и Target Encoding, WoE позволяет поместить информацию о таргете в категориальную переменную.
WoE был изначальное разработан для кредитной и финансовой отраслей, чтобы облегчить скоринг клиентов. Но хитрые датасаентисты приспособили его для своих целей :)
WoE рассчитывается на основе отношения шансов:
WoE = ln(p(1)/p(0))
где p - вероятность для соответствующего класса.
WoE очень понятно отображает связь категорий и таргета:
WoE = 0 - результат случайный
WoE > 0 - с большей вероятностью данная категория относится к классу 1
WoE < 0 - с большей вероятностью данная категория относится к классу 0
Кроме того, WOE создает монотонную связь между категориальной переменной и таргетом, и оставляет все значения в небольшом диапазоне.
А это очень полезно для линейных моделей.
Код на питоне примерно такой:
woe_map = pd.DataFrame(df.groupby('cat')['target'].mean())
woe_map = np.log(woe_map / (1 - woe_map))
woe_map = woe_map['target'].to_dict() | 625 |
| 20 | #Tip33 #TimeSeries
У данных есть такое свойство: со временем они устаревают.
Например, если вы попытаетесь обучить модель на данных 10 летней давности и применить ее в настоящем времени, то скорее всего результат будет не очень...
Особенно это актуально для временных рядов.
И встает вопрос: что делать с устаревшими данными?
Самый простой подход - попробовать выкинуть наиболее старые данные. Например, если у вас в тренеровочном датасете данные за 2 года, то можете попробовать выкинуть самый ранний год.
Но есть более продвинутый способ - sample_weight - это параметр в CatBoost и LGBM, который отвечаете за то, с какой силой сэмплы будут влиять на обучение.
В CatBoost это делается либо через метод fit:
model = CatBoostClassifier()
model.fit(
X_train,
y_train,
sample_weight=train_weight)
либо через объект Pool, и тогда мы можем задать еще и веса для валидационных объектов (они будут влиять на вычисление метрики):
model = CatBoostClassifier()
model.fit(
X = Pool(X_train, y_train, weight=train_weight),
eval_set = Pool(X_test, y_test, weight=test_weight)
)
Объект с весом 0.1 будет вносить вклад в обучение примерно в 10 раз меньше чем с весом 1.0.
В LGBM есть аналогичный функционал. В нативной реализации задается через Dataset:
params = {}
my_data = lgb.Dataset(train_x, train_y, weights, ...)
my_model = lgb.train(params, my_data, ...) | 613 |
