Практическое руководство по подготовке данных для алгоритмов машинного обучения

В частях 1 и 2 этой серии мы обсудили анализ данных и разработку новых функций, которые улучшат наши прогностические модели.

В этом посте будет представлена ​​концепция предварительной обработки данных.

Что такое предварительная обработка данных

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

В своем путешествии по науке о данных вы поймете, что в большинстве задач анализ ваших данных (EDA) составляет 70–80% работы, предварительная обработка ваших данных составляет около 5–10%, а построение ваших моделей — 15–20%.

Существует много аспектов предварительной обработки данных в зависимости от ваших данных, но в этом посте мы будем иметь дело только с двумя из-за характера наших данных.

  1. Отказ от ненужных функций
  2. Масштабирование наших данных

В предыдущем посте мы наблюдали в наших данных о недвижимости, что такие характеристики, как price_per_floor, sqft_living, класс и sqft_above, показывают высокую линейную корреляцию с нашим целевым ярлыком, ценой. Другие функции, такие как почтовый индекс, состояние, is_renovated, yr_renovated, long, waterfront и т. д., плохо коррелируют друг с другом.

Помните, что коэффициент 1 показывает идеальную положительную корреляцию или прямую связь между двумя переменными.

На изображении выше многие функции плохо коррелированы, мы удалим их из наших данных и будем использовать только высококоррелированные функции для построения модели (в данном случае коэффициент корреляции не менее 0,4).

Отбрасывание объектов с плохой линейной корреляцией с ценой

house_data_7 = house_data_6.drop(['price_per_view', 'sqft_lot15', 'long', 
                                  'waterfront', 'condition', 'zipcode',
                                 'yr_renovated', 'is_renovated', 'Basement', 
                                 'Home_Age', 'yr_built', 'sqft_living15',
                                 'sqft_basement', 'bathrooms',
                                 'lat', 'bedrooms', 'Total_Area', 
                                 'floors', 'view'],axis=1)

Здесь мы удалили все функции с коэффициентом корреляции менее 0,4, используя функцию Pandas drop(), и установили ось для обозначения столбцов (1 = столбцы и 0 = строки).

Давайте проверим наличие нулевых значений в наших данных.

house_data_7.isnull().sum()

Из приведенного выше вывода мы видим, что нулевых значений нет. давайте проверим форму данных;

house_data_7.shape

И вот, у нас осталось 8 наиболее коррелированных признаков.

Масштабирование наших данных

Возможно, вы слышали это слово раньше, но почему мы масштабируем наши данные?

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

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

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

Масштабирование особенно важно в таких задачах регрессии, как эта.

Существуют разные типы скалеров

  1. Стандартный масштабатор
  2. Минимальный-максимальный масштаб
  3. Надежный масштабатор
  4. Максимальное абсолютное масштабирование
  5. Нормализатор

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

Например, для нашей модели, которая будет основана на предсказании цены, если одна из характеристик имеет широкий диапазон значений(), прогнозируемая цена будет определяться этой конкретной характеристикой.

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

Теперь давайте посмотрим, как мы можем использовать стандартный масштабатор для масштабирования наших функций. Мы будем использовать встроенный стандартный масштабатор Sci-kit Learn, но сначала мы разделим наши данные на функции и цель, используя X для функций и Y для цели, а затем разделите на обучающие и тестовые данные, снова используя метод обучения-тестирования-разделения Sci-kit.

target = house_data_10["price"]
features = house_data_10.drop("price", axis = 1)


from sklearn.preprocessing import StandardScaler
from sklearn.model_selection import train_test_split

X_train, X_test, Y_train, Y_test = train_test_split(features, target, 
                                                    test_size = 0.3,
                                                    random_state = 1)

Из приведенного выше кода мы разделили наши данные на размер обучения 70% и размер теста 30%. Важно разделить ваши данные на наборы обучения и тестирования, чтобы оценить, как ваша модель будет работать с новыми данными, чтобы убедиться, что она не переоснащать ваши тренировочные данные. Затем мы масштабируем наши данные со следующими кодами;

sc = StandardScaler() #instantiating Standard scaler
X_train_sc = pd.DataFrame(sc.fit_transform(X_train))
X_test_sc = pd.DataFrame(sc.transform(X_test))

Вам может быть интересно, почему мы вызвали fit_transform() для обучающих данных, а transform() для тестовых данных, и почему мы не подогнали или не преобразовали метку target(y) .

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

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

И если вы масштабируете свою целевую метку, то ваша целевая переменная метки, а не естественная шкала, такая как «целые числа», будет иметь шкалу с единицами стандартного отклонения, найденными в вашем образце функций, которые будет трудно прочитать. Кроме того, наши модели машинного обучения не используют целевую метку для прогнозирования (это было бы мошенничеством🙃).

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

Выбор моделей

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

Теперь давайте попробуем некоторые регрессоры,

1.)Линейная регрессия

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

Мы построим простой линейный регрессор, отказавшись от научного обучения;

from sklearn.linear_model import LinearRegression
LR = LinearRegression()
LR.fit(X_train_sc, y_train)
pred = LR.predict(X_train_sc)

