Эта статья перенесена в наш новый блог. Найдите его на странице https://building.nubank.com.br/introduction-fklearn-nubanks-machine-learning-library-part-i-2/.
Прочтите вторую часть этой истории здесь.
Nubank только что выпустил в открытый доступ fklearn, нашу библиотеку Python для машинного обучения!
В Nubank мы в значительной степени полагаемся на машинное обучение для принятия масштабируемых решений на основе данных. Хотя существует множество других библиотек машинного обучения (например, мы широко используем Xgboost, LGBM и ScikitLearn), мы почувствовали потребность в абстракции более высокого уровня, которая помогла бы нам более легко применять эти библиотеки для решения проблем. мы сталкиваемся с. Fklearn эффективно упаковывает эти библиотеки в формат, который делает их использование в производстве более эффективным.
В настоящее время Fklearn поддерживает большой набор моделей машинного обучения в Nubank, решая различные проблемы, от кредитного скоринга до автоматических ответов в чате службы поддержки клиентов. Мы построили его, имея в виду следующие цели:
- Валидация должна отражать реальные жизненные ситуации.
- Производственные модели должны соответствовать проверенным моделям
- Модели должны быть готовы к производству с несколькими дополнительными шагами.
- Воспроизводимость и углубленный анализ результатов модели должны быть легко достижимы.
Вначале мы решили, что функциональное программирование будет мощным союзником в попытках достичь этих целей.
F для функционального
Здесь, в Nubank, мы большие поклонники функционального программирования, и это не ограничивается главой Инженерия. Но как функциональное программирование помогает специалистам по данным?
Машинное обучение часто выполняется с использованием объектно-ориентированного кода Python, и именно так мы делали это и в Nubank. В то время процесс создания моделей машинного обучения и их внедрения в производство был утомительным и часто полон ошибок. Мы развернули модель только для того, чтобы обнаружить, что прогнозы, сделанные в производственной среде, не совпадают с прогнозами, полученными во время проверки. Более того, проверку часто было невозможно воспроизвести, и она часто выполнялась в Jupyter Notebooks с отслеживанием состояния.
Функциональное программирование помогает решить эти проблемы:
- Упрощение построения конвейеров, в которых преобразования данных, происходящие во время обучения, соответствуют моделям в производственной среде.
- Обеспечивает более безопасную итерацию в интерактивных средах (например, Jupyter Notebooks), предотвращает ошибки, вызванные кодом с отслеживанием состояния, и делает исследования более воспроизводимыми.
- Это позволяет нам писать очень общий код проверки, настройки и выбора функций, который работает с разными типами моделей и приложений, что делает нас в целом более эффективными.
Давайте рассмотрим пример, чтобы увидеть, как функциональное программирование делает это на практике. Допустим, мы пытаемся предсказать, сколько кто-то потратит на свою кредитную карту, на основе двух переменных: ежемесячного дохода и суммы предыдущего счета. Поскольку выходные данные этой модели будут использоваться для принятия чувствительных решений, мы хотели бы убедиться, что они устойчивы к выбросам во входных переменных, поэтому мы решили:
- Ограничьте ежемесячный доход до 50 000, поскольку доход является самооценкой и иногда преувеличен.
- Ограничьте выходной диапазон модели интервалом [0, 20,000].
А затем используйте простую модель линейной регрессии. Вот как выглядит код:
Не пугайтесь! Мы шаг за шагом пройдемся по коду, объясняя некоторые важные концепции fklearn.
Функции ученика
В то время как в scikit-learn основной абстракцией для модели является класс с методами fit и transform, в fklearn мы используем то, что мы называем функцией обучаемого. . Функция обучаемого принимает некоторые обучающие данные (плюс другие параметры), чему-то учится и возвращает три вещи: функцию прогнозирования, преобразованные данные обучения и журнал. Первые три строки нашего примера инициализируют три функции обучаемого: capper, linear_regression_learner, и prediction_ranger.
Чтобы лучше проиллюстрировать это, вот упрощенное определение linear_regression_learner:
Обратите внимание на использование подсказок типа! Они помогают сделать функциональное программирование на Python менее неудобным, наряду с чрезвычайно полезной библиотекой toolz.
Как мы уже упоминали, функция обучающегося возвращает три вещи (функцию, DataFrame и словарь), как описано в определении LearnerReturnType:
- Функция прогнозирования всегда имеет одну и ту же сигнатуру: она принимает DataFrame и возвращает DataFrame (мы используем Pandas). Он должен иметь возможность принимать любой новый DataFrame (если он содержит необходимые столбцы) и преобразовывать его (это эквивалентно методу transform объекта scikit-learn). В этом случае функция прогнозирования просто создает новый столбец с прогнозами модели линейной регрессии, которая была обучена.
- Преобразованные обучающие данные обычно представляют собой просто функцию прогнозирования, применяемую к обучающим данным. Это полезно, когда вам нужны прогнозы для вашего обучающего набора или для построения конвейеров, как мы увидим позже.
- Журнал представляет собой словарь и может включать любую информацию, имеющую отношение к проверке или отладке учащегося (например, какие функции использовались, сколько образцов было в обучающем наборе, важность функции или коэффициенты).
Функции обучаемого демонстрируют некоторые общие свойства функционального программирования:
- Это чистые функции, то есть они всегда возвращают один и тот же результат при одном и том же вводе, и у них нет побочных эффектов. На практике это означает, что вы можете звонить учащемуся столько раз, сколько хотите, не беспокоясь о получении противоречивых результатов. Это не всегда так, например, при вызове fit для объекта scikit-learn, поскольку объекты могут изменяться.
- Это функции высшего порядка, поскольку они возвращают другую функцию (функцию прогнозирования). Поскольку функция прогнозирования определяется в самом учащемся, она может получить доступ к переменным в области действия функции учащегося через свое закрытие.
- Имея согласованные подписи, функции обучаемого (и функции прогнозирования) компонуемы. Это означает, что построить из них целые конвейеры несложно, как мы скоро увидим.
- Они curriable, то есть вы можете инициализировать их поэтапно, передавая всего несколько аргументов за раз (это то, что на самом деле происходит в первых трех строках нашего примера). Это будет полезно при определении конвейеров и применении одной модели к разным наборам данных при получении согласованных результатов.
На то, чтобы осмыслить все это, может потребоваться некоторое время, но не волнуйтесь, вам не нужно быть экспертом в функциональном программировании, чтобы эффективно использовать fklearn. Ключевым моментом является понимание того, что модели (и другие преобразования данных) могут быть определены как функции, следующие за абстракцией учащийся .
Трубопроводы
Однако модели машинного обучения редко существуют сами по себе. Сосредоточившись только на модели, специалисты по данным обычно забывают, какие преобразования проходят данные до и после части машинного обучения. Эти преобразования часто должны быть точно такими же при обучении и развертывании моделей, и специалисты по обработке данных могут попытаться вручную воссоздать свои обучающие шаги до и после обработки в производственной среде, что приводит к дублированию кода, которое трудно поддерживать.
Функции учащихся являются компонуемыми, что означает, что два или более учащихся вместе могут рассматриваться как просто новый, более сложный учащийся. Это означает, что независимо от того, сколько шагов у вас есть в конвейере, ваша окончательная модель будет вести себя так же, как и одиночная, и делать прогнозы так же просто, как вызывать функцию окончательного прогнозирования для новых данных. Наличие всех шагов в конвейере моделирования, содержащихся в одной чистой функции, также помогает с проверкой и настройкой, поскольку мы можем передавать их другим функциям, не опасаясь побочных эффектов.
В нашем примере конвейер состоит из трех этапов: ограничение переменной дохода, запуск регрессии, затем ограничение вывода регрессии на [0, 20000] диапазон. После инициализации каждого учащегося мы создаем конвейер и применяем его к обучающему набору, используя эти две строки кода:
Переменная учащийся теперь содержит конвейер, полученный в результате компоновки трех функций учащегося, и применяется к обучающим данным для получения окончательной функции прогнозирования. Эта функция применяет все эквивалентные шаги в конвейере к тестовым данным, как показано на рисунке ниже:
Что дальше?
Мы увидели, как модели и шаги преобразования данных могут быть записаны как обучающие функции и как функциональные конвейеры в fklearn помогают нам гарантировать, что преобразования, выполняемые во время обучения и проверки, соответствуют преобразованиям, выполняемым в производственной среде.
В Части II этого сообщения в блоге мы говорим о проверке и анализе модели, а также об инструментах, которые предоставляет fklearn, чтобы сделать эти шаги более эффективными.
А пока предлагаем вам попробовать fklearn на себе! Мы не ожидаем, что fklearn заменит текущие стандарты машинного обучения, но надеемся, что с него начнутся интересные разговоры о преимуществах функционального программирования для машинного обучения.
Заинтересованы в науке о данных и интересными продуктами, создаваемыми в Nubank? Нанимаем!