Разработка конвейера для компиляции процессов с реализацией на Python

Table of Contents 
1. Introduction
2. Pipeline
3. Pipeline with Grid Search
4. Pipeline with ColumnTransformer, GridSearchCV
5. Pipeline with Feature Selection

1. Введение

О подготовке набора данных для алгоритма, проектировании модели и настройке гиперпараметров алгоритма на усмотрение разработчика для обобщения модели и достижения оптимального значения точности упоминалось в предыдущих статьях. Как известно, в распоряжении разработчика есть альтернативные решения как для предварительной обработки модели, так и для предварительной обработки данных и настройки гиперпараметров алгоритма. Разработчик несет ответственность за применение наиболее подходящих комбинаций и поддержание оптимальности своего проекта с точки зрения как точности, так и обобщения. Эта статья включает в себя реализацию всех упомянутых операций и многое другое за один раз с помощью конвейера, предлагаемого sklearn. Все заголовки поддерживаются реализацией Python.

2. Трубопровод

В своей самой базовой форме конвейер должен реализовать указанные операции предварительной обработки данных и модель в наборе данных с помощью одной строки:

IN[1]
iris=load_iris()
iris_data  =iris.data
iris_target=iris.target
IN[2]
x_train,x_test,y_train,y_test = train_test_split(iris_data, iris_target,test_size=0.2, random_state=2021)
pip_iris = Pipeline([("scaler", RobustScaler()),("lr",LogisticRegression())])
pip_iris.fit(x_train,y_train)
iris_score=pip_iris.score(x_test,y_test)
print(iris_score)
OUT[2]
0.9333333333333333

Набор данных Iris был разделен знаком train_test_split, как обычно, и RobustScaler() был выбран в качестве метода масштабирования для набора данных, известного как числовой набор данных, а LogisticRegression была выбрана в качестве классификатора. Конвейер также содержит различные атрибуты, такие как .fit, .score, точно так же, как поиск по сетке. Набор данных Train был дополнен командой .fit в созданном конвейере, а оценка была создана с помощью .score.

3. Конвейер с поиском по сетке

Grid Search оценивал комбинации гиперпараметров в алгоритме или любую операцию с определенными гиперпараметрами, информируя пользователя о степени точности или лучших комбинациях гиперпараметров с различными атрибутами (для получения дополнительной информации нажмите здесь). Использование GridSearchCV с конвейером - очень эффективный способ устранения рабочей нагрузки и путаницы. Теперь давайте протестируем реализованный выше алгоритм логистической регрессии с различными комбинациями гиперпараметров:

IN[3]
x_train,x_test,y_train,y_test = train_test_split(iris_data, iris_target,test_size=0.2, random_state=2021)
pip_iris_gs = Pipeline([("scaler", RobustScaler()),("lr",LogisticRegression(solver='saga'))])
param_grids={'lr__C':[0.001,0.1,2,10],
             'lr__penalty':['l1','l2']}
gs=GridSearchCV(pip_iris_gs,param_grids)
gs.fit(x_train,y_train)
test_score = gs.score(x_test,y_test)
print("test score:",test_score)
print("best parameters: ",gs.best_params_)
print("best score: ", gs.best_score_)
OUT[3]
test score: 0.9333333333333333
best parameters:  {'lr__C': 2, 'lr__penalty': 'l1'}
best score:  0.9583333333333334

В дополнение к вышесказанному, значения «C» и «штраф» определяются как param_grids путем создания словаря пользователем. Позже конвейер, содержащий алгоритм и масштабирование, был добавлен в GridSearchCV в качестве средства оценки. Набор обучающих данных обучается с помощью .fit command и оценивается с помощью .score. Кроме того, была получена информация о модели, созданной с помощью различных атрибутов в GridSearchCV.

4. Конвейер с ColumnTransformer, GridSearchCV