Здесь мы импортируем линейную регрессию, создаем ее экземпляр и подгоняем наши функции поезда и цель, затем мы вызываем прогнозирование для наших функций поезда, и все готово.

Мы можем проверить общую производительность нашей модели, используя две метрики: оценку rsquared(r2) и среднеквадратичную ошибку (RMSE);

from sklearn.metrics import mean_squared_error, r2_score
lr_mse = mean_squared_error(Y_train, pred)
lr_rmse = np.sqrt(lr_mse)
lr_rmse

И наша стратегия такова;

Это означает, что в среднем мы ошибаемся примерно на 67 тысяч долларов (ниже или выше) от реальной цены в нашем прогнозе. Теперь это хорошо? Что ж, давайте проверим метку цели нашего поезда;

Y_train.describe()

Средняя цена дома составляет 431 тысяч долларов, а 75% домов стоят выше 310 тысяч долларов, в то время как дом с самой низкой ценой в данных стоит около 80 тысяч долларов. Это означает, что наша средняя ошибка ниже или выше реальной цены в 67 тысяч долларов составляет не более 10 % для 25 % домов (верхний 25 % квартиль), не более 19 % для средних 25 % домов и около 80 % для самый дешевый дом.

Неплохо, но вы, вероятно, не захотите платить за свой дом на 10–19% выше рыночной стоимости, так что, возможно, это тоже не совсем хороший прогноз. мы можем проверить r2_score с помощью следующего кода;

r2_score(Y_train, pred)

R-квадрат – это статистическая мера, отражающая степень соответствия регрессионной модели. Его значение находится в диапазоне от 0 до 1. Мы получаем, что r2 равно 1, когда модель полностью соответствует данным и нет разницы между прогнозируемым значением и фактическим значением. И мы получаем, что r2 равно 0, когда модель не предсказывает никакой изменчивости данных и не изучает никакой связи между зависимыми и независимыми переменными.

Таким образом, наша оценка 0,94 выше показывает почти идеальное соответствие между прогнозируемым и фактическим значением, т. е. 94% наших признаков могут объяснить связь с ценой дома, и что большая ошибка, которую мы получили в RMSE, может быть результатом некоторых выбросов. ошибки.

Далее давайте оценим тестовые данные;

lr_test = LR.predict(X_test_sc)
LR_mse = mean_squared_error(Y_test, lr_test)
LR_rmse = np.sqrt(LR_mse)
LR_rmse

Наша модель работает так же на тестовых данных, когда вы наблюдаете за ее описательной статистикой, как и с обучающими данными, с увеличением средней ошибки цены на 200 долларов (незначительно).

Снова проверяем r2_score

r2_score(Y_test, lr_test)

Опять же, оценка rsquared аналогична нашей тренировочной выборке.

2. Стохастический регрессор градиентного спуска

SGDRegressor — это алгоритм машинного обучения в Sci-kit Learn, который реализует стохастический градиентный спуск (SGD) для решения задач регрессии. Это популярный выбор для крупномасштабных задач регрессии из-за его способности обрабатывать многомерные наборы данных и быстрого обучения.

SGD Regressor работает, беря набор данных в качестве входных данных, а затем используя свой алгоритм градиентного спуска, чтобы найти наиболее подходящую линию данных. Затем с помощью этой линии делаются прогнозы. Алгоритм представляет собой итеративный процесс, и каждая итерация находит более подходящую линию с большей точностью, пока не будет достигнута наилучшая точность.

Давайте введем простой SGDR

rom sklearn.linear_model import SGDRegressor
sd = SGDRegressor()
sd.fit(X_train_sc, Y_train)
sd_pred = sd.predict(X_train_sc)

sd_mse = mean_squared_error(Y_train, sd_pred)
sd_rmse = np.sqrt(sd_mse)
sd_rmse

Очень похоже на результат линейной регрессии, что понятно, поскольку это небольшой набор данных. Проверка оценки rsquared;

r2_score(Y_train, sd_pred)

И тестирование на новых данных,

SD_pred = sd.predict(X_test_sc)

SD_mse = mean_squared_error(Y_test, SD_pred)
SD_rmse = np.sqrt(SD_mse)
SD_rmse

Опять же, чуть выше, чем набор поезда.

3. Случайный регрессор леса

Представьте, что вы просите одну женщину угадать цену автомобиля, а затем вы просите 100 человек угадать ее. У вас больше шансов получить правильный прогноз, если 100 человек угадают?

Просто так работает случайный лес, но этот «простой» алгоритм является одним из самых мощных доступных инструментов машинного обучения.

Давайте построим простой регрессор случайного леса,

from sklearn.ensemble import RandomForestRegressor
rf_reg = RandomForestRegressor()
rf_reg.fit(X_train_sc, Y_train)

#predicting on training set
rf_pred = rf_reg.predict(X_train_sc)
rf_mse = mean_squared_error(Y_train, rf_pred)
rf_rmse = np.sqrt(rf_mse)
rf_rmse

Теперь посмотри на это! Random Forest вышел с ошибкой чуть менее 11 тысяч долларов, самой низкой ошибкой на данный момент, как я уже сказал, это мощный алгоритм машинного обучения.

