Ответ 1
Принятый ответ на этот вопрос хорош, насколько это возможно, но на самом деле он не описывает, как оценить недоумение в наборе данных валидации и как использовать перекрестную проверку.
Использование недоумения для простой проверки
Perplexity - это показатель того, насколько хорошо вероятностная модель подходит для нового набора данных. В пакете topicmodels
R просто вписывается в функцию perplexity
, которая принимает в качестве аргументов ранее подходящую модель темы и новый набор данных и возвращает один номер. Чем ниже, тем лучше.
Например, разделение данных AssociatedPress
на обучающий набор (75% строк) и набор проверки (25% строк):
# load up some R packages including a few we'll need later
library(topicmodels)
library(doParallel)
library(ggplot2)
library(scales)
data("AssociatedPress", package = "topicmodels")
burnin = 1000
iter = 1000
keep = 50
full_data <- AssociatedPress
n <- nrow(full_data)
#-----------validation--------
k <- 5
splitter <- sample(1:n, round(n * 0.75))
train_set <- full_data[splitter, ]
valid_set <- full_data[-splitter, ]
fitted <- LDA(train_set, k = k, method = "Gibbs",
control = list(burnin = burnin, iter = iter, keep = keep) )
perplexity(fitted, newdata = train_set) # about 2700
perplexity(fitted, newdata = valid_set) # about 4300
Недоумение выше для набора проверки, отличного от набора тренировок, потому что темы были оптимизированы на основе набора тренировок.
Использование недоумения и кросс-валидации для определения большого количества тем
Расширение этой идеи до перекрестной проверки просто. Разделите данные на разные подмножества (скажем, 5), и каждое подмножество получает один оборот в качестве набора проверки и четыре витка как часть набора тренировок. Тем не менее, это действительно вычислительно интенсивно, особенно при опробовании большего количества тем.
Возможно, вы сможете использовать caret
, но я подозреваю, что он еще не обрабатывает моделирование тем. В любом случае, это то, что я предпочитаю делать сам, чтобы быть уверенным, что я понимаю, что происходит.
В приведенном ниже коде, даже при параллельной обработке на 7 логических процессорах, потребовалось 3,5 часа для работы на моем ноутбуке:
#----------------5-fold cross-validation, different numbers of topics----------------
# set up a cluster for parallel processing
cluster <- makeCluster(detectCores(logical = TRUE) - 1) # leave one CPU spare...
registerDoParallel(cluster)
# load up the needed R package on all the parallel sessions
clusterEvalQ(cluster, {
library(topicmodels)
})
folds <- 5
splitfolds <- sample(1:folds, n, replace = TRUE)
candidate_k <- c(2, 3, 4, 5, 10, 20, 30, 40, 50, 75, 100, 200, 300) # candidates for how many topics
# export all the needed R objects to the parallel sessions
clusterExport(cluster, c("full_data", "burnin", "iter", "keep", "splitfolds", "folds", "candidate_k"))
# we parallelize by the different number of topics. A processor is allocated a value
# of k, and does the cross-validation serially. This is because it is assumed there
# are more candidate values of k than there are cross-validation folds, hence it
# will be more efficient to parallelise
system.time({
results <- foreach(j = 1:length(candidate_k), .combine = rbind) %dopar%{
k <- candidate_k[j]
results_1k <- matrix(0, nrow = folds, ncol = 2)
colnames(results_1k) <- c("k", "perplexity")
for(i in 1:folds){
train_set <- full_data[splitfolds != i , ]
valid_set <- full_data[splitfolds == i, ]
fitted <- LDA(train_set, k = k, method = "Gibbs",
control = list(burnin = burnin, iter = iter, keep = keep) )
results_1k[i,] <- c(k, perplexity(fitted, newdata = valid_set))
}
return(results_1k)
}
})
stopCluster(cluster)
results_df <- as.data.frame(results)
ggplot(results_df, aes(x = k, y = perplexity)) +
geom_point() +
geom_smooth(se = FALSE) +
ggtitle("5-fold cross-validation of topic modelling with the 'Associated Press' dataset",
"(ie five different models fit for each candidate number of topics)") +
labs(x = "Candidate number of topics", y = "Perplexity when fitting the trained model to the hold-out set")
Мы видим в результатах, что 200 тем слишком много, и некоторые из них слишком сложны, а 50 слишком мало. Из числа опробованных тем, 100 является лучшим, с наименьшим средним недоумением на пяти разных наборах простоя.