Рубрики
Без рубрики

Машинное обучение с помощью Python: простой и надежный метод подгонки нелинейных данных

Простая и надежная методология нелинейного моделирования данных с использованием библиотек Python, функций конвейера и регуляризации.

Автор оригинала: Tirthajyoti Sarkar.

Простая и надежная методология нелинейного моделирования данных с использованием библиотек Python, функций конвейера и регуляризации.

Нелинейное моделирование данных-это рутинная задача в области науки о данных и аналитики. Крайне редко можно найти естественный процесс, результат которого изменяется линейно с независимыми переменными. Поэтому нам нужна простая и надежная методология, позволяющая быстро сопоставить измеренный набор данных с набором переменных, предполагая, что измеренные данные могут быть сложной нелинейной функцией. Это должно быть довольно распространенным инструментом в репертуаре специалиста по обработке данных или инженера по машинному обучению .

Есть несколько уместных вопросов для рассмотрения:

  • Как мне решить, какой порядок полинома попытаться подогнать? Нужно ли включать термины перекрестной связи для многомерной регрессии? Есть ли простой способ автоматизировать этот процесс ?
  • Как сделать так, чтобы я не переусердствовал с данными?
  • Является ли моя модель машинного обучения устойчивой к измерительному шуму ?
  • Является ли моя модель легко масштабируемой для более высоких измерений и/или для большего набора данных?

Как решить порядок полинома и связанную с ним дилемму

Могу ли я построить график данных и быстро взглянуть ?”

Это нормально только тогда, когда можно четко визуализировать данные (размерность объекта равна 1 или 2). Это намного сложнее для объектов размером 3 или выше. И это полная трата времени, если есть перекрестная связь внутри функций, влияющих на результат. Позвольте мне показать это с помощью сюжетов,

Легко видеть, что заговор ведет вас только так далеко. Для многомерного взаимно взаимодействующего набора данных вы можете сделать совершенно неправильный вывод, если попытаетесь посмотреть на выходной график по сравнению с одной входной переменной за раз . И нет простого способа визуализировать более 2 переменных одновременно. Итак, мы должны прибегнуть к какой-то технике машинного обучения, чтобы сформировать многомерный набор данных.

На самом деле существует довольно много хороших решений.

Линейная регрессия должна быть первым инструментом, чтобы посмотреть вверх и прежде чем вы закричите ” …но это очень нелинейные наборы данных… “, вспомним, что “ЛИНЕЙНЫЙ” в модели линейной регрессии относится к коэффициентам, а не к степени признаков. Функции (или независимые переменные) могут быть любой степени или даже трансцендентными функциями, такими как экспоненциальные, логарифмические, синусоидальные. И удивительно большое количество природных явлений может быть смоделировано (приблизительно) с помощью этих преобразований и линейной модели.

Итак, допустим, мы получаем следующий набор данных, который имеет один выход и 3 функции. Мы снова показываем сюжеты, но, как и ожидалось, они мало помогают.

Поэтому мы решили изучить линейную модель с до некоторой степени полиномиальными членами высокой степени, чтобы соответствовать набору данных. Сразу возникает несколько вопросов:

— как решить, до каких полиномов нужно

— когда остановиться, если мы начнем с включения терминов 1-й степени, 2-й степени, 3-й степени один за другим?

— как решить, важны ли какие-либо из кросс-связанных терминов, т. Е. Нужны ли нам только термины _X_12, _X_23 или _X_1._X_2 и _X_12.X3?

— И, наконец, нужно ли нам вручную писать уравнения/функции для всех этих полиномиальных преобразований и добавлять их в набор данных?

Потрясающая библиотека машинного обучения Python в помощь

К счастью, scikit-learn , потрясающая библиотека машинного обучения, предлагает готовые классы/объекты, чтобы ответить на все вышеперечисленные вопросы простым и надежным способом.

Вот простое видео обзора линейной регрессии с использованием scikit-learn и вот хорошая средняя статья для вашего обзора . Но в этой статье мы рассмотрим гораздо больше, чем просто линейную подгонку, поэтому, пожалуйста, читайте дальше . Весь код котельной плиты для этой статьи доступен здесь, в моем репо GitHub .

Мы начинаем с импорта нескольких соответствующих классов из scikit-learn,

# Import function to create training and test set splits
from sklearn.cross_validation import train_test_split

# Import function to automatically create polynomial features! 
from sklearn.preprocessing import PolynomialFeatures

# Import Linear Regression and a regularized regression function
from sklearn.linear_model import LinearRegression
from sklearn.linear_model import LassoCV

# Finally, import function to make a machine learning pipeline
from sklearn.pipeline import make_pipeline

Давайте быстро определим/перечислим необходимые концепции, которые мы будем использовать/реализовывать далее.

Train/Test split : Это означает создание двух наборов данных из одного набора, который у нас есть. Один из них (Обучающий набор) будет использоваться для построения модели, а другой (Тестовый набор) будет использоваться исключительно для проверки точности и надежности модели. Это важно для любой задачи машинного обучения, так что мы не создаем модель со всеми нашими данными и думаем, что модель очень точна (потому что она “видела” все данные и хорошо вписалась), но она плохо работает, когда сталкивается с новыми (“невидимыми”) данными в реальном мире . Точность на тестовом наборе имеет гораздо большее значение, чем точность на тренировочном наборе. Вот хорошая средняя статья на всю эту тему для вашего обзора. А ниже вы можете посмотреть, как пионер Google Car Себастьян Тран рассказывает об этой концепции.

Автоматическая генерация полиномиальных объектов : Scikit-learn предлагает аккуратный способ генерации полиномиальных объектов из набора линейных объектов. Все, что вам нужно сделать, это передать линейные объекты в список и указать максимальную степень, до которой вы хотите генерировать члены полиномиальной степени. Это также дает вам выбор генерировать все члены взаимодействия перекрестной связи или только полиномиальные степени основных признаков. Вот пример описания кода Python .

Регуляризованная регрессия : Важность регуляризации трудно переоценить, поскольку она является центральным понятием в машинном обучении. В условиях линейной регрессии основная идея состоит в том, чтобы наказать коэффициенты модели таким образом, чтобы они не росли слишком большими и не перекрывали данные, то есть сделать модель чрезвычайно чувствительной к шуму в данных. Существует два типа широко используемых методов регуляризации, из которых мы используем метод, называемый ЛАССО. Вот хороший обзор по обоим типам методов регуляризации.

Конвейер машинного обучения : Проект машинного обучения (почти) никогда не является единственной задачей моделирования. В своей наиболее распространенной форме она состоит из генерации/приема данных, очистки и преобразования данных, подгонки моделей, перекрестной проверки, тестирования точности моделей и окончательного развертывания . Вот ответ Quora красиво резюмирующий концепцию. Или, вот соответствующая статья Medium . Или еще одна хорошая статья, обсуждающая важность трубопроводной практики. Scikit-learn предлагает функцию конвейера , которая может объединять несколько моделей и классов предварительной обработки данных вместе и превращать ваши необработанные данные в полезные модели.

Если у вас есть время, посмотрите это длинное (1 час +) видео с конференции PyData (Даллас, 2015), чтобы увидеть все это в действии.

Как построить надежную модель, собрав все это вместе?

Итак, вот снимок шаблонного кода. Вы должны изменить его, чтобы он работал правильно для вашего набора данных.

# Alpha (regularization strength) of LASSO regression
lasso_eps = 0.0001
lasso_nalpha=20
lasso_iter=5000

# Min and max degree of polynomials features to consider
degree_min = 2
degree_max = 8

# Test/train split
X_train, X_test, y_train, y_test = 
train_test_split(df['X'], df['y'],test_size=test_set_fraction)

# Make a pipeline model with polynomial transformation and LASSO regression with cross-validation, run it for increasing degree of polynomial (complexity of the model)

for degree in range(degree_min,degree_max+1): 
  model = make_pipeline(PolynomialFeatures(degree, interaction_only=False),LassoCV(eps=lasso_eps,n_alphas=lasso_nalpha,max_iter=lasso_iter,normalize=True,cv=5)) 
    model.fit(X_train,y_train) 
    test_pred = np.array(model.predict(X_test))
    RMSE=np.sqrt(np.sum(np.square(test_pred-y_test))) 
    test_score = model.score(X_test,y_test)

