Конвейер машинного обучения в sklearn

машинное обучение искусственный интеллект регулярное выражение scikit-learn



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

Например, нам нужно проделать следующие операции, нетрудно заметить, что обучающая и тестовая выборки повторяют код,

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)

Обратите внимание, что если на последнем шаге конвейера есть метод predict(), мы можем использовать в конвейере fit_predict() Аналогично, если на последнем шаге есть метод transform(), мы можем использовать fit_transform() метод на конвейере.

Используйте конвейер для перекрестной проверки

Рассмотрим следующий случай, то есть сначала выполните уменьшение размерности PCA на входных данных рукописных чисел, а затем предскажите метки с помощью логистической регрессии. Среди них мы передаем трубопровод к
Измерение уменьшения размерности n_components PCA и размер регулярного члена C логистической регрессии проходят перекрестную проверку.Основные шаги:

  1. Создайте экземпляр каждого объекта компонента по очереди, напримерpca = decomposition.PCA()
  2. Соберите трубопровод с трубкой (имя, объект) в качестве элемента, напримерPipeline(steps=[('pca', pca), ('logistic', logistic)])
  3. Инициализируйте параметры CV, такие какn_components = [20, 40, 64]
  4. Создайте экземпляр объекта CV, напримерestimator = GridSearchCV(pipe, dict(pca__n_components=n_components, logistic__C=Cs)), который обращает внимание на то, как передаются параметры, то есть ключ — это имя элемента конвейера + параметры функции
import numpy as np
import matplotlib.pyplot as plt
from sklearn import linear_model, decomposition, datasets
from sklearn.pipeline import Pipeline
from sklearn.model_selection import GridSearchCV
logistic = linear_model.LogisticRegression()
pca = decomposition.PCA()
pipe = Pipeline(steps=[('pca', pca), ('logistic', logistic)])
digits = datasets.load_digits()
X_digits = digits.data
y_digits = digits.target
# Prediction
n_components = [20, 40, 64]
Cs = np.logspace(-4, 4, 3)
pca.fit(X_digits)
estimator = GridSearchCV(pipe,
                         dict(pca__n_components=n_components, logistic__C=Cs))
estimator.fit(X_digits, y_digits)
plt.figure(1, figsize=(4, 3))
plt.clf()
plt.axes([.2, .2, .7, .7])
plt.plot(pca.explained_variance_, linewidth=2)
plt.axis('tight')
plt.xlabel('n_components')
plt.ylabel('explained_variance_')
plt.axvline(
    estimator.best_estimator_.named_steps['pca'].n_components,
    linestyle=':',
    label='n_components chosen')
plt.legend(prop=dict(size=12))
plt.show()

пользовательский трансформатор

Мы можем настроить трансформатор следующим образом (отUsing Pipelines and FeatureUnions in scikit-learn - Michelle Fullwood)

from sklearn.base import BaseEstimator, TransformerMixin
class SampleExtractor(BaseEstimator, TransformerMixin):
    def __init__(self, vars):
        self.vars = vars  # e.g. pass in a column name to extract
    def transform(self, X, y=None):
        return do_something_to(X, self.vars)  # where the actual feature extraction happens
    def fit(self, X, y=None):
        return self  # generally does nothing

Кроме того, мы также можем обрабатывать каждую функцию отдельно, например следующий относительно большой конвейер (отUsing scikit-learn Pipelines and FeatureUnions | zacstewart.com), мы можем обнаружить, что в пайплайне автора первым являетсяfeaturesFeatureUnion, в котором каждая функция обрабатывается конвейером, конвейер является первымColumnExtractorЭта функция извлекается, после чего следует ряд преобразований обработки, и, наконец, эти конвейеры объединяются в комбинацию функций, а затем передаются в сериюModelTransformerОберните модель для прогнозирования и, наконец, используйтеKNeighborsRegressorПрогнозирование (эквивалентно двум слоям стекирования).

