середа, 30 липня 2014 р.

Acquire Valued Shoppers Challenge

Змагання на kaggle.com класні тим, що незалежно від вашої поточної робочої області можна працювати над реальними заваданнями будь-якої предметної області. Також з плюсів - великі датасети.
Тут опишу досвід роботи з  Acquire Valued Shoppers Challenge.
Завдання: на основі історії покупок, визначити ймовірність, що покупець, який отримав купон на знижку, купить товар повторно.



Структура вхідних даних:
Таблиці:
  • transactions.csv - історія транзакцій всіх клієнтів (300 тисяч) мінімум за рік до того, як їм запропонували купон на знижку(отримана пропозиція - останній запис, середній клієнт має 1000 транзакцій) - 350 мільйонів записів.
  • offers.csv - інформація про купони на знижку(offers) - 37 записів.
  • trainHistory.csv - інформація, який купон(offer) запропоновано клієнту, та його реакцію (повернувся чи ні, якщо так - кількість раз) - 160 тисяч записів.
  • testHistory.csv - інформація, який купон(offer) запропоновано клієнту - 150 тисяч записів.
Опис таблиць:
history:
id - ідентифікатор покупця
chain - код магазину
offer - ідентифікатор купона
market - ідентифікатор георафічного регіону
repeattrips - кількість повторних покупок після отримання пропозиції купона
repeater - повернувся чи ні після отирмання пропозиції купона
offerdate - дата отирмання пропозиції
transactions:
id - дивись вище
chain - дивись вище
dept - узагальнена група категорії(category), наприклад "вода".
category - категорія (напр. "газована вода")
company - ідентифікатор компанії, яка продала товар
brand - ідентифікатор бренду товару
date - дата покупки
productsize - кількість купленого товару (напр. 3 пляшки води)
productmeasure - одиниці вимірювання товару (кг, л)
purchasequantity - кількість куплених одиниць
purchaseamount - сума покупки (може бути і від'ємною, якщо покупець повернув товар пізніше)
offers: 
offer - дивись вище
category -дивись вище
quantity - кількість товару, яку необхідно придбати, щоб отримати знажку
company - дивись вище
offervalue - сума прпозиції
brand - дивись вище

Перша проблема, яку необхідно вирішити: transactions.csv розміром 20 Гб і має 350 млн. записів. Вирішується доволі просто - завантаженням у базу даних. Була вибрана Vertica.
Крім того, ще налаштувала зв'язок між R і базою через JDBC, що дозволило працювати з даними не лише вокристовуючи можливості SQL, але й R (про процес налаштування можна прочитати тут).

Бенчмарки:
  1. Для всіх користувачів вказати ймовірність повторного повернення 0 або 1 - точність 0.5 (що означає, що кількість тих що повернулись та тих, що не повернулись у тестсеті однакова)
  2. Для користувача, який придбав товар  бренду, вказаного в пропозиції принаймі один раз ймовірність повернення 1, для решти - 0. Точність 0.52517
  3. ля користувача, який придбав товар  бренду, компанії та категорії вказаних у пропозиції принаймі один раз ймовірність повернення 1, для решти - 0. Точність - 0.55294
Робоча гіпотеза:
Повернувся користувач чи ні - це міра його лояльності. Виглядає логічним виразити цю лояльність як залежність від кількості всіх покупок цього користувача та покупок конкретного товару. В якості характеристики товару можна обрати три поля: company, brand, category. Також мірою лояльності може бути і розмір повернень всіх товарів/конкретного товару за певний період.
Також логічно було б використовувати властивості конкретних пропозицій, але враховуючи, що пропозицій 37, а користувачів 300 000 (тобто варіативність пропозицій надзвичайно мала і дасть нам додаткової інформації).
Отже, для кожного користувача формуємо нові фічі:
  • кількість покупок/повернень всього/за останні 30/за останні 60/за останні 90/за останні 180 днів
  • кількість покупок/повернень бренду, вказаному в пропозиції всього/за останні 30/за останні 60/за останні 90/за останні 180 днів
  • кількість покупок/повернень категорії, вказаній у пропозиції всього/за останні 30/за останні 60/за останні 90/за останні 180 днів
  • кількість покупок/повернень компанії, вказаній пропозиції
  • кількість покупок/повернень цих категорії, компанії та бренду всього/за останні 30/за останні 60/за останні 90/за останні 180 днів
  • кількість покупок/повернень цих категорії та бренду всього/за останні 30/за останні 60/за останні 90/за останні 180 днів
  • кількість покупок/повернень цих компанії та бренду всього/за останні 30/за останні 60/за останні 90/за останні 180 днів
  • кількість покупок/повернень цих компанії та категорії всього/за останні 30/за останні 60/за останні 90/за останні 180 днів
Технічно це робиться записом результату SQL запиту в .csv файл з допомогою R.
В зв'язку з тим, що ми маємо в таблиці trainHistory два поля: repeater - бінарне і repeattrips - числове можемо це виразити як задачу класифікації, так і регресії.
Оскільки дані з кількістю покупок (всього і за певні періоди) мають дуже високу варіативність (тобто шуму) і 70% значень  для поля repeater має значення 0 (на практиці, це означає що алгоритми ML тяжіють до передбчення значення repeater = 0 в більшості випадків ) - досягти навіть точності 3-го бенчмарку не вдалося.
Більш вдалою виявилась Гіпотеза 2:
Для зменшення шуму дані, які мають високу варіативність (і, відповідно, вносять занадто багато шуму) у було перетворено у вектор (1, 2, 3, 4), який реперезентує відповідну квартиль. (положення в квартилі визначаєтьтся після об'єднання тестового і тренінг датасетів). Дані, які, навапаки мають малу варіативність і не можуть бути розбиті на квартилі - перетворюємо у вектор (0, 1), де 1- значення, які більші 0. Точність на цьому етапі 0.58918 (алгоритм - логістична регресія). 
Подібний підхід описаний на форумі тут: http://www.kaggle.com/c/acquire-valued-shoppers-challenge/forums/t/7688/feature-engineering-and-beat-the-benchmark-0-59347. Найкращий результат такого feature engineering 0.59347 (результат переможця - 0.6314).
За 2 тижні до закінчення змагання у з'явилася Гіпотеза 3, яка буда найбільш багатообіцяючою, але я  не встигла з обчисленнями для її перевірки. Це використання підходів, які широко використовуються при побудові персоналізованих рекомендаційних систем. Алгоритм наступний:

  1. для кожного користувача знайти N подібних за поведінкою користувачів (в нащому випадку подібність - кількість покупок бренду або категорії + компанії + бренду)
  2. визначити, який відсоток з цих подібних за купівельною поведінкою користувачів раніше купував бренд, вказаний у пропозиції та бренд+категорія+ компанія, вказані у пропозиції
  3. В якості фіч використовувати:
  • придбав товар цього бренду, компанії та категорії принаймі один раз
  • придбав товар цього бренду принаймі один раз
  • відсоток  від N подібних користувачів, які придбали бренд, вказаний в пропозиції,  хоча б один раз
  • відсоток  від N подібних користувачів, які придбали товар бренду, категорії та компанії, вказаних в пропозиції, хоча б один раз.
Спочатку крок 1 було імплементовано на R, для оптимізації обчислень було використано паралелізацію між ядрами. Оцінка часу прорахунку подібностей між користувачами в цьому випадку (на 4 ядрах Core i5, 2.6 Ггц) - 15-20 днів, що було занадто багато. Тому алгоритм обрахунку подібності між користувачами було переписано на Pig Latin.
Опис цього процесу, а також як запустити цей обрахунок на Amazon Web Services використовуючи Elastic Map Reduce читайте у продовженні. 




2 коментарі:

  1. Привіт! Вже кілька місяців переглядаю Ваш блог, також цікавлюсь аналізом даних.

    По темі маю питання, якщо можна  Чому не хочете використати інструментарій Apache Mahout для побудови рекомендаційної системи? Наскільки я зрозумів, Ви добре з нею знайомі.

    Я пробував зробити схожу річ на SQL Server та Statistica, але на першому не вистачило місця на харді (обсяг тимчасової таблиці перевалив за 200 Гб, і я вирішив припинити це діло), друга - просто висіла. Дані брав лише за останні три місяці. Потім вирішив спробувати інше ПЗ, вибір впав на Mahout, але зрозумів, що для того, щоб в ньому розібратися і просто встановити, потрібно немало часу. А вже піджимали терміни на Курсері.

    Наскільки зрозумів з обговорення на тематичному форумі, ніхто з лідерів навіть не пробував будувати РС, всі зосередились на побудові характеристик.
    Як на мене, результат лідера досить слабенький, досліджувалась лише лояльність покупців. Практичний результат від такого дослідження сумнівний – акційні товари будуть розповсюджуватись серед вже й так лояльних покупців. Рекомендаційна система могла б запропонувати кандидатів, які навіть не куштували цей продукт, але з великою ймовірністю «підсіли» би на нього.

    Ви ж памятаєте, що серед акційних товарів були такі, які знову купляли 40% покупців, а були такі, до яких вертались лише 10%. Чому?

    Хотілось би, щоб Ви своє дослідження довели до кінця – дуже цікаво, чи РС дасть фору. Я також планую повернутись до цього дослідження після освоєння нового інструментарію та закінчення кількох MOOC.

    ВідповістиВидалити
    Відповіді
    1. Apache Mahout не так важко встановити як кастомізувати )) Якщо хочете з ним ознаймитись - найкраще починати з http://www.manning.com/owen/.
      Планую довести це дослідження до кінця десь у вересні.
      Можемо обговрити результати )

      Видалити