Python - Что такое sklearn.pipeline.Pipeline?
Я не могу понять, как sklearn.pipeline.Pipeline
работает точно.
Есть несколько объяснений в документе. Например, что они подразумевают под:
Трубопровод преобразований с окончательной оценкой.
Чтобы прояснить мой вопрос, каковы steps
? Как они работают?
редактировать
Благодаря ответам я могу прояснить свой вопрос:
Когда я вызываю конвейер и передаю, как шаги, два трансформатора и один оценщик, например:
pipln = Pipeline([("trsfm1",transformer_1),
("trsfm2",transformer_2),
("estmtr",estimator)])
Что происходит, когда я это называю?
pipln.fit()
OR
pipln.fit_transform()
Я не могу понять, как оценщик может быть трансформатором и как трансформатор может быть установлен.
4 ответа
Transformer в scikit-learn - некоторый класс, у которого есть метод fit и transform или метод fit_transform.
Predictor - некоторый класс, который имеет методы подгонки и предсказания, или метод fit_predict.
Конвейер - это просто абстрактное понятие, а не какой-то существующий алгоритм ml. Часто в задачах ML необходимо выполнить последовательность различных преобразований (найти набор функций, сгенерировать новые функции, выбрать только некоторые полезные функции) набора необработанных данных перед применением окончательной оценки.
Вот хороший пример использования конвейера. Конвейер предоставляет единый интерфейс для всех 3 этапов преобразования и итоговой оценки. Он инкапсулирует преобразователи и предикторы внутри, и теперь вы можете сделать что-то вроде:
vect = CountVectorizer()
tfidf = TfidfTransformer()
clf = SGDClassifier()
vX = vect.fit_transform(Xtrain)
tfidfX = tfidf.fit_transform(vX)
predicted = clf.fit_predict(tfidfX)
# Now evaluate all steps on test set
vX = vect.fit_transform(Xtest)
tfidfX = tfidf.fit_transform(vX)
predicted = clf.fit_predict(tfidfX)
С просто:
pipeline = Pipeline([
('vect', CountVectorizer()),
('tfidf', TfidfTransformer()),
('clf', SGDClassifier()),
])
predicted = pipeline.fit(Xtrain).predict(Xtrain)
# Now evaluate all steps on test set
predicted = pipeline.predict(Xtest)
С помощью конвейеров вы можете легко выполнить поиск по сетке по набору параметров для каждого шага этого метаоценщика. Как описано в ссылке выше. Все шаги, кроме последнего, должны быть преобразованиями, последний шаг может быть преобразователем или предиктором.Ответ для редактирования: Когда вы звоните pipln.fit()
- каждый трансформатор внутри трубопровода будет установлен на выходах предыдущего трансформатора (первый трансформатор запоминается на наборе необработанных данных). Последний оценщик может быть преобразователем или предиктором, вы можете вызывать fit_transform() для конвейера, только если ваш последний оценщик является преобразователем (который реализует методы fit_transform или transform и fit отдельно), вы можете вызывать fit_predict() или Forett () для конвейера, только если Ваш последний оценщик является предиктором. Таким образом, вы просто не можете вызвать fit_transform или transform для конвейера, последний шаг которого - предиктор.
Я думаю, что M0rkHaV имеет правильную идею. Класс конвейера Scikit-learn - полезный инструмент для инкапсуляции нескольких различных преобразователей вместе с оценщиком в один объект, так что вам нужно вызывать ваши важные методы только один раз (fit()
, predict()
, так далее). Давайте разберем два основных компонента:
Трансформеры - это классы, которые реализуют оба
fit()
а такжеtransform()
, Возможно, вы знакомы с некоторыми инструментами предварительной обработки sklearn, такими какTfidfVectorizer
а такжеBinarizer
, Если вы посмотрите документы для этих инструментов предварительной обработки, то увидите, что они реализуют оба этих метода. Что мне нравится, так это то, что некоторые оценки также могут быть использованы в качестве шагов преобразования, напримерLinearSVC
!Оценщики - это классы, которые реализуют оба
fit()
а такжеpredict()
, Вы обнаружите, что многие из классификаторов и регрессионных моделей реализуют оба этих метода, и поэтому вы можете легко протестировать множество различных моделей. В качестве окончательной оценки можно использовать другой трансформатор (т. Е. Он не обязательно реализуетpredict()
, но определенно реализуетfit()
). Все это означает, что вы не сможете позвонитьpredict()
,
Что касается вашего редактирования: давайте рассмотрим текстовый пример. Используя LabelBinarizer, мы хотим превратить список меток в список двоичных значений.
bin = LabelBinarizer() #first we initialize
vec = ['cat', 'dog', 'dog', 'dog'] #we have our label list we want binarized
Теперь, когда бинаризатор установлен на некоторых данных, он будет иметь структуру под названием classes_
он содержит уникальные классы, о которых "знает" преобразователь. Без звонка fit()
бинаризатор понятия не имеет, как выглядят данные, поэтому вызов transform()
не имеет никакого смысла. Это верно, если вы распечатываете список классов, прежде чем пытаться уместить данные.
print bin.classes_
Я получаю следующую ошибку при попытке это:
AttributeError: 'LabelBinarizer' object has no attribute 'classes_'
Но когда вы устанавливаете бинаризатор на vec
список:
bin.fit(vec)
и попробуй еще раз
print bin.classes_
Я получаю следующее:
['cat' 'dog']
print bin.transform(vec)
И теперь, после вызова преобразования на vec
объект, мы получаем следующее:
[[0]
[1]
[1]
[1]]
Что касается оценок, используемых в качестве трансформаторов, давайте использовать DecisionTree
классификатор в качестве примера признака-экстрактора. Деревья решений хороши по многим причинам, но для наших целей важно, чтобы у них была возможность ранжировать объекты, которые дерево нашло полезными для предсказания. Когда вы звоните transform()
в дереве решений он будет принимать ваши входные данные и находить, что он считает наиболее важными функциями. Таким образом, вы можете подумать о том, как преобразовать матрицу данных (n строк по m столбцов) в меньшую матрицу (n строк по k столбцов), где k столбцов - это k наиболее важных функций, найденных в дереве решений.
Алгоритмы машинного обучения обычно обрабатывают табличные данные. Возможно, вы захотите выполнить предварительную и постобработку этих данных до и после вашего алгоритма машинного обучения. Конвейер - это способ связать эти этапы обработки данных.
Что такое конвейеры машинного обучения и как они работают?
Конвейер - это последовательность шагов, на которых преобразуются данные. Это происходит из старого шаблона проектирования "конвейер и фильтр" (например, вы можете подумать о командах unix bash с конвейерами "|" или операторами перенаправления ">"). Однако конвейеры - это объекты кода. Таким образом, у вас может быть класс для каждого фильтра (он же каждый шаг конвейера), а затем другой класс для объединения этих шагов в окончательный конвейер. Некоторые конвейеры могут объединять другие конвейеры последовательно или параллельно, иметь несколько входов или выходов и так далее. Нам нравится рассматривать конвейеры машинного обучения как:
- Труба и фильтры. Шаги конвейера обрабатывают данные и управляют своим внутренним состоянием, о котором можно узнать из данных.
- Композиты. Конвейеры могут быть вложенными: например, весь конвейер можно рассматривать как отдельный этап конвейера в другом конвейере. Шаг конвейера не обязательно является конвейером, но конвейер сам по себе, по крайней мере, является шагом конвейера.
- Направленные ациклические графы (DAG). Выходные данные шага конвейера могут быть отправлены на многие другие шаги, а затем полученные выходные данные могут быть повторно объединены и так далее. Боковое примечание: несмотря на то, что конвейеры являются ациклическими, они могут обрабатывать несколько элементов один за другим, и если их состояние изменяется (например, с использованием метода fit_transform каждый раз), то их можно рассматривать как периодически разворачивающиеся во времени, сохраняя свои состояния (подумайте как RNN). Это интересный способ увидеть конвейеры для онлайн-обучения при запуске их в производство и обучении их большему количеству данных.
Методы конвейера Scikit-Learn
У конвейеров (или шагов в конвейере) должны быть эти два метода:
- " Пригодность " для изучения данных и получения состояния (например, нейронные веса нейронной сети являются таким состоянием)
- " Преобразовать " (или "спрогнозировать") для фактической обработки данных и создания прогноза.
Также можно вызвать этот метод для объединения обоих:
- " Fit_transform ", чтобы подогнать и затем преобразовать данные, но за один проход, что позволяет проводить потенциальную оптимизацию кода, когда два метода должны выполняться один за другим напрямую.
Проблемы класса sklearn.pipeline. Pipeline
Шаблон проектирования Scikit-Learn "труба и фильтр" просто прекрасен. Но как использовать его для глубокого обучения, AutoML и сложных конвейеров производственного уровня?
Scikit-Learn выпустила свой первый выпуск в 2007 году, когда еще не было глубокого обучения. Тем не менее, это одна из самых известных и распространенных библиотек машинного обучения, которая продолжает расти. Помимо всего прочего, он использует шаблон проектирования "Труба и фильтр" в качестве архитектурного стиля программного обеспечения - это то, что делает Scikit-Learn таким замечательным, в дополнение к тому факту, что он предоставляет готовые к использованию алгоритмы. Однако у него есть серьезные проблемы, когда дело доходит до следующего, что мы сможем сделать уже в 2020 году:
- Автоматическое машинное обучение (AutoML),
- Конвейеры глубокого обучения,
- Более сложные конвейеры машинного обучения.
Решения, которые мы нашли для проблем Scikit-Learn
Безусловно, Scikit-Learn очень удобен и хорошо построен. Однако его нужно обновить. Вот наши решения с Neuraxle, чтобы сделать Scikit-Learn свежим и пригодным для использования в современных вычислительных проектах!
- Невозможность разумного автоматического машинного обучения (AutoML)
- Неспособность разумно использовать конвейеры глубокого обучения
- Проблема: Scikit-Learn вряд ли позволяет выполнять мини-пакетный градиентный спуск (добавочная подгонка)
- Проблема: инициализация конвейера и освобождение ресурсов
- Проблема: сложно использовать другие библиотеки глубокого обучения (DL) в Scikit-Learn
- Проблема: возможность преобразования выходных этикеток
- Не готов ни к производству, ни к сложным трубопроводам
- Проблема: обработка данных 3D, 4D или ND в конвейере с помощью шагов, сделанных для данных более низкого измерения
- Проблема: модифицируйте конвейер в процессе, например, для предварительного обучения или точной настройки
- Проблема: получение атрибутов модели из конвейера Scikit-Learn
- Проблема: невозможно распараллелить или сохранить конвейеры с помощью шагов, которые нельзя сериализовать "как есть" от Joblib
Дополнительные методы и функции конвейера, предлагаемые Neuraxle
Примечание: если для шага конвейера не требуется один из методов подгонки или преобразования, он может унаследоваться от NonFittableMixin или NonTransformableMixin, чтобы обеспечить реализацию по умолчанию одного из этих методов, чтобы ничего не делать.
Вначале конвейеры или их шаги могут также опционально определять эти методы:
- " Setup ", который будет вызывать метод "setup" на каждом этапе. Например, если шаг содержит нейронную сеть TensorFlow, PyTorch или Keras, шаги могут создавать свои нейронные графы и регистрировать их в графическом процессоре в методе "настройки" перед подгонкой. Не рекомендуется создавать графики непосредственно в конструкторах шагов по нескольким причинам, например, если шаги копируются перед многократным запуском с разными гиперпараметрами в алгоритме автоматического машинного обучения, который ищет для вас лучшие гиперпараметры.
- " Teardown ", который противоположен методу "setup": он очищает ресурсы.
Для управления гиперпараметрами по умолчанию предусмотрены следующие методы:
- " Get_hyperparams " вернет вам словарь гиперпараметров. Если ваш конвейер содержит больше конвейеров (вложенных конвейеров), то ключи гиперпараметров связаны с двойным подчеркиванием разделителями "__".
- " Set_hyperparams " позволит вам установить новые гиперпараметры в том же формате, в котором вы их получили.
- " Get_hyperparams_space " позволяет вам получить пространство гиперпараметра, которое не будет пустым, если вы его определили. Итак, единственная разница с "get_hyperparams" здесь заключается в том, что вы получаете статистические распределения в виде значений вместо точного значения. Например, один гиперпараметр для количества слоев может быть
RandInt(1, 3)
что означает от 1 до 3 слоев. Вы можете позвонить.rvs()
в этом диктовке, чтобы случайным образом выбрать значение и отправить его в "set_hyperparams", чтобы попробовать обучиться на нем. - " Set_hyperparams_space " может использоваться для установки нового пространства с использованием тех же классов распределения гиперпараметров, что и в "get_hyperparams_space".
Для получения дополнительной информации о предлагаемых нами решениях прочтите записи в большом списке со ссылками выше.
from sklearn.feature_extraction.text import TfidfVectorizer, CountVectorizer
from sklearn.base import BaseEstimator, TransformerMixin
from sklearn.model_selection import train_test_split
from sklearn.pipeline import Pipeline, FeatureUnion
from sklearn.preprocessing import StandardScaler
from sklearn import metrics
import pandas as pd
class TextTransformer(BaseEstimator, TransformerMixin):
"""
Преобразование текстовых признаков
"""
def __init__(self, key):
self.key = key
def fit(self, X, y=None, *parg, **kwarg):
return self
def transform(self, X):
return X[self.key]
class NumberTransformer(BaseEstimator, TransformerMixin):
"""
Преобразование числовых признаков
"""
def __init__(self, key):
self.key = key
def fit(self, X, y=None):
return self
def transform(self, X):
return X[[self.key]]
def fit_predict(model, X_train, X_test, y_train, y_test):
vec_tdidf = TfidfVectorizer(ngram_range=(2,2), analyzer='word', norm='l2')
text = Pipeline([
('transformer', TextTransformer(key='clear_messages')),
('vectorizer', vec_tdidf)
])
word_numeric = Pipeline([
('transformer', NumberTransformer(key='word_count')),
('scalar', StandardScaler())
])
word_class = Pipeline([
('transformer', NumberTransformer(key='preds')),
('scalar', StandardScaler())
])
# Объединение всех признаков
features = FeatureUnion([('Text_Feature', text),
('Num1_Feature', word_numeric),
('Num2_Feature', word_class)
])
# Классификатор
clf = model
# Объединение классификатора и признаков
pipe = Pipeline([('features', features),
('clf',clf)
])
# Обучение модели
pipe_fit=pipe.fit(X_train, y_train)
# Предсказание данных
preds = pipe_fit.predict(X_test)
return preds, pipe_fit