Python - что такое sklearn.pipeline.Pipeline?

118

Я не могу понять, как sklearn.pipeline.Pipelineименно работает.

Есть несколько объяснений в доке . Например, что они означают:

Конвейер преобразований с финальной оценкой.

Чтобы прояснить мой вопрос, какие steps? Как они работают?

редактировать

Благодаря ответам я могу прояснить свой вопрос:

Когда я вызываю конвейер и передаю в качестве шагов два трансформатора и одну оценку, например:

pipln = Pipeline([("trsfm1",transformer_1),
                  ("trsfm2",transformer_2),
                  ("estmtr",estimator)])

Что происходит, когда я это звоню?

pipln.fit()
OR
pipln.fit_transform()

Я не могу понять, как оценщик может быть трансформатором и как можно установить трансформатор.

Farhawa
источник
3
Насколько я понял, пайплайн помогает автоматизировать несколько этапов процесса обучения. Например, обучение и тестирование моделей или выбор функций ... Итак, если вы хотите смешать регрессию, используйте ее, например, для подачи на классификатор, вашими шагами будет обучение этой регрессии, а затем классификатора. редактировать: добавить подробности
M0rkHaV
1
queirozf.com/entries/scikit-learn-pipeline-examples Я нашел это полезным
randomSampling

Ответы:

180

Transformer в scikit-learn - некоторый класс, у которого есть метод fit и transform, или метод fit_transform.

Predictor - некоторый класс, у которого есть методы соответствия и прогнозирования, или метод fit_predict.

Конвейер - это просто абстрактное понятие, это не какой-то существующий алгоритм ml. Часто в задачах машинного обучения вам необходимо выполнить последовательность различных преобразований (найти набор функций, создать новые функции, выбрать только некоторые хорошие функции) необработанного набора данных перед применением окончательной оценки.

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

    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 или методы преобразования и подгонки отдельно), вы можете вызвать fit_predict () или прогнозировать () в конвейере, только если ваш последний оценщик - предсказатель. Таким образом, вы просто не можете вызвать fit_transform или преобразовать в конвейере, последний шаг которого является предиктором.

Ибраим Ганиев
источник
1
Что вы имеете в виду predicted = pipeline.fit(Xtrain).predict(Xtrain)?
farhawa
@farhawa, прогнозирование классов на обучающей выборке.
Ибраим Ганиев
4
Почему у него нет больше голосов? Это должно быть сообщение в блоге.
R Claven
1
@iamgin, Интерфейс большинства scikit-learn трансформеров не позволяет выбрать нужные столбцы, которые мы хотим преобразовать. Но вы можете написать свой собственный "Селектор предметов", который поможет вам кормить трансформатор только нужными столбцами. Вот хороший пример с ItemSelector и FeatureUnion scikit-learn.org/stable/auto_examples/…
Ибраим Ганиев,
1
В первом примере, разве вы не хотите избежать повторной подгонки с тестовым набором? Разве он не должен вызывать только преобразование вместо fit_transform? И аналогично, предсказывает ли конвейер внутренний вызов fit_transform или просто преобразование? Можно ли это контролировать?
Стивен
18

Я думаю, что у M0rkHaV правильная идея. Класс конвейера Scikit-learn - полезный инструмент для инкапсуляции нескольких разных преобразователей вместе с оценщиком в один объект, так что вам нужно вызывать важные методы только один раз ( fit(), predict()и т. Д.). Давайте разберем два основных компонента:

  1. Трансформаторы - это классы, реализующие fit()и transform(). Возможно, вы знакомы с некоторыми инструментами предварительной обработки sklearn, такими как TfidfVectorizerи Binarizer. Если вы посмотрите документацию по этим инструментам предварительной обработки, вы увидите, что они реализуют оба этих метода. Что я считаю довольно крутым, так это то, что некоторые оценщики также могут использоваться как шаги преобразования, например LinearSVC!

  2. Оценщики - это классы, которые реализуют 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)

И теперь, после вызова transform на vecобъекте, мы получаем следующее:

[[0]
 [1]
 [1]
 [1]]

Что касается оценщиков, используемых в качестве преобразователей, давайте воспользуемся DecisionTreeклассификатором в качестве примера экстрактора признаков. Деревья решений хороши по многим причинам, но для наших целей важно то, что они имеют возможность ранжировать функции, которые дерево сочло полезными для прогнозирования. Когда вы вызываете transform()дерево решений, оно берет ваши входные данные и обнаруживает, что, по его мнению, является наиболее важными функциями. Таким образом, вы можете представить себе преобразование вашей матрицы данных (n строк на m столбцов) в меньшую матрицу (n строк на k столбцов), где k столбцов - это k наиболее важных функций, обнаруженных деревом решений.

Н.Бартли
источник
В чем разница между fit()и transform()есть Трансформеры? , как оценщики можно использовать в качестве преобразователей?
farhawa
2
fit()- это метод, который вы вызываете, чтобы подогнать или «обучить» свой трансформатор, как если бы вы использовали классификатор или регрессионную модель. Что касается transform(), это метод, который вы вызываете для фактического преобразования входных данных в выходные данные. Например, вызов Binarizer.transform([8,2,2])(после примерки!) Может привести к [[1,0],[0,1],[0,1]]. Что касается использования оценщиков в качестве преобразователей, я отредактирую небольшой пример в своем ответе.
NBartley
9

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

Что такое конвейеры машинного обучения и как они работают?

Конвейер - это последовательность этапов преобразования данных. Это происходит из старого шаблона проектирования «конвейер и фильтр» (например, вы можете подумать о командах 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 свежим и пригодным для использования в современных вычислительных проектах!

Дополнительные методы и функции конвейера, предлагаемые 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».

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

Гийом Шевалье
источник