В последней части серии мы рассмотрим подгонку моделей машинного обучения к нашему предварительно обработанному и спроектированному набору данных выбранных функций, оценим каждую модель и настроим ее гиперпараметры.
В этом примере мы реализуем и сравним следующие модели:
Модели на основе ошибок:
- Линейная регрессия
- Лассо-регрессия
Модель на основе подобия:
- Ближайшие соседи
Информационная модель:
- Древо решений
- Случайный лес
- Повышение градиента
Как обычно, мы начинаем с загрузки соответствующих библиотек и наборов данных.
import pandas as pd import numpy as np from sklearn.linear_model import LinearRegression, Lasso from sklearn.neighbors import KNeighborsRegressor from sklearn.preprocessing import StandardScaler from sklearn.tree import DecisionTreeRegressor from sklearn.metrics import r2_score, mean_squared_error from sklearn.ensemble import RandomForestRegressor, GradientBoostingRegressor from sklearn.model_selection import GridSearchCV, RandomizedSearchCV X_train = pd.read_csv('X_train') X_test = pd.read_csv('X_test') y_train = pd.read_csv('y_train') y_test = pd.read_csv('y_test')
Подбор и оценка модели
Поскольку это проблема регрессии, мы будем использовать R2 и MSE для оценки этих моделей.
R2: рассчитывается как доля дисперсии зависимой переменной, которую можно предсказать по независимым переменным. Интуитивно это можно объяснить тем, что предсказанные данные хорошо соответствуют реальным данным. Хотя R2 обычно находится в диапазоне от 0 до 1, бывают случаи, когда он находится за пределами этого диапазона, что указывает на то, что модель подходит хуже, чем горизонтальная гиперплоскость. Это часто бывает, когда была выбрана неправильная модель (например, использование классификатора в задаче регрессии). Чем выше R2 и ближе к 1, тем лучше.
Среднеквадратическая ошибка (MSE): вычисляется путем получения средних квадратов разностей между прогнозируемым значением и реальным целевым значением. Другая его версия называется RMSE, которая представляет собой квадратный корень из MSE. Чем ниже МСЭ, тем лучше.
Существуют и другие методы оценки, такие как средняя абсолютная ошибка, среднеквадратическая логарифмическая ошибка, которые вы можете опробовать в своих собственных наборах данных.
Давайте подгоним набор для обучения и тестирования к каждой модели и найдем их оценки R2 и MSE:
Давайте определим функции для запуска этих моделей:
Линейная регрессия:
def run_multipleLinearRegressor(X_train, X_test, y_train, y_test): slr = LinearRegression() slr.fit(X_train, y_train) print(‘Train set’) pred = slr.predict(X_train) print(‘Multiple Linear Regression R2: {}’.format(slr.score(X_train, y_train))) print(‘Multiple Linear Regression MSE: {}’.format(mean_squared_error(y_train, pred))) print(‘Test set’) pred = slr.predict(X_test) print(‘Multiple Linear Regression R2: {}’.format(slr.score(X_test, y_test))) print(‘Multiple Linear Regression MSE: {}’.format(mean_squared_error(y_test, pred)))
Лассо регрессия:
def run_lassoRegressor(X_train, X_test, y_train, y_test): lr = Lasso() lr.fit(X_train, y_train) print(‘Train set’) pred = lr.predict(X_train) print(‘Simple Linear Regression R2: {}’.format(lr.score(X_train, y_train))) print(‘Simple Linear Regression MSE: {}’.format(mean_squared_error(y_train, pred))) print(‘Test set’) pred = lr.predict(X_test) print(‘Simple Linear Regression R2: {}’.format(lr.score(X_test, y_test))) print(‘Simple Linear Regression MSE: {}’.format(mean_squared_error(y_test, pred)))
Ближайшие соседи:
def run_nearestNeighbors(X_train, X_test, y_train, y_test): neigh = KNeighborsRegressor(n_neighbors=50) neigh.fit(X_train, y_train) print(‘Train set’) pred = neigh.predict(X_train) print(‘Simple Linear Regression R2: {}’.format(neigh.score(X_train, y_train))) print(‘Simple Linear Regression MSE: {}’.format(mean_squared_error(y_train, pred))) print(‘Test set’) pred = neigh.predict(X_test) print(‘Simple Linear Regression R2: {}’.format(neigh.score(X_test, y_test))) print(‘Simple Linear Regression MSE: {}’.format(mean_squared_error(y_test, pred)))
Древо решений:
def run_decisionTree(X_train, X_test, y_train, y_test): dt = DecisionTreeRegressor() dt.fit(X_train, y_train) print(‘Train set’) pred = dt.predict(X_train) print(‘Decision Tree R2: {}’.format(dt.score(X_train, y_train))) print(‘Decision Tree MSE: {}’.format(mean_squared_error(y_train, pred))) print(‘Test set’) pred = dt.predict(X_test) print(‘Decision Tree R2: {}’.format(dt.score(X_test, y_test))) print(‘Decision Tree MSE: {}’.format(mean_squared_error(y_test, pred)))
Случайный лес:
def run_randomForests(X_train, X_test, y_train, y_test): rf = RandomForestRegressor(n_estimators=200, random_state=39, max_depth=4) rf.fit(X_train, y_train) print(‘Train set’) pred = rf.predict(X_train) print(‘Random Forests R2: {}’.format(r2_score(y_train, pred))) print(‘Random Forests MSE: {}’.format(mean_squared_error(y_train, pred))) print(‘Test set’) pred = rf.predict(X_test) print(‘Random Forests R2: {}’.format(r2_score(y_test, pred))) print(‘Random Forests MSE: {}’.format(mean_squared_error(y_test, pred)))
Повышение градиента:
def run_gradientboosting(X_train, X_test, y_train, y_test): gb = GradientBoostingRegressor(n_estimators=100,random_state=0) gb.fit(X_train, y_train) print(‘Train set’) pred = gb.predict(X_train) print(‘Random Forests R2: {}’.format(r2_score(y_train, pred))) print(‘Random Forests MSE: {}’.format(mean_squared_error(y_train, pred))) print(‘Test set’) pred = gb.predict(X_test) print(‘Random Forests R2: {}’.format(r2_score(y_test, pred))) print(‘Random Forests MSE: {}’.format(mean_squared_error(y_test, pred)))
Затем запустите наш обучающий и тестовый набор для каждого из них, например:
run_randomForests(X_train, X_test, y_train, y_test)
Напомним, в части 3 у нас есть базовая модель:
Сравните это с нашими лучшими моделями:
Наши новые модели существенно превзошли базовую модель!
Настройка гиперпараметров
Во-первых, что такое гиперпараметр? Гиперпараметр — это параметр для оценщика, который мы можем настроить в соответствии с нашим набором данных. В качестве примера возьмем регрессор случайного леса scikit-learn:
Регрессор случайного леса в пакете scikit-learn имеет несколько гиперпараметров, таких как n_estimators, который обозначает количество деревьев в лесу, по умолчанию установленное на 100 деревьев. Однако возможно ли, что чем больше/меньше деревьев у нас есть, тем лучше наша модель? Настраивая гиперпараметры, мы надеемся найти набор гиперпараметров, который оптимизирует производительность нашей модели.
Мы будем использовать 2 наиболее распространенных метода:
- Случайный поиск: мы будем использовать метод RandomizedSearchCV в модуле model_selection scikit-learn. Нам нужно только передать оценщик, гиперпараметры, которые мы хотели бы настроить, а также распределение, количество выборок и метрику оценки. Инструмент случайным образом выберет значения гиперпараметров из заранее заданного распределения и найдет оптимальный гиперпараметр из этих случайно выбранных значений.
- Поиск по сетке: после того, как у нас есть список значений гиперпараметров, оптимизированных с помощью случайного поиска, мы можем уточнить это еще на один шаг, проверив близкие значения, поскольку они могут давать еще лучшие результаты, но не были проверены в случайном поиске. Поскольку использование поиска по сетке для широкого набора значений требует много времени, мы сначала выполняем случайный поиск, чтобы приблизиться к возможным значениям, и только затем мы используем поиск по сетке для дальнейшего точного определения оптимального набора значений.
Мы продемонстрируем на модели случайного леса. Начнем с указания диапазона значений, которые гиперпараметры могут принимать при случайном поиске.
# Number of trees in random forest n_estimators = [int(x) for x in np.linspace(start = 200, stop = 2000, num = 10)] # Number of features to consider at every split max_features = [‘auto’, ‘sqrt’] # Maximum number of levels in tree max_depth = [int(x) for x in np.linspace(10, 110, num = 11)] max_depth.append(None) # Minimum number of samples required to split a node min_samples_split = [2, 5, 10] # Minimum number of samples required at each leaf node min_samples_leaf = [1, 2, 4] # Method of selecting samples for training each tree bootstrap = [True, False] # Create the random grid random_grid = {‘n_estimators’: n_estimators, ‘max_features’: max_features, ‘max_depth’: max_depth, ‘min_samples_split’: min_samples_split, ‘min_samples_leaf’: min_samples_leaf, ‘bootstrap’: bootstrap} print(random_grid)
Примените RandomSearchCV от scikit-learn к обучающему набору:
# Use the random grid to search for best hyperparameters # First create the base model to tune rf = RandomForestRegressor() # Random search of parameters, using 3 fold cross validation, # search across 100 different combinations, and use all available cores rf_random = RandomizedSearchCV(estimator = rf, param_distributions = random_grid, n_iter = 100, cv = 3, verbose=2, random_state=42, n_jobs = -1) # Fit the random search model rf_random.fit(X_train, y_train)
Узнайте лучшие параметры:
rf_random.best_params_
Оцените модель:
def evaluate(model, test_features, test_labels): pred = model.predict(test_features) print(‘Model Performance’) print(‘R2: {}’.format(r2_score(test_labels, pred))) print(‘MSE: {}’.format(mean_squared_error(test_labels, pred))) return base_model = RandomForestRegressor(n_estimators = 10, random_state = 42) base_model.fit(X_train, y_train) base_accuracy = evaluate(base_model, X_test, y_test) best_random = rf_random.best_estimator_ random_accuracy = evaluate(best_random, X_test, y_test)
Затем мы используем поиск по сетке со значениями, близкими к значениям, полученным в результате случайного поиска:
# Create the parameter grid based on the results of random search param_grid = { 'bootstrap': [True], 'max_depth': [60, 70, 80], 'max_features': ['auto'], 'min_samples_leaf': [1,2], 'min_samples_split': [2, 3], 'n_estimators': [1300, 1400, 1500] }
Примените GridSearchCV от scikit-learn к обучающему набору:
# Create a based model rf = RandomForestRegressor() # Instantiate the grid search model grid_search = GridSearchCV(estimator = rf, param_grid = param_grid, cv = 3, n_jobs = -1, verbose = 2) grid_search.fit(X_train, y_train)
Узнайте лучшие параметры:
grid_search.best_params_
Оцените модель:
base_model = RandomForestRegressor(n_estimators=200, random_state=39, max_depth=4) base_model.fit(X_train, y_train) base_accuracy = evaluate(base_model, X_test, y_test) best_random = rf_random.best_estimator_ random_accuracy = evaluate(best_random, X_test, y_test) best_grid = grid_search.best_estimator_ grid_accuracy = evaluate(best_grid, X_test, y_test)
Использование гиперпараметров, оптимизированных с помощью поиска по сетке, улучшило производительность при тестировании с оценкой R2 0,793. Сравнивая производительность нашей последней модели с нашей исходной базовой моделью, мы видим значительный скачок благодаря разработке, выбору и настройке функций!
На этом мы завершаем наш пример сквозного машинного обучения. Спасибо за чтение!
Полный блокнот можно найти на Github.
Ссылки на каждую статью:
Часть 0: Постановка задачи
Часть 1: Веб-парсинг
Часть 2: Исследовательский анализ данных
Часть 3: Очистка данных
Часть 4: Разработка функций
Часть 5: Выбор характеристик
Часть 6: Подгонка модели и настройка
Ссылка:
- Семинар по науке о данных Энтони Со; доктор Самуэль Асаре; Роберт Тас Джон; Томас В. Джозеф; Эндрю Уорсли
- Гиперпараметрическая настройка случайного леса в Python, Уилл Кёрсен