Aspiring Data Science – Telegram
Aspiring Data Science
385 subscribers
465 photos
12 videos
12 files
2.15K links
Заметки экономиста о программировании, прогнозировании и принятии решений, научном методе познания.
Контакт: @fingoldo

I call myself a data scientist because I know just enough math, economics & programming to be dangerous.
Download Telegram
Forwarded from Data notes
Насущная проблема инвесторов из РФ: лимит на продажу заблокированных активов 100 тысяч рублей, превышать который нельзя. Если таковых на бОльшую сумму, то возникает вопрос, какие активы продать, чтобы использовать лимит по-максимуму? С ответом поможет линейное программирование!

from ortools.linear_solver import pywraplp

def maximize_spending(L, prices, stock):
# Create a linear solver object
solver = pywraplp.Solver.CreateSolver('SCIP')

# Define variables
quantities = [solver.IntVar(0, stock[i], f'quantity_{i}') for i in range(len(prices))]

# Define objective function: maximize the total spending
objective = solver.Objective()
for i in range(len(prices)):
objective.SetCoefficient(quantities[i], prices[i])
objective.SetMaximization()

# Add constraint: total spending should not exceed the limit M
constraint_total_spending = solver.Constraint(0, L)
for i in range(len(prices)):
constraint_total_spending.SetCoefficient(quantities[i], prices[i])

# Solve the problem
status = solver.Solve()

if status == pywraplp.Solver.OPTIMAL:
total_spending = sum(quantities[i].solution_value() * prices[i] for i in range(len(prices)))
items_quantities = {f'I{i+1}': int(quantities[i].solution_value()) for i in range(len(prices))}
return total_spending, items_quantities
else:
return None


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

# Money limit
L = 100000

# Prices of items I1, I2, I3, I4
prices = [709.18, 11851.10, 1528.21, 9395.44]

# Quantities of items in stock Q1, Q2, Q3, Q4
stock = [17, 4, 19, 12]

total_spending, items_quantities = maximize_spending(L, prices, stock)

if total_spending is not None:
print("Maximum spending:", total_spending)
print("Items quantities:", items_quantities)
else:
print("No solution found.")
Forwarded from Data notes
На текущем проекте довелось заниматься поиском кандидатов в антифрод правила и в правила отказа для кредитного скоринга в новых источниках данных. Описал подходы, которые помогли, в заметке
Forwarded from Data notes
Долгое время удивлялся, почему мне попадается так мало проектов, где по полной используется sklearn.Pipeline. Под этим я имею в виду не игрушечные примеры из 2-3 шагов, где первый PCA или OHE, а второй - логрег или random forest, а нормальный пайплайн из десятка шагов с отбором и преобразованием признаков из реальных задач, например, шаг, где детектятся группы сильно кореллирующих фичей, затем из каждой группы оставляется только одна, самая сильная. Или, когда на этапе моделирования катбустом мы делаем несколько итераций с отбрасыванием фичей с нулевой значимостью. Мы итак делаем эти шаги, так почему бы не сделать их частью пайплайна? Да, стандартные решения из sklearn вряд ли подойдут, поэтому круто научиться их делать самому. Собрал все свои кастомные трансформеры, совместимые с sklearn.Pipeline, положил их в репу и описал в заметке, думаю, будет полезно (ссылка на репу)
Forwarded from Data notes
Не самые стандартные вопросы по классическому МЛ, которые попадались на собесах за последнее время:

- Почему не стоит в проде использовать RandomForest из sklearn? Какие есть альтернативы, если все-таки нужнен именно RandomForest?
- Как вычислить уверенность RandomForest в прогнозе при решении задачи регрессии?
- Как меняются bias и variance в RandomForest при увеличении числа деревьев? А в GBDT?
- В чем принципиальное отличие логрега из statsmodels и из sklearn?
- В чем различия между дискриминативными и генеративными моделями? (речь про классический МЛ)
- Чем обусловлена разная форма распределения скоров LogisticRegression , SVC, RandomForest?
- Почему нейросети могут генерировать признаки автоматически, а GBDT - нет?
- Какие преимущества дает знание второй производной от функции потерь в GBDT?
- Для чего (и в каких случаях) необходима калибровка ответов бинарного классификатора? А когда можно обойтись без нее?
Forwarded from Data notes
Еще вопросики по Python:
- Когда GIL не помеха для multithreading?
- В чем разница между multithreading и async? А что у них общего?
- Как так получилось, что в Python есть GIL, который создает ограничения при работе с multithreading, когда в других языках, например, C#, многопоточность спокойно работает безо всяких GIL?
- Приведите известные примеры применения множественного наследования
- Про ускорение вычислений. Что такое numba, когда она может помочь ускорить выполнение кода, а когда нет? Аналогичный вопрос про Cython.
- Приведите примеры из Ваших проектов, где примененялись декораторы и генераторы. Как связаны генераторы и async?
- Какие объекты Python хранятся в стеке (stack), а какие - в куче (heap)?
Forwarded from Data notes
Стало попадаться много высказываний вроде "ах, вот N лет назад чтобы устроиться в ДС/МЛ достаточно было сказать, что умеешь писать фит-предикт в ноутбучке и тебе апплодировали стоя и брали на работу с огромной зарплатой. А вот сейчас с джунов три шкуры на собеседованиях дерут, на которые еще и не пробиться никак сквозь тысячи откликов."