До сих пор использовался только набор данных -iris dataset-, содержащий только числовые данные. Чтобы усложнить ситуацию, давайте воспользуемся набором данных игрушек, который содержит как числовые, так и категориальные данные, и применим:

  • Нормализовать столбец «Доход» с помощью MinMaxScaler()
  • Кодировать категориальные столбцы с OneHotEncoder()
  • Сгруппируйте столбец «Возраст» с помощью группировки.

Во-первых, давайте быстро взглянем на набор данных:

IN[4]
toy = pd.read_csv('toy_dataset.csv')
toy_final=toy.drop(['Number'],axis=1)
IN[5]
toy_final.isna().sum()
OUT[5]
City       0
Gender     0
Age        0
Income     0
Illness    0
dtype: int64
IN[6]
numeric_cols=toy.select_dtypes(include=np.number).columns
print("numeric_cols:",numeric_cols)
categorical_cols=toy.select_dtypes(exclude=np.number).columns
print("categorical_cols:",categorical_cols)
print("shape:",toy_final.shape)
OUT[6]
numeric_cols: Index(['Number', 'Age', 'Income'], dtype='object')
categorical_cols: Index(['City', 'Gender', 'Illness'], dtype='object')
shape: (150000, 5)

Теперь выполним указанные выше операции:

IN[7]
bins = KBinsDiscretizer(n_bins=5, encode='onehot-dense', strategy='uniform')
ct = ColumnTransformer([
    ('normalization', MinMaxScaler(), ['Income']),
    ('binning', bins, ['Age']),
    ('categorical-to-numeric', OneHotEncoder(sparse=False, handle_unknown='ignore'), ['City','Gender'])
], remainder='drop')
x_train, x_test, y_train, y_test = train_test_split(toy_final.drop('Illness', axis=1), toy_final.Illness,
                                                   test_size=0.2, random_state=0)
param_grid_lr=[{'lr__solver':['saga'],'lr__C':[0.1,1,10],'lr__penalty':['elasticnet','l1','l2']},
               {'lr__solver':['lbfgs'],'lr__C':[0.1,1,10],'lr__penalty':['l2']}]
IN[8]
pipe_lr = Pipeline([
    ('columntransform', ct),
    ('lr', LogisticRegression()),
    ])
gs_lr =GridSearchCV(pipe_lr,param_grid_lr,cv=5)
gs_lr.fit(x_train,y_train)
test_score_lr = gs_lr.score(x_test,y_test)
print("test score:",test_score_lr)
print("best parameters: ",gs_lr.best_params_)
print("best score: ", gs_lr.best_score_)
OUT[8]
test score: 0.9198666666666667
best parameters:  {'lr__C': 0.1, 'lr__penalty': 'l1', 'lr__solver': 'saga'}
best score:  0.9188750000000001

Метод bins с KBinsDiscretizer(), представленный в библиотеке sklearn, настроен на 5 групп и кодируется OneHotEncoder. Процессы предварительной обработки, которые будут применяться с ColumnTransformer(), были собраны в одни руки. Это следующие операции:
-Нормализация для столбца "Доход",
-Дискретизация для столбца "Возраст",
-Кодирование с OneHotEncoder() для категориальных столбцов

Затем набор данных был разделен на обучение и тестирование. Словарь (param_grids_lr) был создан с выбранными гиперпараметрами для оценки комбинаций параметров. Применяемые методы предварительной обработки данных были собраны в одних руках с помощью ColumnTransformer (для получения дополнительной информации щелкните здесь), а алгоритм - LogisticRegression - был помещен в конвейер. Как и в приведенных выше примерах, модель завершается путем выбора значения перекрестной проверки 5 в GridSearchCV.

Словарь param_grid_lr создается как алгоритм + двойное подчеркивание + гиперпараметр. LogisticRegression() определяется как lr, и мы знаем, что «C» - это гиперпараметр LogisticRegression, поэтому используется lr__C. Чтобы увидеть все доступные гиперпараметры, которые можно использовать, применяется lr.get_params().keys().

