machine learning
September 23, 2023

Парсим, анализируем, предсказываем: Выбираем автомобиль

сгенерировано нейросетью stable diffusion

Предыстория

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

Сбор данных.

Данные собирал с одного известного сайта объявлений. Меня интересовали следующие параметры при выборе автомобиля:

  • Цена (price)
  • Год выпуска(year)
  • Пробег
  • Количество владельцев по ПТС
  • Мощность двигателя
  • Тип коробки передач

Реализация.

Написал код, используя Selenium, для автоматического сбора данных с сайта. Данные по автомобилям сохранялись в базу данных SQLite3. Код состоит из двух основных функций parser, worker

Парсинг данных:

  • Функция parser принимает URL в качестве аргумента и начинает процесс сбора данных.
  • Открывается URL в браузере через драйвер Selenium.
  • Браузер пытается найти и взаимодействовать с некоторыми элементами на странице.
  • Браузер определяет количество объявлений на странице и вычисляет, сколько всего страниц в пагинации.
  • Затем проходится по каждой странице, извлекает ссылки на объявления и их идентификаторы, после чего добавляет их в базу данных

Функция worker

  • В бесконечном цикле пытается извлекать следующий URL для обработки из базы данных.После получения URL, обновляет его статус на «обрабатывается»
  • Открывает URL в драйвере Selenium.Проверяет наличие определенных элементов на странице (например, если объявление было снято с публикации).
  • Если таких элементов нет, пытается сохранить данные с помощью функции save_test_data.
  • Если возникнет исключение в любой части процесса, статус URL обновляется на «ожидание ошибки», драйвер закрывается и прерывает текущую итерацию.

Анализ полученных данных.

import pandas as pd
import numpy as np

Код знакомый многим кто увлекается данными

Подробно описано в предыдущем посте

Первая попытка. Процентили, Квартили.

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

График распределения автомобилей по цене и году. Точки это автомобили.

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

Этот подход был отвергнут так как не учитывал другие параметры - пробег, количество владельцев по ПТС

Вторая попытка. Скоринг.

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

Такой подход был получше, но чего-то не хватало.

Третья попытка. Машинное обучение нейросети

изображение сгенерировано нейросетью Stable Diffusion

Подготовка данных:

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

Прогноз

Для предсказания справедливой цены автомобиля использовал нейронные сети, обучил различные модели машинного обучения, начиная с простой множественной регрессии и заканчивая сложными методами ансамблирования, такими как стекинг. Пробовал различные алгоритмы бустинга, включая XGBoost, AdaBoost, GBM и LightGBM.

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

И как я не пытался улучшить данные для модели, удалить выбросы, "поиграть" с настройками сети. Результат был плюс, минус такой же - 60000 - 80000 разница между фактической ценой и предсказанной.

Подробно об этом написано здесь

Четвертая попытка. Возврат к скорингу.

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

  1. Определение весов для каждого критерия:
    • Например, разница в цене может иметь больший вес, чем разница в пробеге, так как цена может быть более важным фактором для покупателя.
  2. Вычисление баллов для каждого автомобиля:
    • AveragePriceModelDiff: Положительная разница (если средняя цена модели выше, чем цена конкретного автомобиля) будет добавлять баллы, так как это может указывать на более выгодное предложение.
    • average_mileage_model_year_diff: Отрицательная разница (если пробег автомобиля выше среднего по модели и году) будет убавлять баллы.
    • average_pts_diff: количество владельцев автомобиля, меньшее значение PTS будет предпочтительнее, так как автомобиль с меньшим количеством владельцев может быть в лучшем состоянии.
  3. Суммирование баллов для каждого автомобиля:
    • Веса из пункта 1 умножались на разницы каждого критерия на его вес, а затем складывал все вместе, чтобы получить общий балл для каждого автомобиля.
  4. Выбор автомобиля с наивысшим баллом:
    • Автомобиль с наивысшим баллом будет считаться наиболее оптимальным.

Такой подход оказался быстрым и эффективным.

Вишенка на торте

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


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