company_banner

Как дата-сайентист машину покупал

Автор оригинала: Will Casey
  • Перевод
После многих лет жизни и работы в Нидерландах мне с семьёй пришло время возвращаться в Штаты и менять велосипеды на автомобили.



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

Сбор данных


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

Как раздобыть данные по рынку автомобилей? Решить эту задачу нам поможет веб-скрапинг.


Инструменты разработчика Google Chrome

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

В этом проекте я использовал Python-пакет Selenium, который представляет собой браузер без пользовательского интерфейса. Такой браузер открывает страницы и работает с ними так же, как работал бы с ними пользователь (в отличие от чего-то вроде Python-библиотеки Beautiful Soup, которая просто читает HTML-код).

Благодаря инструментам разработчика Google Chrome процесс подготовки к сбору данных сильно упрощается. Всё сводится к щелчкам правой кнопкой мыши по интересующим нас элементам веб-страниц и к копированию их xpath, element_id, или чего угодно другого. Всё это хорошо воспринимает Selenium. Но иногда для поиска нужного элемента и текста приходится немного повозиться.

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

Очистка данных


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

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


Данные перед очисткой

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

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

def get_regex_item(name, pattern):
    item = re.search(pattern, name)
    if item is None:
        return None
    else:
        return item.group()

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

df['4wd'] = df.name.apply(lambda x: 1 if get_regex_item(x, pattern= r'4[a-zA-Z]{2}') else 0)
df['year'] = df.name.apply(lambda x: get_regex_item(x, pattern= r'\d{4}'))
df['type'] = df.name.apply(lambda x: x.split()[-1])
df['certified'] = df.name.apply(lambda x: 1 if get_regex_item(x.lower(), r'certified') else 0)

df['price']  = df.price.apply(lambda x: x[:6].replace(",", "")).astype('int')
df['mileage'] = df.mileage.apply(lambda x: x.split()[0].replace(",", "")).astype('int')

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


Данные после очистки

Разведочный анализ данных


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

import matplotlib.pyplot as plt
import seaborn as sns

plt.gca().spines['top'].set_visible(False)
plt.gca().spines['right'].set_visible(False)

#box plots
sns.boxplot(x = df.year, y=df.price, data=df[['year', 'price']], color='purple')
sns.boxplot(x = df.type, y=df.price, data=df[['year', 'price']], color='cyan')


Зависимость цены автомобиля от года его выпуска


Зависимость цены от типа автомобиля

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

А вот — диаграмма разброса.

import matplotlib.pyplot as plt
import seaborn as sns

plt.gca().spines['top'].set_visible(False)
plt.gca().spines['right'].set_visible(False)

#scatter plot
sns.regplot(x=df.mileage, y=df.price , color='grey')


Диаграмма разброса

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

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

Кодирование независимых признаков


Ещё один шаг, который нужно было выполнить до построения модели, заключается в кодировании независимых признаков. Признаки 4wd и certified уже представлены в логическом виде. Они не нуждаются в дополнительной обработке. А вот признаки type и year нужно закодировать. Для решения этой задачи я воспользовался методом Pandas .get_dummies, который позволяет выполнять кодирование с одним активным состоянием.

Pandas — довольно интеллектуальная система, которая позволила мне передать ей все признаки и закодировала только независимые переменные, а также позволила мне убрать один из только что созданных столбцов для того, чтобы избавиться от полностью коррелирующих друг с другом признаков. Использование подобных данных привело бы к ошибкам в модели и в её интерпретации. Обратите внимание на то, что в итоге у меня осталось только два столбца с информацией о годе выпуска машины, так как столбец _2015 был удалён. То же самое касается и столбцов type.


Данные после кодирования независимых переменных

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

Создание модели


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

Я воспользовался моделью линейной регрессии OLS (Ordinary Least Squares, обычный метод наименьших квадратов). Для построения модели применён Python-пакет statsmodel.

import statsmodels.api as sm
y = model_df.price
X = model_df.drop(columns='price')

model = sm.OLS(y, X).fit()
print(model.summary())

Вот результаты моделирования.


Моделирование привело к получению среднеквадратичной ошибки в 1556.09

Полученные коэффициенты соответствуют тому, что можно было видеть на диаграммах в ходе разведочного анализа данных. Пробег оказывает отрицательное воздействие на цену. В среднем, каждая дополнительная тысяча миль пробега приводит к снижению цены на $1600. Это справедливо для автомобилей GMC Yukon, возможно, не для всех. Вероятно, самыми шокирующими результатами из всех стали те, которые указывают на разницу в цене между SLE (автомобили Yukon низшего класса) и Denali (автомобили Yukon высшего класса). Разница составляет более $9000. Это означает, что покупателю автомобиля более высокого класса приходится платить немалые деньги за все получаемые им премиальные опции. Как результат — хорошо было бы, если бы всё это ему было по-настоящему нужно.

Какую же машину стоит купить?


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

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

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


Купленная нами машина выделена синим

В итоге мы купили 2015 GMC Yukon Denali за $32000. Это было на $3000 дешевле прогноза, выданного моделью.

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


Наша покупка выделена на диаграмме синим цветом

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

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

Уважаемые читатели! Пользуетесь ли вы инструментами для анализа данных при решении каких-нибудь бытовых задач?


RUVDS.com
1 102,37
RUVDS – хостинг VDS/VPS серверов
Поделиться публикацией

Комментарии 38

    0
    Делал примерно тоже самое когда прорешивал задания Яндекса размещенные у них в разделе с вакансиями. Задачей было максимально точно спрогнозировать цену машины.

    Подход был похожий, основную боль вызывали рандомные блокировки моего миникраулера со стороны auto.ru при сборе датасета. В итоге удалось на catboost'e при помощи линейной регрессии соорудить вполне жизнеспособное решение без каких-либо ML'ных изысков, но вот вакансия к тому моменту закрылась :)
      +1
      Очень многие сайты научились детектить Selenium. Кто научился это обходить?
        +1
        AutoIt + OpenCV + любой браузер.
        Минус — намного больше геморроя, чем с Selenium, времени на настройку и отладку уходит больше, сам сбор данных работает дольше, надо парсить полученные html, работает только в винде.
        Плюс — стопроцентная эмуляция кликающего в браузере юзера, невозможно задетектить в принципе (ок, в принципе возможно, если анализировать скорость и траекторию движения мышки или регулярность частоты кликов, но и в это можно добавить рандома, максимально приблизив к обычному юзеру).
        Нормально настроенное на определенный сайт и отлаженное, такое поделие скрапит сайт не менее надежно, чем селениум.
        0
        Я научился ;)
          0
          Непонятно за что минусят, ведь ответ хоть и бесполезный, но семантически абсолютно корректный. :-) Как и в анекдоте.
            0
            Завидуют! ;)
            Мой ответ совсем не бесполезен! Он показывает, что это возможно!
            Однажды один ̶ч̶е̶л̶о̶в̶е̶к̶ подонок рассказал мне, что продавая банки кофе научился вскрывать мембрану из фольги отсыпать хороший кофе и досыпать дешевый. Мембрану потом как-то обратно запаивал.
            На вопрос как это делать он ответил: «На таких знаниях состояния делаются!»
            Но на вопрос в личке я отвечу, я не жадный
      +12
      Просто человек поупражнялся в своём ремесле. А на факту купил ту, которая была ближе к дому при равном бюджете. Даже на в его таблице есть машина и новее и с большим количеством опций и чуть дешевле:
      Выделил красным
      image
        0
        На 7% аж дешевле, т.е. $2000. Это почти столько же, сколько его «сэкономленные» $3000!
          0
          Так вроде список отсортирован — певая еще выгоднее
          +2
          Хорошая б/у машина определяется не собранными метриками, а капризностью эксплуатации конкретного экземпляра. Но для поиска оптимального диапазона цен — норм.
            0
            Ну это вопрос подготовки датасета же, делая такое по авто.ру можно отсеять автомобили с низкими баллами в отзывах, например.
              +16
              Суть не в этом, надо смотреть конкретный экземпляр. Одни автомобилисты со своих авто пылинки сдувают, другие годами масло не меняют. А перекупы сварят два авто после серьезного ДТП в одно, и будут продавать как «не бит, не крашен, бабушка в церковь по воскресеньям ездила». Данные этого не покажут. Вполне может быть, что более плохой авто по данным окажется лучше других, потому что владелец «более плохого авто с точки зрения данных» написал честно.
                0
                Вот-вот.
                  0
                  Опять же, могу смотреть только с позиции своего опыта. Потенциально проблемная машина на авто.ру имеет:
                  1. Большое кол-во хозяев за небольшой промежуток времени.
                  2. Подсвеченную красным проверку по VIN.
                  3. Странные идентификаторы или шаблоны в описании.
                  4. Низкую цену относительно комплекса базовых параметров (год, пробег, комплектация, двигатель, тип кпп, итд).
                  (Может ещё что-то забыл)

                  Всё что частично или в комплексе подпадает под эти критерии — должно настораживать. При этом не зависимо от глубины проведённой аналитики правду удастся узнать лишь увидев машину, продавца и документы в живую (и то не в 100% случаев).
                    +3
                    Ну а допустим машина с одним владельцем, проверка VIN-зеленая, инфы по ДТП нет, а по фото видно что зазоры кривые и некоторые элементы кузова не попадают в цвет при хорошем освещении? В печально известном АТЦ М… таких объявлений половина
                      0
                      Скорее всего такое объявление подпадет под пункты 3 и 4 из моего ответа выше. На моей практике выбора авто — это утверждение подтверждается.
                        +1

                        Я выбрал по формальным параметрам машину, приехал за 700 км и оказалось, что на фото всё хорошо, а глазами видно столько мелочей, что совсем не хочется покупать. В итоге взял машину ниже классом, но новее, с ДТП формальным, и дороже. И только зря время потратил и деньги на пробив десятка моделей, которую хотел взять изначально.

                          0
                          Такое бывает. Из спортивного интереса: первое авто было по низу рынка для этой модели а второе середина-верх?
              0

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


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

                +3
                Вы придумали «перекупов»
                  0

                  Не, "киберперекупов" :-)

                  0
                  а разве цена на машину не падает с увеличением количества бывших владельцев?
                    0

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

                  0
                  Это ж очень старое приседание, которе я читал года 3-4 назад… может даже на хабре… правда, скорее всего, было на R, а не py.
                  P.S. Я себе бюджет планирую: собрал банковские выписки (все траты со всех банков) за несколько лет -> получил сезонку -> использовал как веса при планировании операционных затрат. Да, модель весьма специфична, работает далеко не для всех: несколько лет как стараюсь жить на одну и ту же сумму в месяц (+- сезонка). Поэтому мне подходит.
                  –2
                  Годнота! Просто, понятно, практично.
                    +7
                    Выбирал, выбирал и итоге купил ту, что поближе.
                    Отличная статья.
                      0

                      Я с самого начала ожидал, что пробег и год влияет на цену. Так и оказалось :)

                        0

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


                        Некоторые падают быстрее ( французы все приходят к нулю через 3 года исчезают) некоторые падают медленнее ( немцы кроме vw).


                        Некоторые сильно сбрасывают цену в начале (выезд из салона) но потом достаточно долгое плато. Вот такие и нужны на вторичке. Купил Вольво в результате.

                          +2
                          При прочих равных сильно зависит от хозяина и хранения. Некоторые за пару лет уделают авто так, как другие за 10. И это вам ни пробег, ни год не покажут.
                            +2
                            тормоза, ой, фильтры придумал трус! вот если честно, неужели стандартные фильтры не смогли бы помочь с поиском? или надо было вот прям убедиться, что обвес и пробег/год увеличивают и уменьшают цену, соответственно?
                            Вероятно, самыми шокирующими результатами из всех стали те, которые указывают на разницу в цене между SLE и Denali
                            вот это серьёзно? без шуток?

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

                            когда коту делать нечего…
                              +4
                              Мои выводы из сего опуса:

                              1. датасатанист — сущность бессмысленная. Ибо рисует отчёты в стиле КО, а ЗП просит огого.
                              2. ИТшники ботаны, кто так машину выбирает?
                                0
                                Как представитель этих самых дата сантистов, имею сказать следующее:
                                1. Главное не картинки а модель, а точнее поддержка принятия решения
                                2. Интуицию и экспертное мнение никто не отменял, но подтвердить достоверность при помощи матеши — это аргумент.
                                3. Пример в статье скорее игрушечно — фановый, в реальной работе ДСа данных намного больше и критериев для выбора решения тоже.
                                +1
                                Я примерно так супруге Фиат купил. Но мне было проще, ибо нужна была определенная марка — Фиат пятисотый с коробкой — роботом и «красненькая». С пробегом в 30-40 тыщ они стоили в районе 7-8 килоевро. Я купил у турка за шесть тыщ. В итоге — зимой на летней резине, с убитым аккумулятором, масло ни разу не меняли, коробка через некоторое время начала глючить. Ее обслуживание примерно в тысячу и вышло. Машина была предназначена для обучения вождению и мы довольно быстро распрощались с ней, купив такой же, но почти новый Фиат с гарантией у официалов. Я это к тому, что если машина сильно ниже рынка, то тому могут быть причины, и в конечном итоге с учетом доп вложений так на так и выйдет. Либо придется потратить кучу временми на осмотры. Хотя не купить сильно выше рынка этот метод безусловно может помочь.
                                  0

                                  Есть сайт, robasta.ru, то же самое делает, автор здесь про него рассказывал.

                                    +3
                                    Сеймур Крей ( Основатель компании Cray Inc. которая создавала суперкомпьютеры ) автор другого интересного метода выбора подходящей машины для покупки.
                                    Метод заключается в следующем: вы идете в магазин, ближайший к вашему дому, показываете на машину, ближайшую к двери, и говорите: «Я беру эту». Этот алгоритм оптимален по одному важному показателю: он позволяет тратить минимум времени на не очень важные дела (покупку автомобилей) и оставляет большую часть времени на важные (разработку суперкомпьютеров).
                                      0
                                      Сеймур Крей не образчик здравого смысла, если почитать его биографию…
                                      В те времена гики милиардерами становились, а он всю жизнь скакал от банкротства к банкротству, в перерывах работая на ЗП (возможно и неплохую).

                                      Ну и машины выбирать есть способы лучше…

                                      Следует отметить, что у многих русских, в отличие от буржуев, машина — почти член семьи ;) хотя потреблядство, конечно понемногу заполоняет.

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

                                    Самое читаемое