Методи машинного навчання для оцінки віку користувачів на основі сайтів у Facebook, які їм подобаються


25

У мене є база даних з моєї програми Facebook, і я намагаюся використовувати машинне навчання для оцінки віку користувачів, виходячи з того, які сайти Facebook їм подобаються.

У моїй базі даних є три найважливіші характеристики:

  • розподіл за віком у моєму навчальному наборі (загалом 12 тис. користувачів) спрямований на молодших користувачів (тобто у мене 1157 користувачів у віці 27 років та 23 користувачі у віці 65 років);

  • на багатьох сайтах не більше 5 любителів (я відфільтрував FB сайти з менш ніж 5 любителями).

  • є набагато більше функцій, ніж зразки.

Отже, мої запитання: яка стратегія ви б запропонували підготувати дані для подальшого аналізу? Чи слід проводити якесь зменшення розмірності? Який метод ML найкраще використовувати в цьому випадку?

В основному я використовую Python, тому специфічні для Python підказки будуть дуже вдячні.


1
Коли ви говорите "набагато більше функцій, ніж зразки", я припускаю, що ви маєте на увазі, що унікальна кількість сайтів, що сподобалися, >> кількість користувачів. Це також стосується кореневого домену сайтів? тобто це кількість URL-адрес youtube.com чи cnn.com на веб-сайтах чи вони вже пов’язані з доменом? Я схиляюся до зменшення розмірності, згортаючи URL-адреси для коренів домену, а не конкретні сторінки, якщо це можливо.
cwharland

Дякую за відповідь Кількість функцій (унікальних сайтів, що сподобалися) становить 32 к, а кількість зразків (користувачів) - 12 к. Особливості - це Сторінки Facebook, тому не потрібно визначати URL-адреси. Користувач може любити facebook.com/cnn чи ні. Мені подобається ідея спробувати оцінити вік користувачів на основі посилань, якими вони поділяються :)
Войцех Вальчак

Аааа, я неправильно прочитав опис сподобалися сайтів. Дякуємо за роз’яснення.
cwharland

Відповіді:


16

Одне з чого слід почати - k-NN. Ідея тут полягає в тому, що у вас є матриця користувача / елемента, а для деяких користувачів - вік. Вік людини в матриці елемента користувача може бути добре визначений чимось на зразок середнього або середнього віку деяких найближчих сусідів у просторі предмета.

Отже, кожен користувач виражається як вектор у просторі предмета, знаходите k найближчих сусідів і присвоюйте цьому вектору деяку підсумкову статистику найближчого віку сусідів. Ви можете обрати k на відстані відрізку або, більш реалістично, шляхом ітеративного присвоєння вікам витримці поїзда і вибору k, що мінімізує помилку в цьому призначенні.

Якщо розмірність є проблемою, ви можете легко виконати зменшення цієї установки шляхом розкладання на одне значення, вибравши m векторів, які фіксують найбільшу дисперсію в групі.

У всіх випадках, оскільки кожна функція є двійковою, схоже, що косинусна схожість була б вашим переходом до метрики відстані.

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

Одне застереження, якщо віки, які ви маєте для поїздів, повідомляються про себе, можливо, вам доведеться виправити деякі з них. Люди у фейсбуці, як правило, повідомляють про віки за десятиліття, коли вони народились. Накресліть гістограму дати народження (отриману за віками) і подивіться, чи є у вас шипи в десятки років, як 70-ті, 80-ті, 90-ті.


Привіт, ваша відповідь досить схожа на мою фактичну стратегію. Я використовував sklearn.neighbors.KNeighborsRegressorкосинусну метрику на зменшеному SVD просторі (після застосування SVD середня помилка оцінки знизилася з ~ 6 років до ~ 4). Користувачі моєї бази даних мають вік 18-65 років (старші користувачі були відфільтровані), тому існує 48 можливих класів. Цікаво, чи не занадто багато класів для kNN, і чи слід розглядати це як регресію чи проблему класифікації (я думаю, що обидва застосовні).
Войцех Вальчак

Я можу сказати, анекдотично, що я використовую для класів випадкові ліси, щоб підходити до декількох класів індивідуально, а потім комбінувати результати кожної з цих моделей різними способами. У цьому випадку ви навіть можете подумати про присвоєння попередніх ймовірностей віку кожного користувача за допомогою kNN, а потім пройти через кожну модель на основі класу, використовувати ці показники, щоб оновити попередні ймовірності для кожного класу та вибрати найбільш ймовірний клас з цих плакатів. Це звучить як надто ускладнення, але в гіршому випадку ви б мали точність kNN.
cwharland

