ИИ в электронной коммерции

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

Конкурс предложения цены Mercari

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

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

Бизнес-проблемы и вызовы

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

Предсказать цену продукта - сложная задача, поскольку очень похожие продукты, имеющие незначительные различия, такие как разные торговые марки, дополнительные характеристики, качество, спрос на продукт и т. Д., Могут иметь очень разные цены. Например, один из этих свитеров стоит 335 долларов, а другой - 9,99 доллара. Сможете угадать, какой из них какой?

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

Давайте посмотрим на эту проблему с точки зрения машинного обучения.

Проблема машинного обучения

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

Показатели производительности и бизнес-ограничения

У нас должен быть критерий для измерения того, насколько хороша или плоха наша модель. В терминологии машинного обучения мы называем этот эталон производительности метрикой или просто метрикой. Существуют различные метрики для измерения эффективности регрессионной модели, например, средняя абсолютная ошибка, среднеквадратичная ошибка, среднеквадратичная логарифмическая ошибка, максимальная остаточная ошибка, медианная абсолютная ошибка, коэффициент детерминации (R²) и т. д..
Для этой задачи Kaggle использует среднеквадратичную логарифмическую ошибку (RMSLE). Чем меньше RMSLE, тем лучше наша модель. RMSLE рассчитывается как

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

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

  1. Решение за 18-е место: Общая идея состоит в том, чтобы обучить модель FM_FTRL, а затем модель LightGBM и использовать их совокупность для получения окончательных прогнозов.
  2. Mercari Golf: 0,3875 CV в 75 LOC, 1900-е: ансамбль из 4 моделей MLP, каждая из которых имеет одинаковую архитектуру, но обучается на двух разных наборах данных.

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

1. Обзор данных

Данные можно скачать со страницы конкурса Kaggle. Есть два файла train.tsv и test.tsv и шаблон отправки Kaggle sample_submission.csv. Общий размер данных составляет 1,03 ГБ. после декомпрессии.

Файлы состоят из списков продуктов. Эти файлы разделены табуляцией. train.tsv содержит 1 482 535 строк, а test.tsv - 3 460 725 строк. И обучающий, и тестовый файлы имеют следующие поля данных

  • train_id или test_id - идентификатор листинга
  • name - заголовок листинга
  • item_condition_id - состояние товара, предоставленного продавцом
  • category_name - категория листинга
  • brand_name
  • price - цена, по которой был продан товар. Это целевая переменная, которую мы будем прогнозировать. Единица - доллар США. Этот столбец не существует в test.tsv, поскольку это то, что мы будем прогнозировать.
  • shipping - 1, если стоимость доставки оплачивается продавцом, и 0, если оплачивается покупателем.
  • item_description - полное описание товара

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

Ниже приведен образец данных поезда.

Мы видим, что в данных есть несколько нулевых значений (NaN). Мы бы заменили их на «отсутствует». Кроме того, мы разделили список из трех значений в столбце category_name на три новых столбцаgencat_name, subcat1_name, subcat2_name. Например, точка данных с category_name = [Men, Tops, T-shirts] будет иметь gencat_name = Men, subcat1_name = Tops и subcat2_name = Футболки.

2. Исследовательский анализ данных

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

2.1. Базовый EDA: анализ столбцов данных поезда

имя

train.name.describe()
count     1481661
unique    1224596
top        Bundle
freq         2232
Name: name, dtype: object

В необработанных данных (до предварительной обработки) содержится 1 224 596 уникальных наименований продуктов. Наиболее распространенное название продукта - «Пакет», которое встречается в 2232 точках данных.

item_condition_id

Большинство элементов находится в состоянии 1 . Очень мало элементов находятся в состоянии 5

brand_name

train.brand_name.describe()
count     1481661
unique       4808
top       missing
freq       632336
Name: brand_name, dtype: object

brand_name отсутствует для большого количества (42,68%) точек данных.

