Создание матрицы перехода из данных потока кликов Википедии

#r #matrix #transition #markov-chains

#r #матрица #переход #цепи Маркова

Вопрос:

Я пытаюсь создать матрицу перехода из набора данных Википедии Clickstream. С помощью этого я хотел бы показать вероятность того, что пользователи перейдут из одной статьи Википедии в другую.

У меня есть фрейм данных, состоящий из трех столбцов. Source.category ссылается на заголовок исходной статьи, а target.category ссылается на заголовок целевой статьи. Третий столбец является «общим» и относится к количеству кликов (т. Е. количество раз, когда пользователи перешли из этой исходной статьи в целевую статью).

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

Вот краткое описание моего фрейма данных:

 source.category    target.category        total      
 Length:98          Length:98          Min.   :   21  
 Class :character   Class :character   1st Qu.:  684  
 Mode  :character   Mode  :character   Median : 2132  
                                       Mean   : 5395  
                                       3rd Qu.: 5296  
                                       Max.   :53378 
  

Было бы лучшим способом создать функцию?

trans.matrix <- функция(…)

Как бы выглядела эта функция?

И затем вставьте это в: trans.matrix(как.matrix (df))?

Ответ №1:

Я бы сделал это с помощью reshape2 пакета. Я создал минимальный набор данных, чтобы проиллюстрировать это:

 set.seed(42)

dataset <- expand.grid(letters[1:4], LETTERS[1:4])
dataset$total <- rpois(16, 1)

names(dataset) <- c("source.category", "target.category", "total")
# set the last row to the first row to illustrate fill and aggregate
dataset[16, ] <- dataset[1, ] 
  

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

 require(reshape2)

# reshape to wide format
res <- acast(
  dataset, # the dataset
  source.category ~ target.category, # the margins of the result
  value.var = "total", # which variable should be in the cells
  fill=0L, # fill empty cells with this value
  fun.aggregate = sum # aggregate double cells with this function
  )

# normalize rowSums to 1
res <- res / rowSums(res)

# this is your result
res
  

Редактировать: на больших наборах данных это займет вечность или даже завершится неудачей. Для больших наборов данных используйте разреженные матрицы из Matrix пакета, это намного быстрее и дает результат, который намного меньше в хранилище.

 require(Matrix)

dataset$target.category <- factor(dataset$target.category)
dataset$source.category <- factor(dataset$source.category)

res <- sparseMatrix(
  as.integer(dataset$target.category),
  as.integer(dataset$source.category),
  x = dataset$total
)

res <- res/rowSums(res)
  

Это достаточно быстро для всего набора данных для интерактивной работы.