Вспомнил, как я искал свою первую работу в сфере в 2016-17 годах. На тот момент диплом, основанный на решении задачи из реальной жизни с помощью МЛ (прогнозирование стоимости ремонта оборудования) был уже фактически написан и оставалась только формальная защита, что сильно пригодилось при обсуждении опыта и навыков на собесах.

Из фейлов - общение с tutu.ru на джуна-аналитика. Вопросы по основам SQL, которые зашли, а затем последовала задача, где нужно было определить оптимальное кол-во СМС-напоминалок клиенту, чтобы он продолжил покупку билетов на сайте, если он вдруг забросил процесс по каким-то причинам. Наивно верящий тогда в то, что МЛ - это серебрянная пуля, я начал бормотать что-то про выборку, которую нам надо собрать, пробовать разное кол-во СМС ну и так далее. Естественно, решение было гораздо проще. Справедливый отказ как итог.

Из успехов - мой тогдашний шеф зареферил меня в известный рекламный холдинг на data scientist intern. Они только начали набирать команду, в которой еще никого не было, но главное, что они точно знали, какие задачи нужно было решать и кто именно им нужен, что далеко не всегда верно даже сегодня!
Собственно, собес:
- Две задачи по терверу, одна из которых нередко попадается и сейчас. Вторая на смесь комбинаторики с тервером на расчет агрегированных показателей ТВ охватов. Простой вариант затащил, а сложный - облом, причем как оказалось потом, эту задачу они сами не могли решить за вменяемое время (спойлер: потом мне ее как раз и дали в течение первых месяцев)
- Кодинг на бумаге: обход бинарного дерева в глубину. Кажется ерундой, но позиция стажерская да и без подготовки далеко не все мидлы осилят (сужу по опыту собесов уже со стороны собеседующего)
- Поскольку питона тогда в отделе еще и в помине не было, основным языком разработки был C# и требовалось знать и его, чтобы в первое время интегрировать наработки в существующую систему. C# на тот момент я уже год как изучал в универе, поэтому здесь тоже все было ок
- Вопросы по дипломному проекту. Как собирал данные, как строил модель, как валидировал и как это потом можно будет внедрить. Не очень-то отличается от того, что спрашивают сегодня, а это, еще раз напомню, стажерская позиция.
- Какие задачи интересны, чем хотелось бы заниматься .. бихейв. Здесь тоже сошлись

В итоге проработал в этой компании больше 3 лет и очень благодарен людям за наставничество.
#numpy #codegems #vectorize

Будьте осторожны с vectorize )
💯1
#news

Канал достиг 100π подπисчиков )
🔥61
#recommenders #google #youtube #wizards

Задумался о реализации системы рекомендаций рекламы в ютубе.

Ожидания: топовые дата сайентисты гугла наверняка сделают что-то крутое и интересное.

Реальность: 3 задроченных ролика про то как увольняют Jira, какую-то палестинскую вымогательницу на фоне руин, какие-то блядские игры в браузере. всё это крутится в цикле.

А, еще сервис составления опросов и сервис AI-войсоверов. Всё.

Убрать набившее оскомину рекламное объявление невозможно. Технически кнопка такая есть, но она по факту ничего не меняет.

Спасибо, что хоть ублюдков, продвигавших какие-то финансовые махинации на фоне выступлений Маска, вышвырнули (надолго ли?).

Я, наверное, чего-то не понимаю, но зачем мне показывать одну и ту же рекламу сотни и тысячи раз?
#binning #optbinning #papers

Приятное, лёгкое для чтения интро в библиотеку OptBinning. А вот уже публикация посолиднее, с указанием алгоритмов.

Мне кажется, для задач регрессии уж точно можно уменьшить потерю информации, если заменять бин не константой (например, WoE бина), а какой-то линейной функцией от константы и значений точки. Даже странно, почему это никто еще не рассмотрел.


https://medium.com/@makhija.amit/mastering-optimal-binning-with-optbinning-a-comprehensive-guide-c6cf52572d64
🔥1
#scoring #binning #woe #gini #psi