gencat_name

  • Продукты распределены по 10 основным категориям. Этот столбец пуст для некоторых продуктов, они были помещены в отдельную категорию пропавших без вести.
  • Огромное количество товаров относится к категории Женщины. Это может быть связано с тем, что обычно женщины склонны делать покупки больше, чем мужчины.
  • gencat_name отсутствует для 6314 точек данных, то есть 0,43% данных поезда.

subcat1_name, subcat2_name

train.subcat1_name.describe()         train.subcat2_name.describe()
count              1481661            count                  1481661
unique                 114            unique                     871
top       Athletic Apparel            top    Pants, Tights, Leggings
freq                134321            freq                     60152

Помимо 10 общих категорий, существует 114 подкатегорий продуктов, которые, в свою очередь, могут принадлежать еще 871 подкатегориям. Проще говоря, subcat1_name сообщает о категории элемента в более широком смысле, тогда как subcat2_name идет на один уровень глубже и дает более подробную информацию о том, что именно представляет собой элемент. Вспомните пример [Мужчины, топы, футболки]
На рисунках ниже показаны первые 15 подкатегорий по количеству элементов.

цена

Это целевая переменная или «y» в данных о наших поездах. Нам нужно предсказать это для тестовых данных. Он имеет широкий диапазон значений от 3 до 2009 долларов. Однако цена большинства товаров ниже 200 долларов, как это видно на графиках и значениях процентилей ниже.

0 percentile value is 3.0
10 percentile value is 7.0
20 percentile value is 10.0
30 percentile value is 12.0
40 percentile value is 14.0
50 percentile value is 17.0
60 percentile value is 20.0
70 percentile value is 26.0
80 percentile value is 34.0
90 percentile value is 51.0
100 percentile value is  2009.0
90 percentile value is 51.0
91 percentile value is 55.0
92 percentile value is 58.0
93 percentile value is 62.0
94 percentile value is 67.0
95 percentile value is 75.0
96 percentile value is 85.0
97 percentile value is 99.0
98 percentile value is 122.0
99 percentile value is 170.0
100 percentile value is  2009.0
  • 97% точек данных имеют цену менее 100 долларов США.
  • Очень немногие (всего 1%) точки данных имеют цену более 170 долларов США.

2.2. Универсальный анализ: корреляция между характеристиками (столбцы) и целевой переменной «y»

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

Изменение цены в зависимости от состояния товара

Я использовал простые прямоугольные диаграммы, чтобы увидеть, как цена предмета меняется в зависимости от состояния предмета.
Обратите внимание, что на прямоугольной диаграмме нижняя граница прямоугольника обозначает перцентиль 25ᵗʰ, верхняя граница обозначает процентиль 75ᵗʰ, а линия внутри рамки обозначает 50 ° процентиль или медианное значение.

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

Изменение цены в зависимости от категории товара (gencat_name)

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

Изменение цены в зависимости от подкатегории товара (subcat1_name)

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

Это указывает на то, что категории и подкатегории будут важными характеристиками при определении цены товара.

3. Очистка данных: предварительная обработка

3.1. Функции предварительной обработки текста

Я выполнил некоторую предварительную обработку текста, такую ​​как удаление не буквенно-цифровых символов, регулярных выражений, игнорируемых слов и т. Д. Из name и item_description. Код приведен ниже.

3.2. Категории предварительной обработки

Это похоже на предварительную обработку текста. Я удалил пробелы и заменил символ «&» (и) на «_» (подчеркивание). Я выполнил эту очистку, чтобы получить точное кодирование категорий, которое объясняется в разделе о характеристиках.

3.3. Цена предварительной обработки: удаление недействительных записей

Removed 874 rows

4. Извлечение функций из данных

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

4.1. Ручные функции: Feature Engineering

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

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

Универсальный анализ некоторых специально разработанных функций

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

example code:
sns.regplot(x=’brand_mean_price’, y=’price’, data=train,
            scatter_kws={‘alpha’:0.3}, line_kws={‘color’:’orange’})

Такие функции, как brand_mean_price, brand_median price, subcat2_mean_price, subcat2_median_price, демонстрируют сильные линейные тенденции. Таким образом, они кажутся полезными при определении цен на товары.

4.2. Тренировка, разделение тестов для перекрестной проверки

В целях перекрестной проверки (проверки того, хорошо ли обученная модель работает с невидимыми данными), я разделил наши данные на train и cv в соотношении 90:10. Я обучу наши модели на поезде и проверю их на cv.
Обратите внимание, что целевая переменная цена была преобразована в логарифмическую шкалу с помощью функции NumPy log1p (). Это было сделано для того, чтобы мы могли использовать среднеквадратичную ошибку в качестве метрики вместо явного определения сложной метрики RMSLE. (поскольку RMSLE - это не что иное, как RMSE значений журнала)

Train size: (1332967, 58), CV size: (148108, 58), Test size: (3460725, 58)

4.3. Преобразование категориальных функций в числа: быстрое кодирование

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

Я преобразовал все категориальные переменные (brand_name, gencat_name, subcat1_name, subcat2_name) в их горячо закодированные векторы. Пример кода показан ниже:

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

4.4. Преобразование текстовых функций в числа: векторизатор TF-IDF

TF-IDF (термин частота-обратная частота документов) - это статистическая мера, которая оценивает, насколько слово релевантно документу в коллекции документов. Это достигается путем умножения двух показателей: сколько раз слово встречается в документе, и обратная частота этого слова в наборе документов. Подробнее о TF-IDF и его математических деталях можно прочитать здесь.

униграммы, биграммы и n-граммы: в области компьютерной лингвистики и вероятности n -грамма представляет собой непрерывную последовательность из n элементов из заданного образца текста или речи. Элементы могут быть слогами, буквами, словами и т. Д. В зависимости от приложения (в нашем случае слова). n -грамм размера 1 называется «юнграмм», размер 2 - «биграмм» и так далее.

Я закодировал name и item_description в векторы TF-IDF униграмм, биграмм и триграмм. Обратите внимание, что использование 1,2,3-граммов вместе приведет к огромному количеству слов в словаре векторизатора TF-IDF, а использование всех их приведет к очень большим размерным векторам. Чтобы избежать этого, я ограничил количество измерений до 250 КБ для name и 500 КБ для векторов item_description.

5. Подготовка данных для моделей.

5.1. Нормализация столбца по числовым характеристикам

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

5.2. Объедините все функции в разреженную матрицу

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

Train size: (1332967, 755695), CV size: (148108, 755695), Test size: (3460725, 755695)

Теперь наши данные готовы к загрузке в модели. Приступим к моделированию.

6. Моделирование: модели машинного обучения.

Я буду обучать следующие регрессионные модели одну за другой и оценивать их эффективность на данных проверки:

  • Ridge regresso r: линейный метод наименьших квадратов с регуляризацией l2.
  • SVM regresso r: поддержка векторной регрессии с ядром RBF.
  • RandomForest regresso r: метаоценка, которая соответствует ряду деревьев решений на различных подвыборках набора данных и использует усреднение для повышения точности прогнозов и контроля чрезмерной подгонки.
  • Регрессор LightGBM: модель повышения градиента, использующая древовидные алгоритмы обучения.

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

6.1. Регрессия хребта

Ридж - это линейная модель наименьших квадратов с регуляризацией l2. Другими словами, это линейная регрессия с регуляризатором l2.
Чрезмерная или недостаточная подгонка модели Ridge зависит от параметра alpha, который можно настроить на правильное значение, выполнив настройку гиперпараметров, как показано ниже.

RMSLE for alpha =  1 is 0.45166601980352833
RMSLE for alpha =  2 is 0.44431546233122515
RMSLE for alpha =  3 is 0.4424425182737627
RMSLE for alpha =  3.5 is 0.44171501703551286
RMSLE for alpha =  4 is 0.44154616529145424
RMSLE for alpha =  4.5 is 0.4415286167861061
RMSLE for alpha =  5 is 0.44161632764828285
RMSLE for alpha =  6 is 0.4421832813533032
RMSLE for alpha =  7 is 0.44267468278758176

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

Best alpha:  4.5                            Train RMSLE: 0.383449898
Cross validation RMSLE:  0.441528616

SelectKBest: выбор 48k лучших функций из категорийных и текстовых функций

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

Я объединяю их с числовыми характеристиками, прогнозами модели гребня (y_pred используется как функция) и использую их с моими моделями.

Train size: (1332967, 48049), CV size: (148108, 48049), Test size: (3460725, 48049)

6.2. SVM регрессия

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

Подобно альфа в линейной регрессии, C в SVR определяется настройкой гиперпараметров.

Best C:  0.3
SVR(C=0.3, epsilon=0.1, gamma='scale',kernel='rbf', max_iter=200)
Train RMSLE: 0.441563037
Cross validation RMSLE:  0.457637217

6.3. RandomForest Regression

Обучение RandomForest Regressor с более высокими значениями n_estimators (N) занимало огромное количество времени без каких-либо результатов. По этой причине мы обучили его с меньшим количеством оценщиков. Как нетрудно догадаться, результаты были неудовлетворительными.

RMSLE for N=10 is 0.487657647	 elapsed time:0:46:21.136700
RMSLE for N=20 is 0.472606976	 elapsed time:2:02:11.229545

6.4. LightGBM регрессия

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

Настройка гиперпараметров для LightGBM была выполнена с использованием 3-кратной перекрестной проверки с использованием RandomizedSearchCV.

{'colsample_bytree': 0.44583275285359114, 'learning_rate': 0.09997491581800289, 'max_depth': 12, 'min_child_weight': 1.7323522915498704, 'n_estimators': 1323, 'num_leaves': 123}
Train RMSLE: 0.319789825
Cross validation RMSLE:  0.424231390

6.5. Сравнение производительности моделей

  • Оценка проверки LGBM (RMSLE = 0,42423) была лучшей из всех вышеперечисленных моделей.
  • Я отправил предсказания Риджа и ЛГБМ в Kaggle. Мы получили лучший результат с Ridge, RMSLE = 0,45444.
  • Оценка LGBM (RMSLE = 0,45785) была очень близка к оценке Риджа.

7. Окончательное решение: регрессия с использованием многослойных персептронов.

Кажется, что классические модели машинного обучения работают неплохо, но мы должны иметь гораздо лучшую производительность, чтобы получить хороший результат в Kaggle. В большинстве существующих подходов используются те или иные модели глубокого обучения, такие как сверточные нейронные сети (CNN), рекуррентные нейронные сети (RNN) или их комбинация. Производительность моделей глубокого обучения кажется значительно лучше, чем у классических моделей машинного обучения, что побудило меня попробовать базовую модель глубокого обучения, MLP.

7.1. Предварительная обработка

Я выполнил следующую обработку данных поездов и тестов:

  • стандартная предварительная обработка текста (стемминг, заполнение НП)
  • объединение name, brand_name в один столбец name.
  • объединение name, item_description, category_name в один столбец, текст.

7.2. Векторизация

  • Tfidf 1-граммовая векторизация имени.
  • Tfidf 1 грамм, 2-граммовая векторизация текста.
  • Быстрое кодирование категориальных характеристик item_condition_id, доставка.

7.3. Архитектура модели MLP

Причины выбора MLP вместо CNN или RNN:

  • Быстро обучается, может иметь скрытый размер 256 вместо 32–64 для RNN или Conv1D.
  • MLP фиксирует взаимодействие между текстом и категориальными функциями.
  • Огромная вариативность дает сильный ансамбль с единым типом модели.

Я обучил 4 модели с высокой дисперсией с точно такой же архитектурой и, наконец, взял их совокупность, чтобы получить окончательные прогнозы. Это похоже на Бэггинг в RandomForest. Для 2 из 4 моделей я преобразовал входные данные в двоичную форму, установив для всех ненулевых значений значение 1. Это похоже на получение дополнительного набора данных с двоичным CountVectorizer вместо TF-IDF.

Я использовал оптимизатор Adam со скоростью обучения 0,003 и начальным размером пакета 512 и обучил модель для 2 эпох, удваивая размер пакета в каждую эпоху. Для бинаризованного ввода я таким же образом обучил 3 эпохи.

7.3. Оценка производительности модели и представление Kaggle

С помощью приведенной выше модели я получил RMSLE = 0,3848, что является большим улучшением по сравнению со всеми моими предыдущими моделями.

Окончательная оценка отправки на Kaggle с этой моделью в частной таблице лидеров составила 0,39446.

Улучшения существующих подходов

  • Я внес некоторые изменения в архитектуру MLP, а также в такие параметры, как скорость обучения и размер пакета, чтобы получить лучшие результаты. Я также изменил количество эпох с 3 на 2 для модели с недвоичными данными, поскольку она начинает переобучаться с 3-й эпохи.
  • Вместо того, чтобы брать простое среднее, я взял средневзвешенное значение прогнозов из 4 моделей / прогонов.
  • Для простоты кода, а также потому, что я использовал Google Colab (обучение выполняется быстрее с графическими процессорами, чем с многоядерными процессорами), я обучил модели одну за другой, в отличие от обработки пула в исходном ядре. .

Полученный мной RMSLE проверки составил 0,3848 по сравнению с 0,3875 в исходном ядре.

Вещи, которые не сработали

  • На обучение RandomForest уходило слишком много времени, поэтому мне пришлось отказаться от этой модели.
  • В MLP я также пробовал использовать выпадения (0,1, 0,2, 0,3,… 0,5), но модели работали лучше без выпадений и, следовательно, удалили их. (Я получил RMSLE проверки 0,3872 с отсеиванием).
  • Я также экспериментировал с различными единицами активации («tanh», «сигмовидная», «линейная», «relu»). «Relu» работает значительно лучше, чем все остальные.

Будущая работа

  • Использование глубокого обучения было продуктивным и дало очень хорошие результаты по тестовым данным. Можно попробовать более сложные модели, такие как LSTM и сверточные нейронные сети.
  • Мы можем экспериментировать с более сложными MLP, добавляя дополнительные слои и большее количество единиц в скрытых слоях.
  • Другие схемы векторизации, такие как Wordbatch, можно экспериментировать с моделями машинного обучения.
  • Также можно попробовать модели регрессии, такие как FTRL и FM_FTRL.

Заключение

Проведение этого тематического исследования было забавным, а также отличным опытом обучения. Я благодарю вас за чтение этого блога и надеюсь, что это принесло вам пользу. Я включил минимальный код в этот блог. Полный код можно найти в записных книжках ipython в моем репозитории GitHub Mercari-Price-Suggestion-Challenge.
Я хотел бы услышать ваши реакции, предложения или вопросы.
Вы можете связаться со мной на LinkedIn. Вот мой профиль.

использованная литература

  1. Https://blog.exploratory.io/a-practical-guide-of-exploratory-data-analysis-with-linear-regression-part-1-9f3a182d7a92
  2. Https://www.kaggle.com/c/mercari-price-suggestion-challenge/overview
  3. Https://www.kaggle.com/c/mercari-price-suggestion-challenge/discussion/50252
  4. Https://www.kaggle.com/lopuhin/mercari-golf-0-3875-cv-in-75-loc-1900-s
  5. Https://www.appliedaicourse.com/course/11/Applied-Machine-learning-course