#machine-learning #scikit-learn #pipeline #pca #grid-search
Вопрос:
Можно ли удалить или вставить шаг в sklearn.pipeline.Pipeline
объект?
Я пытаюсь выполнить поиск по сетке с одним шагом в объекте конвейера или без него. И задаюсь вопросом, могу ли я вставить или удалить шаг в конвейере. Я видел в Pipeline
исходном коде, что есть self.steps
объект, содержащий все шаги. Мы можем пройти по ступенькам named_steps()
. Прежде чем изменять его, я хочу убедиться, что я не вызываю неожиданных эффектов.
Вот пример кода:
from sklearn.pipeline import Pipeline
from sklearn.svm import SVC
from sklearn.decomposition import PCA
estimators = [('reduce_dim', PCA()), ('svm', SVC())]
clf = Pipeline(estimators)
clf
Возможно ли , что мы сделаем что-то вроде steps = clf.named_steps()
, а затем вставим или удалим в этот список? Вызывает ли это нежелательное воздействие на объект clf?
Ответ №1:
Я вижу, что все упомянули только шаг удаления. В случае, если вы также хотите вставить шаг в конвейер:
pipe.steps.append(['step name',transformer()])
pipe.steps
работает так же, как и списки, поэтому вы также можете вставить элемент в определенное место:
pipe.steps.insert(1,['estimator',transformer()]) #insert as second step
Комментарии:
1. Спасибо вам за полезный ответ! Я думаю
append
, что orinsert
следует выполнять с помощью atuple
вместо ` списка», потому что каждый шаг в конвейере-это atuple
. Как в:pipe.steps.append(('step name',transformer()))
иpipe.steps.insert(1,('estimator',transformer()))
Ответ №2:
Основываясь на элементарном тестировании, вы можете безопасно удалить шаг из конвейера scikit-learn, как и любой элемент списка, с помощью простого
clf_pipeline.steps.pop(n)
где n — позиция индивидуального оценщика, которую вы пытаетесь удалить.
Комментарии:
1. Спасибо за ваш ответ. Не могли бы вы, пожалуйста, подробнее остановиться на «на основе элементарного тестирования»?
2. У меня есть около 500 предварительно обученных конвейеров с одинаковыми шагами векторизации. Я преобразовал входящие данные, используя этап векторизации одного из этих конвейеров, затем удалил этот этап из всех конвейеров перед запуском метода predict_proba каждого конвейера для предварительно векторизованных данных. Полученные результаты были такими же, как если бы я запускал каждый немодифицированный конвейер на необработанных данных без предварительной векторизации, и общее время выполнения было улучшено, так как я не выполнял один и тот же шаг векторизации снова и снова. Обратите внимание, что это работает только с преобразователями без состояния, такими как векторизатор хэширования.
3. Возможно, вы могли бы вместо этого использовать кэширование
memory
, установив параметры конвейера?
Ответ №3:
Просто вмешиваюсь, потому что я чувствую, что другие ответы очень хорошо ответили на вопрос о добавлении шагов в конвейер, но на самом деле не описывали, как удалить шаг из конвейера.
Однако будьте осторожны с моим подходом. Нарезка списков в этом случае немного странная.
from sklearn.pipeline import Pipeline
from sklearn.svm import SVC
from sklearn.decomposition import PCA
from sklearn.preprocessing import PolynomialFeatures
estimators = [('reduce_dim', PCA()), ('poly', PolynomialFeatures()), ('svm', SVC())]
clf = Pipeline(estimators)
Если вы хотите создать конвейер только с помощью шагов PCA/полинома, вы можете просто разрезать список шаг за шагом по индексам и передать его в конвейер
clf1 = Pipeline(clf.steps[0:2])
Хотите просто использовать шаги 2/3?
Следите за тем, чтобы эти кусочки не всегда имели наибольший смысл
clf2 = Pipeline(clf.steps[1:3])
Хотите просто использовать шаги 1/3?
Кажется, я не могу использовать этот подход
clf3 = Pipeline(clf.steps[0] clf.steps[2]) # errors
Комментарии:
1.
clf3 = Pipeline([clf.steps[0], clf.steps[2]])
Ответ №4:
Да, это возможно, но вы должны выполнить те же требования, которые трубопроводе требуется при инициализации, т. е. нельзя вставить предсказатель на любом этапе, кроме последнего, вам должны позвонить fit
после обновления трубопровода.шаги, потому что после такого обновления все шаги (может быть, они узнали в предыдущих fit
вызовов) будет признан недействительным, и последний шаг трубопровода всегда должен реализовать fit
метод, все предыдущие шаги следует выполнить fit_transform
.
Так что да, это будет работать в текущей кодовой базе, но я думаю, что это не очень хорошее решение для вашей задачи, это делает ваш код более зависимым от текущей реализации Конвейера, я думаю, что удобнее создавать новый конвейер с измененными шагами, потому что Конвейер, по крайней мере, проверит все ваши шаги при инициализации, также создание нового конвейера не будет существенно отличаться по скорости от изменения шагов существующего конвейера, но, как я только что сказал — создание нового конвейера после каждого изменения шагов безопаснее в случае, если кто-то существенно изменит реализацию конвейера.
Комментарии:
1. Спасибо за ваши комментарии. Озабоченность по поводу непосредственного изменения шагов также является моей заботой, поэтому я спросил, есть ли безопасный способ сделать это. О, о том, почему я хочу модифицировать трубопроводы вместо создания новых трубопроводов. Причина в том, что я хочу провести кучу экспериментов с разными трубопроводами. Поэтому предпочтительным способом является изменение их в коде. Я согласен, что создание нового трубопровода-это тоже хороший путь. Я, наверное, передумаю. Спасибо. (Все еще надеясь, что у кого-то есть способ безопасно изменить шаги 🙂