Прогнозирование времени тестирования автомобилей с использованием модели машинного обучения

В этом блоге я демонстрирую свою работу над формулировкой проблемы Mercedes-Benz Greener Manufacturing ».

Начиная с первого автомобиля, Benz Patent Motor Car в 1886 году, Mercedes-Benz олицетворяет важные автомобильные инновации. К ним относятся, например, ячейка безопасности пассажира с зоной деформации, подушка безопасности и интеллектуальные вспомогательные системы. Mercedes-Benz подает почти 2000 патентов в год, что делает бренд европейским лидером среди производителей автомобилей премиум-класса. Автомобили Mercedes-Benz, выпускаемые Daimler, являются лидерами в автомобильной промышленности премиум-класса. Благодаря огромному выбору функций и опций клиенты могут выбрать индивидуализированный Mercedes-Benz своей мечты.

Итак, прежде чем начинать, давайте просто разберемся в процессе этой работы,

Содержание:

  1. Бизнес-проблема
  2. Сопоставление бизнес-проблемы с проблемой машинного обучения
  3. Показатель производительности
  4. Загрузка данных и EDA (исследовательский анализ данных)
  5. Функциональная инженерия
  6. Существующие подходы
  7. Мой первый подход
  8. Модели машинного обучения
  9. Сравнение моделей
  10. Конечный конвейер ML
  11. Будущие расширения
  12. использованная литература

А теперь приступим,

1. Деловая проблема:

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

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

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

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

1.1 Бизнес-цели и ограничения

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

2. Сопоставление бизнес-проблемы с проблемой машинного обучения:

2.1 Данные

2.1.1 Обзор данных

Этот набор данных содержит анонимный набор переменных, каждая из которых представляет собой особенность автомобиля Mercedes. Например, переменной может быть 4WD, добавленная пневмоподвеска или проекционный дисплей.

Абсолютная истина помечена как «y» и представляет время (в секундах), которое потребовалось автомобилю, чтобы пройти тестирование по каждой переменной.

У нас есть два файла, разделенных запятыми:

  • train.csv - содержит обучающий набор из 4209 строк (точек данных) и 378 столбцов (функций) с ярлыками.
  • test.csv - содержит набор тестов с 4209 строками (точками данных) и 377 столбцами (функциями) без ярлыков.

Столбцы:

Ссылка на набор данных: https://www.kaggle.com/c/mercedes-benz-greener-manufacturing/data

2.2 Сопоставление реальной проблемы с проблемой машинного обучения

2.2.1 Тип задачи машинного обучения

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

3. Показатель эффективности:

Теперь, когда мы знаем, что это проблема регрессии машинного обучения, мы должны использовать соответствующую метрику для оценки производительности нашей модели прогнозирования. Здесь уже дано в конкурсе использовать метрику R² для оценки. R² также известен как коэффициент детерминации, R-квадрат дает процентное изменение «y» (время тестирования в данном случае), объясняемое «x-переменными» (в данном случае комбинацией пользовательских функций автомобиля). Проще говоря, R² дает нам процент точек данных, попадающих в линию регрессии. Чем выше значение R², тем выше будут точки данных, попадающие в линию. Например, если значение R² равно 0,66, это означает, что 66% точек данных лежат в пределах линии регрессии от общих точек данных. Математически R² обозначается следующим образом:

Есть 4 случая для значений R²:

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

Как я объяснил в четырех приведенных выше случаях, мы можем видеть, что метрика R² находится в диапазоне от -∞ до 1, поскольку -∞ оценка R² является худшей, а оценка 1 R² - лучшей моделью. Кроме того, в очень редких случаях R² может быть отрицательным, поэтому обычно мы получаем оценку R² от 0 до 1. Таким образом, для метрики R² верхняя граница равна 1, но в случае RMSE и MAE оценка варьируется от 0 до ∞. (бесконечность) нет верхней границы, поэтому нам будет сложно сравнить модель с оценкой базовой модели. Преимущество использования метрики R² заключается в том, что она имеет верхнюю границу 1, за которой оценка не может увеличиваться, поэтому мы можем сравнивать оценку нашей модели с оценкой базовой модели, поэтому в этой задаче метрика R² предпочтительнее, чем RMSE и MAE.

4. Загрузка данных и EDA (исследовательский анализ данных):

4.1 Загрузка данных:

Используя библиотеку pandas, загрузите имеющиеся у нас наборы данных в формате CSV:

  • Здесь мы видим, что 4209 точек данных индексируются от 0 до 4208 и 378 столбцов / функций.

В наборе данных есть три типа данных:

  • float64 (1): Зависимая функция, время тестирования в секундах
  • int64 (369): Независимые двоичные функции
  • объект (8): Независимые категориальные признаки

  • Здесь мы видим, что 4209 точек данных индексируются от 0 до 4208 и 377 столбцов / функций.

В наборе данных есть три типа данных:

  • int64 (369): Независимые двоичные функции
  • объект (8): Независимые категориальные признаки

Мы видим, что у нас одинаковое количество точек данных в наборе данных для поезда и в тестовом наборе.

А теперь давайте начнем собственно EDA,

4.2 Статистическое описание ID и зависимых переменных:

Сначала я проверю значение отсутствующих значений во всем наборе данных,

Давайте также проверим повторяющиеся строки,

Теперь давайте проверим, есть ли повторяющиеся значения в столбце «ID»,

4.3 Проверьте распределение зависимой переменной:

  • Из этих двух графиков я вижу, что большинство точек принадлежат диапазону от 75 до 150 секунд. Здесь мы видим крайнюю точку, на тестирование которой уходит более 250 секунд. Возможно, эта конфигурация автомобиля является той, которую покупают очень редко, также может быть довольно дорогой, и поэтому у нас есть только одна такая точка данных, доступная здесь. Мы можем с уверенностью рассматривать это как выброс, потому что это только одна точка, которая находится далеко от других.
  • Теперь я обнаружил один выброс, нам нужно проверить, нет ли других выбросов. Для этого давайте определим процентили времени тестирования, а затем я определю порог для допустимых точек данных на основе этого. Теперь я просто проверю только 90-й процентиль на 100-й процентиль.
90.0th percentile:  115.25
91.0th percentile:  116.0484
92.0th percentile:  116.89160000000001
93.0th percentile:  118.0376
94.0th percentile:  119.056
95.0th percentile:  120.80600000000001
96.0th percentile:  122.4
97.0th percentile:  125.89319999999998
98.0th percentile:  129.2992
99.0th percentile:  137.4304
100th percentile:  265.32

Я уже объявил значение 100-го процентиля, то есть 265,32, как выброс, теперь давайте проверим 99-й процентиль на 99,99-й процентиль, чтобы определить порог.

99.0th percentile:  137.4304
99.1th percentile:  139.09024
99.2th percentile:  140.1836
99.3th percentile:  140.81639999999993
99.4th percentile:  142.6480000000001
99.5th percentile:  146.23040000000006
99.6th percentile:  149.0374399999998
99.7th percentile:  151.4276800000003
99.8th percentile:  154.68695999999994
99.9th percentile:  160.38328000000087

Давайте возьмем 155 в качестве порогового времени и рассмотрим значения, превышающие 155, как выбросы.

4.4 Анализ независимых характеристик:

- We have total 8 categorical features.
- We have total 368 Binary features.

4.4.1 Анализ категориальных признаков:

Построим коробчатую диаграмму для каждого категориального признака,

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

  • Мы видим, что после удаления выбросов (экстремальных значений «y») набор данных выглядит намного чище.
  • Характеристики X0, X1, X2, X3, X5, X6, X8 содержат некоторую важную информацию, поскольку их дисперсия довольно высока.
  • Функция X4, похоже, имеет очень меньшую вариативность, что означает, что она содержит очень мало информации.

Следовательно, я могу с уверенностью удалить X4 из набора данных из-за его низкой дисперсии (меньше информации).

4.4.2 Анализ двоичных функций:

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

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

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

Теперь давайте проверим признаки, которые имеют 0 отклонений и одинаковое отклонение.

There following 13 features having 0 variance:

['X11' 'X93' 'X107' 'X233' 'X235' 'X268' 'X289' 'X290' 'X293' 'X297'
 'X330' 'X339' 'X347']
There following 53 features having same variance:

['X35' 'X37' 'X39' 'X57' 'X76' 'X84' 'X94' 'X102' 'X113' 'X119' 'X120'
 'X122' 'X130' 'X134' 'X136' 'X146' 'X147' 'X157' 'X172' 'X194' 'X199'
 'X205' 'X213' 'X214' 'X216' 'X222' 'X226' 'X227' 'X232' 'X239' 'X242'
 'X243' 'X244' 'X245' 'X247' 'X248' 'X253' 'X254' 'X262' 'X263' 'X266'
 'X279' 'X296' 'X299' 'X302' 'X320' 'X324' 'X326' 'X360' 'X364' 'X365'
 'X382' 'X385']
  • Из приведенного выше анализа категориальных функций и двоичных функций я пришел к выводу, что могу отбросить функции, которые имеют нулевую дисперсию, такую ​​же дисперсию и те, которые имеют очень небольшую дисперсию. Потому что их низкая дисперсия не сильно повлияет на прогнозирование времени тестирования при моделировании. Теперь я соберу все черты, которые нужно отбросить, вместе.
  • Вот всего 67 функций, которые я могу отбросить:
['X4', 'X11', 'X93', 'X107', 'X233', 'X235', 'X268', 'X289', 'X290', 'X293', 'X297', 'X330', 'X339', 'X347', 'X35', 'X37', 'X39', 'X57', 'X76', 'X84', 'X94', 'X102', 'X113', 'X119', 'X120', 'X122', 'X130', 'X134', 'X136', 'X146', 'X147', 'X157', 'X172', 'X194', 'X199', 'X205', 'X213', 'X214', 'X216', 'X222', 'X226', 'X227', 'X232', 'X239', 'X242', 'X243', 'X244', 'X245', 'X247', 'X248', 'X253', 'X254', 'X262', 'X263', 'X266', 'X279', 'X296', 'X299', 'X302', 'X320', 'X324', 'X326', 'X360', 'X364', 'X365', 'X382', 'X385']

Теперь давайте просто узнаем некоторые важные двоичные файлы с помощью модели случайного леса и выполним визуальный EDA только для этих функций. Я обучил модель RandomForest двоичным функциям и использовал атрибут ‘feature_importances_’, чтобы получить важные функции.

These are top 8 binary features :
 ['X314', 'X315', 'X118', 'X29', 'X54', 'X189', 'X46', 'X127']

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

  • Для функций «X314», «X315», «X118», «X189», когда они присутствуют в конфигурации автомобиля, большинство конфигураций требует больше времени для тестирования.
  • Для функций «X29», «X54», «X127» конфигурации, в которых эти функции отсутствуют, обычно требуют больше времени для тестирования.
  • Для «X46» конфигурации проходят почти одинаковое тестирование, когда оно присутствует, а также когда его нет в конфигурации.

