Наша работа инженера по машинному обучению в основном связана с настройкой моделей. Именно гиперпараметры, которые мы можем корректировать, действительно дают нам власть над нашими моделями и делают наш опыт таким ценным. При этом одним из самых важных инструментов, которыми владеет инженер по машинному обучению, является регуляризация. В этой статье я дам определение регуляризации простыми словами и расскажу о трех основных методах регуляризации, о том, когда их использовать и как их кодировать в python с помощью sklearn
.
Зачем нужна регуляризация?
Регуляризация — это стратегия, используемая в машинном обучении для борьбы с переоснащением. Переобучение происходит, когда наша модель слишком хорошо соответствует нашему обучающему набору данных. К сожалению, хорошая работа с обучающими данными не обязательно означает, что модель будет хорошо соответствовать невидимым данным. На самом деле часто бывает с точностью до наоборот. Когда модель очень хорошо соответствует обучающим данным, это обычно означает, что она улавливает слишком много шума или вариации в точках данных, которые либо случайны, либо нерелевантны. Это может привести к тому, что модель зациклится на более мелких особенностях обучающих данных, которых на самом деле нет в невидимых наборах данных. И поскольку сила моделей машинного обучения заключается в их способности предсказывать, а не просто сообщать нам то, что мы уже знаем, мы отдаем приоритет тому, насколько хорошо модель соответствует невидимым данным, а не обучающим данным. Так как же нам убедиться, что наши модели не настолько точно соответствуют нашим обучающим данным, что они теряют способность обобщать? Вот где регуляризация пригодится!
Понимание регуляризации:
Когда мы используем регуляризацию, мы, по сути, создаем границы или ограничения для наших моделей. Мы вводим штрафы в процессе обучения, которые снижают сложность модели и значения коэффициентов. Это помогает управлять нашими моделями, чтобы они не улавливали каждое небольшое изменение в обучающих данных, а вместо этого придерживались шаблонов, которые являются более обобщаемыми.
Точнее, мы добавляем член регуляризации к функции потерь. Распространенной функцией потерь является MSE (среднеквадратичная ошибка), которая рассчитывается путем сложения всех квадратов невязок модели с последующим делением на количество невязок. Когда мы добавляем регуляризацию, чтобы избежать переобучения, наша функция потерь выглядит примерно так:
Потеря = MSE + регуляризация
Фактический расчет этого члена регуляризации будет зависеть от того, какой метод вы применяете к своей модели. Три основных метода регуляризации: L1 (лассо), L2 (конек) и эластичная сеть.
Регуляризация L1 (лассо):
Регуляризация L1, также называемая «регуляризацией лассо», добавляет сумму абсолютных значений коэффициентов в качестве штрафа. В некоторых случаях это уменьшит коэффициенты до нуля, эффективно выполняя выбор признаков. L1 лучше всего использовать, когда есть подозрение на нерелевантные или избыточные функции в модели или когда вы хотите отдать приоритет низкой сложности в своей модели.
#import relevant functions import pandas as pd from sklearn.model_selection import train_test_split from sklearn.linear_model import Lasso from sklearn.metrics import mean_squared_error from sklearn.datasets import load_diabetes from sklearn.preprocessing import StandardScaler #load in dataset data = load_diabetes(return_X_y=True, as_frame=True) X = data[0] y = data[1] X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=.25, random_state=42) #standard scale data scaler = StandardScaler() X_train_scaled = scaler.fit_transform(X_train) X_test_scaled = scaler.transform(X_test) #instantiate and fit Lasso Regression lasso = Lasso(alpha=1) lasso.fit(X_train_scaled, y_train) #R2 scores for train and test data train_r2 = lasso.score(X_train_scaled, y_train) test_r2 = lasso.score(X_test_scaled, y_test) print(train_r2, test_r2)
Регуляризация L2 (хребет):
Регуляризация L2 добавляет сумму квадратов значений коэффициентов в качестве штрафного члена. Возводя коэффициенты в квадрат, те, у которых более высокая величина, добавят более высокий штраф, поощряя модель к меньшим и более распределенным коэффициентам. Он более эффективен в борьбе с чрезмерным выделением какой-либо отдельной функции в модели. L2 работает хорошо, когда все функции вносят свой вклад в предсказательную силу модели, поскольку вероятность отбрасывания функций меньше, чем у L1.
Гребневая регрессия уменьшает коэффициенты и помогает справиться со сложностью и коллинеарностью модели.
#import relevant packages from sklearn.linear_model import Ridge from sklearn.datasets import load_diabetes from sklearn.model_selection import train_test_split from sklearn.preprocessing import StandardScaler from sklearn.metrics import mean_squared_error import pandas as pd #load data as dataframe data = load_diabetes(return_X_y = True, as_frame = True) X = data[0] y = data[1] #perform train_test_split X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=.25, random_state=42) #instantiate, fit, transform Standard Scaler scaler = StandardScaler() X_train_scaled = scaler.fit_transform(X_train) X_test_scaled = scaler.transform(X_test) #instantiate Ridge Regression, fit on training data ridge = Ridge(alpha=100) ridge.fit(X_train_scaled, y_train) #assess train and test scores train_score = ridge.score(X_train_scaled, y_train) test_score = ridge.score(X_test_scaled, y_test) print(f"Train Score: {train_score}") print(f"Test Score: {test_score}") y_pred_test = ridge.predict(X_test_scaled) y_pred_train = ridge.predict(X_train_scaled) train_mse = mean_squared_error(y_train, y_pred_train) test_mse = mean_squared_error(y_test, y_pred_test) print(f"Train MSE: {train_mse}") print(f"Test MSE: {test_mse}")
Эластичная сетка:
Elastic Net эффективно сочетает в себе как Lasso, так и Ridge, чтобы использовать сильные стороны обоих. Он добавляет к функции потерь линейную комбинацию штрафов L1 и L2, которую можно настроить, изменив параметр l1_ratio
класса ElasticNet()
. Полученная функция потерь выглядит примерно так:
elastic_net_regularization = (альфа * L1_regularization) + ((1-альфа) * L2_regularization)
#import relevant functions import pandas as pd from sklearn.model_selection import train_test_split from sklearn.linear_model import ElasticNet from sklearn.metrics import mean_squared_error from sklearn.datasets import load_diabetes from sklearn.preprocessing import StandardScaler #load in dataset data = load_diabetes(return_X_y=True, as_frame=True) X = data[0] y = data[1] X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=.25, random_state=42) #standard scale data scaler = StandardScaler() X_train_scaled = scaler.fit_transform(X_train) X_test_scaled = scaler.transform(X_test) #instantiate and fit Elastic Net en = ElasticNet(alpha=.1, l1_ratio=.5) en.fit(X_train_scaled, y_train) #R2 scores for train and test data train_r2 = en.score(X_train_scaled, y_train) test_r2 = en.score(X_test_scaled, y_test) print(train_r2, test_r2)
Хотя существует множество нюансов и стратегий использования регуляризации, знание основных идей L1, L2 и Elastic Net значительно расширит ваши возможности настройки модели. Когда у вас будет базовый код, вы можете продолжить настройку альфы, L1_ratio и других аспектов регуляризации, чтобы получить лучшую модель!