Но эй, код-это для машин! Для простого человека нам нужны липкие заметки. Итак, вот аннотированная версия того же самого с примечаниями и комментариями

Чтобы дистиллировать его дальше, вот поток в более формальных терминах…

Давайте обсудим результаты!

Для всех моделей мы также фиксируем ошибку тестирования, ошибку обучения (среднеквадратичную) и обычный коэффициент R2 в качестве меры точности модели. Вот как они выглядят после нашего заговора,

Эти сюжеты отвечают на два наших предыдущих вопроса:

  • Нам действительно нужен полином 4-й или 5-й степени, чтобы смоделировать это явление. Линейные, квадратичные или даже кубические модели не являются достаточно сложными для подгонки данных.
  • Однако нам не нужно выходить за пределы 5-й степени и чрезмерно усложнять модель. Подумайте об этом как о границе бритвы Оккама для нашей модели.

Но, эй, где же знакомый компромисс смещения/дисперсии (он же underfit/overfit) в этой кривой? Почему ошибка теста не резко возрастает для слишком сложных моделей?

Ответ заключается в том, что используя регрессию ЛАССО, мы по существу исключаем члены более высокого порядка в более сложных моделях . Для получения более подробной информации и некоторых фантастических интуитивных рассуждений о том, почему это происходит, пожалуйста, прочтите эту статью или посмотрите следующее видео. На самом деле, это одно из ключевых преимуществ регрессии ЛАССО или штрафа L1-нормы, заключающееся в том, что она устанавливает некоторые коэффициенты модели точно в ноль, а не просто сжимает их. Фактически, это делает ” автоматический выбор функции ” для вас, т. е. пусть вы автоматически игнорируете несущественные функции, даже если вы начинаете с очень сложной модели, чтобы соответствовать данным.

Мы можем легко проверить это, НЕ выполняя регуляризацию и используя простой класс модели линейной регрессии из scikit-learn . Вот результат в этом случае. Знакомая форма смещения-дисперсии появляется для графика зависимости сложности модели от ошибки.

Итак, что же происходит с зашумленными данными?

Вы можете скачать мой код и попробовать изменить параметр noise_magnitude , чтобы увидеть влияние добавления шума в набор данных. Шум мешает модели быть свободной от смещения, а также подталкивает модель к переоснащению, потому что модель пытается разобраться в шумных паттернах данных и вместо того, чтобы обнаружить реальный паттерн, приспосабливается к шуму. В принципе, простая линейная регрессионная модель (без регуляризации) может с треском провалиться в этом состоянии. Регуляризованная модель по-прежнему работает хорошо, но компромисс между смещением и дисперсией начинает проявляться даже для производительности регуляризованной модели. Вот краткое содержание,

Эпилог

Итак, вкратце, мы обсудили методический способ подгонки многомерных регрессионных моделей к набору данных с сильно нелинейными и взаимно связанными членами в присутствии шума. Мы видели, как мы можем использовать преимущества библиотеки машинного обучения Python для генерации полиномиальных функций, нормализации данных, подгонки модели, предотвращения слишком больших коэффициентов, тем самым поддерживая компромисс между смещением и дисперсией, и построения регрессионного балла для оценки точности и надежности модели.

Для более продвинутых типов моделей с неполиномиальными функциями вы можете проверить регрессию ядра и Регрессор опорных векторов модели из стабильной версии scikit-learn. Кроме того, проверьте эту красивую статью о регрессии гауссова ядра .

Если у вас есть какие-либо вопросы или идеи, которыми вы хотите поделиться, пожалуйста, свяжитесь с автором по адресу tirthajyoti[AT]gmail[DOT]com . Вы можете проверить авторские репозитории GitHub на наличие других забавных фрагментов кода в Python, R или MATLAB и ресурсах машинного обучения. Кроме того, если вы, как и я, увлечены машинным обучением/наукой о данных/полупроводниками, пожалуйста, не стесняйтесь добавить меня в LinkedIn или следовать за мной в Twitter .