Красивый конвейер машинного обучения с помощью Scikit-Learn
Разработка функций — самая сложная часть при применении машинного обучения к вашему продукту. Эта заметка направлена на то, чтобы улучшить манеру использования scikit-learn для проектирования функций и машинного обучения на основе моего личного опыта.
Прежде чем представить мои стратегии, давайте сначала рассмотрим общие проблемы разработки функций:
- обработка пропущенных значений
- номарлизация / стандартизация
- интерактивное взаимодействие
- кодировка этикетки
- одна горячая кодировка
Когда мы начинаем часть разработки функций при разработке модели машинного обучения, нам обычно нужно попробовать множество возможных решений и быстро перебрать различные возможные комбинации приемов функций. Есть много статей, рассказывающих о том, как выполнять вышеуказанные инженерные работы. Но когда вы хотите применить разные подходы к разным функциям, вы можете написать сложный код для разработки функций. Код может содержать несколько преобразований numpy/scipy и возвращаться в конвейеры обучения scikit. Это приводит к тому, что код сложно поддерживать и трудно отлаживать при возникновении проблемы. В этой статье я хочу представить несколько трюков в scikit-learn для создания конвейера модели машинного обучения, который охватывает:
- разработка функций на разных столбцах
- ансамблевое обучение с индивидуальными трансформерами
- API глубокого обучения со сложным конвейером функций
Здесь мы определяем некоторые фрагменты кода для входных/выходных данных, прежде чем говорить о деталях:
train_data = pd.read_csv("input_data.csv")
train_labels = pd.read_csv("input_labels.cs v")
predict_data = pd.read_csv("predict_data.csv")
Давайте посмотрим, как выполнить простую разработку функций, если вы не применяете конвейер.
Пример кода
pca_transform = PCA(n_components=10)
pca_transform.fit(train_data.values)
pca_transform_data = pca_transform.transform(train_data.values)
nmf_transform = NMF()
nmf_transform.fit(train_data.values)
nmf_transform_data = nmf_transform.transform(train_data.values)
union_data = np.hstack(nmf_transform_data, pca_transform_data)
model = RandomForestClassifier()
model.fit(union_data, train_labels.values)
pca_transform_predict_data = pca_transform.transform(predict_data.values)
nmf_transform_predict_data = nmf_transform.transform(predict_data.values)
union_predict_data = np.hstack(
pca_transform_predict_data, nmf_transform_predict_data)
predictions = model.predict(union_predict_data)
Как видите, это довольно интуитивно понятная реализация, если вы хотите применить к своим данным некоторые технические приемы. Но вы можете себе представить, что код превратится в беспорядочного монстра, если вы примените множество трюков и к различным функциям.
Плюсы
Минусы
- Нужно заботиться о многих деталях с интерфейсом numpy/scipy
- Имейте много повторяющегося кода, чтобы делать похожие вещи
Чтобы сделать всю операцию более чистой, scikit-learn предоставляет конвейерный API чтобы позволить пользователю создать конвейер машинного обучения, не заботясь о деталях.
Пример кода
model_pipeline = Pipeline(steps=[
("dimension_reduction", PCA(n_components=10)),
("classifiers", RandomForestClassifier())
])
model_pipeline.fit(train_data.values, train_labels.values)
predictions = model_pipeline.predict(predict_data.values)
Плюсы
- Избавьтесь от обработки деталей между двумя этапами.
- Код легко поддерживать
Минусы
- Если вы используете эту реализацию, применяйте только 1 тип преобразования к заданным функциям. Но это первый шаг к тому, чтобы сделать ваш пайплайн более элегантным.
Если вы хотите применить различные функции обработки объектов к вашему набору данных. Можешь попробовать API объединения функций. API предоставляет простой способ объединения массивов из преобразований разных типов. Вот фрагменты кода, если вы хотите его использовать:
Пример кода
model_pipeline = Pipeline(steps=[
("feature_union", FeatureUnion([
("pca", PCA(n_components=1)),
("svd", TruncatedSVD(n_components=2))
])),
("classifiers", RandomForestClassifier())
])
model_pipeline.fit(train_data.values, train_labels.values)
predictions = model_pipeline.predict(predict_data.values)
Плюсы
- Используйте другой преобразователь функций, не разделяя код на несколько частей и составляя их.
Минусы
- Невозможно применить различное преобразование по разным функциям
- Невозможно напрямую отправить кадр данных pandas и использовать диктофонный способ доступа к данным в вашем конвейере.
С Идея 3, вы можете легко реализовать свой конвейер с различными преобразованиями. Но есть две проблемы, о которых мы упоминали выше, мы пытаемся решить эти проблемы и найти API преобразователя столбцов после осмотра разных материалов. Мне очень нравится этот API, потому что он позволяет упростить конвейер, например настройку, и обучать/прогнозировать данные с помощью простой команды.
Пример кода
model_pipeline = Pipeline(steps=[
("features", FeatureUnion([
(
"numerical_features",
ColumnTransformer([
(
"numerical",
Pipeline(steps=[(
"impute_stage",
SimpleImputer(missing_values=np.nan, strategy="median",)
)]),
["feature_1"]
)
])
), (
"categorical_features",
ColumnTransformer([
(
"country_encoding",
Pipeline(steps=[
("ohe", OneHotEncoder(handle_unknown="ignore")),
("reduction", NMF(n_components=8)),
]),
["country"],
),
])
), (
"text_features",
ColumnTransformer([
(
"title_vec",
Pipeline(steps=[
("tfidf", TfidfVectorizer()),
("reduction", NMF(n_components=50)),
]),
"title"
)
])
)
])),
("classifiers", RandomForestClassifier())
])
model_pipeline.fit(train_data, train_labels.values)
predictions = model_pipeline.predict(predict_data)
Плюсы
Все преобразования данных могут быть интегрированы в конвейер модели и просты в обслуживании. Вы можете разделить различные типы данных, такие как числовые данные и категориальные данные, и обрабатывать их различными методами.
Минусы
Я не вижу никаких трудностей, если бы мы использовали такую реализацию при разработке функций.
С помощью описанных выше приемов вы можете элегантно создать конвейер машинного обучения. Здесь я хочу представить некоторые продвинутые приемы, в том числе:
- как сделать обучение ансамбля стека в вашем конвейере
- как интегрировать keras в ваш пайплайн
Объединение методов ансамбля в конвейер
Как вы знаете, мы обычно хотим использовать метод суммирования, чтобы избежать предвзятости от одного конкретного метода. Если вы все еще новичок в обучении стекированию, вы можете прочитать этот учебник первый. Итак, при реализации методов стекирования возникает вопрос: как сделать метод стекирования одним из шагов в вашем конвейере? Я читаю этот материал и дух создания шага строит индивидуальный класс трансформатора.
Реализация здесь не идеальна, но является хорошим исходным материалом для расширения.
Быстро адаптируйте модель нейронной сети с помощью Keras API
Жесткий API Scikit-Learn предоставляет простой способ интеграции модели нейронной сети с API обучения scikit. Вы можете быстро реализовать свою модель keras и интегрировать ее с собственным конвейером в качестве одного шага в объекте конвейера.
Но есть недостаток в том, что шаги вне нейронных сетей не могут быть оптимизированы нейронной сетью. Вам по-прежнему нужно оптимизировать часть разработки функций самостоятельно, но она может обрабатывать часть предварительной обработки данных, если вы хотите использовать нейронную сеть в своем конвейере. Еще один момент заключается в том, что я не пытался реализовать конвейер, если моя часть нейронной сети имеет несколько входов, поэтому я понятия не имею, как интегрировать нейронную сеть с несколькими входами в конвейер scikit-learn.
Это простое введение, чтобы дать представление о том, как сделать разработку функций элегантным способом. Я считаю, что есть еще много замечательных трюков, которые могут помочь нам создать конвейеры машинного обучения с помощью простого кода. Изучив документацию и дизайн API в scikit-learn, мне понравились их мысли о разработке машинного обучения, и я думаю, что им стоит следовать.