Статьи

R: Особенности проектирования для линейной модели

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

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

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

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

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

Первое, что я решил сделать, — это ввести данные для всех лондонских собраний по NoSQL, а не только по Neo4j, чтобы дать себе немного больше данных для работы.

Членство в группах

Сделав это, из визуального осмотра стало ясно, что группы встреч с большинством участников (например, Data Science London, Big Data London), похоже, получили наибольшую явку.

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

Я сгенерировал эту функцию с помощью комбинации запроса Neo4j и кода R, в результате чего этот кадр данных был представлен в виде файла CSV .

Мы можем быстро просмотреть его, чтобы увидеть некоторые события и членство в группе в то время:

> df = read.csv("/tmp/membersWithGroupCounts.csv")
> df$eventTime = as.POSIXct(df$eventTime)
> df %>% sample_n(10) %>% select(event.name, g.name, eventTime, groupMembers, rsvps)
 
                                                                  event.name                                   g.name           eventTime groupMembers rsvps
23  Scoring Models, Apache Drill for querying structured & unstructured data                      Data Science London 2014-09-18 18:30:00         3466   159
421                                                      London Office Hours                London MongoDB User Group 2012-08-22 17:00:00          468     6
304                            MongoDB University Study Group London Meet up                London MongoDB User Group 2014-07-16 17:00:00         1256    23
43                                                           December Meetup          London ElasticSearch User Group 2014-12-10 18:30:00          721   126
222                                                          Intro to Graphs                Neo4j - London User Group 2014-09-03 18:30:00         1453    39
207                              Intro to Machine Learning with Scikit-Learn                            Women in Data 2014-11-11 18:15:00          574    41
168                                        NoSQL panel and LevelDB + Node.js                             London NoSQL 2014-04-15 18:30:00          183    51
443                                                      London Office Hours                London MongoDB User Group 2012-11-29 17:00:00          590     3
79                                  Apache Cassandra 1.2 with Jonathan Ellis                         Cassandra London 2013-03-06 19:00:00          399    95
362                                                          Span conference Span: scalable and distributed computing 2014-10-28 09:00:00           67    13

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

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

ggplot(aes(x = groupMembers, y = rsvps), data = df) + 
  geom_point()
2014 12 28 21 02 21

Похоже, что есть положительная корреляция между этими двумя переменными, но давайте создадим линейную модель с одной переменной, чтобы увидеть, как объясняется большая часть вариации:

> fit = lm(rsvps ~ groupMembers, data = df)
> fit$coef
 (Intercept) groupMembers 
 20.03579637   0.05382738

Наше линейное модельное уравнение поэтому:

rsvps = 20,03579637 + 0,05382738 (группа членов)

Давайте посмотрим, насколько хорошо коррелируют наши прогнозируемые RSVP и фактические RSVP:

> df$predictedRSVPs = predict(fit, df)
> with(df, cor(rsvps, predictedRSVPs))
[1] 0.6263096

Не плохо! Между этими переменными существует довольно сильная корреляция, хотя она не идеальна.

Часы в день

В моей первой модели я рассматривал время как категориальную переменную, но Антониос отметил, что зачастую легче понять взаимосвязь между переменными, если они являются непрерывными, поэтому я преобразовал время события следующим образом:

df$hoursIntoDay = as.numeric(df$eventTime - trunc(df$eventTime, "day"), units="hours")

Давайте посмотрим, как это соотносится с подсчетом RSVP:

ggplot(aes(x = hoursIntoDay, y = rsvps), data = df) + 
  geom_point()
2014 12 28 21 27 48

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

> fit = lm(rsvps ~ hoursIntoDay, data = df)
> fit$coef
 (Intercept) hoursIntoDay 
   -18.79895      4.12984 
> 
> df$predictedRSVPs = predict(fit, df)
> with(df, cor(rsvps, predictedRSVPs))
[1] 0.181472

Расстояние от центра Лондона

Затем я попробовал функцию, основанную на расположении места проведения мероприятий. Предполагалось, что если место будет ближе к центру Лондона, люди будут чаще посещать.

Чтобы рассчитать это расстояние, я использовал функцию distHaversine из пакета geosphere, как показано в предыдущем сообщении в блоге .

Давайте посмотрим на график для этой переменной:

ggplot(aes(x = distanceFromCentre, y = rsvps), data = df) + 
  geom_point()
2014 12 28 21 37 41

Трудно сказать многое из этого сюжета, в основном потому, что большинство точек сгруппированы вокруг отметки 2500 метров, которая представляет объекты Shoreditch. Давайте подключим его к линейной модели и посмотрим, что мы придумаем:

> fit = lm(rsvps ~ distanceFromCentre, data = df)
> fit$coef
       (Intercept) distanceFromCentre 
      57.243646619       -0.001310492 
> 
> df$predictedRSVPs = predict(fit, df)
> with(df, cor(rsvps, predictedRSVPs))
[1] 0.02999708

Интересно, что здесь почти нет корреляции, что меня удивило. Я попытался объединить эту переменную в модели с несколькими переменными, но она все еще не оказала большого влияния, поэтому я думаю, что мы пока оставим эту переменную.

Это то же самое, что я сделал в данный момент, и, несмотря на то, что я потратил на это немало времени, я до сих пор не очень-то объяснил разницу в скорости передачи RSVP!

Мне удалось определить некоторые способы, с помощью которых я смог придумать новые функции, чтобы попробовать их:

  • Прочитайте, что делают другие люди, например, у меня есть некоторые идеи для переменных лагов (например, сколько людей пошло на вашу предыдущую встречу), прочитав об этой линейной модели бейсбола
  • Поговорите с другими людьми о вашей модели — у них часто бывают идеи, о которых вы даже не думаете, что слишком глубоко вникли в проблему.
  • Посмотрите, какие данные у вас уже есть, попробуйте включить их и посмотрите, к чему это приведет

Следующее направление, которое я начал изучать, — это тематическое моделирование, поскольку у меня есть гипотеза о том, что люди проводят RSVP для мероприятий, основанных на содержании переговоров, но я не уверен в том, как лучше это сделать.

Моя текущая мысль состоит в том, чтобы извлечь некоторые темы / термины, следуя примеру из главы 6 « Машинное обучение для хакеров» .