Вот еще была интересная либа vtb_scorekit.

"Алгоритм работы этого метода следующий:

Ищется разбиение на максимальное кол-во бинов. Для этого может использоваться либо наш собственный алгоритм, основанный на деревьях, либо библиотека optbinning.

Далее в найденном биннинге проводятся проверки

на тренд WOE — он может быть либо монотонным, либо V (или /\)‑образным, но во втором случае Gini переменной должно быть выше относительно монотонного тренда на заданную в параметрах величину. Такая дополнительная проверка позволяет исключить случайные отклонения от монотонности в трендах

стабильность тренда WOE — тренд должен сохраняться на всех тестовых сэмплах, и доверительные интервалы WOE в соседних бинах не должны пересекаться

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

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

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

В результате всех этих расчетов мы получаем и тестируем десятки (а иногда и сотни) биннингов для каждой переменной и выбираем из них лучший. Благодаря тому, что расчет каждой переменной идет полностью независимо от остальных, можно проводить все эти вычисления параллельно и, выделив большое число ядер для расчета, получать результат достаточно быстро."

Тут уже есть из коробки многофакторный анализ, проводящийся в 4 этапа:

"Сначала будут отсечены слабые и не стабильные факторы по заданным трешхолдам Gini и PSI факторов

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

На третьем этапе проводится итерационный отбор факторов, который может отбирать переменные как для максимизации заданной метрики, так и по p-value переменных.

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

https://habr.com/ru/companies/vtb/articles/743392/
👍1🔥1
#abtesting

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

https://www.youtube.com/watch?v=gMx-juYkNCw
#abtesting

Самое лучшее выступление по А/Б тестам с управленческой точки зрения, что я видел.

Фишка культуры А/Б тестирования в том, что ценность мнения CEO компании становится равной ценности мнения любого сотрудника.

Наверное, это один из главных барьеров к распространению этого подхода к принятию решений.

https://youtu.be/_sx5LV23hIE?si=B7wuha09eOp2XVYj
#dummy #baselines #sklearn #timeseries

Чёт я задумался, что Dummy* модели в sklearn совсем не предназначены для временных рядов. Сел сочинять Feature Request, посмотрим, если не зарубят, даже сам над ним поработаю.

И, кстати сказать, неудобно, что на практике всегда перебираешь все доступные стратегии, чтобы создать хоть какой-то разумный бэйз.

У меня пока такие идеи:

1) дать возможность указывать окно, как в pandas при вычислении rolling/expanding. Вводим для этого параметр scope:str={"rolling","expanding","all"}. Если scope!="all", стратегия применяется не ко всему датасету, а к окошку. параметры **kwargs передаются напрямую в метод scope ряда pandas.

Для полной поддержки взвешенных окон придётся добавить **extra_kwargs:

kwargs=dict(window=5, win_type="gaussian")
extra_kwargs=dict(std=0.1)
# Supplementary Scipy arguments passed in the aggregation function
y.rolling(**kwargs).mean(**extra_kwargs)


2) добавить strategy="lag" (только для scope="rolling")

3) добавить strategy="best", которая будет внутри перебирать все остальные стратегии, чтобы выдать пользователю самую сильную базу. Также придётся добавить параметр scoring, как в cross_validate, чтоб можно было сравнивать стратегии.

4) добавить strategy="ewm" на базе того же пандас. параметры **kwargs передаются напрямую в метод ewm pandas.

5) добавить strategy="apply" (для scope!="all") для применения кастомных аггрегирующих функций. Будет транслироваться в

def mad(x):
return np.fabs(x - x.mean()).mean()

kwargs=dict(window=4)
extra_kwargs=dict(func=mad, raw=True)

y.rolling(**kwargs).apply(**extra_kwargs)


6) в случае задания окна, хотелось бы добавить классу немного ума. пусть бы сам искал, какое окно даёт наилучший скоринг? только вот как это сделать, если индексом служит время, слишком много же вариантов получается.

Ещё придётся думать о сортировке y (если это ряд pandas с datetimelike-индексом) и заполнении пропусков (у окон есть параметр min_period, так что пропуски вполне могут появиться). Думаю заполнять пропуски либо backfill-ом, либо стратегией, применённой ко всему датасету. Нужен новый параметр fill_na:str={"backfill","strategy"}, видимо.

Есть ещё предложения по стратегиям?

В общем, запостил FR: https://github.com/scikit-learn/scikit-learn/issues/29813
2🏆1
Forwarded from Data Secrets
⚡️ Breaking: чтобы выйти из кризиса, Nvidia начала выпускать женские сумочки
Please open Telegram to view this post
VIEW IN TELEGRAM