7

Нещодавно я робив подібний проект у Python (прогнозував думки, використовуючи дані, подібні FB), і мав хороші результати при наступному базовому процесі:

  1. Прочитайте у навчальному наборі (n = N) шляхом повторення через розділені комами, як записи, по черзі, та використовуйте лічильник, щоб визначити найпопулярніші сторінки
  2. Для кожної з найпопулярніших сторінок K (я використав близько 5000, але ви можете пограти з різними значеннями), використовуйте pandas.DataFrame.isin, щоб перевірити, чи подобається кожній особі в навчальному наборі кожну сторінку, а потім складіть фрейм даних N x K результатів (я назву це xdata_train)
  3. Створіть серію (я буду називати її ydata_train), що містить усі змінні результати (на мій випадок, у вашому віці) з тим же індексом, що і xdata_train
  4. Налаштуйте випадковий класифікатор лісу через scikit-навчіться прогнозувати ydata_train на основі xdata_train
  5. Використовуйте крос-валідаційне тестування scikit-learn для налаштування параметрів та уточнення точності (налаштування кількості популярних сторінок, кількості дерев, мінімум розміру листя тощо)
  6. Виведіть випадковий класифікатор лісу та список найпопулярніших сторінок із солінням (або збережіть у пам’яті, якщо ви все робите відразу)
  7. Завантажте решту своїх даних, завантажте список популярних сторінок (якщо потрібно) та повторіть крок 2, щоб створити xdata_new
  8. Завантажте випадковий класифікатор лісу (якщо необхідно) і використовуйте його для прогнозування значень для даних xdata_new
  9. Виведіть прогнозовані бали у новий CSV або інший вихідний формат на ваш вибір

