Предварительно обработайте данные правильно
Предварительная обработка данных — это то, с чем вы, возможно, уже знакомы. Обычно мы поступаем следующим образом:
- Оценка качества данных
– Поиск пропущенных значений
– Поиск выбросов
– Поиск несоответствия типов данных в функциях - Преобразование данных
– Выбор функций/выборка
– Агрегация данных
– Нормализация данных - Feature Encoding
-Label Encoding для порядковых переменных
-One Hot Encoding для номинальных переменных - Уменьшение размерности (PCA, SVD)
- Масштабирование функций
-Стандартизация
- Нормализация
Хотя такой подход абсолютно правильный, но если ваш код выглядит примерно так, дочитать этот блог до конца?
import numpy as np import sklearn from sklearn.preprocessing import OneHotEncoder,StandardScaler,SimpleImputer categorical=list() numerical=list() for column in train_data.columns: if train_data[column].dtype=='object': categorical.append(column) elif train_data[column].dtype==np.number: numerical.append(column) imputer=SimpleImputer(strategy='mean') transformed_data=imputer.fit_transform(train_data[numerical]) transformed_numerical=scaler.fit_transform(train_data[numerical]) encoder=OneHotEncoder() transformed_categorical=encoder.fit(train_data[categorical]) scaler=StandardScaler() final_train_data=transformed_categorical+transformed_numerical
*просто абстрактный пример, не подлежащий компиляции или выполнению
Хотя этот подход будет работать, он не оптимален при работе с массивными наборами данных или в производственной среде.
Для этого вам нужен организованный рабочий процесс. Введите, scikit-learn конвейеры. Цель конвейера sklearn — собрать вместе несколько шагов.
Представьте себе конвейер, который находит и разделяет числовые и категориальные переменные, затем выполняет преобразования, предназначенные для каждого типа данных, соответственно, а затем передает модели необходимые данные для обучения, проверки и тестирования.
Compose в scikit-learn (sklearn.compose) поможет вам его разработать.
Попробуем своими руками. А не ___ ли нам? Рассмотрим этот набор данных для воспроизведения.
#Here are allthe libraries you will be needing to play this project out import numpy as np import pandas as pd import os import sklearn from sklearn import preprocessing from sklearn.pipeline import make_pipeline from sklearn.impute import SimpleImputer from sklearn.compose import make_column_selector from sklearn.compose import make_column_transformer from sklearn.preprocessing import OrdinalEncoder from sklearn.preprocessing import OneHotEncoder from sklearn.preprocessing import StandardScaler from sklearn.model_selection import train_test_split from sklearn.model_selection import cross_val_score from sklearn.model_selection import KFold import time from sklearn.ensemble import RandomForestClassifier from sklearn.ensemble import StackingClassifier from sklearn.svm import LinearSVC from sklearn.model_selection import GridSearchCV import warnings warnings.filterwarnings("ignore") #I have kept the code in relevance with kaggle for ease of use input_paths=list() for dirname, _, filenames in os.walk('/kaggle/input'): for filename in filenames: input_paths+=[os.path.join(dirname, filename)] print(os.path.join(dirname, filename)) train_data=pd.DataFrame(pd.read_csv(input_paths[1])) test_data=pd.DataFrame(pd.read_csv(input_paths[2])) target=train_data['failure'] print(target.unique()) #To observe the type & distribution of our target feature train_data=train_data.drop(columns=['failure','id'])
Выход для вышеуказанного блока кода — «0» и «1». Следовательно, целевая функция имеет дискретные значения, поэтому мы будем выполнять классификацию.
Решив, над какой проблемой мы работаем, то есть над классификацией, мы начинаем исследовательский анализ данных (EDA), проверяя неверные значения.
train_data.isna().sum()
Вы заметите, что у нас есть куча пропущенных значений в наборе данных.
(EDA предполагает внимательное наблюдение за функциями с помощью различных статистических методов и методов визуализации, но я буду ссылаться на наиболее известные методы и сосредоточу внимание блога на разработке конвейера)
Выполнение приведенного ниже блока кода также покажет, что в нашем наборе данных есть как числовые (int, float), так и категориальные (объектные) функции.
train_data.info()
Итак, давайте приступим к разработке нашего конвейера, не так ли?
make_column_selector в sklearn.compose помогает выбрать необходимые столбцы на основе их типа данных или путем сопоставления шаблона регулярного выражения с именами столбцов. Мы будем использовать его для неявного выбора числовых и категориальных признаков.
categorical_data = make_column_selector(dtype_include=object) numerical_data=make_column_selector(dtype_include=np.number)
Теперь давайте создадим конвейер трансформатора.
#for categorical transformations categorical_processor=OneHotEncoder(handle_unknown="ignore") #for numerical transformations numerical_processor=make_pipeline(StandardScaler(), SimpleImputer(strategy="mean", add_indicator=True)) #combining the transformations into one common column transformer transformer=make_column_transformer((numerical_processor,numerical_data),(categorical_processor,categorical_data))
Теперь давайте добавим модели в наш конвейер. Мы будем работать с классификаторами Random Forest и Support Vector.
'''To include everything in one pipeline at the end, we have to keep including the previously done work. Hence, we add our column transformer first and then the classifier''' rf_pipeline = make_pipeline(transformer, RandomForestClassifier(n_estimators=10, random_state=42)) svc_pipeline = make_pipeline(transformer,LinearSVC(random_state=42)) #Then we group the pipelines in a list estimators = [ ('rf', rf_pipeline), ('svc', svc_pipeline) ]
Теперь мы добавим оценщики в StackingClassifier. Стекирующий классификатор в буквальном смысле — это просто набор классификаторов. Мы делаем это, потому что обобщение с накоплением объединяет выходные данные отдельной оценки и использует классификатор для вычисления окончательного прогноза.
sclf = StackingClassifier(estimators=estimators)
Теперь займемся настройкой гиперпараметров. Чтобы получить информацию о том, с какими параметрами вы на самом деле имеете дело в выбранных вами оценщиках, запустите эту строку кода.
sclf.get_params()
После просмотра всех параметров и выбора тех, которые мы хотим настроить, теперь нам нужно определить наилучшие значения для этих параметров. Для этого мы будем использовать GridSearchCV. Мы должны создать сетку параметров выбранных параметров, используя словарь. Затем, после подачи его в функцию, параметры оценок будут оптимизированы путем перекрестного поиска по сетке на основе предоставленной сетки параметров.
param_grid = { 'svc__linearsvc__penalty': ['l1','l2'], 'svc__linearsvc__loss': ['hinge', 'squared_hinge'], 'svc__linearsvc__max_iter' : [10,100,1000], 'rf__randomforestclassifier__max_depth' : [3,5,7,9], } clf = GridSearchCV(estimator=sclf, param_grid=param_grid, cv= 5) clf.fit(X_train, Y_train) print(clf.best_params_)
Теперь у нас есть лучшие значения параметров. Мы можем перенастроить наши оценщики и продолжить обучение модели.
rf_pipeline = make_pipeline(transformer, RandomForestClassifier(max_depth=3, random_state=42)) svc_pipeline = make_pipeline(transformer,LinearSVC(loss='hinge',max_iter=10,penalty='l2')) estimators = [ ('rf', rf_pipeline), ('svc', svc_pipeline) ] sclf=StackingClassifier(estimators=estimators) sclf.fit_transform(X_train,Y_train)
Теперь на секунду подумайте, какой из них является нашим последним конвейером. Ответ в следующей строке. Сделанный?
Наш последний конвейер — sclf. Если вы все поняли правильно, погладьте себя. Если нет, не беспокойтесь. Просто просмотрите статью еще раз. Не стесняйтесь комментировать любые вопросы, которые у вас могут возникнуть.
Итак, это было все. Наш трубопровод готов. Чтобы получить прогнозы, вы можете просто запустить sclf.predict, а также сравнить результат с метриками оценки, которые вам нравятся.