Проверяя свой показатель rsquared,

r2_score(Y_train, rf_pred)

Идеально подходит!

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

rfr_pred = rf_reg.predict(X_test_sc)

rfr_mse = mean_squared_error(Y_test, rfr_pred)
rfr_rmse = np.sqrt(rfr_mse)
rfr_rmse

Вот оно, оно превосходит тренировочные данные, но, тем не менее, дает нам наилучшие результаты на новых данных.

Опять же, вы можете проверить оценку rsquared,

r2_score(Y_test, rfr_pred)

Почти идеальная посадка.

4.) Регрессор XGBoost

С момента своего появления в 2014 году XGBoost стал предпочтительным алгоритмом машинного обучения для специалистов по данным и инженеров по машинному обучению. Это библиотека с открытым исходным кодом, которая может обучать и тестировать модели на больших объемах данных. Он использовался во многих областях, от прогнозирования рейтинга кликов по объявлениям до классификации явлений физики высоких энергий. XGBoost — это реализация градиентных деревьев решений, в большинстве случаев не требующая оптимизации параметров или настройки, а значит, может быть использована сразу.

Давайте создадим простой регрессор xgboost

from xgboost import XGBRegressor
xgb = XGBRegressor()
xgb.fit(X_train_sc, Y_train)
xgb_pred = xgb.predict(X_train_sc)
xgb_mse = mean_squared_error(Y_train, xgb_pred)
xgb_rmse = np.sqrt(xgb_mse)
xgb_rmse

Средняя ошибка всего в 8 000 долларов — это поразительно, это дает нам самые высокие результаты на данный момент.

Оценивая тестовые данные,

XGB_pred = xgb.predict(X_test_sc)
XGB_mse = mean_squared_error(Y_test, XGB_pred)
XGB_rmse = np.sqrt(XGB_mse)
XGB_rmse

Как и случайный лес, он превосходит тренировочный набор, но по-прежнему дает наилучшую производительность.

5.) Регрессор AdaBoost

AdaBoost, также называемый Adaptive Boosting, представляет собой метод машинного обучения, используемый в качестве ансамблевого метода. Он работает, собирая различные классификаторы, а затем выбирая лучший прогноз, как регрессор голосования.

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

Наиболее распространенной оценкой, используемой с AdaBoost, являются деревья решений с одним уровнем, что означает деревья решений только с 1 разделением. Эти деревья также называют пнями решений.

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

Давайте посмотрим, что мы делали выше, чтобы понять это: мы построили линейный регрессор с прогнозом, который в среднем отличается на 67 тысяч долларов, затем мы попробовали SGDR и получили еще одну ошибку в 67 тысяч долларов, мы видим, что среднеквадратичное значение примерно такое же. когда мы построили две разные модели на одном и том же наборе данных, но что, если мы используем комбинации всех этих двух алгоритмов выше, чтобы сделать окончательный прогноз? В большинстве случаев мы можем увеличить мощность предсказания таким образом.

Давайте построим простой регрессор AdaBoost со встроенным деревом решений,

from sklearn.ensemble import AdaBoostRegressor
from sklearn.tree import DecisionTreeRegressor

ada_reg = AdaBoostRegressor(DecisionTreeRegressor(),learning_rate=0.1)
ada_reg.fit(X_train_sc, Y_train)

Мы устанавливаем скорость обучения на 0,1, чтобы дать нашей модели больше времени для изучения данных.

ada_pred = ada_reg.predict(X_train_sc)
ada_mse = mean_squared_error(Y_train, ada_pred)
ada_rmse = np.sqrt(ada_mse)
ada_rmse

Ошибка всего $7! но не стоит сильно заморачиваться, модель, скорее всего, переобучает тренировочные данные, давайте оценим тестовые данные,

Ada_pred = ada_reg.predict(X_test_sc)
Ada_mse = mean_squared_error(Y_test, Ada_pred)
Ada_rmse = np.sqrt(Ada_mse)
Ada_rmse

Да, это было переоснащением. Но он по-прежнему работает лучше всех используемых моделей.

Есть много других регрессоров, которые вы можете попробовать, включая машинный регрессор опорных векторов, регрессор K ближайших соседей, регрессор Softmax, лассо и др.

Сравнение всех используемых моделей

В поезде, как и следовало ожидать в большинстве случаев, ансамблевые модели показали себя намного лучше. Лучше всего показал себя AdaBoost, за ним следуют XGBoost и RandomForest, и SGDR, и линейная регрессия показали одинаковые результаты.

На тестовом наборе,

Хотя AdaBoost по-прежнему работает лучше всего, XGBoost и Random Forest не сильно отстают. И SGD, и линейная регрессия снова показали одинаковую производительность.

На этапе обучения вам, вероятно, следует меньше использовать ансамблевые модели, чтобы оценить, насколько хорошо вы очищаете данные.

Заинтересованы в данных, нажмите здесь, чтобы просмотреть репозиторий кода

Нашли эту статью вдохновляющей? Следуйте за мной на Medium

Свяжитесь со мной в Twitter

Свяжитесь со мной на Kaggle