pipeline = Pipeline([
    ('features', FeatureUnion([
        ('continuous', Pipeline([
            ('extract', ColumnExtractor(CONTINUOUS_FIELDS)),
            ('scale', Normalizer())
        ])),
        ('factors', Pipeline([
            ('extract', ColumnExtractor(FACTOR_FIELDS)),
            ('one_hot', OneHotEncoder(n_values=5)),
            ('to_dense', DenseTransformer())
        ])),
        ('weekday', Pipeline([
            ('extract', DayOfWeekTransformer()),
            ('one_hot', OneHotEncoder()),
            ('to_dense', DenseTransformer())
        ])),
        ('hour_of_day', HourOfDayTransformer()),
        ('month', Pipeline([
            ('extract', ColumnExtractor(['datetime'])),
            ('to_month', DateTransformer()),
            ('one_hot', OneHotEncoder()),
            ('to_dense', DenseTransformer())
        ])),
        ('growth', Pipeline([
            ('datetime', ColumnExtractor(['datetime'])),
            ('to_numeric', MatrixConversion(int)),
            ('regression', ModelTransformer(LinearRegression()))
        ]))
    ])),
    ('estimators', FeatureUnion([
        ('knn', ModelTransformer(KNeighborsRegressor(n_neighbors=5))),
        ('gbr', ModelTransformer(GradientBoostingRegressor())),
        ('dtr', ModelTransformer(DecisionTreeRegressor())),
        ('etr', ModelTransformer(ExtraTreesRegressor())),
        ('rfr', ModelTransformer(RandomForestRegressor())),
        ('par', ModelTransformer(PassiveAggressiveRegressor())),
        ('en', ModelTransformer(ElasticNet())),
        ('cluster', ModelTransformer(KMeans(n_clusters=2)))
    ])),
    ('estimator', KNeighborsRegressor())
])
class HourOfDayTransformer(TransformerMixin):
    def transform(self, X, **transform_params):
        hours = DataFrame(X['datetime'].apply(lambda x: x.hour))
        return hours
    def fit(self, X, y=None, **fit_params):
        return self
class ModelTransformer(TransformerMixin):
    def __init__(self, model):
        self.model = model
    def fit(self, *args, **kwargs):
        self.model.fit(*args, **kwargs)
        return self
    def transform(self, X, **transform_params):
        return DataFrame(self.model.predict(X))

FeatureUnion

sklearn.pipeline.FeatureUnion — документация scikit-learn 0.19.1В отличие от последовательного выполнения конвейера, FeatureUnion относится к параллельному применению множества преобразователей к входным данным, а затем к объединению результатов, поэтому он, естественно, подходит для добавления функций в разработку функций, а комбинация FeatureUnion и конвейера может легко выполнить многие сложные операции, например следующий пример,

pipeline = Pipeline([
  ('extract_essays', EssayExractor()),
  ('features', FeatureUnion([
    ('ngram_tf_idf', Pipeline([
      ('counts', CountVectorizer()),
      ('tf_idf', TfidfTransformer())
    ])),
    ('essay_length', LengthTransformer()),
    ('misspellings', MispellingCountTransformer())
  ])),
  ('classifier', MultinomialNB())
])

весьfeatures— это FeatureUnion, а ngram_tf_idf — конвейер, включающий два шага.

В следующем примере используйте FeatureUnion в сочетании с функциями уменьшения размерности PCA и выберите несколько исходных функций в качестве комбинаций функций, а затем передайте их в классификацию SVM и, наконец, используйте grid_search для выполнения pca.n_components, Выберите Лучшийkи SVMCРЕЗЮМЕ.

from sklearn.pipeline import Pipeline, FeatureUnion
from sklearn.model_selection import GridSearchCV
from sklearn.svm import SVC
from sklearn.datasets import load_iris
from sklearn.decomposition import PCA
from sklearn.feature_selection import SelectKBest
iris = load_iris()
X, y = iris.data, iris.target
print(X.shape, y.shape)
# This dataset is way too high-dimensional. Better do PCA:
pca = PCA()
# Maybe some original features where good, too?
selection = SelectKBest()
# Build estimator from PCA and Univariate selection:
svm = SVC(kernel="linear")
# Do grid search over k, n_components and C:
pipeline = Pipeline([("features",
                      FeatureUnion([("pca", pca), ("univ_select",
                                                   selection)])), ("svm",
                                                                   svm)])
param_grid = dict(
    features__pca__n_components=[1, 2, 3],
    features__univ_select__k=[1, 2],
    svm__C=[0.1, 1, 10])
grid_search = GridSearchCV(pipeline, param_grid=param_grid, verbose=10)
grid_search.fit(X, y)
grid_search.best_estimator_
grid_search.best_params_
grid_search.best_score_