У вашому випадку вам потрібно буде замінити класифікатор на регресор (тому дивіться тут: http://scikit-learn.org/stable/modules/generated/sklearn.ensemble.RandomForestRegressor.html ), але в іншому випадку той самий процес повинен працювати без особливих проблем.

Також вам слід знати про найдивовижнішу особливість випадкових лісів на Python: миттєву паралелізацію! Ті з нас, хто почав це робити в R, а потім переїхали, завжди вражені, особливо коли ти працюєш на машині з кількома десятками ядер (див. Тут: http://blog.yhathq.com/posts/comparing- випадкові ліси-в-пітон-і-р.html ).

Нарешті, зауважте, що це був би ідеальний додаток для аналізу мережі, якщо у вас є дані про друзів, а також самих людей. Якщо ви можете проаналізувати вік друзів користувача, вік користувача майже напевно буде протягом року-двох середньої серед його друзів, особливо якщо користувачі досить молоді, щоб створити свої мережі друзів, поки ще школа (оскільки більшість буде однокласниками). Це передбачення, ймовірно, козир будь-якого, що ви отримаєте від моделювання --- це підручник з прикладом проблеми, коли потрібні дані> правильна модель кожен раз.

Удачі!


2
Одним із цікавих аспектів використання перших 5000 сайтів є той факт, що вони можуть бути непоганими в сегментації користувачів за віком. Найпопулярніші сайти за будівництвом - це ті, які відвідують усі. Тому вони не дуже добре сегментують ваших користувачів, оскільки всі можливі класифікації (епохи) співпрацюють з цими сайтами. Це подібне поняття до idf частини tf-idf. idf допомагає відфільтрувати шум "всі мають цю особливість". Як найбільш відвідувані сайти відносяться до особливостей у графіках вашої змінної важливості за допомогою RF?
cwharland

1
Влучне зауваження. Простим виправленням цього було б стратифікувати навчальний набір даних у вікових скриньках (наприклад, 13-16, 17-20, 21-24 тощо) та взяти верхню (K / J) сторінки для кожної групи. Це забезпечило б значне представництво кожної групи. Звичайно, буде кілька збігів у групах, тож якщо ви були дуже прискіпливі, ви, можливо, захочете взяти найкращі (K / J) унікальні сторінки для кожної групи, але я думаю, що це може бути надмірним.
Therriault

5

Ще одна пропозиція - перевірити логістичну регресію . Як додатковий бонус, ваги (коефіцієнти) моделі дадуть вам уявлення про те, які сайти залежать від віку.

Sklearn пропонує пакет sklearn.linear_model.LogisticRegression, який також призначений для обробки рідких даних.

Як зазначалося в коментарях, у цьому випадку з більшою кількістю вхідних змінних, ніж зразків, вам потрібно регулювати модель (за допомогою аргументу використовується sklearn.linear_model.LogisticRegressionpenalty='l1' ).


1
З LR вам доведеться робити кілька моделей для вікових кошиків, я думаю. Як би порівняти дві моделі для різних вікових скриньок, які передбачають одну й ту ж проблему щодо включення для користувача?
cwharland

1
Зауважте, що LR виходить з ладу, коли є більше змінних, ніж спостереження, і працює погано, якщо припущення моделі не виконані. Для його використання зменшення розмірності повинно бути першим кроком.
Крістофер Луден

1
@cwharland ви не повинні вважати змінну відповіді категоричною, оскільки вона є суцільною за своєю природою і дискретизована визначенням проблеми. Вважаючи це категоричним, це означатиме сказати алгоритму, що прогнозування віку 16, коли насправді це 17, є настільки ж серйозною помилкою, як і прогнозування 30, коли насправді 17 років. Вважаючи, що вона є постійною, гарантує, що невеликі помилки (16 проти 17) вважаються малими та великими помилками ( 30 проти 17) вважаються великими. Логістична регресія використовується в цьому випадку для прогнозування постійного значення, а не для оцінки задніх ймовірностей.
Даміенфрансуа

@ChristopherLouden Ви маєте рацію, що ванільний варіант логістичної регресії не підходить для випадку "великого p малого n", я мав би зазначити, що регуляризація є важливою в даному випадку. Я оновлюю свою відповідь. Але L1-регульований LR - це свого роду вибір функцій, тому я вважаю, що немає необхідності в попередньому кроці FS.
Даміенфрансуа

@damienfrancois: Я безумовно згоден. Мене трохи хвилює, що в цьому випадку LR буде занадто різко штрафувати проміжні значення. Здається, немає ніякої мотивації до відображення сигмоїдальної кривої, враховуючи, що вас не особливо цікавлять екстремальні вікові значення. Можливо, я неправильно трактую використання.
cwharland

4

Деякі дослідження від D. Nguyen та ін. спробуйте передбачити вік користувача щебета на основі твітів. Можливо, ви вважаєте їх корисними. Вони використовують логістичну та лінійну регресію.


3

Крім фантазійних методів, ви можете спробувати формулу Байєса

P (I | p1 ... pn) = P (p1 ... pn | I) P (I) / sum_i (P (p1 ... pn | i) P (i))

P (I | p1 ... pn) - це ймовірність того, що користувач належить до вікової групи I, якщо йому сподобалось p1, .., pn

P (i) - ймовірність того, що користувач належить до вікової групи i

P (p1 .. pn | i) - це ймовірність того, що користувачеві сподобалось p1, .., pn, якщо він належить до вікової групи i.

  • Ви вже маєте оцінку для P (i) за вашими даними: це лише частка користувачів у віковій групі I.
  • Щоб оцінити P (p1 ... pn | i), для кожної вікової групи я оцінюю ймовірність (частоту) p_ij на зразок сторінки j. Щоб p_ij не дорівнював нулю для всіх j, ви можете змішувати частоту для всієї сукупності з невеликою вагою.

  • Тоді log P (p1 ... pn | i) = sum (log p_ij, i = p1, .., pn) - сума на всіх сторінках, що подобається новому користувачеві. Ця формула може бути приблизно вірною, якщо припустити, що користувач самостійно любить сторінки своєї вікової групи.

  • Теоретично ви також повинні додати журнал (1-p_ij) для всіх, що йому не сподобалось, але на практиці ви повинні виявити, що сума журналу (1-p_ij) буде неактуально малою, тому вам також не знадобиться багато пам’яті.

Якщо ви чи хтось інший спробував це, будь ласка, прокоментуйте результат.


2

Це дуже цікава проблема.

Я зіткнувся з подібним, проаналізувавши фотографії, які користувачі завантажують у соціальну мережу. Я зробив такий підхід:

  • Замість того, щоб пов'язувати дані з віками (15 років, 27 років, ...), що я зробив, це встановити різні групи віків: менше 18, від 18 до 30 і більше 30 (це пов'язано з конкретною проблемою, яку ми мали обличчя, але ви можете вибирати будь-які інтервали ви хочете). Цей поділ дуже допомагає вирішити проблему.
  • Згодом я створив ієрархічну кластеризацію (поділу або сукупність). Тоді я вибираю ті гілки, у яких були користувачі із відомим віком (або груповим віком), а потім для цієї гілки я переніс цей же вік на цю групу.

Цей підхід є напівконтрольним навчанням, і я рекомендував його у випадку, якщо у вас є лише деякі дані.

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

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.