- BrainTools - https://www.braintools.ru -
В ML-проектах достижение оптимальной эффективности моделей требует внимания [1] к различным этапам процесса обучения [2]. Но, прежде чем заниматься техническими аспектами обучения моделей, важно правильно описать решаемую задачу, важно понять особенности среды, в которой существует эта задача, важно хорошо проанализировать имеющийся набор данных.
После того, как вы получите чёткое представление о задаче и о данных, вы сможете идти дальше, реализуя стратегии, которые помогут вам строить надёжные и эффективные модели. Вот пять практических советов по обучению ML-моделей.
Препроцессинг (preprocessing, предварительная обработка) данных — это один из самых важных этапов ML-пайплайна (конвейера машинного обучения). Данные, которые прошли адекватную предварительную обработку, могут серьёзно повысить эффективность модели и её обобщающие способности. Вот некоторые ключевые этапы препроцессинга данных:
Разберитесь с отсутствующими значениями. Используйте для этого такие методы, как подстановка среднего или модального значения вместо пропущенных значений, или более совершенные подходы — вроде восстановления пропущенных значений с использованием метода K-ближайших соседей (K-Nearest Neighbors, KNN).
Нормализуйте или стандартизируйте значения признаков. Масштабируйте значения признаков в том случае, если используете алгоритмы, чувствительные к масштабу признаков.
Кодируйте категориальные переменные. Преобразуйте категориальные переменные в числовые значения, используя такие методы, как одноразовое кодирование (one-hot encoding) или кодирование меток (label encoding).
Разбивайте данные на обучающую и тестовую выборки. Разбивайте данные на обучающую и тестовую выборки до их обработки, проводимой с использованием каких-либо методик препроцессинга данных. Это позволит исключить утечку данных.
Следующий фрагмент кода демонстрирует пример ML-пайплайна:
import pandas as pd
from sklearn.impute import SimpleImputer
from sklearn.preprocessing import StandardScaler, OneHotEncoder
from sklearn.compose import ColumnTransformer
from sklearn.pipeline import Pipeline
from sklearn.model_selection import train_test_split
# Прочесть данные из CSV-файла
data = pd.read_csv('your_data.csv')
# Указать имя столбца, в котором находится целевая переменная
target_column = 'target'
# Разделить данные на признаки и целевую переменную
X = data.drop(target_column, axis=1)
y = data[target_column]
# Разделить данные на обучающую и тестовую выборки
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.20, random_state=10)
# Идентифицировать столбцы, содержащие числовые и категориальные переменные
numeric_features = X.select_dtypes(include=['int64', 'float64']).columns.tolist()
categorical_features = X.select_dtypes(include=['object', 'category']).columns.tolist()
# Определить процедуру препроцессинга для числовых значений
numeric_transformer = Pipeline(steps=[
('imputer', SimpleImputer(strategy='mean')),
('scaler', StandardScaler())
])
# Определить процедуру препроцессинга для категориальных признаков
categorical_transformer = Pipeline(steps=[
('encoder', OneHotEncoder(drop='first'))
])
# Скомбинировать процедуры препроцессинга данных
preprocessor = ColumnTransformer(
transformers=[
('num', numeric_transformer, numeric_features),
('cat', categorical_transformer, categorical_features)
]
)
# Применить процедуру препроцессинга к обучающим данным
X_train_processed = preprocessor.fit_transform(X_train)
# Применить процедуру препроцессинга к тестовым данным
X_test_processed = preprocessor.transform(X_test)
Последовательности процедур, применяемых в ходе препроцессинга данных, определяются отдельно для числовых и категориальных признаков. А именно, при обработке числовых признаков мы восстанавливаем отсутствующие значения, используя среднее, после чего масштабируем значения, используя StandardScaler [3]. Категориальные признаки мы обрабатываем, применяя одноразовое кодирование. Эти процедуры препроцессинга мы комбинируем, используя ColumnTransformer [4], после чего применяем их по-отдельности к обучающей и тестовой выборкам, что позволяет избежать утечки данных.
Конструирование признаков (Feature Engineering) — это систематический процесс модификации существующих признаков и создания новых. Делается это для того, чтобы повысить качество работы модели. Грамотное конструирование признаков способно значительно повысить эффективность моделей машинного обучения. Вот несколько важнейших приёмов из этой сферы.
Признаки, отражающие взаимоотношения других признаков (Interaction Features) способны выявить скрытые закономерности, которые могут не раскрыться при работе с отдельными переменными.
Предположим, у нас имеются признаки price
(цена) и qty_sold
(количество проданных товаров). В качестве признака, отражающего взаимодействие других признаков, может выступать произведение двух исходных переменных, показывающее общий объём продажи товара:
# Создать признак, отражающий взаимоотношения других признаков
data['price_qty_interaction'] = data['price'] * data['qty_sold']
Данные, содержащие сведения о дате и времени, можно разобрать на информативные компоненты — такие, как год, месяц, день и день недели. Эти компоненты способны помочь в выявлении временных закономерностей, присутствующих в данных.
Например, имеется признак date
(дата). Из него можно извлечь различные компоненты — год (year
), месяц (month
), день недели (day_of_week
):
# Извлечь признаки из date
data['date'] = pd.to_datetime(['2020-01-01', '2020-02-01', '2020-03-01', '2020-04-01'])
data['year'] = data['date'].dt.year
data['month'] = data['date'].dt.month
data['day_of_week'] = data['date'].dt.dayofweek
Биннинг (Binning, дискретизация, квантование, «бакетирование») предусматривает «раскладывание» непрерывных значений признаков в ограниченное количество «контейнеров» (bin). Применение этого подхода к обработке данных может способствовать уменьшению влияния выбросов и созданию более репрезентативных признаков.
Пусть имеется признак income
(доход). Мы можем создать «контейнеры», позволяющие разделить данные о доходе на три категории: Low
, Medium
, High
(низкий, средний и высокий доход):
# Биннинг признаков, представленных непрерывными значениями
data['income_bin'] = pd.cut(data['income'], bins=3, labels=['Low', 'Medium', 'High'])
Обращая внимание на конструирование признаков, вы можете создать более информативные признаки, которые помогут модели лучше понять данные. Это ведёт к повышению эффективности работы модели и к улучшению её обобщающих способностей. Взгляните на этот [5] материал — там вы найдёте практические советы по конструированию признаков.
Дисбаланс классов (Class Imbalance) — это распространённая проблема, возникающая при работе с наборами данных, собранными в реальном мире. Это — ситуация, когда в целевой переменной классы представлены неравномерно. Метрики эффективности работы модели, которая обучена на несбалансированных наборах данных, нельзя назвать надёжными.
Борьба с дисбалансом классов необходима для того, чтобы обеспечить хорошие результаты работы модели на всех классах. Вот несколько методов решения этой проблемы.
Методики повторной выборки (Resampling) предусматривают модификацию набора данных с целью получения сбалансированного распределения классов. Вот два основных подхода к выполнению повторной выборки:
Увеличение выборки (Oversampling). Увеличение количества экземпляров в классе, представленном недостаточным количеством образцов (minority class, «малый класс»). Делается это путём дублирования элементов или путём создания синтетических образцов. Популярным методом для генерирования искусственных образцов является SMOTE (Synthetic Minority Over-sampling Technique, метод синтетической передискретизации меньшинства).
Уменьшение выборки (Undersampling). Уменьшение количества экземпляров в классе, представленном избыточным количеством образцов, путём случайного удаления некоторых из них.
Вот пример применения SMOTE для увеличения выборки класса, представленного недостаточным количеством образцов:
from imblearn.over_sampling import SMOTE
from sklearn.model_selection import train_test_split
X = data.drop('target', axis=1)
y = data['target']
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.20, random_state=10)
# Применить SMOTE
smote = SMOTE(random_state=10)
X_resampled, y_resampled = smote.fit_resample(X_train, y_train)
Коррекция весов классов (Adjusting Class Weights) в алгоритмах машинного обучения может помочь в борьбе с неправильной классификацией при работе с «малыми классами». Это повышает чувствительность модели при работе с такими классами.
Взгляните на следующий пример:
import pandas as pd
from sklearn.model_selection import train_test_split
# Прочесть данные из CSV-файла
data = pd.read_csv('your_data.csv')
# Указать имя столбца, в котором находится целевая переменная
target_column = 'target'
# Разделить данные на признаки и целевую переменную
X = data.drop(target_column, axis=1)
y = data[target_column]
# Разделить данные на обучающую и тестовую выборки
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.20, random_state=10)
При вычислении весов классов можно прибегнуть к такому подходу, в результате применения которого окажется, что «малым классам» назначают большие веса — обратно пропорциональные частоте, с которой встречаются образцы, входящие в этот класс. Затем полученные веса используют при инициализации классификатора. Например — это может выглядеть так:
import numpy as np
from sklearn.ensemble import RandomForestClassifier
from sklearn.metrics import accuracy_score, classification_report
from sklearn.utils.class_weight import compute_class_weight
# Вычислить веса классов
classes = np.unique(y_train)
class_weights = compute_class_weight(class_weight='balanced', classes=classes, y=y_train)
class_weights_dict = dict(zip(classes, class_weights))
print(f"Class weights: {class_weights_dict}")
model = RandomForestClassifier(class_weight=class_weights_dict, random_state=10)
model.fit(X_train, y_train)
# Сформировать прогноз на наборе тестовых данных
y_pred = model.predict(X_test)
# Оценить модель
print(f'Accuracy: {accuracy_score(y_test, y_pred):.2f}')
print(classification_report(y_test, y_pred))
Используя эти методики можно эффективно справляться с несбалансированностью классов. Это позволяет добиться хорошей работы модели в применении ко всем классам. Подробности о том, как бороться с несбалансированностью классов, можете посмотреть в этой [6] статье.
Кросс-валидация (Cross-Validation, перекрёстная проверка) и тюнинг гиперпараметров (Hyperparameter Tuning) — это основные методы, используемые при выборе модели, наилучшим образом подходящей для решения задачи. Их применение помогает избежать переобучения модели. Они позволяют добиться того, чтобы модель, встречаясь с ранее неизвестными ей данными, хорошо работала бы с ними и не теряла бы эффективности.
Когда, перед обучением и проверкой модели, данные лишь один раз делят на обучающий и тестовый наборы, это приводит к получению модели, отличающейся высокой дисперсией. На такую модель влияют (сильнее, чем того хотелось бы) отдельные образцы, которые оказываются в обучающем и тестовом наборах данных.
Кросс-валидация [7] — это методика, используемая для оценки эффективности работы модели путём разбиения данных на несколько подмножеств, или блоков (fold) данных, с последующими обучением и проверкой модели на этих подмножествах.
Чаще всего для кросс-валидации моделей используется метод K-Fold Cross-Validation (K-блочная кросс-валидация). Данные разбивают на K подмножеств, а модель обучают и оценивают K раз. Каждый раз один из блоков используется в качестве тестового набора данных, а оставшиеся (k-1) блоков — в качестве обучающего набора данных.
Снова воспользуемся уже знакомым вам шаблонным кодом из предыдущих примеров:
import pandas as pd
from sklearn.model_selection import train_test_split
# Прочесть данные из CSV-файла
data = pd.read_csv('your_data.csv')
# Указать имя столбца, в котором находится целевая переменная
target_column = 'target'
# Разделить данные на признаки и целевую переменную
X = data.drop(target_column, axis=1)
y = data[target_column]
Вот как можно применить K-блочную кросс-валидацию для того чтобы оценить работу
RandomForestClassifier:
from sklearn.ensemble import RandomForestClassifier
from sklearn.model_selection import cross_val_score
# Инициализировать модель
model = RandomForestClassifier(random_state=10)
# Выполнить 5-блочную кросс-валидацию
cv_scores = cross_val_score(model, X, y, cv=5)
# Вывести оценки, полученные в ходе кросс-валидации
print(f'Cross-Validation Scores: {cv_scores}')
print(f'Mean CV Score: {cv_scores.mean():.2f}')
Тюнинг гиперпараметров предусматривает нахождение оптимальных гиперпараметров для конкретной модели. Вот две распространённых методики тюнинга:
Поиск по сетке (Grid search) включает в себя полный поиск по выбранной сетке параметров. В большинстве случаев такой поиск требует неоправданно большого объёма вычислительных ресурсов.
Случайный поиск (Randomized search) — в ходе поиска осуществляется случайный выбор значений параметров из заданного распределения.
В этой [8] статье вы можете найти подробности о тюнинге гиперпараметров.
Ниже приведён пример применения поиска по сетке для нахождения наилучших значений гиперпараметров:
from sklearn.ensemble import RandomForestClassifier
from sklearn.model_selection import GridSearchCV
# Определить сетку параметров
param_grid = {
'n_estimators': [50, 100, 200],
'max_depth': [None, 10, 20, 30],
'min_samples_split': [2, 5, 10]
}
# Инициализировать модель
model = RandomForestClassifier(random_state=10)
# Выполнить поиск по сетке с 5-блочной кросс-валидацией
grid_search = GridSearchCV(estimator=model, param_grid=param_grid, cv=5, scoring='accuracy')
grid_search.fit(X, y)
print(f'Best Parameters: {grid_search.best_params_}')
print(f'Best Cross-Validation Score: {grid_search.best_score_:.2f}')
Кросс-валидация позволяет обеспечить высококачественную работу модели на неизвестных ей данных, а тюнинг гиперпараметров помогает оптимизировать параметры модели с целью улучшения её эффективности.
Для оптимизации выбранной модели можно воспользоваться тюнингом гиперпараметров, но подбор подходящей модели — это так же важно, как тюнинг выбранной модели. Оценка множества моделей и выбор той из них, которая наилучшим образом соответствует имеющемуся набору данных и решаемой задаче — это очень важно.
Кросс-валидация позволяет надёжно оценить эффективность работы модели с неизвестными ей данными. Поэтому сравнение различных моделей с использованием оценок, полученных в ходе их кросс-валидации, помогает выявить модель, которая наилучшим образом обрабатывает имеющиеся данные.
Вот как можно воспользоваться кросс-валидацией для сравнения моделей, основанных на алгоритме логистической регрессии и на алгоритме случайного леса (начальный фрагмент кода здесь опущен):
from sklearn.linear_model import LogisticRegression
from sklearn.ensemble import RandomForestClassifier
from sklearn.model_selection import cross_val_score
# Разделить данные на признаки и целевую переменную
X = data.drop('target', axis=1)
y = data['target']
# Определить модели, которые будем сравнивать
models = {
'Logistic Regression': LogisticRegression(random_state=10),
'Random Forest': RandomForestClassifier(random_state=10),
}
# Сравнить модели с использованием кросс-валидации
for name, model in models.items():
cv_scores = cross_val_score(model, X, y, cv=5, scoring='accuracy')
print(f'{name} CV Score: {cv_scores.mean():.2f}')
Ещё для повышения эффективности работы моделей можно использовать ансамблевые методы, объединяющие несколько моделей. Такие методы особенно эффективны для снижения негативных последствий переобучения. Их применение приводит к созданию более надёжных моделей. Здесь [9] вы можете найти советы по подбору модели машинного обучения, подходящей под конкретные данные.
Надеюсь, вы нашли в этой статье что-то такое, что пригодится вам при обучении ML-моделей. Вспомним то, о чём мы говорили:
При необходимости разбирайтесь с пропущенными значениями, масштабируйте признаки, кодируйте категориальные переменные. Разбивайте данные на обучающую и тестовую выборки на раннем этапе работы, до выполнения каких-либо операций по препроцессингу данных.
Создавайте признаки, отражающие взаимоотношения других признаков, извлекайте полезные признаки из значений, представляющих дату и время, используйте биннинг и другие техники для создания более репрезентативных значений.
Боритесь с дисбалансом классов — используйте методики повторной выборки и подстраивайте веса, назначаемые классам.
Для надёжной оценки эффективности модели примените K-блочную кросс-валидацию и приёмы оптимизации гиперпараметров вроде поиска по сетке и случайного поиска.
Сравнивайте модели, используя оценки, полученные в ходе их кросс-валидации, подумайте о применении ансамблевых методов для повышения эффективности работы моделей.
Удачи вам в создании моделей машинного обучения!
Мы в wunderfund.io [10] занимаемся высокочастотной алготорговлей [11] с 2014 года. Высокочастотная торговля — это непрерывное соревнование лучших программистов и математиков всего мира. Присоединившись к нам, вы станете частью этой увлекательной схватки.
Мы предлагаем интересные и сложные задачи по анализу данных и low latency разработке для увлеченных исследователей и программистов. Гибкий график и никакой бюрократии, решения быстро принимаются и воплощаются в жизнь.
Сейчас мы ищем плюсовиков, питонистов, дата-инженеров и мл-рисерчеров.
Автор: mr-pickles
Источник [13]
Сайт-источник BrainTools: https://www.braintools.ru
Путь до страницы источника: https://www.braintools.ru/article/13516
URLs in this post:
[1] внимания: http://www.braintools.ru/article/7595
[2] обучения: http://www.braintools.ru/article/5125
[3] StandardScaler: https://scikit-learn.org/stable/modules/generated/sklearn.preprocessing.StandardScaler.html
[4] ColumnTransformer: https://scikit-learn.org/stable/modules/generated/sklearn.compose.ColumnTransformer.html
[5] этот: https://machinelearningmastery.com/tips-for-effective-feature-engineering-in-machine-learning/
[6] этой: https://machinelearningmastery.com/5-effective-ways-to-handle-imbalanced-data-in-machine-learning/
[7] Кросс-валидация: https://machinelearningmastery.com/k-fold-cross-validation/
[8] этой: https://www.kdnuggets.com/hyperparameter-tuning-gridsearchcv-and-randomizedsearchcv-explained
[9] Здесь: https://machinelearningmastery.com/tips-for-choosing-the-right-machine-learning-model-for-your-data/
[10] wunderfund.io: http://wunderfund.io
[11] высокочастотной алготорговлей: https://en.wikipedia.org/wiki/High-frequency_trading
[12] Присоединяйтесь к нашей команде: http://wunderfund.io/#join_us
[13] Источник: https://habr.com/ru/companies/wunderfund/articles/894100/?utm_campaign=894100&utm_source=habrahabr&utm_medium=rss
Нажмите здесь для печати.