Теперь давайте попробуем модель, которую мы подготовили с помощью DecisionTreeClassifier():

IN[9]
pipe_dt = Pipeline([
    ('columntransform', ct),
    ('dt', DecisionTreeClassifier()),
])
param_grid_dt={'dt__max_depth':[2,3,4,5,6,7,8]}
gs_dt =GridSearchCV(pipe_dt,param_grid_dt,cv=5)
gs_dt.fit(x_train,y_train)
test_score_dt = gs_dt.score(x_test,y_test)
print("test score:",test_score_dt)
print("best parameters: ",gs_dt.best_params_)
print("best score: ", gs_dt.best_score_)
OUT[9]
test score: 0.9198333333333333
best parameters:  {'dt__max_depth': 2}
best score:  0.9188750000000001

Выбранные нами значения max_depth подходили одно за другим, и наиболее успешное из них было определено с помощью поиска по сетке.

5. Конвейер с выбором функций

Как упоминалось во введении, использование конвейера и GridSearchCV - очень эффективный способ оценивать комбинации гиперпараметров и легко их компилировать. Это очень полезно не только для предварительной обработки данных и алгоритмов, но также для очистки данных (SimpleImputer), обработки функций (SelectKBest, SelectPercentile , подробнее нажмите здесь) и т. Д. Теперь давайте применим следующее к набору данных груди_cancer, содержащему 30 функций:

- Стандартизация к числовым значениям с StandardScaler()

- PolynomialFeatures() в числовых значениях

- ANOVA с SelectPercentile()

- гиперпараметры логистической регрессии («C» и «штраф»)

- настроить Cross-Validation = 3

IN[10]
cancer=load_breast_cancer()
cancer_data   =cancer.data
cancer_target =cancer.target
IN[11]
anova = SelectPercentile()
poly = PolynomialFeatures()
lr=LogisticRegression(solver='saga')
param_grid_cancer=dict(poly__degree=[2,3,4],
                   anova__percentile=[20, 30, 40, 50],
                   lr__C=[0.01,0.1,1,10],
                   lr__penalty=['l1','l2']
                   )
pipe_cancer = Pipeline([
    ('standardization',StandardScaler()),
    ('poly',poly),
    ('anova',anova),
    ('lr',lr)
    ])
gs_final = GridSearchCV(pipe_cancer,param_grid_cancer,cv=3,n_jobs=-1)
x_train, x_test, y_train, y_test = train_test_split(cancer_data, cancer_target,test_size=0.2,random_state=2021)
gs_final.fit(x_train,y_train)
test_score_final = gs_final.score(x_test,y_test)
print("test score:",test_score_final)
print("best parameters: ",gs_final.best_params_)
print("best score: ", gs_final.best_score_)
OUT[11]
test score: 0.9736842105263158
best parameters:  {'anova__percentile': 20, 'lr__C': 0.1, 'lr__penalty': 'l1', 'poly__degree': 2}
best score:  0.9626612059951203

Были определены комбинации гиперпараметров, которые будут проверяться с param_grid_cancer:

степень = [2,3,4] для PolynomialFeatures()

процентиль = [20, 30, 40, 50] для SelectPercentile()

C = [0,01,0,1,1,10] для LogisticRegression()

штраф = [‘l1’, ’l2’] для LogisticRegression()

Все это было подключено к StandardScaler(). Затем значение перекрестной проверки было установлено на 3 в GridSearchCV. Набор данных был разделен на train_test_split и, как всегда, был дополнен .fit. Если для параметра «процентиль» в SelectPercentile установлено значение 20%, значение «C» в LogisticRegression установлено на 0,1, параметр «штраф» в LogisticRegression имеет значение "L1", а значение "deg" в PolynomialFeatures равно 2, точность является наивысшей.

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

Вернуться к руководству нажмите здесь.