#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)
Это достаточно быстро для всего набора данных для интерактивной работы.