AutoML расшифровывается как автоматизированное машинное обучение, и его основная цель — сократить или полностью исключить роль специалистов по данным в построении моделей машинного обучения. Рассмотрим два варианта реализации решений AutoML : работа с библиотеками PyCaret и TROT.
Начнем с регрессии и рассмотрим два учебных руководства с сайта библиотеки PyCaret, а также пример из книги "Tolios G. Simplifying Machine Learning with PyCaret: A Low-code Approach for Beginners and Experts".
Пример из книги , поехали!
Импортируем необходимые библиотеки Python : pandas, Matplotlib и Seaborn. Кроме того, мы импортируем все функции PyCaret, связанные с регрессией. Последняя строка указывает, что рисунки Matplotlib будут иметь разрешение 300 DPI
import matplotlib.pyplot as plt
import matplotlib as mpl
import seaborn as sns
from pycaret.datasets import get_data
from pycaret.regression import *
mpl.rcParams['figure.dpi'] = 300
age | sex | bmi | children | smoker | region | charges | |
---|---|---|---|---|---|---|---|
0 | 19 | female | 27.900 | 0 | yes | southwest | 16884.92400 |
1 | 18 | male | 33.770 | 1 | no | southeast | 1725.55230 |
2 | 28 | male | 33.000 | 3 | no | southeast | 4449.46200 |
3 | 33 | male | 22.705 | 0 | no | northwest | 21984.47061 |
4 | 32 | male | 28.880 | 0 | no | northwest | 3866.85520 |
<class 'pandas.core.frame.DataFrame'> RangeIndex: 1338 entries, 0 to 1337 Data columns (total 7 columns): # Column Non-Null Count Dtype --- ------ -------------- ----- 0 age 1338 non-null int64 1 sex 1338 non-null object 2 bmi 1338 non-null float64 3 children 1338 non-null int64 4 smoker 1338 non-null object 5 region 1338 non-null object 6 charges 1338 non-null float64 dtypes: float64(2), int64(2), object(3) memory usage: 73.3+ KB
Исследовательский анализ данных (EDA)
EDA — это метод, который помогает нам понять свойства набора данных с помощью
описательной статистике и визуализацию. Это важная часть каждого проекта машинного обучения, так как мы должны понять набор данных, прежде чем его использовать.
Распределение числовых переменных можно визуализировать с помощью гистограммы, которую можно легко создается с помощью функции pandas hist(). Очевидно, что
некоторые переменные имеют правостороннее распределение, что может вызвать
проблемы с регрессионными моделями.
numeric = ['age', 'bmi', 'children', 'charges']
data[numeric].hist(bins=20, figsize = (12,8))
Использование столбчатых диаграмм — стандартный способ отображения
категориальных переменных. Это легко, используя функции pandas value_counts() и
plot().
В этом примере используем функцию subplots(), первые два параметра
задают количество строк и столбцов сетки. Функция subplots() возвращает два объекта,
первый — это Figure, подложка, на которой будут размещены поля с
графиками, второй — объект (или массив объектов) Axes, через который
можно получить полных доступ к настройке внешнего вида отображаемых элементов.
categorical = ['smoker', 'sex', 'region']
color = ['C0', 'C1', 'C2', 'C3']
fig, axes = plt.subplots(2, 2, figsize = (12,10))
#Отключаем вывод четвертого графика
axes[1,1].set_axis_off()
# axes.flatten () сгладит ax из группы осей n * m в группу осей 1 * nm
for ax, col in zip(axes.flatten(), categorical) :
data[col].value_counts().plot(kind = 'bar', ax = ax, color = color)
ax.set_xlabel(col)
Как мы видим, переменная курильщик имеет неравномерное распределение,
только 20% люди курят. С другой стороны, переменные пол и регион одинаково
распределены.
Функция Seaborn histplot() позволяет визуализировать взаимосвязь между числовыми
и категориальные переменные с помощью цвета. Гистограмма целевой функции
(страховых расходов) окрашена по разному для курильщиков, пола и регионов.
Очевидно, что у курильщики расходы значительно больше. Это ожидаемо,
поскольку риски для здоровья, связанные с курением, хорошо известны.
fig, axes = plt.subplots(2, 2, figsize=(12,8))
axes[1,1].set_axis_off()
for ax, col in zip(axes.flatten(), categorical):
sns.histplot(data, x='charges', hue=col, multiple='stack', ax=ax)
Диаграммы рассеяния — это тип визуализации, который помогает понять взаимосвязь
между числовыми переменными. Функция steamplot() Seaborn создает матрицу диаграмм рассеяния для всех пар числовых переменных в заданном наборе данных. На диагонали располагаются графики распределения в виде гистограмм или KDE. Цвет используем для выделения различий между курящими и некурящими.
Анализируя этот график можно сделать некоторые выводы : начисления коррелируют с возрастом, чем старше, тем больше расходов на поддержания здоровья, при этом у некурящих все равно эта тенденция ниже; у людей с избыточным весом нет более высоких расходов, если они не курят.
cols = ['age', 'bmi', 'charges', 'smoker']
sns.pairplot(data[cols], hue='smoker')
plt.tight_layout()
Инициализация среды PyCaret
reg = setup(data=data, target='charges', train_size = 0.8, session_id = 7402,
numeric_features = numeric[:-1], categorical_features = categorical,
transformation = True, normalize = True, transform_target = True,fold_shuffle=True)
Функция setup() инициализирует среду в pycaret и создает конвейер преобразования для подготовки данных для моделирования и развертывания. setup() необходимо вызывать
перед выполнением любой другой функции в pycaret. Он принимает два обязательных
параметра: DataFrame pandas и имя целевого столбца. Все остальные параметры
являются необязательными и используются для настройки конвейера предварительной обработки.
Разберем параметры, заданные в примере :
data - типа DataFrame Pandas
Набор данных с формой (n_samples, n_features), где n_samples — количество выборок, а n_features — количество признаков. Если данные не являются DataFrame pandas, они преобразуются в DataFrame с использованием имен столбцов по умолчанию.
target: int, str или последовательность, по умолчанию = -1
Если int или str, соответственно индекс или имя целевого столбца в данных. Значение
по умолчанию выбирает последний столбец в наборе данных. Если
последовательность, она должна иметь форму (n_samples). Цель может быть либо
бинарной, либо мультиклассовой.
train_size: с плавающей запятой, по умолчанию = 0,7
Доля набора данных, которая будет использоваться для обучения и проверки. Должно
быть между 0,0 и 1,0.
session_id: целое, по умолчанию = None
Предоставляет начальное значение внутреннему генератору случайных чисел,
эквивалентно «random_state» в scikit-learn. Если None, генерируется псевдослучайное
число. Используется для последующей воспроизводимости всего эксперимента.
numeric_features: list of str, по умолчанию = None
Список имен столбцов с числовыми признаками, задаются, если не согласны с
автоматическим определение типов
categorical_features: list of str, по умолчанию = None
Список имен столбцов с категориальными признаками, задаются, если не согласны с
автоматическим определение типов
ordinal_features: dict, по умолчанию = нет
Категориальные признаки должны кодироваться порядково.
Например, категориальный признак со значениями «низкий», «средний», «высокий»,
где низкий < средний < высокий, может быть передан как
ordinal_features = {'column_name' : ['low', 'medium', 'high']} .
Помимо этих, есть date_features для дат и text_features для строк, а также
ignore_features - список столбцов, которые надо игнорировать и keep_features - список
столбцов, которые всегда должны присутствовать в модели.
transformation: bool, по умолчанию = False
Если установлено значение True, применяется степенное преобразование,
чтобы сделать данные более похожими на нормальное распределение.
Тип преобразования определяется параметром transform_method.
transform_target: bool, по умолчанию = False
Если установлено значение True, целевая переменная преобразуется с
использованием метода, определенного в параметре transform_target_method.
Целевое преобразование применяется отдельно от преобразования признаков.
normalize: bool, по умолчанию = False
Если установлено значение True, он преобразует объекты, масштабируя их до
заданного диапазона. Тип масштабирования определяется параметром
normalize_method.
normalize_method: str, по умолчанию = ‘zscore’
Определяет метод масштабирования. По умолчанию метод нормализации установлен
на «zscore». Стандартный zscore рассчитывается как z = (x - u) / s. Игнорируется,
если для нормализации не установлено значение True. Другие варианты:
- minmax: масштабируйте каждую функцию в диапазоне [0, 1],
- maxabs: масштабируйте каждую функцию в диапазоне [-1, 1],
- robust: масштабирует и переводит каждый признак в соответствии
с межквартильным диапазоном. Когда набор данных содержит выбросы,
часто дает лучшие результаты.
fold_shuffle: bool, по умолчанию = False
Управляет параметром перемешивания CV. Применимо, только если fold_strategy
имеет значение «kfold» или «stratifiedkfold». Игнорируется, если fold_strategy
является настраиваемым объектом.
fold_strategy: str or sklearn CV generator object,, по умолчанию = ‘kfold’
Выбор стратегии перекрестной проверки. Возможные значения:
‘kfold’
‘groupkfold’
‘timeseries’
собственный объект генератора CV, совместимый с scikit-learn.
Для groupkfold имя столбца должно быть передано в параметре fold_groups.
Пример: setup(fold_strategy="groupkfold", fold_groups="COLUMN_NAME")
Получается, что раз fold_strategy по умолчанию ‘kfold’, то fold_shuffle должен быть
по умолчанию True, однако это не так и приходиться задавать его явно, иначе будет
ошибка
max_encoding_ohe: целое число, по умолчанию = 25
Категориальные столбцы с max_encoding_ohe или менее уникальными значениями
кодируются с использованием OneHotEncoding. Если больше, используется
оценщик encoding_method. Обратите внимание, что столбцы с ровно двумя
классами всегда кодируются по порядку. Установите значение ниже 0,
чтобы всегда использовать OneHotEncoding.
encoding_method: оценка кодировщиков категорий, по умолчанию = None
Средство оценки кодировщиков категорий для кодирования категориальных столбцов
с более чем max_encoding_ohe уникальными значениями. Если нет,
используется category_encoders.leave_one_out.LeaveOneOutEncoder.
Подробнее о параметрах настройки
https://pycaret.readthedocs.io/en/latest/api/regression.html
После запуска функции setup() распечатывается таблица с ее параметрами
и настройками.
Печать предварительно обработанных элементов
get_config('X').head().T
0 1 2 3 4 age -1.462763 -1.535749 -0.807782 -0.445654 -0.517962 bmi -0.408971 0.543953 0.426243 -1.350171 -0.240519 children -1.053884 0.203960 1.414612 -1.053884 -1.053884 sex_female 1.000000 0.000000 0.000000 0.000000 0.000000 smoker_no 0.000000 1.000000 1.000000 1.000000 1.000000 region_northeast 0.000000 0.000000 0.000000 0.000000 0.000000 region_northwest 0.000000 0.000000 0.000000 1.000000 1.000000 region_southeast 0.000000 1.000000 1.000000 0.000000 0.000000 region_southwest 1.000000 0.000000 0.000000 0.000000 0.000000
Это то, что получилось после конвейера предварительной обработки. Мы видим, что
числовые признаки имеют разные значения из-за нормализация/преобразование
и категориальные признаки были преобразованы к нескольким двоичным переменным
из-за применения one-hot encoding.
Сравнение моделей регрессии
best = compare_models(sort='RMSE')
Model MAE MSE RMSE R2 RMSLE MAPE TT (Sec) rf Random Forest Regressor 2314.0407 22718644.0723 4715.8663 0.8406 0.4149 0.2083 0.1720 gbr Gradient Boosting Regressor 2248.6895 23025672.3030 4723.3879 0.8387 0.3831 0.1800 0.0430 lightgbm Light Gradient Boosting Machine 2472.4682 23306959.3877 4766.9966 0.8372 0.4116 0.2064 0.2010 ada AdaBoost Regressor 3240.7127 23938991.4595 4847.0155 0.8316 0.4804 0.4266 0.0210 catboost CatBoost Regressor 2508.4919 25307119.9727 4953.3531 0.8228 0.4044 0.1971 0.5440 et Extra Trees Regressor 2418.7871 26054884.6612 5056.1186 0.8158 0.4411 0.2261 0.1450 xgboost Extreme Gradient Boosting 2832.3074 32979184.8000 5568.3325 0.7744 0.4465 0.2536 0.0670 dt Decision Tree Regressor 3169.9592 44888037.8142 6676.8115 0.6705 0.5351 0.3550 0.0100 omp Orthogonal Matching Pursuit 5637.7005 58885229.9609 7602.7504 0.5888 0.6836 0.6873 0.0100 ridge Ridge Regression 4053.7931 60899553.2000 7749.9366 0.5714 0.4388 0.2693 0.0110 br Bayesian Ridge 4060.2318 61248984.3482 7772.2583 0.5688 0.4388 0.2691 0.0100 lar Least Angle Regression 4068.5723 61713577.6000 7801.8819 0.5654 0.4388 0.2688 0.0110 lr Linear Regression 4068.5899 61714293.2000 7801.9242 0.5654 0.4388 0.2688 0.8460 knn K Neighbors Regressor 4557.1271 71071863.6416 8351.8991 0.5091 0.5320 0.3122 0.0130 huber Huber Regressor 4225.8635 80592753.4246 8895.4947 0.4321 0.4542 0.2076 0.0140 par Passive Aggressive Regressor 6234.6940 132789408.9789 10197.7140 -0.0615 0.6154 0.5927 0.0100 en Elastic Net 8222.1528 160880655.2000 12599.0370 -0.1178 0.9073 0.9694 0.0110 llar Lasso Least Angle Regression 8248.0973 161187188.0000 12610.6184 -0.1198 0.9100 0.9767 0.0100 lasso Lasso Regression 8248.0973 161187188.0000 12610.6184 -0.1198 0.9100 0.9767 0.0100
Существует множество доступных регрессионных моделей, и выбор лучшего для наших данных может быть сложной задачей. Функция compare_models() упрощает этот
процесс, обучая все доступные модели и отображая таблицу с результатами. Первый
столбец содержит имя модели регрессии, а остальные являются различными
показателями. Как мы видим, существуют различные метрики, которые могут быть
используется для оценки эффективности регрессионной модели, но мы сосредоточимся на среднеквадратичной ошибке (RMSE), поэтому результаты отсортированы на ее
основе. RMSE — одна из наиболее широко используемых метрик для регрессии, и она определяется как квадратный корень из среднего квадрата ошибок между фактическими и прогнозируемыми значениями.
У меня по этому показателю лучшая модель rf (Random Forest Regressor) co значением
4715.8663, в книге это Gradient Boosting Regressor со значением RMSE 4750.1089.
Так как работаем по книге, не будем от нее отходить и также для дальнейшего
рассмотрения выберем gbr, тем более что у этой модели лучший показатель MAPE,
который показывает ошибку в процентах и не связан с размерностью.
Далее мы можем обучить модель с помощью функции create_model(). Функция, которая использует k-кратную перекрестную проверку для оценки точности модели. Набор
данных разбивается на k подвыборок, одна из которых сохраняется для проверки,
а остальные используются для обучения модели. Этот процесс повторяется k раз,
в результате метрики для каждой подвыборки отображаются после ее завершения.
model = create_model('gbr', fold = 10)
MAE MSE RMSE R2 RMSLE MAPE 0 1577.8011 11712642.1869 3422.3738 0.8957 0.3940 0.1563 1 1778.3542 13278923.7169 3644.0258 0.8975 0.3028 0.1778 2 2454.4445 24687957.8424 4968.6978 0.8807 0.3893 0.1730 3 2764.9351 34137006.0998 5842.6883 0.8154 0.3857 0.1847 4 1823.5426 13710743.4009 3702.8021 0.8927 0.3537 0.1706 5 2146.7377 21985576.7261 4688.8780 0.8403 0.4166 0.1849 6 2683.9864 31434415.1573 5606.6403 0.7652 0.3780 0.1930 7 2245.5226 19903097.8245 4461.2888 0.8372 0.3422 0.1745 8 2535.3463 28168373.3010 5307.3886 0.8031 0.4506 0.2017 9 2476.2245 31237986.7739 5589.0953 0.7594 0.4179 0.1839 Mean 2248.6895 23025672.3030 4723.3879 0.8387 0.3831 0.1800 SD 386.6178 7819241.0112 845.7419 0.0499 0.0401 0.0120
Настройка гиперпараметров — это метод, при котором различные параметры модели машинного обучения настраиваются для оптимизации ее производительности. Функцию
tune_model() можно использовать для применения настройки гиперпараметров к
обученной модели с помощью рандомизированный метод поиска, при котором
производится случайная выборка возможных комбинаций.
Словарь с нашими гиперпараметрами был передан в параметр функции custom_grid.
Мы видим, что после настройки модели RMSE значение уменьшилось до 4585.6787.
Необходимо иметь в виду, что настройка гиперпараметров может быть вычислительно интенсивным и трудоемким процессом. В случае, если это будет выполняться слишком долго ,можно попробовать уменьшить количество итераций, установив меньшее
значение параметра n_iter. Каждая регрессионная модель имеет свой набор
гиперпараметров, которые можно настроить, поэтому придется проработать его
документации для их выбора. В для Gradient Boosting документация по регрессии
scikit-learn : ttps://scikit-learn.org/stable/modules/generated/
sklearn.ensemble.GradientBoostingRegressor.html
params = {'learning_rate': [0.01, 0.02, 0.05], 'max_depth': [1,2, 3, 4, 5, 6, 7, 8], 'subsample': [0.4, 0.5, 0.6, 0.7, 0.8], 'n_estimators' : [100, 200, 300, 400, 500, 600]} tuned_model = tune_model(model, optimize = 'RMSE', fold = 10, custom_grid = params, n_iter = 100)
MAE MSE RMSE R2 RMSLE MAPE 0 1603.8218 12188586.8674 3491.2157 0.8914 0.3966 0.1645 1 1728.3064 13112545.5846 3621.1249 0.8988 0.3000 0.1749 2 2309.4411 23388076.1592 4836.1220 0.8870 0.3775 0.1603 3 2676.3443 34715313.4200 5891.9702 0.8122 0.3768 0.1742 4 1579.9455 11948234.3211 3456.6218 0.9065 0.3498 0.1588 5 2050.6347 20786022.2314 4559.1690 0.8490 0.4058 0.1761 6 2601.8791 30444354.7121 5517.6403 0.7726 0.3733 0.1911 7 2208.3415 19712289.8404 4439.8525 0.8387 0.3487 0.1857 8 2440.9072 27343035.9489 5229.0569 0.8089 0.4455 0.1986 9 2106.4445 23174724.1145 4814.0133 0.8215 0.4300 0.1709 Mean 2130.6066 21681318.3200 4585.6787 0.8487 0.3804 0.1755 SD 374.6723 7394738.2223 808.0034 0.0432 0.0401 0.0124
Функция predict_model() делает прогнозы на набор тестовых данных, что позволяет нам оценить производительность модели на данных, которые не использовался для
обучения модели. Как мы видим, значение RMSE в тестовом наборе данных равно
4046.7334,что говорит о том, что модель имеет отличные характеристики
Комментариев нет:
Отправить комментарий