4.4.3 Резюме EDA:

  • В наборе данных нет значений NaN
  • В наборе данных нет повторяющихся строк
  • Обрезана зависимая переменная на 155 в качестве порогового времени и все значения выше 155 рассматриваются как выбросы.
  • Удалена категориальная функция с низкой дисперсией: [‘X4’]
  • Удалены двоичные функции с нулевой дисперсией: ['X11', 'X93', 'X107', 'X233', 'X235', 'X268', 'X289', 'X290', 'X293', 'X297', 'X330' , 'X339', 'X347']
  • Удалены одинаковые двоичные функции дисперсии: ['X35', 'X37', 'X39', 'X57', 'X76', 'X84', 'X94', 'X102', 'X113', 'X119', 'X120' , 'X122', 'X130', 'X134', 'X136', 'X146', 'X147', 'X157', 'X172', 'X194', 'X199', 'X205', 'X213', ' X214, X216, X222, X226, X227, X232, X239, X242, X243, X244, X245, X247, X248 , «X253», «X254», «X262», «X263», «X266», «X279», «X296», «X299», «X302», «X320», «X324», «X326», » X360, X364, X365, X382, X385]

5. Разработка функций:

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

Я использую LabelEncoder для кодирования категориальных функций

5.1.1 Закодируйте набор данных для обучения и тестирования:

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

Теперь давайте создадим несколько новых функций,

5.2 PCA (анализ главных компонентов):

PCA двоичных функций

5.3 SVD (разложение по сингулярным значениям):

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

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

Если X ∈ R ^ n × m прямоугольное и m ‹n, то соотношение сторон

β = m/n

Когда шум неизвестен, нет решения для ‘τ’ в замкнутой форме, и его необходимо аппроксимировать численно,

Для неизвестного шума и прямоугольной матрицы X ∈ R ^ n × m оптимальный жесткий порог определяется выражением:

σ med - среднее сингулярное значение

Здесь ω (β) = λ (β) / µβ, где µβ - решение следующей задачи:

Медиана µβ и, следовательно, коэффициент ω (β) не доступны аналитически;

Некоторые значения коэффициента ω (β) для удобства приведены в таблице ниже.

Теперь давайте выясним Hard Threshold, используя описанный выше метод.

Теперь, используя указанное выше значение для количества компонентов, добавьте функцию SVD.

СВД бинарных функций

5.4 Взаимодействия:

  • Двустороннее взаимодействие X314, X315
  • Трехстороннее взаимодействие X118, X314, X315

5.5 Гауссовские случайные проекции:

6. Существующие подходы:

6.1 Решение за 11 место:



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

Одна из групп кластеров практически постоянна. Он использовал только двоичные функции для окончательного представления и отказался от всех категориальных функций. Он использовал 4 оценщика Xgboost и настроил их независимо, а затем, используя подмножества функций, объединил окончательный результат. В частной таблице лидеров он набрал 0,55263 балла. Он сохранил настройку для перекрестной проверки, что помогло ему доверять своим выступлениям и достичь этого результата в таблице лидеров. Интересно то, что он отказался от всех категориальных функций и получил гораздо лучшие результаты.

6.2 Алгоритм стекирования машинного обучения для конкурса Mercedes-Benz Greener Manufacturing Competition:



Этот блог написан Эми Ладдадом. Он объясняет, как подошел к проблеме. Вначале он объясняет, что складывается, поскольку весь его подход основан на стеке.

Он обучил три типа моделей, первый - XGboost, и обнаружил, что функции, сгенерированные TSVD, PCA и ICA, эффективно участвуют в прогнозировании, во-вторых, он обучил многослойный персептрон, где он обнаружил, что графики метрик потерь и R2 сходятся через несколько эпох и модель хороша для прогнозирования без переобучения, и, наконец, модель наложения, которая состоит из оценок LassoLarsCV и GradientBoostingRegressor и не включает функции PCA, SVD и ICA для этой модели, суммирование дает лучшие результаты, чем первые две модели.

7. Мой первый подход:

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

б. Итак, теперь данные готовы, и я готов создать базовую регрессионную модель. Я буду использовать KNeighborsRegressor в качестве базовой модели

c. Я проверю его эффективность по данным поездов и резюме, используя метрику R².

d. При обучении базовой модели я сначала буду использовать исходные функции без включения вновь созданных функций. В следующих моделях буду пробовать разные комбинации функций.

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

8. Модели машинного обучения.

8.1 KNeighborsRegressor

Я буду использовать единственный исходный набор данных для этой модели,

import time
start = time.time()
leaf_sizes = list(range(1,50))
neighbors = list(range(1,30))
norms=[1,2]
# create parameters dictionary
parameters = {'leaf_size':leaf_sizes, 'n_neighbors':neighbors, 'p':norms}
#Create a KNN Regressor model
knn = KNeighborsRegressor()
#Tune hyperparameters using RandomizedSearchCV
regressor = RandomizedSearchCV(knn, param_distributions=parameters, verbose=10, n_jobs=-1)
#Fit the model
best_regressor = regressor.fit(X_train, y_train)
# get the best parameters
best_K = best_regressor.best_estimator_.get_params()['n_neighbors']
best_leaf_size = best_regressor.best_estimator_.get_params()['leaf_size']
norm = best_regressor.best_estimator_.get_params()['p']
#Print The best parameters
print('Best K:', best_K)
print('Best leaf_size=', best_leaf_size)
print('Best norm:', norm)
elapsed = time.time() - start
print(f"Time elapsed: {elapsed}")
# Output:
Best K: 13
Best leaf_size= 41
Best norm: 1
Time elapsed: 12.097684621810913
  • Поезд R2 = 0,5817266349749117
  • Тестовый частный R2 = 0,43537
  • Публичный тест R2 = 0,46360

Здесь я использовал KNeighborsRegressor () с RandomizedSearchCV. Эта модель переоснащается исходным набором данных, потому что мы получаем меньшее значение R² как для перекрестной проверки, так и для набора тестирования, чем для обучающего набора.

Давай попробуем другую модель,

8.2 Регрессор дерева решений:

С исходным набором данных,

import time
start = time.time()
depth = [1, 5, 10, 50, 100, 500, 1000]
# create parameters dictionary
parameters = {'max_depth' : depth}
#Create a Decision Tree Regressor model
dtr = DecisionTreeRegressor()
#Tune hyperparameters using RandomizedSearchCV
regressor = RandomizedSearchCV(dtr, param_distributions=parameters, verbose=10, n_jobs=-1)
#Fit the model
best_regressor = regressor.fit(X_train, y_train)
# get the best parameters
best_max_depth = best_regressor.best_estimator_.get_params()['max_depth']

#Print The best parameters
print('Best max_depth:', best_max_depth)
elapsed = time.time() - start
print(f"Time elapsed: {elapsed}")
# output:
Best max_depth: 5
Time elapsed: 2.031101703643799
  • Поезд R2 = 0,6312890285381911
  • Тестовый частный R2 = 0,53732
  • Публичный тест R2 = 0,55129

Здесь я попробовал DecisionTreeRegressor с RandomizedSearchCV, эта модель работает лучше, чем предыдущая модель KnearestRegressor. Теперь давайте попробуем DecisionTreeRegressor с новыми функциями.

8.3 Регрессор дерева решений:

С «Исходным набором данных + PCA + SVD»,

import time
start = time.time()
depth = [1, 3, 5, 10, 50, 100, 500, 1000]

# create parameters dictionary
parameters = {'max_depth' : depth}
#Create a Decision Tree Regressor model
dtr = DecisionTreeRegressor()
#Tune hyperparameters using RandomizedSearchCV
regressor = RandomizedSearchCV(dtr, param_distributions=parameters, verbose=10, n_jobs=-1)
#Fit the model
best_regressor = regressor.fit(train_svd_pca, y_train)
# get the best parameters
best_max_depth = best_regressor.best_estimator_.get_params()['max_depth']

#Print The best parameters
print('Best max_depth:', best_max_depth)
elapsed = time.time() - start
print(f"Time elapsed: {elapsed}")
# Output:
Best max_depth: 3
Time elapsed: 6.751556634902954
  • Поезд R2 = 0,6155964859539103
  • Тестовый частный R2 = 0,53800
  • Публичный тест R2 = 0,55070

Здесь Регрессор дерева решений с «Исходным набором данных + PCA + SVD» дает несколько улучшенные результаты, чем предыдущий.

8.4 Регрессор случайного леса:

С исходным набором данных,

import time
start = time.time()

# Number of trees in random forest
n_estimators = [10, 25, 50, 100, 200, 300, 400, 500]
# Number of features to consider at every split
max_features = ['auto', 'sqrt']
# Maximum number of levels in tree
max_depth = [3, 5, 10, 15, 20, 25, 30]
# Minimum number of samples required to split a node
min_samples_split = [2, 3, 5, 10, 15, 100]
# Minimum number of samples required at each leaf node
min_samples_leaf = [1, 2, 5, 10]

# create parameters dictionary
parameters = {'n_estimators': n_estimators,
               'max_features': max_features,
               'max_depth': max_depth,
               'min_samples_split': min_samples_split,
               'min_samples_leaf': min_samples_leaf}
#Create a Random Forest Regressor model
rf = RandomForestRegressor()
#Tune hyperparameters using RandomizedSearchCV
regressor = RandomizedSearchCV(rf, param_distributions=parameters, verbose=10, n_jobs=-1)
#Fit the model
best_regressor = regressor.fit(X_train, y_train)
# get the best parameters
best_max_depth = best_regressor.best_estimator_.get_params()['max_depth']
best_n_estimators = best_regressor.best_estimator_.get_params()['n_estimators']
best_max_features = best_regressor.best_estimator_.get_params()['max_features']
best_min_samples_split = best_regressor.best_estimator_.get_params()['min_samples_split']
best_min_samples_leaf = best_regressor.best_estimator_.get_params()['min_samples_leaf']
#Print The best parameters
print('Best max_depth:', best_max_depth)
print('Best n_estimators:', best_n_estimators)
print('Best max_features:', best_max_features)
print('Best min_samples_split:', best_min_samples_split)
print('Best min_samples_leaf:', best_min_samples_leaf)

elapsed = time.time() - start
print(f"Time elapsed: {elapsed}")
# Output:
Best max_depth: 5
Best n_estimators: 300
Best max_features: auto
Best min_samples_split: 100
Best min_samples_leaf: 2
Time elapsed: 78.28886032104492
  • Поезд R2 = 0,6290333793346686
  • Тестовый частный R2 = 0,54763
  • Публичный тест R2 = 0,55442

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

8.5 Регрессор случайного леса:

С «Исходным набором данных + PCA + SVD»,

import time
start = time.time()

# Number of trees in random forest
n_estimators = [10, 25, 50, 100, 200, 300, 400, 500]
# Number of features to consider at every split
max_features = ['auto', 'sqrt']
# Maximum number of levels in tree
max_depth = [3, 5, 10, 15, 20, 25, 30]
# Minimum number of samples required to split a node
min_samples_split = [2, 3, 5, 10, 15, 100]
# Minimum number of samples required at each leaf node
min_samples_leaf = [1, 2, 3, 5, 10]

# create parameters dictionary
parameters = {'n_estimators': n_estimators,
               'max_features': max_features,
               'max_depth': max_depth,
               'min_samples_split': min_samples_split,
               'min_samples_leaf': min_samples_leaf}
#Create a Random Forest Regressor model
rf = RandomForestRegressor()
#Tune hyperparameters using RandomizedSearchCV
regressor = RandomizedSearchCV(rf, param_distributions=parameters, verbose=10, n_jobs=-1)
#Fit the model
best_regressor = regressor.fit(train_svd_pca, y_train)
# get the best parameters
best_max_depth = best_regressor.best_estimator_.get_params()['max_depth']
best_n_estimators = best_regressor.best_estimator_.get_params()['n_estimators']
best_max_features = best_regressor.best_estimator_.get_params()['max_features']
best_min_samples_split = best_regressor.best_estimator_.get_params()['min_samples_split']
best_min_samples_leaf = best_regressor.best_estimator_.get_params()['min_samples_leaf']
#Print The best parameters
print('Best max_depth:', best_max_depth)
print('Best n_estimators:', best_n_estimators)
print('Best max_features:', best_max_features)
print('Best min_samples_split:', best_min_samples_split)
print('Best min_samples_leaf:', best_min_samples_leaf)

elapsed = time.time() - start
print(f"Time elapsed: {elapsed}")
# Output:
Best max_depth: 5
Best n_estimators: 500
Best max_features: auto
Best min_samples_split: 100
Best min_samples_leaf: 10
Time elapsed: 290.3807260990143
  • Поезд R2 = 0,6364927215350347
  • Тестовый частный R2 = 0,54145
  • Публичный тест R2 = 0,55076

Эта модель с новыми функциями не так хороша, как модель с оригинальными функциями.

8.6 Регрессор случайного леса:

С «Исходным набором данных + PCA + SVD + GRP + взаимодействия»

start = time.time()

# Number of trees in random forest
n_estimators = [10, 25, 50, 100, 200, 300, 400, 500]
# Number of features to consider at every split
max_features = ['auto', 'sqrt']
# Maximum number of levels in tree
max_depth = [2, 3, 5, 10, 15, 20, 25]
# Minimum number of samples required to split a node
min_samples_split = [2, 3, 5, 10, 15, 25]
# Minimum number of samples required at each leaf node
min_samples_leaf = [1, 2, 3, 5, 10]

# create parameters dictionary
parameters = {'n_estimators': n_estimators,
               'max_features': max_features,
               'max_depth': max_depth,
               'min_samples_split': min_samples_split,
               'min_samples_leaf': min_samples_leaf}
#Create a Random Forest Regressor model
rf = RandomForestRegressor()
#Tune hyperparameters using RandomizedSearchCV
regressor = RandomizedSearchCV(rf, param_distributions=parameters, verbose=10, n_jobs=-1)
#Fit the model
best_regressor = regressor.fit(train_grp_pca_svd_inter, y_train)
# get the best parameters
best_max_depth = best_regressor.best_estimator_.get_params()['max_depth']
best_n_estimators = best_regressor.best_estimator_.get_params()['n_estimators']
best_max_features = best_regressor.best_estimator_.get_params()['max_features']
best_min_samples_split = best_regressor.best_estimator_.get_params()['min_samples_split']
best_min_samples_leaf = best_regressor.best_estimator_.get_params()['min_samples_leaf']
#Print The best parameters
print('Best max_depth:', best_max_depth)
print('Best n_estimators:', best_n_estimators)
print('Best max_features:', best_max_features)
print('Best min_samples_split:', best_min_samples_split)
print('Best min_samples_leaf:', best_min_samples_leaf)

elapsed = time.time() - start
print(f"Time elapsed: {elapsed}")
# Output:
Best max_depth: 5
Best n_estimators: 500
Best max_features: auto
Best min_samples_split: 5
Best min_samples_leaf: 3
Time elapsed: 390.1909713745117
  • Поезд R2 = 0,6527769059803106
  • Тестовый частный R2 = 0,54220
  • Публичный тест R2 = 0,54920

Здесь он работает немного лучше, но не лучше, чем модель с оригинальными характеристиками.

8.7 Регрессор XGBoost:

С «Исходным набором данных + PCA + SVD + GRP + взаимодействия»,

neigh=XGBRegressor(random_state=42, n_jobs=-1) 
parameters = {'learning_rate':[0.001,0.01,0.05,0.1,1], 
              'n_estimators':[100,150,200,500], 
              'max_depth':[2,3,5,10], 
              'colsample_bytree':[0.1,0.5,0.7,1], 
              'subsample':[0.2,0.3,0.5,1], 
              'gamma':[1e-2,1e-3,0,0.1,0.01,0.5,1],             
              'reg_alpha':[1e-5,1e-3,1e-1,1,1e1]} 

reg=RandomizedSearchCV(neigh,parameters,cv=5, scoring='r2', return_train_score=True, n_jobs=-1,
                       verbose=10) 
reg.fit(train_grp_pca_svd_inter, y_train)
best_max_depth = reg.best_estimator_.get_params()['max_depth']
best_n_estimators = reg.best_estimator_.get_params()['n_estimators']
best_colsample_bytree = reg.best_estimator_.get_params()['colsample_bytree']
best_subsample = reg.best_estimator_.get_params()['subsample']
best_gamma = reg.best_estimator_.get_params()['gamma']
best_reg_alpha = reg.best_estimator_.get_params()['reg_alpha']
best_learning_rate = reg.best_estimator_.get_params()['learning_rate']
#Print The best parameters
print('Best max_depth:', best_max_depth)
print('Best n_estimators:', best_n_estimators)
print('Best colsample_bytree:', best_colsample_bytree)
print('Best subsample:', best_subsample)
print('Best reg_alpha:', best_reg_alpha)
print('Best gamma:', best_gamma)
print('Best learning_rate:', best_learning_rate)
# Output:
Best max_depth: 2
Best n_estimators: 100
Best colsample_bytree: 1
Best subsample: 1
Best reg_alpha: 10.0
Best gamma: 0
Best learning_rate: 0.1
  • Поезд R2 = 0,6551805553802594
  • Тестовый частный R2 = 0,54682
  • Публичный тест R2 = 0,54759

Регрессор XGboost работает немного аналогично модели RandomForest.

8.8 Регрессор стекирования:

С «Исходным набором данных + PCA + SVD + GRP + взаимодействия»,

Здесь я объединил все вышеперечисленные модели, кроме KnearestRegressor, и использовал регрессор стекирования. Я использовал модель регрессии хребта в качестве мета-регрессора.

Загрузить сохраненные модели,

filename = 'RF_Orig_Feat_model.sav'
rf1 = joblib.load(filename)
print(f'Loaded {filename}')
# Output:
Loaded RF_Orig_Feat_model.sav
filename = 'RF_PCA_SVD_inter_GPR_model.sav'
rf2 = joblib.load(filename)
print(f'Loaded {filename}')
# Output:
Loaded RF_PCA_SVD_inter_GPR_model.sav
filename = 'RF_PCA_SVD_model.sav'
rf3 = joblib.load(filename)
print(f'Loaded {filename}')
# Output:
Loaded RF_PCA_SVD_model.sav
filename = 'XGB_PCA_SVD_inter_GPR_model.sav'
xgb = joblib.load(filename)
print(f'Loaded {filename}')
# Output:
Loaded XGB_PCA_SVD_inter_GPR_model.sav

Сложите их вместе,

ridge_reg =  Ridge(random_state=42, fit_intercept=False, alpha=0)
stacked_model = StackingCVRegressor(regressors=(rf1, rf2, rf3, xgb),                           
           meta_regressor=ridge_reg,use_features_in_secondary=False,
           refit=True, cv=5) 
 
stacked_model.fit(train_grp_pca_svd_inter, y_train)
  • Поезд R2 = 0,6530002337544227
  • Тестовый частный R2 = 0,55017
  • Публичный тест R2 = 0,55310

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

8.9 Пользовательская модель:

С «Исходным набором данных + PCA + SVD + GRP + взаимодействия»,

Базовый поток этой нестандартной модели показан на рисунке ниже.

Код модели:

Я использовал показанную выше модель для разного количества K следующим образом, здесь используются базовые модели DecisionTreeRegressors ()

import time
start = time.time()
n_estimators = [3,5,10,20,50,75,100,225,500]
train_scores = []
cv_scores = []
n_models = []
for k in n_estimators:
    model, R2_train, R2_cv = CustomEnsembleRegressor(D_train, y_train.values, k)
    n_models.append(model)
    train_scores.append(R2_train)
    cv_scores.append(R2_cv)
    print(f"Train R2:{R2_train}, CV R2:{R2_cv}")
    
elapsed = time.time() - start
print(f"Time elapsed: {elapsed}")
# Output:
100%|██████████| 3/3 [00:00<00:00, 573.99it/s]
Train R2:0.08220279658407303, CV R2:-0.01337314473045259
100%|██████████| 5/5 [00:00<00:00, 985.04it/s]
Train R2:0.09105626276132484, CV R2:-0.01563382377423217
100%|██████████| 10/10 [00:00<00:00, 1151.36it/s]
Train R2:0.1297652945230663, CV R2:-0.03525505486195346
100%|██████████| 20/20 [00:00<00:00, 1238.28it/s]
Train R2:0.1456421992646002, CV R2:-0.024534879198908177

100%|██████████| 50/50 [00:00<00:00, 773.68it/s]
Train R2:0.16835058802053093, CV R2:-0.05085436003144661

100%|██████████| 75/75 [00:00<00:00, 792.55it/s]
Train R2:0.19105718148989337, CV R2:-0.036930656218675306

100%|██████████| 100/100 [00:00<00:00, 772.30it/s]
Train R2:0.20514241360525387, CV R2:-0.028996842506092246

100%|██████████| 225/225 [00:00<00:00, 798.80it/s]
Train R2:0.23149152275845875, CV R2:-0.037854168858211024

100%|██████████| 500/500 [00:00<00:00, 788.68it/s]
Train R2:0.27910345041117934, CV R2:-0.01996754386214894
Time elapsed: 267.02857732772827

И получил эти результаты,

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

8.10 Модель усреднения:

С исходными данными,

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

Ниже приводится логика модели.

Как показано выше,

а. Я использовал две регрессионные модели Xgboost и обучил их всем данным поезда.

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

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

Код для этого выглядит следующим образом:

Используя этот метод усреднения,

  • Поезд R2 = 0,6142291
  • Тестовый частный R2 = 0,55179
  • Публичный тест R2 = 0,55631

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

9. Сравнение моделей:

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

10. Конечный трубопровод:

Теперь у меня есть лучшая модель - модель усреднения.

Итак, давайте просто создадим финальный конвейер для модели, которую мы можем использовать для производства. Ниже приведен код финального конвейера.

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

Для следующих 10 баллов

Здесь я использовал конвейер и спрогнозировал время тестирования для 10 конфигураций автомобилей.

11. Будущие расширения:

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

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

12. Ссылки:

  1. Https://www.kaggle.com/c/mercedes-benz-greener-manufacturing/
  2. Https://www.epa.gov/ghgemissions/global-greenhouse-gas-emissions-data
  3. Https://www.geeksforgeeks.org/ml-r-squared-in-regression-analysis/
  4. Https://www.kaggle.com/c/mercedes-benz-greener-manufacturing/discussion/36242
  5. Https://arxiv.org/pdf/1305.5870.pdf
  6. Https://www.youtube.com/watch?v=9vJDjkx825k
  7. Https://blog.goodaudience.com/stacking-ml-algorithm-for-mercedes-benz-greener-manufacturing-competition-5600762186ae
  8. Https://medium.com/@williamkoehrsen/capstone-project-mercedes-benz-greener-manufacturing-competition-4798153e2476
  9. Https://www.kaggle.com/adityakumarsinha/stacked-then-averaged-models-private-lb-0-554?scriptVersionId=1337077
  10. Https://www.kaggle.com/c/mercedes-benz-greener-manufacturing/discussion/37700#411807
  11. Https://statisticsbyjim.com/regression/interaction-effects/
  12. Https://www.appliedaicourse.com/

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

Полную работу со всем кодом можно найти здесь, в моем профиле Github:



Подключите меня к LinkedIn: