Как стать автором
Обновить

Анализ изменения цен в российских интернет-магазинах

Время на прочтение3 мин
Количество просмотров48K

В последние пару лет меня достаточно сильно интересовал вопрос ценообразования в российских интернет-магазинах. Каждый раз при заявлении интернет-магазина о большой скидке в душу закрадывается сомнение… Действительно ли такая большая скидка? Была ли реальна цена которая сейчас зачеркнута?
Резкие изменения курса доллара в конце 2014г. подлили масла в огонь. Очень захотелось получить ответ на вопрос как зависят цены от курса доллара в реальности.
В итоге, я решил покончить с этими вопросами и собрать историю изменения цен по российским интернет-магазинам. По катом результаты работы + несколько интересных закономерностей.

Немного технический подробностей


На данный момент в системе работают несколько десятков парсеров написанных на python.
Хранить данные в лоб мне показалось очень расточительным, решил хранить только изменения цены. Если цена не меняется — записи в БД не создаются, такой подход позволяет очень хорошо экономить ресурсы. На данный момент в таблице всего 200 000 000 строк, что не так много для данных по ~100 000 товаров в >1000 магазинов за 8 месяцев.
В качестве хранилища используется MySQL 5.6. Недавно пришлось переехать на SSD, так как обычные HDD на Hetzner не очень справлялись с большой нагрузкой на запись.

В данной статье я хотел бы описать интересные закономерности найденные при анализе собранных данных:

1. Синхронное изменение цены


Собрав базу за несколько месяцев, я решил проанализировать коэффициент корреляции между предложениями одного и того же товара от разных магазинов. Для этого был быстренько набросан скрипт на python + pandas. Pandas в данном случае очень помог наличием функции resample.

sql = """
SELECT pr.date, pr.shopitemid, price from prices AS pr
JOIN shopitems AS si
ON pr.shopitemid = si.id
WHERE si.itemid = 1
AND si.shopid > 10
AND si.last_price IS NOT NULL
ORDER BY pr.date
""" 
df = pd.read_sql_query(sql, engine)
for item in df['shopitemid'].unique():
    x= df[df['shopitemid'] == item]
    nans = x.isnull().sum()['price']/float(len(x))
    if nans > 0.2 or len(x['price'].unique()) < 10 or \
    x['date'].min() >  (datetime.now() - relativedelta(months=3)):
        df = df.drop(df[df['shopitemid'] == item].index)
df = df.dropna()

df = df.pivot(index='date', columns='shopitemid', values='price')
df = df.fillna(method='pad')
df = df.dropna()
df = df.resample('24h', fill_method='pad', how='last', loffset='24h')
mtrx =  df.as_matrix().T
columns = df.columns.values

corr = np.corrcoef(mtrx)
z = np.where(corr > 0.90)
for x,y in zip(z[0],z[1]):
    if x<y:
        print columns[x],columns[y]
        myplot(mtrx[x])
        myplot(mtrx[y])
        
        plt.show()

Проанализируем историю изменения цен на примере холодильника Indesit SB 185.
На выходе получились достаточно интересные графики типа такого:


Ещё графики





Здесь можно посмотреть данный график в более удобном формате.
В данном примере видно что у трех магазинов цена изменяется абсолютно синхронно в течение 8 месяцев. Мне видятся такие вероятные причины такого явления:
  • В двух из трёх используются системы автоматического выставления цены на основе цен конкурентов.
  • Магазины как-то связаны организационно и имеют доступ к общей БД цен


2. Появление нового смартфона.
В момент анализа я наткнулся на график цен по Samsung Galaxy S6.



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

3. Самые дешевые интернет-магазины для каждой категории товаров


Собрав достаточно большую базу цен, появилась идея сформировать ТОП-10 самых дешевых магазинов для каждой категории товаров.
Разберем принципы формирования данного списка на примере категории Холодильники:
Пробегаемся по каждому товару категории.
Каждому магазину, продающему данный товар, начисляем баллы от 0-дорого, до 1-дешево.
Алгоритм расчета баллов score = (maxprice-price)/(maxprice-minprice)
Вычисляем среднее от баллов набранных каждым магазином.
Удаляем магазины продающие очень мало товаров данной категории.

Например, для категории телевизоры, получился такой список:
Название
Кол-во баллов
Рейтинг на Yandex.Market
Кол-во оценок на Yandex.Market
КРАСНАЯ КНОПКА
0,877
5
697
Топтел
0,854
5
1358
Pleer.ru
0,853
4
52711
Greenbook
0,853
5
200
ОГО
0,832
5
4009
Technosteps.ru
0,832
5
294
Soundbreeze
0,812
5
662
ELECTROGOR
0,808
5
6445
ЦИФРОВИК
0,805
5
460
ЭЛЕКТРОЗОН
0,804
5
1664


4. Зачем же я всё это писал?


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

UPD 01.12.2015: Добавил возможность уведомления при снижении цены ниже определенного порога.
Теги:
Хабы:
Всего голосов 33: ↑31 и ↓2+29
Комментарии62

Публикации